From ce8c582c6121469db64197b1b4aa4e4c377c660f Mon Sep 17 00:00:00 2001
From: Frank Wunderlich <frank-w@public-files.de>
Date: Tue, 23 Oct 2018 13:12:12 +0200
Subject: [PATCH] [wifi] adding driver-folder

---
 drivers/misc/Kconfig                          |     1 +
 drivers/misc/Makefile                         |     1 +
 drivers/misc/mediatek/Kconfig                 |    11 +
 drivers/misc/mediatek/Makefile                |    19 +
 drivers/misc/mediatek/btif/Kconfig            |     4 +
 drivers/misc/mediatek/btif/Makefile           |    33 +
 drivers/misc/mediatek/btif/common/Makefile    |    31 +
 .../misc/mediatek/btif/common/btif_dma_plat.c |  1436 ++
 drivers/misc/mediatek/btif/common/btif_plat.c |  1396 ++
 .../misc/mediatek/btif/common/inc/mtk_btif.h  |   370 +
 .../mediatek/btif/common/inc/mtk_btif_exp.h   |   280 +
 drivers/misc/mediatek/btif/common/mtk_btif.c  |  3472 +++++
 .../misc/mediatek/btif/common/mtk_btif_exp.c  |   786 ++
 .../btif/common/plat_inc/btif_dma_priv.h      |   164 +
 .../btif/common/plat_inc/btif_dma_pub.h       |   197 +
 .../mediatek/btif/common/plat_inc/btif_priv.h |   105 +
 .../mediatek/btif/common/plat_inc/btif_pub.h  |   237 +
 .../btif/common/plat_inc/plat_common.h        |   307 +
 drivers/misc/mediatek/connectivity/Kconfig    |   299 +
 drivers/misc/mediatek/connectivity/Makefile   |    41 +
 .../mediatek/connectivity/common/Makefile     |    23 +
 .../common/common_detect/Makefile             |    47 +
 .../common/common_detect/drv_init/Makefile    |    22 +
 .../common_detect/drv_init/ant_drv_init.c     |    38 +
 .../drv_init/bluetooth_drv_init.c             |    35 +
 .../common_detect/drv_init/common_drv_init.c  |   103 +
 .../common_detect/drv_init/conn_drv_init.c    |    80 +
 .../common_detect/drv_init/fm_drv_init.c      |    33 +
 .../common_detect/drv_init/gps_drv_init.c     |    35 +
 .../common_detect/drv_init/inc/ant_drv_init.h |    20 +
 .../drv_init/inc/bluetooth_drv_init.h         |    20 +
 .../drv_init/inc/common_drv_init.h            |    31 +
 .../drv_init/inc/conn_drv_init.h              |    18 +
 .../common_detect/drv_init/inc/fm_drv_init.h  |    20 +
 .../common_detect/drv_init/inc/gps_drv_init.h |    19 +
 .../drv_init/inc/wlan_drv_init.h              |    30 +
 .../common_detect/drv_init/wlan_drv_init.c    |    74 +
 .../common/common_detect/mtk_wcn_stub_alps.c  |   605 +
 .../common/common_detect/sdio_detect.c        |   269 +
 .../common/common_detect/sdio_detect.h        |    43 +
 .../common/common_detect/wmt_detect.c         |   380 +
 .../common/common_detect/wmt_detect.h         |   114 +
 .../common/common_detect/wmt_detect_pwr.c     |   232 +
 .../common/common_detect/wmt_detect_pwr.h     |    29 +
 .../common/common_detect/wmt_gpio.c           |   371 +
 .../common/common_detect/wmt_gpio.h           |   103 +
 .../common/common_detect/wmt_stp_exp.c        |   480 +
 .../common/common_detect/wmt_stp_exp.h        |   610 +
 .../connectivity/common/conn_soc/Makefile     |    65 +
 .../common/conn_soc/core/Makefile             |    22 +
 .../common/conn_soc/core/btm_core.c           |  1376 ++
 .../common/conn_soc/core/dbg_core.c           |    13 +
 .../common/conn_soc/core/include/btm_core.h   |   133 +
 .../common/conn_soc/core/include/dbg_core.h   |    69 +
 .../common/conn_soc/core/include/psm_core.h   |   251 +
 .../common/conn_soc/core/include/stp_core.h   |   629 +
 .../common/conn_soc/core/include/stp_wmt.h    |    89 +
 .../common/conn_soc/core/include/wmt_conf.h   |    74 +
 .../common/conn_soc/core/include/wmt_core.h   |   428 +
 .../common/conn_soc/core/include/wmt_ctrl.h   |   120 +
 .../common/conn_soc/core/include/wmt_func.h   |   140 +
 .../common/conn_soc/core/include/wmt_ic.h     |   122 +
 .../common/conn_soc/core/include/wmt_lib.h    |   300 +
 .../common/conn_soc/core/psm_core.c           |  1890 +++
 .../common/conn_soc/core/stp_core.c           |  3358 +++++
 .../common/conn_soc/core/wmt_conf.c           |   529 +
 .../common/conn_soc/core/wmt_core.c           |  2521 ++++
 .../common/conn_soc/core/wmt_ctrl.c           |  1019 ++
 .../common/conn_soc/core/wmt_func.c           |   713 +
 .../common/conn_soc/core/wmt_ic_soc.c         |  2452 ++++
 .../common/conn_soc/core/wmt_lib.c            |  1938 +++
 .../common/conn_soc/include/stp_exp.h         |   252 +
 .../common/conn_soc/include/wmt.h             |    19 +
 .../common/conn_soc/include/wmt_exp.h         |   329 +
 .../common/conn_soc/include/wmt_plat.h        |   295 +
 .../common/conn_soc/linux/Makefile            |     6 +
 .../conn_soc/linux/include/bgw_desense.h      |    74 +
 .../common/conn_soc/linux/include/osal.h      |   349 +
 .../conn_soc/linux/include/osal_typedef.h     |    90 +
 .../common/conn_soc/linux/include/wmt_idc.h   |    97 +
 .../common/conn_soc/linux/pri/Makefile        |    21 +
 .../conn_soc/linux/pri/include/stp_btif.h     |    31 +
 .../conn_soc/linux/pri/include/stp_dbg.h      |   316 +
 .../conn_soc/linux/pri/include/wmt_dev.h      |    71 +
 .../common/conn_soc/linux/pri/stp_btif.c      |   279 +
 .../common/conn_soc/linux/pri/stp_dbg.c       |  2061 +++
 .../common/conn_soc/linux/pri/stp_exp.c       |   279 +
 .../common/conn_soc/linux/pri/wmt_dev.c       |  2566 ++++
 .../common/conn_soc/linux/pri/wmt_exp.c       |   610 +
 .../common/conn_soc/linux/pub/Makefile        |    27 +
 .../common/conn_soc/linux/pub/bgw_desense.c   |   153 +
 .../common/conn_soc/linux/pub/osal.c          |  1211 ++
 .../common/conn_soc/linux/pub/stp_chrdev_bt.c |   899 ++
 .../conn_soc/linux/pub/wmt_chrdev_wifi.c      |   668 +
 .../common/conn_soc/linux/pub/wmt_idc.c       |   307 +
 .../common/conn_soc/mt7623/Makefile           |    25 +
 .../mt7623/include/mtk_wcn_consys_hw.h        |   287 +
 .../conn_soc/mt7623/mtk_wcn_consys_hw.c       |   738 ++
 .../common/conn_soc/mt7623/wmt_plat_alps.c    |  1071 ++
 .../misc/mediatek/connectivity/wlan/Makefile  |     8 +
 .../mediatek/connectivity/wlan/gen2/Makefile  |   237 +
 .../connectivity/wlan/gen2/common/debug.c     |   165 +
 .../connectivity/wlan/gen2/common/dump.c      |   345 +
 .../connectivity/wlan/gen2/common/wlan_bow.c  |  3442 +++++
 .../connectivity/wlan/gen2/common/wlan_lib.c  |  6240 +++++++++
 .../connectivity/wlan/gen2/common/wlan_oid.c  | 11050 ++++++++++++++++
 .../connectivity/wlan/gen2/common/wlan_p2p.c  |  1654 +++
 .../wlan/gen2/include/CFG_Wifi_File.h         |   238 +
 .../connectivity/wlan/gen2/include/config.h   |  1628 +++
 .../connectivity/wlan/gen2/include/debug.h    |   466 +
 .../connectivity/wlan/gen2/include/link.h     |   368 +
 .../wlan/gen2/include/mgmt/aa_fsm.h           |   188 +
 .../wlan/gen2/include/mgmt/ais_fsm.h          |   573 +
 .../wlan/gen2/include/mgmt/assoc.h            |   112 +
 .../wlan/gen2/include/mgmt/auth.h             |   125 +
 .../wlan/gen2/include/mgmt/bow_fsm.h          |   184 +
 .../connectivity/wlan/gen2/include/mgmt/bss.h |   265 +
 .../connectivity/wlan/gen2/include/mgmt/cnm.h |   258 +
 .../wlan/gen2/include/mgmt/cnm_mem.h          |  1164 ++
 .../wlan/gen2/include/mgmt/cnm_scan.h         |   169 +
 .../wlan/gen2/include/mgmt/cnm_timer.h        |   235 +
 .../wlan/gen2/include/mgmt/hem_mbox.h         |   446 +
 .../wlan/gen2/include/mgmt/hs20.h             |   148 +
 .../connectivity/wlan/gen2/include/mgmt/mib.h |   153 +
 .../wlan/gen2/include/mgmt/p2p_assoc.h        |    55 +
 .../wlan/gen2/include/mgmt/p2p_bss.h          |    56 +
 .../wlan/gen2/include/mgmt/p2p_fsm.h          |  2190 +++
 .../wlan/gen2/include/mgmt/p2p_func.h         |   155 +
 .../wlan/gen2/include/mgmt/p2p_ie.h           |   156 +
 .../wlan/gen2/include/mgmt/p2p_rlm.h          |    74 +
 .../wlan/gen2/include/mgmt/p2p_rlm_obss.h     |    64 +
 .../wlan/gen2/include/mgmt/p2p_scan.h         |    81 +
 .../wlan/gen2/include/mgmt/p2p_state.h        |    43 +
 .../wlan/gen2/include/mgmt/privacy.h          |   230 +
 .../wlan/gen2/include/mgmt/rate.h             |    93 +
 .../connectivity/wlan/gen2/include/mgmt/rlm.h |   396 +
 .../wlan/gen2/include/mgmt/rlm_domain.h       |   557 +
 .../wlan/gen2/include/mgmt/rlm_obss.h         |   150 +
 .../wlan/gen2/include/mgmt/rlm_protection.h   |   122 +
 .../wlan/gen2/include/mgmt/rlm_txpwr_init.h   |  1213 ++
 .../wlan/gen2/include/mgmt/roaming_fsm.h      |   171 +
 .../connectivity/wlan/gen2/include/mgmt/rsn.h |   271 +
 .../wlan/gen2/include/mgmt/scan.h             |   988 ++
 .../wlan/gen2/include/mgmt/sec_fsm.h          |   233 +
 .../wlan/gen2/include/mgmt/stats.h            |   368 +
 .../wlan/gen2/include/mgmt/swcr.h             |   187 +
 .../wlan/gen2/include/mgmt/tdls.h             |   262 +
 .../wlan/gen2/include/mgmt/wapi.h             |   104 +
 .../wlan/gen2/include/mgmt/wlan_typedef.h     |    87 +
 .../connectivity/wlan/gen2/include/mgmt/wnm.h |    95 +
 .../wlan/gen2/include/nic/adapter.h           |  1506 +++
 .../connectivity/wlan/gen2/include/nic/bow.h  |   322 +
 .../wlan/gen2/include/nic/cmd_buf.h           |   150 +
 .../connectivity/wlan/gen2/include/nic/hal.h  |   618 +
 .../wlan/gen2/include/nic/hif_rx.h            |   220 +
 .../wlan/gen2/include/nic/hif_tx.h            |   214 +
 .../connectivity/wlan/gen2/include/nic/mac.h  |  2323 ++++
 .../wlan/gen2/include/nic/mtreg.h             |   272 +
 .../connectivity/wlan/gen2/include/nic/nic.h  |   498 +
 .../wlan/gen2/include/nic/nic_rx.h            |   420 +
 .../wlan/gen2/include/nic/nic_tx.h            |   642 +
 .../connectivity/wlan/gen2/include/nic/p2p.h  |   192 +
 .../wlan/gen2/include/nic/p2p_cmd_buf.h       |    83 +
 .../wlan/gen2/include/nic/p2p_mac.h           |   207 +
 .../wlan/gen2/include/nic/p2p_nic.h           |    62 +
 .../wlan/gen2/include/nic/p2p_nic_cmd_event.h |    70 +
 .../wlan/gen2/include/nic/que_mgt.h           |   971 ++
 .../wlan/gen2/include/nic/wlan_def.h          |  1010 ++
 .../wlan/gen2/include/nic_cmd_event.h         |  2290 ++++
 .../wlan/gen2/include/nic_init_cmd_event.h    |   177 +
 .../wlan/gen2/include/p2p_precomp.h           |   201 +
 .../wlan/gen2/include/p2p_typedef.h           |   165 +
 .../connectivity/wlan/gen2/include/precomp.h  |   388 +
 .../connectivity/wlan/gen2/include/pwr_mgt.h  |   141 +
 .../connectivity/wlan/gen2/include/queue.h    |   195 +
 .../connectivity/wlan/gen2/include/rftest.h   |   294 +
 .../wlan/gen2/include/tdls_extr.h             |   427 +
 .../connectivity/wlan/gen2/include/typedef.h  |   244 +
 .../connectivity/wlan/gen2/include/wlan_bow.h |   352 +
 .../connectivity/wlan/gen2/include/wlan_lib.h |  1001 ++
 .../connectivity/wlan/gen2/include/wlan_oid.h |  1715 +++
 .../connectivity/wlan/gen2/include/wlan_p2p.h |   307 +
 .../connectivity/wlan/gen2/mgmt/aaa_fsm.c     |  1303 ++
 .../connectivity/wlan/gen2/mgmt/ais_fsm.c     |  5039 +++++++
 .../connectivity/wlan/gen2/mgmt/assoc.c       |  1932 +++
 .../connectivity/wlan/gen2/mgmt/auth.c        |  1211 ++
 .../connectivity/wlan/gen2/mgmt/bss.c         |  2521 ++++
 .../connectivity/wlan/gen2/mgmt/cnm.c         |   738 ++
 .../connectivity/wlan/gen2/mgmt/cnm_mem.c     |  1236 ++
 .../connectivity/wlan/gen2/mgmt/cnm_timer.c   |   482 +
 .../connectivity/wlan/gen2/mgmt/hem_mbox.c    |   816 ++
 .../connectivity/wlan/gen2/mgmt/hs20.c        |   498 +
 .../connectivity/wlan/gen2/mgmt/mib.c         |   111 +
 .../connectivity/wlan/gen2/mgmt/p2p_assoc.c   |    87 +
 .../connectivity/wlan/gen2/mgmt/p2p_bss.c     |    58 +
 .../connectivity/wlan/gen2/mgmt/p2p_fsm.c     |  3139 +++++
 .../connectivity/wlan/gen2/mgmt/p2p_func.c    |  3796 ++++++
 .../connectivity/wlan/gen2/mgmt/p2p_ie.c      |   612 +
 .../connectivity/wlan/gen2/mgmt/p2p_rlm.c     |   905 ++
 .../wlan/gen2/mgmt/p2p_rlm_obss.c             |   313 +
 .../connectivity/wlan/gen2/mgmt/p2p_scan.c    |   756 ++
 .../connectivity/wlan/gen2/mgmt/p2p_state.c   |   466 +
 .../connectivity/wlan/gen2/mgmt/privacy.c     |   915 ++
 .../connectivity/wlan/gen2/mgmt/rate.c        |   497 +
 .../connectivity/wlan/gen2/mgmt/rlm.c         |  1858 +++
 .../connectivity/wlan/gen2/mgmt/rlm_domain.c  |  1791 +++
 .../connectivity/wlan/gen2/mgmt/rlm_obss.c    |   436 +
 .../wlan/gen2/mgmt/rlm_protection.c           |   105 +
 .../connectivity/wlan/gen2/mgmt/roaming_fsm.c |   539 +
 .../connectivity/wlan/gen2/mgmt/rsn.c         |  2533 ++++
 .../connectivity/wlan/gen2/mgmt/saa_fsm.c     |  1788 +++
 .../connectivity/wlan/gen2/mgmt/scan.c        |  3103 +++++
 .../connectivity/wlan/gen2/mgmt/scan_fsm.c    |  2136 +++
 .../connectivity/wlan/gen2/mgmt/sec_fsm.c     |  1112 ++
 .../connectivity/wlan/gen2/mgmt/stats.c       |  1342 ++
 .../connectivity/wlan/gen2/mgmt/swcr.c        |  1170 ++
 .../connectivity/wlan/gen2/mgmt/tdls.c        |  5199 ++++++++
 .../connectivity/wlan/gen2/mgmt/tdls_com.c    |   741 ++
 .../connectivity/wlan/gen2/mgmt/wapi.c        |   491 +
 .../connectivity/wlan/gen2/mgmt/wnm.c         |   301 +
 .../connectivity/wlan/gen2/nic/cmd_buf.c      |   254 +
 .../mediatek/connectivity/wlan/gen2/nic/nic.c |  4062 ++++++
 .../wlan/gen2/nic/nic_cmd_event.c             |  1636 +++
 .../connectivity/wlan/gen2/nic/nic_pwr_mgt.c  |   669 +
 .../connectivity/wlan/gen2/nic/nic_rx.c       |  3782 ++++++
 .../connectivity/wlan/gen2/nic/nic_tx.c       |  2350 ++++
 .../connectivity/wlan/gen2/nic/p2p_nic.c      |   192 +
 .../connectivity/wlan/gen2/nic/que_mgt.c      |  5038 +++++++
 .../connectivity/wlan/gen2/os/linux/gl_bow.c  |  1177 ++
 .../wlan/gen2/os/linux/gl_cfg80211.c          |  3110 +++++
 .../connectivity/wlan/gen2/os/linux/gl_init.c |  3502 +++++
 .../connectivity/wlan/gen2/os/linux/gl_kal.c  |  4799 +++++++
 .../connectivity/wlan/gen2/os/linux/gl_p2p.c  |  4672 +++++++
 .../wlan/gen2/os/linux/gl_p2p_cfg80211.c      |  1935 +++
 .../wlan/gen2/os/linux/gl_p2p_init.c          |   433 +
 .../wlan/gen2/os/linux/gl_p2p_kal.c           |  1314 ++
 .../connectivity/wlan/gen2/os/linux/gl_proc.c |  1020 ++
 .../connectivity/wlan/gen2/os/linux/gl_rst.c  |   228 +
 .../wlan/gen2/os/linux/gl_vendor.c            |  1220 ++
 .../connectivity/wlan/gen2/os/linux/gl_wext.c |  4158 ++++++
 .../wlan/gen2/os/linux/gl_wext_priv.c         |  3142 +++++
 .../wlan/gen2/os/linux/hif/ahb/ahb.c          |  1643 +++
 .../wlan/gen2/os/linux/hif/ahb/arm.c          |    31 +
 .../wlan/gen2/os/linux/hif/ahb/include/hif.h  |   340 +
 .../gen2/os/linux/hif/ahb/include/hif_gdma.h  |   154 +
 .../gen2/os/linux/hif/ahb/include/hif_pdma.h  |   141 +
 .../os/linux/hif/ahb/include/mtk_porting.h    |    91 +
 .../gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c   |   480 +
 .../wlan/gen2/os/linux/include/gl_cfg80211.h  |   341 +
 .../wlan/gen2/os/linux/include/gl_kal.h       |  1565 +++
 .../wlan/gen2/os/linux/include/gl_os.h        |  1270 ++
 .../wlan/gen2/os/linux/include/gl_p2p_ioctl.h |   743 ++
 .../wlan/gen2/os/linux/include/gl_p2p_kal.h   |   243 +
 .../wlan/gen2/os/linux/include/gl_p2p_os.h    |   242 +
 .../wlan/gen2/os/linux/include/gl_rst.h       |   133 +
 .../wlan/gen2/os/linux/include/gl_sec.h       |    21 +
 .../wlan/gen2/os/linux/include/gl_typedef.h   |   298 +
 .../wlan/gen2/os/linux/include/gl_vendor.h    |   619 +
 .../wlan/gen2/os/linux/include/gl_wext.h      |   357 +
 .../wlan/gen2/os/linux/include/gl_wext_priv.h |   402 +
 .../wlan/gen2/os/linux/platform.c             |   542 +
 .../connectivity/wlan/gen2/os/version.h       |   190 +
 drivers/misc/mediatek/include/mt-plat/aee.h   |   284 +
 .../misc/mediatek/include/mt-plat/mrdump.h    |   204 +
 .../mt-plat/mt7622/include/mach/mtk_thermal.h |   295 +
 .../mt8127/include/mach/mt_freqhopping.h      |   159 +
 .../mt8127/include/mach/mt_spm_mtcmos.h       |    37 +
 .../mt8127/include/mach/mtk_boot_share_page.h |    40 +
 .../mt-plat/mt8127/include/mach/mtk_thermal.h |   301 +
 .../misc/mediatek/include/mt-plat/mt_sched.h  |    34 +
 .../misc/mediatek/include/mt-plat/mtk_io.h    |    23 +
 .../misc/mediatek/include/mt-plat/mtk_lpae.h  |    62 +
 .../include/mt-plat/mtk_mdm_monitor.h         |    42 +
 .../include/mt-plat/mtk_platform_debug.h      |    28 +
 .../include/mt-plat/mtk_ram_console.h         |   162 +
 .../misc/mediatek/include/mt-plat/mtk_rtc.h   |    85 +
 .../include/mt-plat/mtk_thermal_ext_control.h |    69 +
 .../include/mt-plat/mtk_thermal_monitor.h     |   102 +
 .../include/mt-plat/mtk_thermal_platform.h    |   114 +
 .../include/mt-plat/mtk_thermal_trace.h       |    47 +
 .../include/mt-plat/mtk_thermal_typedefs.h    |   241 +
 .../include/mt-plat/mtk_wcn_cmb_stub.h        |   185 +
 .../misc/mediatek/include/mt-plat/rt-regmap.h |   291 +
 .../mediatek/include/mt-plat/sync_write.h     |    88 +
 .../misc/mediatek/include/mt-plat/wakelock.h  |    67 +
 285 files changed, 213970 insertions(+)
 create mode 100644 drivers/misc/mediatek/Kconfig
 create mode 100644 drivers/misc/mediatek/Makefile
 create mode 100644 drivers/misc/mediatek/btif/Kconfig
 create mode 100644 drivers/misc/mediatek/btif/Makefile
 create mode 100644 drivers/misc/mediatek/btif/common/Makefile
 create mode 100644 drivers/misc/mediatek/btif/common/btif_dma_plat.c
 create mode 100644 drivers/misc/mediatek/btif/common/btif_plat.c
 create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif.h
 create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h
 create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif.c
 create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif_exp.c
 create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h
 create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h
 create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h
 create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h
 create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/plat_common.h
 create mode 100644 drivers/misc/mediatek/connectivity/Kconfig
 create mode 100644 drivers/misc/mediatek/connectivity/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c
 create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/Makefile
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c
 create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/aee.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mrdump.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mt_sched.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_io.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_lpae.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_rtc.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/rt-regmap.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/sync_write.h
 create mode 100644 drivers/misc/mediatek/include/mt-plat/wakelock.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 3726eacdf65de..9008a09172e17 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -527,4 +527,5 @@ source "drivers/misc/echo/Kconfig"
 source "drivers/misc/cxl/Kconfig"
 source "drivers/misc/ocxl/Kconfig"
 source "drivers/misc/cardreader/Kconfig"
+source "drivers/misc/mediatek/Kconfig"
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index af22bbc3d00cb..cdced6d59e2c7 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
 obj-$(CONFIG_PCI_ENDPOINT_TEST)	+= pci_endpoint_test.o
 obj-$(CONFIG_OCXL)		+= ocxl/
 obj-$(CONFIG_MISC_RTSX)		+= cardreader/
+obj-$(CONFIG_MTK_COMBO)	+= mediatek/
diff --git a/drivers/misc/mediatek/Kconfig b/drivers/misc/mediatek/Kconfig
new file mode 100644
index 0000000000000..4829a6598c7aa
--- /dev/null
+++ b/drivers/misc/mediatek/Kconfig
@@ -0,0 +1,11 @@
+menu "Mediatek Peripherals "
+
+config MTK_PLATFORM
+        string "MTK platform name"
+source "drivers/misc/mediatek/btif/Kconfig"
+
+menu "Modem & Connectivity related configs"
+source "drivers/misc/mediatek/connectivity/Kconfig"
+endmenu
+
+endmenu  # CONN
diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile
new file mode 100644
index 0000000000000..5e7f06db38f28
--- /dev/null
+++ b/drivers/misc/mediatek/Makefile
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+#$(call all-subdir-src-or-makefile)
+subdir-ccflags-y += -Werror
+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/
+
+obj-$(CONFIG_MTK_COMBO) += connectivity/
+obj-$(CONFIG_MTK_BTIF) += btif/
diff --git a/drivers/misc/mediatek/btif/Kconfig b/drivers/misc/mediatek/btif/Kconfig
new file mode 100644
index 0000000000000..908898bd95c3d
--- /dev/null
+++ b/drivers/misc/mediatek/btif/Kconfig
@@ -0,0 +1,4 @@
+config MTK_BTIF
+	tristate"MediaTek BTIF Driver"
+	help
+	  MTK connectivity BTIF driver for A/D die
diff --git a/drivers/misc/mediatek/btif/Makefile b/drivers/misc/mediatek/btif/Makefile
new file mode 100644
index 0000000000000..2be3ab66f4268
--- /dev/null
+++ b/drivers/misc/mediatek/btif/Makefile
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+# BTIF driver for AD DIE
+# If KERNELRELEASE is defined, we've been invoked from the
+# kernel build system and can use its language.
+ifneq ($(KERNELRELEASE),)
+	#subdir-ccflags-y can be used in 2.6.34 in the future
+	MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM))
+	subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include
+	subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/include/mach
+	subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat
+
+    obj-y += common/
+
+# Otherwise we were called directly from the command
+# line; invoke the kernel build system.
+else
+    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+    PWD  := $(shell pwd)
+default:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+endif
diff --git a/drivers/misc/mediatek/btif/common/Makefile b/drivers/misc/mediatek/btif/common/Makefile
new file mode 100644
index 0000000000000..61e9d4ea9e890
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/Makefile
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+# BTIF driver for AD DIE
+# If KERNELRELEASE is defined, we've been invoked from the
+# kernel build system and can use its language.
+ifneq ($(KERNELRELEASE),)
+	ccflags-y += -I$(src)/inc
+	ccflags-y += -I$(src)/plat_inc
+
+	obj-y += btif.o
+	btif-y	:= mtk_btif.o mtk_btif_exp.o btif_dma_plat.o btif_plat.o
+
+# Otherwise we were called directly from the command
+# line; invoke the kernel build system.
+else
+    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+    PWD  := $(shell pwd)
+default:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+endif
diff --git a/drivers/misc/mediatek/btif/common/btif_dma_plat.c b/drivers/misc/mediatek/btif/common/btif_dma_plat.c
new file mode 100644
index 0000000000000..58be46927953b
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/btif_dma_plat.c
@@ -0,0 +1,1436 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <mtk_lpae.h>
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG "MTK-BTIF-DMA"
+
+#include "btif_dma_priv.h"
+
+#define DMA_USER_ID "btif_driver"
+
+/************************************Global variable***********************************/
+
+static MTK_BTIF_DMA_VFIFO mtk_tx_dma_vfifo = {
+	.vfifo = {
+		  .p_vir_addr = NULL,
+		  .phy_addr = 0,
+		  .vfifo_size = TX_DMA_VFF_SIZE,
+		  .thre = DMA_TX_THRE(TX_DMA_VFF_SIZE),
+		  },
+	.wpt = 0,
+	.last_wpt_wrap = 0,
+	.rpt = 0,
+	.last_rpt_wrap = 0,
+};
+
+static MTK_BTIF_IRQ_STR mtk_btif_tx_dma_irq = {
+	.name = "mtk btif tx dma irq",
+	.is_irq_sup = true,
+	.reg_flag = false,
+#ifdef CONFIG_OF
+	.irq_flags = IRQF_TRIGGER_NONE,
+#else
+	.irq_id = MT_DMA_BTIF_TX_IRQ_ID,
+	.sens_type = IRQ_SENS_LVL,
+	.lvl_type = IRQ_LVL_LOW,
+#endif
+	.p_irq_handler = NULL,
+};
+
+static MTK_BTIF_DMA_VFIFO mtk_rx_dma_vfifo = {
+	.vfifo = {
+		  .p_vir_addr = NULL,
+		  .phy_addr = 0,
+		  .vfifo_size = RX_DMA_VFF_SIZE,
+		  .thre = DMA_RX_THRE(RX_DMA_VFF_SIZE),
+		  },
+
+	.wpt = 0,
+	.last_wpt_wrap = 0,
+	.rpt = 0,
+	.last_rpt_wrap = 0,
+};
+
+static MTK_BTIF_IRQ_STR mtk_btif_rx_dma_irq = {
+	.name = "mtk btif rx dma irq",
+	.is_irq_sup = true,
+	.reg_flag = false,
+#ifdef CONFIG_OF
+	.irq_flags = IRQF_TRIGGER_NONE,
+#else
+	.irq_id = MT_DMA_BTIF_RX_IRQ_ID,
+	.sens_type = IRQ_SENS_LVL,
+	.lvl_type = IRQ_LVL_LOW,
+#endif
+	.p_irq_handler = NULL,
+};
+
+static MTK_DMA_INFO_STR mtk_btif_tx_dma = {
+#ifndef CONFIG_OF
+	.base = AP_DMA_BASE + BTIF_TX_DMA_OFFSET,
+#endif
+	.dir = DMA_DIR_TX,
+	.p_irq = &mtk_btif_tx_dma_irq,
+	.p_vfifo = &(mtk_tx_dma_vfifo.vfifo),
+};
+
+static MTK_DMA_INFO_STR mtk_btif_rx_dma = {
+#ifndef CONFIG_OF
+	.base = AP_DMA_BASE + BTIF_RX_DMA_OFFSET,
+#endif
+	.dir = DMA_DIR_RX,
+	.p_irq = &mtk_btif_rx_dma_irq,
+	.p_vfifo = &(mtk_rx_dma_vfifo.vfifo),
+};
+
+static spinlock_t g_clk_cg_spinlock;	/*dma clock's spinlock */
+
+/************************************Function declearation***********************************/
+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info);
+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info);
+static int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info,
+			    ENUM_DMA_CTRL ctrl_id);
+static int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info,
+			    ENUM_DMA_CTRL ctrl_id);
+static int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en);
+static int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en);
+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info,
+			       ENUM_BTIF_REG_ID flag);
+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info,
+			       ENUM_BTIF_REG_ID flag);
+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info);
+static int _btif_dma_dump_dbg_reg(void);
+static void hal_btif_tx_dma_vff_set_for_4g(void);
+static void hal_btif_rx_dma_vff_set_for_4g(void);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_ier_ctrl
+* DESCRIPTION
+*  BTIF Tx DMA's interrupt enable/disable
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* enable    [IN]        control if tx interrupt enabled or not
+* dma_dir  [IN]         DMA's direction
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+static int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_receive_data
+* DESCRIPTION
+*  receive data from btif module in DMA polling mode
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  positive means data is available, 0 means no data available
+*****************************************************************************/
+#ifndef MTK_BTIF_MARK_UNUSED_API
+static int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info,
+				unsigned char *p_buf,
+				const unsigned int max_len);
+
+/************************************Function***********************************/
+#endif
+
+#ifdef CONFIG_OF
+static void hal_dma_set_default_setting(ENUM_DMA_DIR dma_dir)
+{
+	struct device_node *node = NULL;
+	unsigned int irq_info[3] = {0, 0, 0};
+	unsigned int phy_base;
+
+	if (dma_dir == DMA_DIR_RX) {
+		node = of_find_compatible_node(NULL, NULL, "mediatek,btif_rx");
+		if (node) {
+			mtk_btif_rx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0);
+			/*fixme, be compitable arch 64bits*/
+			mtk_btif_rx_dma.base = (unsigned long)of_iomap(node, 0);
+			BTIF_INFO_FUNC("get rx_dma irq(%d),register base(0x%lx)\n",
+				mtk_btif_rx_dma.p_irq->irq_id, mtk_btif_rx_dma.base);
+		} else {
+			BTIF_ERR_FUNC("get rx_dma device node fail\n");
+		}
+		/* get the interrupt line behaviour */
+		if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) {
+			BTIF_ERR_FUNC("get interrupt flag from DTS fail\n");
+		} else {
+			mtk_btif_rx_dma.p_irq->irq_flags = irq_info[2];
+			BTIF_INFO_FUNC("get interrupt flag(0x%x)\n",
+				mtk_btif_rx_dma.p_irq->irq_flags);
+		}
+		if (of_property_read_u32_index(node, "reg", 1, &phy_base)) {
+			BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n",
+					dma_dir);
+		} else {
+			BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n",
+					dma_dir, (unsigned int)phy_base);
+		}
+	} else if (dma_dir == DMA_DIR_TX) {
+		node = of_find_compatible_node(NULL, NULL, "mediatek,btif_tx");
+		if (node) {
+			mtk_btif_tx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0);
+			/*fixme, be compitable arch 64bits*/
+			mtk_btif_tx_dma.base = (unsigned long)of_iomap(node, 0);
+			BTIF_INFO_FUNC("get tx_dma irq(%d),register base(0x%lx)\n",
+				mtk_btif_tx_dma.p_irq->irq_id, mtk_btif_tx_dma.base);
+		} else {
+			BTIF_ERR_FUNC("get tx_dma device node fail\n");
+		}
+		/* get the interrupt line behaviour */
+		if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) {
+			BTIF_ERR_FUNC("get interrupt flag from DTS fail\n");
+		} else {
+			mtk_btif_tx_dma.p_irq->irq_flags = irq_info[2];
+			BTIF_INFO_FUNC("get interrupt flag(0x%x)\n",
+				mtk_btif_tx_dma.p_irq->irq_flags);
+		}
+
+		if (of_property_read_u32_index(node, "reg", 1, &phy_base)) {
+			BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n",
+				dma_dir);
+		} else {
+			BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n",
+					dma_dir, (unsigned int)phy_base);
+		}
+	}
+
+}
+#endif
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_info_get
+* DESCRIPTION
+*  get btif tx dma channel's information
+* PARAMETERS
+* dma_dir        [IN]         DMA's direction
+* RETURNS
+*  pointer to btif dma's information structure
+*****************************************************************************/
+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir)
+{
+	P_MTK_DMA_INFO_STR p_dma_info = NULL;
+
+	BTIF_TRC_FUNC();
+#ifdef CONFIG_OF
+	hal_dma_set_default_setting(dma_dir);
+#endif
+	if (dma_dir == DMA_DIR_RX)
+		/*Rx DMA*/
+		p_dma_info = &mtk_btif_rx_dma;
+	else if (dma_dir == DMA_DIR_TX)
+		/*Tx DMA*/
+		p_dma_info = &mtk_btif_tx_dma;
+	else
+		/*print error log*/
+		BTIF_ERR_FUNC("invalid DMA dir (%d)\n", dma_dir);
+	spin_lock_init(&g_clk_cg_spinlock);
+	BTIF_TRC_FUNC();
+	return p_dma_info;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_ctrl
+* DESCRIPTION
+*  control clock output enable/disable of DMA module
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag)
+{
+/*In MTK DMA BTIF channel, there's only one global CG on AP_DMA, no sub channel's CG bit*/
+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/
+	int i_ret = 0;
+	unsigned long irq_flag = 0;
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	static atomic_t s_clk_ref = ATOMIC_INIT(0);
+#else
+	static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE;
+#endif
+
+	spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);
+
+#if MTK_BTIF_ENABLE_CLK_CTL
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+
+	if (flag == CLK_OUT_ENABLE) {
+		if (atomic_inc_return(&s_clk_ref) == 1) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID);
+#else
+			BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n");
+			i_ret = clk_enable(clk_btif_apdma);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d",
+					 i_ret);
+			}
+		}
+	} else if (flag == CLK_OUT_DISABLE) {
+		if (atomic_dec_return(&s_clk_ref) == 0) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID);
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d",
+					 i_ret);
+			}
+#else
+			BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif_apdma) calling\n");
+			clk_disable(clk_btif_apdma);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+		}
+	} else {
+		i_ret = ERR_INVALID_PAR;
+		BTIF_ERR_FUNC("invalid  clock ctrl flag (%d)\n", flag);
+	}
+
+#else
+
+	if (status == flag) {
+		i_ret = 0;
+		BTIF_DBG_FUNC("dma clock already %s\n",
+			      CLK_OUT_ENABLE ==
+			      status ? "enabled" : "disabled");
+	} else {
+		if (flag == CLK_OUT_ENABLE) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID);
+#else
+			BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n");
+			i_ret = clk_enable(clk_btif_apdma);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+			status = (i_ret == 0) ? flag : status;
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d",
+					 i_ret);
+			}
+		} else if (flag == CLK_OUT_DISABLE) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID);
+			status = (i_ret == 0) ? flag : status;
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d",
+					 i_ret);
+			}
+#else
+			BTIF_DBG_FUNC("[CCF] clk_disable_unprepare(clk_btif_apdma) calling\n");
+			clk_disable(clk_btif_apdma);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+		} else {
+			i_ret = ERR_INVALID_PAR;
+			BTIF_ERR_FUNC("invalid  clock ctrl flag (%d)\n", flag);
+		}
+	}
+#endif
+
+#else
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+
+#else
+
+	status = flag;
+#endif
+
+	i_ret = 0;
+#endif
+
+	spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	if (i_ret == 0) {
+		BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled");
+	} else {
+		BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n",
+				flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret);
+	}
+#else
+
+	if (i_ret == 0) {
+		BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled");
+	} else {
+		BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n",
+				flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret);
+	}
+#endif
+#if defined(CONFIG_MTK_CLKMGR)
+	BTIF_DBG_FUNC("DMA's clock is %s\n", (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) ? "off" : "on");
+#endif
+	return i_ret;
+}
+
+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info)
+{
+	int i_ret = 0;
+	unsigned int dat = 0;
+	unsigned long base = p_dma_info->base;
+	unsigned long addr_h = 0;
+	P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo;
+	P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo,
+							    MTK_BTIF_DMA_VFIFO,
+							    vfifo);
+
+	if (p_dma_info->dir == DMA_DIR_RX) {
+		/*Rx DMA*/
+		/*do hardware reset*/
+		/*		BTIF_SET_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/
+		/*		BTIF_CLR_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/
+		BTIF_SET_BIT(RX_DMA_RST(base), DMA_WARM_RST);
+		do {
+			dat = BTIF_READ32(RX_DMA_EN(base));
+		} while (0x01 & dat);
+		/*write vfifo base address to VFF_ADDR*/
+		btif_reg_sync_writel(p_vfifo->phy_addr, RX_DMA_VFF_ADDR(base));
+		if (enable_4G())
+			hal_btif_rx_dma_vff_set_for_4g();
+		else {
+			addr_h = p_vfifo->phy_addr >> 16;
+			addr_h = addr_h >> 16;
+			btif_reg_sync_writel(addr_h, RX_DMA_VFF_ADDR_H(base));
+		}
+		/*write vfifo length to VFF_LEN*/
+		btif_reg_sync_writel(p_vfifo->vfifo_size, RX_DMA_VFF_LEN(base));
+		/*write wpt to VFF_WPT*/
+		btif_reg_sync_writel(p_mtk_dma_vfifo->wpt,
+				     RX_DMA_VFF_WPT(base));
+		btif_reg_sync_writel(p_mtk_dma_vfifo->rpt,
+					 RX_DMA_VFF_RPT(base));
+		/*write vff_thre to VFF_THRESHOLD*/
+		btif_reg_sync_writel(p_vfifo->thre, RX_DMA_VFF_THRE(base));
+		/*clear Rx DMA's interrupt status*/
+		BTIF_SET_BIT(RX_DMA_INT_FLAG(base),
+			     RX_DMA_INT_DONE | RX_DMA_INT_THRE);
+
+		/*enable Rx IER by default*/
+		btif_rx_dma_ier_ctrl(p_dma_info, true);
+	} else {
+/*Tx DMA*/
+/*do hardware reset*/
+/*		BTIF_SET_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/
+/*		BTIF_CLR_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/
+		BTIF_SET_BIT(TX_DMA_RST(base), DMA_WARM_RST);
+		do {
+			dat = BTIF_READ32(TX_DMA_EN(base));
+		} while (0x01 & dat);
+/*write vfifo base address to VFF_ADDR*/
+		btif_reg_sync_writel(p_vfifo->phy_addr, TX_DMA_VFF_ADDR(base));
+		if (enable_4G())
+			hal_btif_tx_dma_vff_set_for_4g();
+		else {
+			addr_h = p_vfifo->phy_addr >> 16;
+			addr_h = addr_h >> 16;
+			btif_reg_sync_writel(addr_h, TX_DMA_VFF_ADDR_H(base));
+		}
+/*write vfifo length to VFF_LEN*/
+		btif_reg_sync_writel(p_vfifo->vfifo_size, TX_DMA_VFF_LEN(base));
+/*write wpt to VFF_WPT*/
+		btif_reg_sync_writel(p_mtk_dma_vfifo->wpt,
+				     TX_DMA_VFF_WPT(base));
+		btif_reg_sync_writel(p_mtk_dma_vfifo->rpt,
+				     TX_DMA_VFF_RPT(base));
+/*write vff_thre to VFF_THRESHOLD*/
+		btif_reg_sync_writel(p_vfifo->thre, TX_DMA_VFF_THRE(base));
+
+		BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK);
+
+		hal_btif_dma_ier_ctrl(p_dma_info, false);
+	}
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_ctrl
+* DESCRIPTION
+* enable/disable Tx DMA channel
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* ctrl_id          [IN]        enable/disable ID
+* RETURNS
+*  0 means success; negative means fail
+*****************************************************************************/
+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id)
+{
+	unsigned int i_ret = -1;
+	ENUM_DMA_DIR dir = p_dma_info->dir;
+
+	if (dir == DMA_DIR_RX)
+		i_ret = btif_rx_dma_ctrl(p_dma_info, ctrl_id);
+	else if (dir == DMA_DIR_TX)
+		i_ret = btif_tx_dma_ctrl(p_dma_info, ctrl_id);
+	else {
+		/*TODO: print error log*/
+		BTIF_ERR_FUNC("invalid dma ctrl id (%d)\n", ctrl_id);
+		i_ret = ERR_INVALID_PAR;
+	}
+	return i_ret;
+}
+
+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info,
+			   dma_rx_buf_write rx_cb)
+{
+	if (p_dma_info->rx_cb != NULL) {
+		BTIF_DBG_FUNC
+		    ("rx_cb already registered, replace (0x%p) with (0x%p)\n",
+		     p_dma_info->rx_cb, rx_cb);
+	}
+	p_dma_info->rx_cb = rx_cb;
+	return 0;
+}
+
+int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id)
+{
+	unsigned int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+	unsigned int dat;
+
+	BTIF_TRC_FUNC();
+	if (ctrl_id == DMA_CTRL_DISABLE) {
+		/*if write 0 to EN bit, DMA will be stopped imediately*/
+		/*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/
+		/*BTIF_CLR_BIT(TX_DMA_EN(base), DMA_EN_BIT);*/
+		BTIF_SET_BIT(TX_DMA_STOP(base), DMA_STOP_BIT);
+		do {
+			dat = BTIF_READ32(TX_DMA_STOP(base));
+		} while (0x1 & dat);
+		BTIF_DBG_FUNC("BTIF Tx DMA disabled,EN(0x%x),STOP(0x%x)\n",
+			BTIF_READ32(TX_DMA_EN(base)), BTIF_READ32(TX_DMA_STOP(base)));
+		i_ret = 0;
+	} else if (ctrl_id == DMA_CTRL_ENABLE) {
+		BTIF_SET_BIT(TX_DMA_EN(base), DMA_EN_BIT);
+		BTIF_DBG_FUNC("BTIF Tx DMA enabled\n");
+		i_ret = 0;
+	} else {
+/*TODO: print error log*/
+		BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id);
+		i_ret = ERR_INVALID_PAR;
+	}
+	BTIF_TRC_FUNC();
+	return i_ret;
+}
+
+int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id)
+{
+	unsigned int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+	unsigned int dat;
+
+	BTIF_TRC_FUNC();
+
+	if (ctrl_id == DMA_CTRL_DISABLE) {
+		/*if write 0 to EN bit, DMA will be stopped imediately*/
+		/*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/
+		/*BTIF_CLR_BIT(RX_DMA_EN(base), DMA_EN_BIT);*/
+		BTIF_SET_BIT(RX_DMA_STOP(base), DMA_STOP_BIT);
+		do {
+			dat = BTIF_READ32(RX_DMA_STOP(base));
+		} while (0x1 & dat);
+		BTIF_DBG_FUNC("BTIF Rx DMA disabled,EN(0x%x),STOP(0x%x)\n",
+			BTIF_READ32(RX_DMA_EN(base)), BTIF_READ32(RX_DMA_STOP(base)));
+		i_ret = 0;
+	} else if (ctrl_id == DMA_CTRL_ENABLE) {
+		BTIF_SET_BIT(RX_DMA_EN(base), DMA_EN_BIT);
+		BTIF_DBG_FUNC("BTIF Rx DMA enabled\n");
+		i_ret = 0;
+	} else {
+/*TODO: print error log*/
+		BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id);
+		i_ret = ERR_INVALID_PAR;
+	}
+	BTIF_TRC_FUNC();
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_vfifo_reset
+* DESCRIPTION
+*  reset tx virtual fifo information, except memory information
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info)
+{
+	unsigned int i_ret = -1;
+	P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo;
+	P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo,
+							    MTK_BTIF_DMA_VFIFO,
+							    vfifo);
+
+	BTIF_TRC_FUNC();
+	p_mtk_dma_vfifo->rpt = 0;
+	p_mtk_dma_vfifo->last_rpt_wrap = 0;
+	p_mtk_dma_vfifo->wpt = 0;
+	p_mtk_dma_vfifo->last_wpt_wrap = 0;
+	BTIF_TRC_FUNC();
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_ier_ctrl
+* DESCRIPTION
+*  BTIF Tx DMA's interrupt enable/disable
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* enable    [IN]        control if tx interrupt enabled or not
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en)
+{
+	unsigned int i_ret = -1;
+	ENUM_DMA_DIR dir = p_dma_info->dir;
+
+	if (dir == DMA_DIR_RX) {
+		i_ret = btif_rx_dma_ier_ctrl(p_dma_info, en);
+	} else if (dir == DMA_DIR_TX) {
+		i_ret = btif_tx_dma_ier_ctrl(p_dma_info, en);
+	} else {
+/*TODO: print error log*/
+		BTIF_ERR_FUNC("invalid DMA dma dir (%d)\n", dir);
+		i_ret = ERR_INVALID_PAR;
+	}
+
+	return i_ret;
+}
+
+int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en)
+{
+	unsigned int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+
+	BTIF_TRC_FUNC();
+	if (!en) {
+		BTIF_CLR_BIT(RX_DMA_INT_EN(base),
+			     (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN));
+	} else {
+		BTIF_SET_BIT(RX_DMA_INT_EN(base),
+			     (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN));
+	}
+	i_ret = 0;
+	BTIF_TRC_FUNC();
+
+	return i_ret;
+}
+
+int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en)
+{
+	unsigned int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+
+	BTIF_TRC_FUNC();
+	if (!en)
+		BTIF_CLR_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT);
+	else
+		BTIF_SET_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT);
+	i_ret = 0;
+	BTIF_TRC_FUNC();
+
+	return i_ret;
+}
+
+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info)
+{
+	int tx_irq_done = 0;
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+/*if we enable this clock reference couner, just return , because when enter IRQ handler, DMA's clock will be opened*/
+	tx_irq_done = 1;
+#else
+	unsigned long flag = 0;
+	unsigned long base = p_dma_info->base;
+
+	spin_lock_irqsave(&(g_clk_cg_spinlock), flag);
+	tx_irq_done = ((BTIF_READ32(TX_DMA_INT_FLAG(base)) & TX_DMA_INT_FLAG_MASK) == 0) ? 1 : 0;
+	spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag);
+#endif
+	return tx_irq_done;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_irq_handler
+* DESCRIPTION
+*  lower level tx interrupt handler
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info)
+{
+#define MAX_CONTINIOUS_TIMES 512
+	unsigned int i_ret = -1;
+	unsigned int valid_size = 0;
+	unsigned int vff_len = 0;
+	unsigned int left_len = 0;
+	unsigned long base = p_dma_info->base;
+	static int flush_irq_counter;
+	static struct timeval start_timer;
+	static struct timeval end_timer;
+	unsigned long flag = 0;
+
+	spin_lock_irqsave(&(g_clk_cg_spinlock), flag);
+
+#if defined(CONFIG_MTK_CLKMGR)
+	if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) {
+		spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag);
+		BTIF_ERR_FUNC
+		    ("%s: clock is off before irq status clear done!!!\n",
+		     __FILE__);
+		return i_ret;
+	}
+#endif
+/*check if Tx VFF Left Size equal to VFIFO size or not*/
+	vff_len = BTIF_READ32(TX_DMA_VFF_LEN(base));
+	valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base));
+	left_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base));
+	if (flush_irq_counter == 0)
+		do_gettimeofday(&start_timer);
+	if ((valid_size > 0) && (valid_size < 8)) {
+		i_ret = _tx_dma_flush(p_dma_info);
+		flush_irq_counter++;
+		if (flush_irq_counter >= MAX_CONTINIOUS_TIMES) {
+			do_gettimeofday(&end_timer);
+/*
+ * when btif tx fifo cannot accept any data and counts of bytes left in tx vfifo < 8 for a while
+ * we assume that btif cannot send data for a long time
+ * in order not to generate interrupt continiously, which may effect system's performance.
+ * we clear tx flag and disable btif tx interrupt
+ */
+/*clear interrupt flag*/
+			BTIF_CLR_BIT(TX_DMA_INT_FLAG(base),
+				     TX_DMA_INT_FLAG_MASK);
+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/
+			i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false);
+			BTIF_ERR_FUNC
+			    ("**********************ERROR, ERROR, ERROR**************************\n");
+			BTIF_ERR_FUNC
+			    ("BTIF Tx IRQ happened %d times (continiously), between %d.%d and %d.%d\n",
+			     MAX_CONTINIOUS_TIMES, start_timer.tv_sec,
+			     start_timer.tv_usec, end_timer.tv_usec,
+			     end_timer.tv_usec);
+		}
+	} else if (vff_len == left_len) {
+		flush_irq_counter = 0;
+/*clear interrupt flag*/
+		BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK);
+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/
+		i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false);
+	} else {
+#if 0
+		BTIF_ERR_FUNC
+		    ("**********************WARNING**************************\n");
+		BTIF_ERR_FUNC("invalid irq condition, dump register\n");
+		hal_dma_dump_reg(p_dma_info, REG_TX_DMA_ALL);
+#endif
+		BTIF_DBG_FUNC
+		    ("superious IRQ occurs, vff_len(%d), valid_size(%d), left_len(%d)\n",
+		     vff_len, valid_size, left_len);
+	}
+
+	spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag);
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_send_data
+* DESCRIPTION
+*  send data through btif in DMA mode
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* p_buf     [IN]        pointer to rx data buffer
+* max_len  [IN]        tx buffer length
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info,
+		      const unsigned char *p_buf, const unsigned int buf_len)
+{
+	unsigned int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+	P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo;
+	unsigned int len_to_send = buf_len;
+	unsigned int ava_len = 0;
+	unsigned int wpt = 0;
+	unsigned int last_wpt_wrap = 0;
+	unsigned int vff_size = 0;
+	unsigned char *p_data = (unsigned char *)p_buf;
+	P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo,
+							MTK_BTIF_DMA_VFIFO,
+							vfifo);
+
+	BTIF_TRC_FUNC();
+	if ((p_buf == NULL) || (buf_len == 0)) {
+		i_ret = ERR_INVALID_PAR;
+		BTIF_ERR_FUNC("invalid parameters, p_buf:0x%p, buf_len:%d\n",
+			      p_buf, buf_len);
+		return i_ret;
+	}
+/*check if tx dma in flush operation? if yes, should wait until DMA finish flush operation*/
+/*currently uplayer logic will make sure this pre-condition*/
+/*disable Tx IER, in case Tx irq happens, flush bit may be set in irq handler*/
+	btif_tx_dma_ier_ctrl(p_dma_info, false);
+
+	vff_size = p_mtk_vfifo->vfifo.vfifo_size;
+	ava_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base));
+	wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_MASK;
+	last_wpt_wrap = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_WRAP;
+
+/*
+ * copy data to vFIFO, Note: ava_len should always large than buf_len,
+ * otherwise common logic layer will not call hal_dma_send_data
+ */
+	if (buf_len > ava_len) {
+		BTIF_ERR_FUNC
+		    ("length to send:(%d) < length available(%d), abnormal!!!---!!!\n",
+		     buf_len, ava_len);
+		WARN_ON(buf_len > ava_len);	/* this will cause kernel panic */
+	}
+
+	len_to_send = buf_len < ava_len ? buf_len : ava_len;
+	if (len_to_send + wpt >= vff_size) {
+		unsigned int tail_len = vff_size - wpt;
+
+		memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), p_data, tail_len);
+		p_data += tail_len;
+		memcpy(p_mtk_vfifo->vfifo.p_vir_addr,
+		       p_data, len_to_send - tail_len);
+/*make sure all data write to memory area tx vfifo locates*/
+		mb();
+
+/*calculate WPT*/
+		wpt = wpt + len_to_send - vff_size;
+		last_wpt_wrap ^= DMA_WPT_WRAP;
+	} else {
+		memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt),
+		       p_data, len_to_send);
+/*make sure all data write to memory area tx vfifo locates*/
+		mb();
+
+/*calculate WPT*/
+		wpt += len_to_send;
+	}
+	p_mtk_vfifo->wpt = wpt;
+	p_mtk_vfifo->last_wpt_wrap = last_wpt_wrap;
+
+/*make sure tx dma is allowed(tx flush bit is not set) to use before update WPT*/
+	if (hal_dma_is_tx_allow(p_dma_info)) {
+		/*make sure tx dma enabled*/
+		hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE);
+
+		/*update WTP to Tx DMA controller's control register*/
+		btif_reg_sync_writel(wpt | last_wpt_wrap, TX_DMA_VFF_WPT(base));
+
+		if ((BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) < 8) &&
+		    (BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) > 0)) {
+			/*
+			 * 0 < valid size in Tx vFIFO < 8 && TX Flush is not in process<should always be done>?
+			 * if yes, set flush bit to DMA
+			 */
+			_tx_dma_flush(p_dma_info);
+		}
+		i_ret = len_to_send;
+	} else {
+/*TODO: print error log*/
+		BTIF_ERR_FUNC("Tx DMA flush operation is in process, this case should never happen,",
+		"please check if tx operation is allowed before call this API\n");
+/*if flush operation is in process , we will return 0*/
+		i_ret = 0;
+	}
+
+/*Enable Tx IER*/
+	btif_tx_dma_ier_ctrl(p_dma_info, true);
+
+	BTIF_TRC_FUNC();
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_is_tx_complete
+* DESCRIPTION
+*  get tx complete flag
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  true means tx complete, false means tx in process
+*****************************************************************************/
+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info)
+{
+	bool b_ret = -1;
+	unsigned long base = p_dma_info->base;
+	unsigned int valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base));
+	unsigned int inter_size = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base));
+	unsigned int tx_done = is_tx_dma_irq_finish_done(p_dma_info);
+
+/*
+ * only when virtual FIFO valid size and Tx channel internal buffer size are both becomes to be 0,
+ * we can identify tx operation finished
+ * confirmed with DE.
+ */
+	if ((valid_size == 0) && (inter_size == 0) && (tx_done == 1)) {
+		b_ret = true;
+		BTIF_DBG_FUNC("DMA tx finished.\n");
+	} else {
+		BTIF_DBG_FUNC
+		    ("DMA tx is in process. vfifo valid size(%d), dma internal size (%d), tx_done(%d)\n",
+		     valid_size, inter_size, tx_done);
+		b_ret = false;
+	}
+
+	return b_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_get_ava_room
+* DESCRIPTION
+*  get tx available room
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  available room  size
+*****************************************************************************/
+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info)
+{
+	int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+
+/*read vFIFO's left size*/
+	i_ret = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base));
+	BTIF_DBG_FUNC("DMA tx ava room (%d).\n", i_ret);
+	if (i_ret == 0)
+		BTIF_INFO_FUNC("DMA tx vfifo is full.\n");
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_is_tx_allow
+* DESCRIPTION
+*  is tx operation allowed by DMA
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  true if tx operation is allowed; false if tx is not allowed
+*****************************************************************************/
+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info)
+{
+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000)
+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000)
+
+	bool b_ret = false;
+	unsigned int wait_us = 8 / MIN_TX_MB;	/*only ava length */
+/*see if flush operation is in process*/
+	b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true;
+	if (!b_ret) {
+		usleep_range(wait_us, 2 * wait_us);
+		b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true;
+	}
+	if (!b_ret)
+		BTIF_WARN_FUNC("btif tx dma is not allowed\n");
+/*after Tx flush operation finished, HW will set DMA_EN back to 0 and stop DMA*/
+	return b_ret;
+}
+
+
+/*****************************************************************************
+* FUNCTION
+*  hal_rx_dma_irq_handler
+* DESCRIPTION
+*  lower level rx interrupt handler
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info,
+			   unsigned char *p_buf, const unsigned int max_len)
+{
+	int i_ret = -1;
+	unsigned int valid_len = 0;
+	unsigned int wpt_wrap = 0;
+	unsigned int rpt_wrap = 0;
+	unsigned int wpt = 0;
+	unsigned int rpt = 0;
+	unsigned int tail_len = 0;
+	unsigned int real_len = 0;
+	unsigned long base = p_dma_info->base;
+	P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo;
+	dma_rx_buf_write rx_cb = p_dma_info->rx_cb;
+	unsigned char *p_vff_buf = NULL;
+	unsigned char *vff_base = p_vfifo->p_vir_addr;
+	unsigned int vff_size = p_vfifo->vfifo_size;
+	P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo,
+							MTK_BTIF_DMA_VFIFO,
+							vfifo);
+	unsigned long flag = 0;
+
+	spin_lock_irqsave(&(g_clk_cg_spinlock), flag);
+#if defined(CONFIG_MTK_CLKMGR)
+	if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) {
+		spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag);
+		BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n",
+			      __FILE__);
+		return i_ret;
+	}
+#endif
+/*disable DMA Rx IER*/
+	hal_btif_dma_ier_ctrl(p_dma_info, false);
+
+/*clear Rx DMA's interrupt status*/
+	BTIF_SET_BIT(RX_DMA_INT_FLAG(base), RX_DMA_INT_DONE | RX_DMA_INT_THRE);
+
+	valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base));
+	rpt = BTIF_READ32(RX_DMA_VFF_RPT(base));
+	wpt = BTIF_READ32(RX_DMA_VFF_WPT(base));
+	if ((valid_len == 0) && (rpt == wpt)) {
+		BTIF_DBG_FUNC
+		    ("rx interrupt, no data available in Rx DMA, wpt(0x%08x), rpt(0x%08x)\n",
+		     rpt, wpt);
+	}
+
+	i_ret = 0;
+
+	while ((valid_len > 0) || (rpt != wpt)) {
+		rpt_wrap = rpt & DMA_RPT_WRAP;
+		wpt_wrap = wpt & DMA_WPT_WRAP;
+		rpt &= DMA_RPT_MASK;
+		wpt &= DMA_WPT_MASK;
+
+/*calcaute length of available data  in vFIFO*/
+		if (wpt_wrap != p_mtk_vfifo->last_wpt_wrap)
+			real_len = wpt + vff_size - rpt;
+		else
+			real_len = wpt - rpt;
+
+		if (rx_cb != NULL) {
+			tail_len = vff_size - rpt;
+			p_vff_buf = vff_base + rpt;
+			if (tail_len >= real_len) {
+				(*rx_cb) (p_dma_info, p_vff_buf, real_len);
+			} else {
+				(*rx_cb) (p_dma_info, p_vff_buf, tail_len);
+				p_vff_buf = vff_base;
+				(*rx_cb) (p_dma_info, p_vff_buf, real_len -
+					  tail_len);
+			}
+			i_ret += real_len;
+		} else
+			BTIF_ERR_FUNC("no rx_cb found, please check your init process\n");
+		mb();
+		rpt += real_len;
+		if (rpt >= vff_size) {
+			/*read wrap bit should be revert*/
+			rpt_wrap ^= DMA_RPT_WRAP;
+			rpt %= vff_size;
+		}
+		rpt |= rpt_wrap;
+/*record wpt, last_wpt_wrap, rpt, last_rpt_wrap*/
+		p_mtk_vfifo->wpt = wpt;
+		p_mtk_vfifo->last_wpt_wrap = wpt_wrap;
+
+		p_mtk_vfifo->rpt = rpt;
+		p_mtk_vfifo->last_rpt_wrap = rpt_wrap;
+
+/*update rpt information to DMA controller*/
+		btif_reg_sync_writel(rpt, RX_DMA_VFF_RPT(base));
+
+/*get vff valid size again and check if rx data is processed completely*/
+		valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base));
+
+		rpt = BTIF_READ32(RX_DMA_VFF_RPT(base));
+		wpt = BTIF_READ32(RX_DMA_VFF_WPT(base));
+	}
+
+/*enable DMA Rx IER*/
+	hal_btif_dma_ier_ctrl(p_dma_info, true);
+
+	spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag);
+
+	return i_ret;
+}
+
+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info,
+			       ENUM_BTIF_REG_ID flag)
+{
+	int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+	unsigned int int_flag = 0;
+	unsigned int enable = 0;
+	unsigned int stop = 0;
+	unsigned int flush = 0;
+	unsigned int wpt = 0;
+	unsigned int rpt = 0;
+	unsigned int int_buf = 0;
+	unsigned int valid_size = 0;
+	/*unsigned long irq_flag = 0;*/
+
+#if defined(CONFIG_MTK_CLKMGR)
+	/*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/
+	if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) {
+		/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/
+		BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n",
+			      __FILE__);
+		return i_ret;
+	}
+#endif
+	int_flag = BTIF_READ32(TX_DMA_INT_FLAG(base));
+	enable = BTIF_READ32(TX_DMA_EN(base));
+	stop = BTIF_READ32(TX_DMA_STOP(base));
+	flush = BTIF_READ32(TX_DMA_FLUSH(base));
+	wpt = BTIF_READ32(TX_DMA_VFF_WPT(base));
+	rpt = BTIF_READ32(TX_DMA_VFF_RPT(base));
+	int_buf = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base));
+	valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base));
+	/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/
+
+	BTIF_INFO_FUNC("DMA's clock is on\n");
+	BTIF_INFO_FUNC("Tx DMA's base address: 0x%lx\n", base);
+
+	if (flag == REG_TX_DMA_ALL) {
+		BTIF_INFO_FUNC("TX_EN(:0x%x\n", enable);
+		BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag);
+		BTIF_INFO_FUNC("TX_STOP:0x%x\n", stop);
+		BTIF_INFO_FUNC("TX_FLUSH:0x%x\n", flush);
+		BTIF_INFO_FUNC("TX_WPT:0x%x\n", wpt);
+		BTIF_INFO_FUNC("TX_RPT:0x%x\n", rpt);
+		BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf);
+		BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size);
+		BTIF_INFO_FUNC("INT_EN:0x%x\n",
+			       BTIF_READ32(TX_DMA_INT_EN(base)));
+		BTIF_INFO_FUNC("TX_RST:0x%x\n", BTIF_READ32(TX_DMA_RST(base)));
+		BTIF_INFO_FUNC("VFF_ADDR:0x%x\n",
+			       BTIF_READ32(TX_DMA_VFF_ADDR(base)));
+		BTIF_INFO_FUNC("VFF_LEN:0x%x\n",
+			       BTIF_READ32(TX_DMA_VFF_LEN(base)));
+		BTIF_INFO_FUNC("TX_THRE:0x%x\n",
+			       BTIF_READ32(TX_DMA_VFF_THRE(base)));
+		BTIF_INFO_FUNC("W_INT_BUF_SIZE:0x%x\n",
+			       BTIF_READ32(TX_DMA_W_INT_BUF_SIZE(base)));
+		BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n",
+			       BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)));
+		BTIF_INFO_FUNC("DBG_STATUS:0x%x\n",
+			       BTIF_READ32(TX_DMA_DEBUG_STATUS(base)));
+		i_ret = 0;
+	} else {
+		BTIF_WARN_FUNC("unknown flag:%d\n", flag);
+	}
+	BTIF_INFO_FUNC("tx dma %s\n", (enable & DMA_EN_BIT) &&
+		       (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped");
+	BTIF_INFO_FUNC("data in tx dma is %s sent by HW\n",
+		       ((wpt == rpt) &&
+			(int_buf == 0)) ? "completely" : "not completely");
+
+	return i_ret;
+}
+
+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info,
+			       ENUM_BTIF_REG_ID flag)
+{
+	int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+	unsigned int int_flag = 0;
+	unsigned int enable = 0;
+	unsigned int stop = 0;
+	unsigned int flush = 0;
+	unsigned int wpt = 0;
+	unsigned int rpt = 0;
+	unsigned int int_buf = 0;
+	unsigned int valid_size = 0;
+	/*unsigned long irq_flag = 0;*/
+#if defined(CONFIG_MTK_CLKMGR)
+	/*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/
+	if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) {
+		/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/
+		BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n",
+			      __FILE__);
+		return i_ret;
+	}
+#endif
+	BTIF_INFO_FUNC("dump DMA status register\n");
+	_btif_dma_dump_dbg_reg();
+
+	int_flag = BTIF_READ32(RX_DMA_INT_FLAG(base));
+	enable = BTIF_READ32(RX_DMA_EN(base));
+	stop = BTIF_READ32(RX_DMA_STOP(base));
+	flush = BTIF_READ32(RX_DMA_FLUSH(base));
+	wpt = BTIF_READ32(RX_DMA_VFF_WPT(base));
+	rpt = BTIF_READ32(RX_DMA_VFF_RPT(base));
+	int_buf = BTIF_READ32(RX_DMA_INT_BUF_SIZE(base));
+	valid_size = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base));
+	/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/
+
+	BTIF_INFO_FUNC("DMA's clock is on\n");
+	BTIF_INFO_FUNC("Rx DMA's base address: 0x%lx\n", base);
+
+	if (flag == REG_RX_DMA_ALL) {
+		BTIF_INFO_FUNC("RX_EN(:0x%x\n", enable);
+		BTIF_INFO_FUNC("RX_STOP:0x%x\n", stop);
+		BTIF_INFO_FUNC("RX_FLUSH:0x%x\n", flush);
+		BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag);
+		BTIF_INFO_FUNC("RX_WPT:0x%x\n", wpt);
+		BTIF_INFO_FUNC("RX_RPT:0x%x\n", rpt);
+		BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf);
+		BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size);
+		BTIF_INFO_FUNC("INT_EN:0x%x\n",
+			       BTIF_READ32(RX_DMA_INT_EN(base)));
+		BTIF_INFO_FUNC("RX_RST:0x%x\n", BTIF_READ32(RX_DMA_RST(base)));
+		BTIF_INFO_FUNC("VFF_ADDR:0x%x\n",
+			       BTIF_READ32(RX_DMA_VFF_ADDR(base)));
+		BTIF_INFO_FUNC("VFF_LEN:0x%x\n",
+			       BTIF_READ32(RX_DMA_VFF_LEN(base)));
+		BTIF_INFO_FUNC("RX_THRE:0x%x\n",
+			       BTIF_READ32(RX_DMA_VFF_THRE(base)));
+		BTIF_INFO_FUNC("RX_FLOW_CTRL_THRE:0x%x\n",
+			       BTIF_READ32(RX_DMA_FLOW_CTRL_THRE(base)));
+		BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n",
+			       BTIF_READ32(RX_DMA_VFF_LEFT_SIZE(base)));
+		BTIF_INFO_FUNC("DBG_STATUS:0x%x\n",
+			       BTIF_READ32(RX_DMA_DEBUG_STATUS(base)));
+		i_ret = 0;
+	} else {
+		BTIF_WARN_FUNC("unknown flag:%d\n", flag);
+	}
+	BTIF_INFO_FUNC("rx dma %s\n", (enable & DMA_EN_BIT) &&
+		       (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped");
+	BTIF_INFO_FUNC("data in rx dma is %s by driver\n",
+		       ((wpt == rpt) &&
+			(int_buf == 0)) ? "received" : "not received");
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_dump_reg
+* DESCRIPTION
+*  dump BTIF module's information when needed
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* flag             [IN]        register id flag
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag)
+{
+	unsigned int i_ret = -1;
+
+	if (p_dma_info->dir == DMA_DIR_TX)
+		i_ret = hal_tx_dma_dump_reg(p_dma_info, flag);
+	else if (p_dma_info->dir == DMA_DIR_RX)
+		i_ret = hal_rx_dma_dump_reg(p_dma_info, flag);
+	else
+		BTIF_WARN_FUNC("unknown dir:%d\n", p_dma_info->dir);
+
+	return i_ret;
+}
+
+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info)
+{
+	unsigned int i_ret = -1;
+	unsigned long base = p_dma_info->base;
+	unsigned int stop = BTIF_READ32(TX_DMA_STOP(base));
+
+/*in MTK DMA BTIF channel we cannot set STOP and FLUSH bit at the same time*/
+	if ((stop && DMA_STOP_BIT) != 0)
+		BTIF_ERR_FUNC("BTIF's DMA in stop state, omit flush operation\n");
+	else {
+		BTIF_DBG_FUNC("flush tx dma\n");
+		BTIF_SET_BIT(TX_DMA_FLUSH(base), DMA_FLUSH_BIT);
+		i_ret = 0;
+	}
+	return i_ret;
+}
+
+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info)
+{
+	bool b_ret = true;
+	unsigned long base = p_dma_info->base;
+
+/*see if flush operation is in process*/
+	b_ret = ((DMA_FLUSH_BIT & BTIF_READ32(TX_DMA_FLUSH(base))) != 0) ? true : false;
+
+	return b_ret;
+}
+
+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid)
+{
+	int i_ret = -1;
+
+	BTIF_INFO_FUNC("op id: %d\n", opid);
+	switch (opid) {
+	case BTIF_PM_DPIDLE_EN:
+		i_ret = 0;
+		break;
+	case BTIF_PM_DPIDLE_DIS:
+		i_ret = 0;
+		break;
+	case BTIF_PM_SUSPEND:
+		i_ret = 0;
+		break;
+	case BTIF_PM_RESUME:
+		i_ret = 0;
+		break;
+	case BTIF_PM_RESTORE_NOIRQ:{
+			unsigned int flag = 0;
+			P_MTK_BTIF_IRQ_STR p_irq = p_dma_info->p_irq;
+
+#ifdef CONFIG_OF
+			flag = p_irq->irq_flags;
+#else
+			switch (p_irq->sens_type) {
+			case IRQ_SENS_EDGE:
+				if (p_irq->edge_type == IRQ_EDGE_FALL)
+					flag = IRQF_TRIGGER_FALLING;
+				else if (p_irq->edge_type == IRQ_EDGE_RAISE)
+					flag = IRQF_TRIGGER_RISING;
+				else if (p_irq->edge_type == IRQ_EDGE_BOTH)
+					flag = IRQF_TRIGGER_RISING |
+					    IRQF_TRIGGER_FALLING;
+				else
+					flag = IRQF_TRIGGER_FALLING;	/*make this as default type */
+				break;
+			case IRQ_SENS_LVL:
+				if (p_irq->lvl_type == IRQ_LVL_LOW)
+					flag = IRQF_TRIGGER_LOW;
+				else if (p_irq->lvl_type == IRQ_LVL_HIGH)
+					flag = IRQF_TRIGGER_HIGH;
+				else
+					flag = IRQF_TRIGGER_LOW;	/*make this as default type */
+				break;
+			default:
+				flag = IRQF_TRIGGER_LOW;	/*make this as default type */
+				break;
+			}
+#endif
+/* irq_set_irq_type(p_irq->irq_id, flag); */
+			i_ret = 0;
+		}
+		i_ret = 0;
+		break;
+	default:
+		i_ret = ERR_INVALID_PAR;
+		break;
+	}
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_receive_data
+* DESCRIPTION
+*  receive data from btif module in DMA polling mode
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  positive means data is available, 0 means no data available
+*****************************************************************************/
+#ifndef MTK_BTIF_MARK_UNUSED_API
+int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info,
+			 unsigned char *p_buf, const unsigned int max_len)
+{
+	unsigned int i_ret = -1;
+
+	return i_ret;
+}
+#endif
+
+int _btif_dma_dump_dbg_reg(void)
+{
+#if 0
+	static MTK_BTIF_DMA_REG_DMP_DBG g_dma_dbg_regs[] = {
+		{0x10201180, 0x0},
+		{0x10201184, 0x0},
+		{0x10201188, 0x0},
+		{0x1020118C, 0x0},
+		{0x10201190, 0x0},
+		{0x1000320C, 0x0},
+		{0x10003210, 0x0},
+		{0x10003214, 0x0},
+	};
+
+	int i = 0;
+	char *addr1 = NULL;
+	char *addr2 = NULL;
+
+	int array_num = ARRAY_SIZE(g_dma_dbg_regs)
+
+	addr1 = ioremap(g_dma_dbg_regs[0].reg_addr, 0x20);
+	if (addr1) {
+		for (i = 0; i < 5; i++)
+			g_dma_dbg_regs[i].reg_val = *(volatile unsigned int*)(addr1 + i*4);
+		iounmap(addr1);
+	}
+
+	addr2 = ioremap(g_dma_dbg_regs[5].reg_addr, 0x10);
+	if (addr2) {
+		g_dma_dbg_regs[5].reg_val = *(volatile unsigned int*)(addr2);
+		g_dma_dbg_regs[6].reg_val = *(volatile unsigned int*)(addr2+4);
+		g_dma_dbg_regs[7].reg_val = *(volatile unsigned int*)(addr2+8);
+		iounmap(addr2);
+	}
+
+	for (i = 0; i < array_num; i++)
+		BTIF_INFO_FUNC("<reg, val>-<0x%lx, 0x%08x>\n", g_dma_dbg_regs[i].reg_addr, g_dma_dbg_regs[i].reg_val);
+#endif
+	return 0;
+}
+
+static void hal_btif_tx_dma_vff_set_for_4g(void)
+{
+	BTIF_DBG_FUNC("Set btif tx_vff_addr bit29\n");
+	BTIF_SET_BIT(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), DMA_VFF_BIT29_OFFSET);
+	BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base),
+					BTIF_READ32(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base)));
+}
+static void hal_btif_rx_dma_vff_set_for_4g(void)
+{
+	BTIF_DBG_FUNC("Set btif rx_vff_addr bit29\n");
+	BTIF_SET_BIT(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), DMA_VFF_BIT29_OFFSET);
+	BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base),
+					BTIF_READ32(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base)));
+}
+
diff --git a/drivers/misc/mediatek/btif/common/btif_plat.c b/drivers/misc/mediatek/btif/common/btif_plat.c
new file mode 100644
index 0000000000000..e098e902317cc
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/btif_plat.c
@@ -0,0 +1,1396 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG "MTK-BTIF"
+
+#define NEW_TX_HANDLING_SUPPORT 1
+
+#include "btif_pub.h"
+#include "btif_priv.h"
+
+#define BTIF_USER_ID "btif_driver"
+
+static spinlock_t g_clk_cg_spinlock;	/*BTIF clock's spinlock */
+
+/*-----------------------------BTIF Module Clock and Power Control Defination------------------*/
+
+MTK_BTIF_IRQ_STR mtk_btif_irq = {
+	.name = "mtk btif irq",
+	.is_irq_sup = true,
+	.reg_flag = false,
+#ifdef CONFIG_OF
+	.irq_flags = IRQF_TRIGGER_NONE,
+#else
+	.irq_id = MT_BTIF_IRQ_ID,
+	.sens_type = IRQ_SENS_LVL,
+	.lvl_type = IRQ_LVL_LOW,
+#endif
+	.p_irq_handler = NULL,
+};
+
+/*
+ * will call clock manager's API export by WCP to control BTIF's clock,
+ * but we may need to access these registers in case of btif clock control logic is wrong in clock manager
+ */
+
+MTK_BTIF_INFO_STR mtk_btif = {
+#ifndef CONFIG_OF
+	.base = MTK_BTIF_REG_BASE,
+#endif
+	.p_irq = &mtk_btif_irq,
+	.tx_fifo_size = BTIF_TX_FIFO_SIZE,
+	.rx_fifo_size = BTIF_RX_FIFO_SIZE,
+	.tx_tri_lvl = BTIF_TX_FIFO_THRE,
+	.rx_tri_lvl = BTIF_RX_FIFO_THRE,
+	.rx_data_len = 0,
+	.p_tx_fifo = NULL,
+};
+#if !(NEW_TX_HANDLING_SUPPORT)
+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif);
+#endif
+
+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info,
+			       unsigned char *p_buf,
+			       const unsigned int max_len);
+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_rx_ier_ctrl
+* DESCRIPTION
+*  BTIF Rx interrupt enable/disable
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* enable    [IN]        control if rx interrupt enabled or not
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+static int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_tx_ier_ctrl
+* DESCRIPTION
+*  BTIF Tx interrupt enable/disable
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* enable    [IN]        control if tx interrupt enabled or not
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+static int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en);
+
+#ifndef MTK_BTIF_MARK_UNUSED_API
+static int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en);
+
+/*****************************************************************************
+* FUNCTION
+*  _btif_receive_data
+* DESCRIPTION
+*  receive data from btif module in FIFO polling mode
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  positive means data is available, 0 means no data available
+*****************************************************************************/
+static int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif,
+			      unsigned char *p_buf, const unsigned int max_len);
+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count);
+#endif
+
+static int btif_dump_array(char *string, char *p_buf, int len)
+{
+	unsigned int idx = 0;
+	unsigned char str[30];
+	unsigned char *p_str;
+
+	pr_debug("========dump %s start <length:%d>========\n", string, len);
+	p_str = &str[0];
+	for (idx = 0; idx < len; idx++, p_buf++) {
+		sprintf(p_str, "%02x ", *p_buf);
+		p_str += 3;
+		if (7 == (idx % 8)) {
+			*p_str++ = '\n';
+			*p_str = '\0';
+			pr_debug("%s", str);
+			p_str = &str[0];
+		}
+	}
+	if (len % 8) {
+		*p_str++ = '\n';
+		*p_str = '\0';
+		pr_debug("%s", str);
+	}
+	pr_debug("========dump %s end========\n", string);
+	return 0;
+}
+
+#if NEW_TX_HANDLING_SUPPORT
+static int _btif_tx_fifo_init(P_MTK_BTIF_INFO_STR p_btif_info)
+{
+	int i_ret = -1;
+
+	spin_lock_init(&(p_btif_info->tx_fifo_spinlock));
+
+	if (p_btif_info->p_tx_fifo == NULL) {
+		p_btif_info->p_tx_fifo = kzalloc(sizeof(struct kfifo),
+						 GFP_ATOMIC);
+		if (p_btif_info->p_tx_fifo == NULL) {
+			i_ret = -ENOMEM;
+			BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n");
+			goto ret;
+		}
+
+		i_ret = kfifo_alloc(p_btif_info->p_tx_fifo,
+				    BTIF_HAL_TX_FIFO_SIZE, GFP_ATOMIC);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret);
+			i_ret = -ENOMEM;
+			goto ret;
+		}
+		i_ret = 0;
+	} else {
+		BTIF_WARN_FUNC
+		    ("p_btif_info->p_tx_fifo is already init p_btif_info->p_tx_fifo(0x%p)\n",
+		     p_btif_info->p_tx_fifo);
+		i_ret = 0;
+	}
+ret:
+	return i_ret;
+}
+
+static int _get_btif_tx_fifo_room(P_MTK_BTIF_INFO_STR p_btif_info)
+{
+	int i_ret = 0;
+	unsigned long flag = 0;
+
+	spin_lock_irqsave(&(p_btif_info->tx_fifo_spinlock), flag);
+	if (p_btif_info->p_tx_fifo == NULL)
+		i_ret = 0;
+	else
+		i_ret = kfifo_avail(p_btif_info->p_tx_fifo);
+	spin_unlock_irqrestore(&(p_btif_info->tx_fifo_spinlock), flag);
+	BTIF_DBG_FUNC("tx kfifo:0x%p, available room:%d\n", p_btif_info->p_tx_fifo, i_ret);
+	return i_ret;
+}
+
+static int _btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif_info)
+{
+	int i_ret = 0;
+
+	if (p_btif_info->p_tx_fifo != NULL)
+		kfifo_reset(p_btif_info->p_tx_fifo);
+	return i_ret;
+}
+
+#endif
+
+#ifdef CONFIG_OF
+static void _btif_set_default_setting(void)
+{
+	struct device_node *node = NULL;
+	unsigned int irq_info[3] = {0, 0, 0};
+	unsigned int phy_base;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mtk-btif");
+	if (node) {
+		mtk_btif.p_irq->irq_id = irq_of_parse_and_map(node, 0);
+		/*fixme, be compitable arch 64bits*/
+		mtk_btif.base = (unsigned long)of_iomap(node, 0);
+		BTIF_INFO_FUNC("get btif irq(%d),register base(0x%lx)\n",
+			mtk_btif.p_irq->irq_id, mtk_btif.base);
+	} else {
+		BTIF_ERR_FUNC("get btif device node fail\n");
+	}
+
+	/* get the interrupt line behaviour */
+	if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) {
+		BTIF_ERR_FUNC("get interrupt flag from DTS fail\n");
+	} else {
+		mtk_btif.p_irq->irq_flags = irq_info[2];
+		BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", mtk_btif.p_irq->irq_flags);
+	}
+
+	if (of_property_read_u32_index(node, "reg", 1, &phy_base))
+		BTIF_ERR_FUNC("get register phy base from DTS fail\n");
+	else
+		BTIF_INFO_FUNC("get register phy base(0x%x)\n", (unsigned int)phy_base);
+}
+#endif
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_info_get
+* DESCRIPTION
+*  get btif's information included base address , irq related information
+* PARAMETERS
+* RETURNS
+*  BTIF's information
+*****************************************************************************/
+P_MTK_BTIF_INFO_STR hal_btif_info_get(void)
+{
+#if NEW_TX_HANDLING_SUPPORT
+	int i_ret = 0;
+/*tx fifo and fifo lock init*/
+	i_ret = _btif_tx_fifo_init(&mtk_btif);
+	if (i_ret == 0)
+		BTIF_INFO_FUNC("_btif_tx_fifo_init succeed\n");
+	else
+		BTIF_ERR_FUNC("_btif_tx_fifo_init failed, i_ret:%d\n", i_ret);
+
+#endif
+
+#ifdef CONFIG_OF
+	_btif_set_default_setting();
+#endif
+
+	spin_lock_init(&g_clk_cg_spinlock);
+
+	return &mtk_btif;
+}
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_get_and_prepare
+* DESCRIPTION
+*  get clock from device tree and prepare for enable/disable control
+* PARAMETERS
+* pdev  device pointer
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+#if !defined(CONFIG_MTK_CLKMGR)
+int hal_btif_clk_get_and_prepare(struct platform_device *pdev)
+{
+		int i_ret = -1;
+
+		clk_btif = devm_clk_get(&pdev->dev, "main");
+		if (IS_ERR(clk_btif)) {
+			BTIF_ERR_FUNC("[CCF]cannot get clk_btif clock.\n");
+			return PTR_ERR(clk_btif);
+		}
+		BTIF_ERR_FUNC("[CCF]clk_btif=%p\n", clk_btif);
+		clk_btif_apdma = devm_clk_get(&pdev->dev, "apdmac");
+		if (IS_ERR(clk_btif_apdma)) {
+			BTIF_ERR_FUNC("[CCF]cannot get clk_btif_apdma clock.\n");
+			return PTR_ERR(clk_btif_apdma);
+		}
+		BTIF_ERR_FUNC("[CCF]clk_btif_apdma=%p\n", clk_btif_apdma);
+
+		i_ret = clk_prepare(clk_btif);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("clk_prepare clk_btif failed! ret:%d\n", i_ret);
+			return i_ret;
+		}
+
+		i_ret = clk_prepare(clk_btif_apdma);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("clk_prepare clk_btif_apdma failed! ret:%d\n", i_ret);
+			return i_ret;
+		}
+		return i_ret;
+}
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_unprepare
+* DESCRIPTION
+*  unprepare btif clock and apdma clock
+* PARAMETERS
+* none
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_clk_unprepare(void)
+{
+	clk_unprepare(clk_btif);
+	clk_unprepare(clk_btif_apdma);
+	return 0;
+}
+#endif
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_ctrl
+* DESCRIPTION
+*  control clock output enable/disable of BTIF module
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag)
+{
+/*In MTK BTIF, there's only one global CG on AP_DMA, no sub channel's CG bit*/
+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/
+	int i_ret = 0;
+	unsigned long irq_flag = 0;
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	static atomic_t s_clk_ref = ATOMIC_INIT(0);
+#else
+	static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE;
+#endif
+
+	spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);
+
+#if MTK_BTIF_ENABLE_CLK_CTL
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+
+	if (flag == CLK_OUT_ENABLE) {
+		if (atomic_inc_return(&s_clk_ref) == 1) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID);
+#else
+			BTIF_DBG_FUNC("[CCF]enable clk_btif\n");
+			i_ret = clk_enable(clk_btif);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d",
+					 i_ret);
+			}
+		}
+	} else if (flag == CLK_OUT_DISABLE) {
+		if (atomic_dec_return(&s_clk_ref) == 0) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID);
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d",
+					 i_ret);
+			}
+#else
+			BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n");
+			clk_disable(clk_btif);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+		}
+	} else {
+		i_ret = ERR_INVALID_PAR;
+		BTIF_ERR_FUNC("invalid	clock ctrl flag (%d)\n", flag);
+	}
+
+#else
+
+	if (status == flag) {
+		i_ret = 0;
+		BTIF_DBG_FUNC("btif clock already %s\n",
+			      CLK_OUT_ENABLE ==
+			      status ? "enabled" : "disabled");
+	} else {
+		if (flag == CLK_OUT_ENABLE) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID);
+#else
+			BTIF_DBG_FUNC("[CCF]enable clk_btif\n");
+			i_ret = clk_enable(clk_btif);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+			status = (i_ret == 0) ? flag : status;
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d",
+					 i_ret);
+			}
+		} else if (flag == CLK_OUT_DISABLE) {
+#if defined(CONFIG_MTK_CLKMGR)
+			i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID);
+			status = (i_ret == 0) ? flag : status;
+			if (i_ret) {
+				BTIF_WARN_FUNC
+					("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d",
+					 i_ret);
+			}
+#else
+			BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n");
+			clk_disable(clk_btif);
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+		} else {
+			i_ret = ERR_INVALID_PAR;
+			BTIF_ERR_FUNC("invalid	clock ctrl flag (%d)\n", flag);
+		}
+	}
+#endif
+
+#else
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+
+#else
+
+	status = flag;
+#endif
+
+	i_ret = 0;
+#endif
+
+	spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	if (i_ret == 0) {
+		BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled");
+	} else {
+		BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n",
+				flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret);
+	}
+#else
+
+	if (i_ret == 0) {
+		BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled");
+	} else {
+		BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n",
+			      flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret);
+	}
+#endif
+#if defined(CONFIG_MTK_CLKMGR)
+	BTIF_DBG_FUNC("BTIF's clock is %s\n", (clock_is_on(MTK_BTIF_CG_BIT) == 0) ? "off" : "on");
+#endif
+	return i_ret;
+}
+
+static int btif_new_handshake_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool enable)
+{
+	unsigned long base = p_btif->base;
+
+	if (enable == true)
+		BTIF_SET_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE);
+	else
+		BTIF_CLR_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE);
+	return true;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_hw_init
+* DESCRIPTION
+*  BTIF hardware init
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif)
+{
+/*Chaozhong: To be implement*/
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+#if NEW_TX_HANDLING_SUPPORT
+	_btif_tx_fifo_reset(p_btif);
+#endif
+
+/*set to normal mode*/
+	btif_reg_sync_writel(BTIF_FAKELCR_NORMAL_MODE, BTIF_FAKELCR(base));
+/*set to newhandshake mode*/
+	btif_new_handshake_ctrl(p_btif, true);
+/*No need to access: enable sleep mode*/
+/*No need to access: set Rx timeout count*/
+/*set Tx threshold*/
+/*set Rx threshold*/
+/*disable internal loopback test*/
+
+/*set Rx FIFO clear bit to 1*/
+	BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX);
+/*clear Rx FIFO clear bit to 0*/
+	BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX);
+/*set Tx FIFO clear bit to 1*/
+	BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX);
+/*clear Tx FIFO clear bit to 0*/
+	BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX);
+
+	btif_reg_sync_writel(BTIF_TRI_LVL_TX(p_btif->tx_tri_lvl)
+			     | BTIF_TRI_LVL_RX(p_btif->rx_tri_lvl)
+			     | BTIF_TRI_LOOP_DIS, BTIF_TRI_LVL(base));
+	hal_btif_loopback_ctrl(p_btif, false);
+/*disable BTIF Tx DMA mode*/
+	hal_btif_tx_mode_ctrl(p_btif, false);
+/*disable BTIF Rx DMA mode*/
+	hal_btif_rx_mode_ctrl(p_btif, false);
+/*auto reset*/
+	BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_AUTORST_EN);
+/*disable Tx IER*/
+	hal_btif_tx_ier_ctrl(p_btif, false);
+/*enable Rx IER by default*/
+	hal_btif_rx_ier_ctrl(p_btif, true);
+
+	i_ret = 0;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_rx_ier_ctrl
+* DESCRIPTION
+*  BTIF Rx interrupt enable/disable
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* enable    [IN]        control if rx interrupt enabled or not
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+	if (en == false)
+		BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_RXFEN);
+	else
+		BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_RXFEN);
+
+/*TODO:do we need to read back ? Answer: no*/
+	i_ret = 0;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_tx_ier_ctrl
+* DESCRIPTION
+*  BTIF Tx interrupt enable/disable
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* enable    [IN]        control if tx interrupt enabled or not
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+	if (en == false)
+		BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_TXEEN);
+	else
+		BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_TXEEN);
+
+/*TODO:do we need to read back ? Answer: no*/
+	i_ret = 0;
+
+	return i_ret;
+}
+
+#ifndef MTK_BTIF_MARK_UNUSED_API
+
+/*****************************************************************************
+* FUNCTION
+*  _btif_receive_data
+* DESCRIPTION
+*  receive data from btif module in FIFO polling mode
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  positive means data is available, 0 means no data available
+*****************************************************************************/
+int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif,
+		       unsigned char *p_buf, const unsigned int max_len)
+{
+/*Chaozhong: To be implement*/
+	int i_ret = -1;
+
+/*check parameter valid or not*/
+	if ((p_buf == NULL) || (max_len == 0)) {
+		i_ret = ERR_INVALID_PAR;
+		return i_ret;
+	}
+	i_ret = btif_rx_irq_handler(p_btif, p_buf, max_len);
+
+	return i_ret;
+}
+
+int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+	if (en == false)
+		BTIF_CLR_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT);
+	else
+		BTIF_SET_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT);
+
+/*TODO:do we need to read back ? Answer: no*/
+/*TODO:do we need to dsb?*/
+	i_ret = 0;
+	return i_ret;
+}
+
+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+	unsigned int value = 0;
+
+/*read BTIF_TRI_LVL*/
+	value = BTIF_READ32(BTIF_TRI_LVL(base));
+/*clear Tx threshold bits*/
+	value &= (~BTIF_TRI_LVL_TX_MASK);
+/*set tx threshold bits*/
+	value |= BTIF_TRI_LVL_TX(BTIF_TX_FIFO_THRE);
+/*write back to BTIF_TRI_LVL*/
+	btif_reg_sync_writel(value, BTIF_TRI_LVL(base));
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  btif_rx_fifo_reset
+* DESCRIPTION
+*  reset BTIF's rx fifo
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* ec         [IN]        control if loopback mode is enabled or not
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+static int btif_rx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif)
+{
+/*Chaozhong: To be implement*/
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+/*set Rx FIFO clear bit to 1*/
+	BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX);
+
+/*clear Rx FIFO clear bit to 0*/
+	BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX);
+
+/*TODO:do we need to read back ? Answer: no*/
+/*TODO:do we need to dsb?*/
+	i_ret = 0;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  btif_tx_fifo_reset
+* DESCRIPTION
+*  reset BTIF's tx fifo
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+static int btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+/*set Tx FIFO clear bit to 1*/
+	BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX);
+
+/*clear Tx FIFO clear bit to 0*/
+	BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX);
+
+/*TODO:do we need to read back ? Answer: no*/
+/*TODO:do we need to dsb?*/
+	i_ret = 0;
+	return i_ret;
+}
+
+#endif
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_loopback_ctrl
+* DESCRIPTION
+*  BTIF Tx/Rx loopback mode set, this operation can only be done after set BTIF to normal mode
+* PARAMETERS
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+	if (en == false)
+		BTIF_CLR_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN);
+	else
+		BTIF_SET_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN);
+
+/*TODO:do we need to read back ? Answer: no*/
+/*TODO:do we need to dsb?*/
+	i_ret = 0;
+	return i_ret;
+}
+
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_rx_handler
+* DESCRIPTION
+*  lower level interrupt handler
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  0 means success; negative means fail; positive means rx data length
+*****************************************************************************/
+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif,
+			 unsigned char *p_buf, const unsigned int max_len)
+{
+/*Chaozhong: To be implement*/
+	int i_ret = -1;
+	unsigned int iir = 0;
+	unsigned int rx_len = 0;
+	unsigned long base = p_btif->base;
+
+#if 0
+/*check parameter valid or not*/
+	if ((p_buf == NULL) || (max_len == 0)) {
+		i_ret = ERR_INVALID_PAR;
+		return i_ret;
+	}
+#endif
+	unsigned long irq_flag = 0;
+
+	spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);
+
+#if defined(CONFIG_MTK_CLKMGR)
+	if (clock_is_on(MTK_BTIF_CG_BIT) == 0) {
+		spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);
+		BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n",
+			      __FILE__);
+		return i_ret;
+	}
+#endif
+/*read interrupt identifier register*/
+	iir = BTIF_READ32(BTIF_IIR(base));
+
+/*is rx interrupt exist?*/
+#if 0
+	while ((iir & BTIF_IIR_RX) && (rx_len < max_len)) {
+		rx_len +=
+		    btif_rx_irq_handler(p_btif, (p_buf + rx_len),
+					(max_len - rx_len));
+
+/*update IIR*/
+		iir = BTIF_READ32(BTIF_IIR(base));
+	}
+#endif
+
+	while (iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) {
+		rx_len += btif_rx_irq_handler(p_btif, p_buf, max_len);
+
+/*update IIR*/
+		iir = BTIF_READ32(BTIF_IIR(base));
+	}
+
+/*is tx interrupt exist?*/
+	if (iir & BTIF_IIR_TX_EMPTY)
+		i_ret = btif_tx_irq_handler(p_btif);
+	spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);
+
+	i_ret = rx_len != 0 ? rx_len : i_ret;
+	return i_ret;
+}
+
+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, btif_rx_buf_write rx_cb)
+{
+	if (p_btif_info->rx_cb != NULL)
+		BTIF_DBG_FUNC("rx_cb already registered, replace (0x%p) with (0x%p)\n",
+		     p_btif_info->rx_cb, rx_cb);
+	p_btif_info->rx_cb = rx_cb;
+
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  btif_rx_irq_handler
+* DESCRIPTION
+*  lower level rx interrupt handler
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  positive means length of rx data , negative means fail
+*****************************************************************************/
+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info,
+			       unsigned char *p_buf, const unsigned int max_len)
+{
+/*Chaozhong: To be implement*/
+	int i_ret = 0;
+	unsigned int iir = 0;
+	unsigned int rx_len = 0;
+	unsigned long base = p_btif_info->base;
+	unsigned char rx_buf[256];
+	unsigned int local_buf_len = 256;
+	btif_rx_buf_write rx_cb = p_btif_info->rx_cb;
+	unsigned int total_len = 0;
+
+/*read interrupt identifier register*/
+	iir = BTIF_READ32(BTIF_IIR(base));
+	while ((iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) &&
+	       (rx_len < local_buf_len)) {
+		rx_buf[rx_len] = BTIF_READ8(base);
+		rx_len++;
+/*need to consult CC Hwang for advice */
+/*
+ * whether we need to do memory barrier here
+ * Ans: no
+ */
+/*
+ * whether we need to d memory barrier when call BTIF_SET_BIT or BTIF_CLR_BIT
+ * Ans: no
+ */
+		if (rx_len == local_buf_len) {
+			if (rx_cb)
+				(*rx_cb) (p_btif_info, rx_buf, rx_len);
+			rx_len = 0;
+			total_len += rx_len;
+		}
+		iir = BTIF_READ32(BTIF_IIR(base));
+	}
+	total_len += rx_len;
+	if (rx_len && rx_cb)
+		(*rx_cb) (p_btif_info, rx_buf, rx_len);
+
+/*
+ * make sure all data write back to memory, mb or dsb?
+ * need to consult CC Hwang for advice
+ * Ans: no need here
+ */
+	i_ret = total_len;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  btif_tx_irq_handler
+* DESCRIPTION
+*  lower level tx interrupt handler
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif)
+{
+	int i_ret = -1;
+
+#if NEW_TX_HANDLING_SUPPORT
+	int how_many = 0;
+	unsigned int lsr;
+	unsigned int ava_len = 0;
+	unsigned long base = p_btif->base;
+	char local_buf[BTIF_TX_FIFO_SIZE];
+	char *p_data = local_buf;
+	unsigned long flag = 0;
+
+	struct kfifo *p_tx_fifo = p_btif->p_tx_fifo;
+
+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/
+	lsr = BTIF_READ32(BTIF_LSR(base));
+
+	if (lsr & BTIF_LSR_TEMT_BIT)
+		/*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/
+		ava_len = BTIF_TX_FIFO_SIZE;
+	else if (lsr & BTIF_LSR_THRE_BIT)
+		/*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/
+		ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE;
+	else {
+		/*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/
+		ava_len = 0;
+		goto ret;
+	}
+	spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag);
+	how_many = kfifo_out(p_tx_fifo, local_buf, ava_len);
+	spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag);
+	BTIF_DBG_FUNC("BTIF tx size %d done, left:%d\n", how_many,
+		      kfifo_avail(p_tx_fifo));
+	while (how_many--)
+		btif_reg_sync_writeb(*(p_data++), BTIF_THR(base));
+
+	spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag);
+/*clear Tx enable flag if necessary*/
+	if (kfifo_is_empty(p_tx_fifo)) {
+		hal_btif_tx_ier_ctrl(p_btif, false);
+		BTIF_DBG_FUNC("BTIF tx FIFO is empty\n");
+	}
+	spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag);
+ret:
+#else
+/*clear Tx enable flag*/
+	hal_btif_tx_ier_ctrl(p_btif, false);
+#endif
+	i_ret = 0;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_tx_mode_ctrl
+* DESCRIPTION
+*  set BTIF tx to corresponding mode (PIO/DMA)
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* mode     [IN]        rx mode <PIO/DMA>
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+	if (mode == BTIF_MODE_DMA)
+		/*set to DMA mode*/
+		BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX);
+	else
+		/*set to PIO mode*/
+		BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX);
+
+	i_ret = 0;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_rx_mode_ctrl
+* DESCRIPTION
+*  set BTIF rx to corresponding mode (PIO/DMA)
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* mode     [IN]        rx mode <PIO/DMA>
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+
+	if (mode == BTIF_MODE_DMA)
+		/*set to DMA mode*/
+		BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX);
+	else
+		/*set to PIO mode*/
+		BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX);
+
+	i_ret = 0;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_send_data
+* DESCRIPTION
+*  send data through btif in FIFO mode
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* p_buf     [IN]        pointer to rx data buffer
+* max_len  [IN]        tx buffer length
+* RETURNS
+*   positive means number of data sent; 0 means no data put to FIFO; negative means error happens
+*****************************************************************************/
+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif,
+		       const unsigned char *p_buf, const unsigned int buf_len)
+{
+/*Chaozhong: To be implement*/
+	int i_ret = -1;
+
+	unsigned int ava_len = 0;
+	unsigned int sent_len = 0;
+
+#if !(NEW_TX_HANDLING_SUPPORT)
+	unsigned long base = p_btif->base;
+	unsigned int lsr = 0;
+	unsigned int left_len = 0;
+	unsigned char *p_data = (unsigned char *)p_buf;
+#endif
+
+/*check parameter valid or not*/
+	if ((p_buf == NULL) || (buf_len == 0)) {
+		i_ret = ERR_INVALID_PAR;
+		return i_ret;
+	}
+#if NEW_TX_HANDLING_SUPPORT
+	ava_len = _get_btif_tx_fifo_room(p_btif);
+	sent_len = buf_len <= ava_len ? buf_len : ava_len;
+	if (sent_len > 0) {
+		int enqueue_len = 0;
+		unsigned long flag = 0;
+
+		spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag);
+		enqueue_len = kfifo_in(p_btif->p_tx_fifo,
+				       (unsigned char *)p_buf, sent_len);
+		if (sent_len != enqueue_len) {
+			BTIF_ERR_FUNC("target tx len:%d, len sent:%d\n",
+				      sent_len, enqueue_len);
+		}
+		i_ret = enqueue_len;
+		mb();
+/*enable BTIF Tx IRQ*/
+		hal_btif_tx_ier_ctrl(p_btif, true);
+		spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag);
+		BTIF_DBG_FUNC("enqueue len:%d\n", enqueue_len);
+	} else {
+		i_ret = 0;
+	}
+#else
+	while ((_btif_is_tx_allow(p_btif)) && (sent_len < buf_len)) {
+		/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/
+		lsr = BTIF_READ32(BTIF_LSR(base));
+
+		if (lsr & BTIF_LSR_TEMT_BIT)
+			/*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/
+			ava_len = BTIF_TX_FIFO_SIZE;
+		else if (lsr & BTIF_LSR_THRE_BIT)
+			/*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/
+			ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE;
+		else {
+			/*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/
+			ava_len = 0;
+			break;
+		}
+
+		left_len = buf_len - sent_len;
+/*ava_len will be real length will write to BTIF THR*/
+		ava_len = ava_len > left_len ? left_len : ava_len;
+/*update sent length valud after this operation*/
+		sent_len += ava_len;
+/*
+ * whether we need memory barrier here?
+ * Ans: No, no memory ordering issue exist,
+ * CPU will make sure logically right
+ */
+		while (ava_len--)
+			btif_reg_sync_writeb(*(p_data++), BTIF_THR(base));
+
+	}
+/* while ((hal_btif_is_tx_allow()) && (sent_len < buf_len)); */
+
+	i_ret = sent_len;
+
+/*enable BTIF Tx IRQ*/
+	hal_btif_tx_ier_ctrl(p_btif, true);
+#endif
+	return i_ret;
+}
+
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_raise_wak_sig
+* DESCRIPTION
+*  raise wakeup signal to counterpart
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif)
+{
+	int i_ret = -1;
+	unsigned long base = p_btif->base;
+#if defined(CONFIG_MTK_CLKMGR)
+	if (clock_is_on(MTK_BTIF_CG_BIT) == 0) {
+		BTIF_ERR_FUNC("%s: clock is off before send wakeup signal!!!\n",
+			      __FILE__);
+		return i_ret;
+	}
+#endif
+/*write 0  to BTIF_WAK to pull ap_wakeup_consyss low */
+	BTIF_CLR_BIT(BTIF_WAK(base), BTIF_WAK_BIT);
+
+/*wait for a period for longer than 1/32k period, here we use 40us*/
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	usleep_range(128, 160);
+/*
+ * according to linux/documentation/timers/timers-how-to, we choose usleep_range
+ * SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms):      * Use usleep_range
+ */
+/*write 1 to pull ap_wakeup_consyss high*/
+	BTIF_SET_BIT(BTIF_WAK(base), BTIF_WAK_BIT);
+	i_ret = 0;
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_dump_reg
+* DESCRIPTION
+*  dump BTIF module's information when needed
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* flag        [IN]        register id flag
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag)
+{
+/*Chaozhong: To be implement*/
+	int i_ret = -1;
+	int idx = 0;
+	/*unsigned long irq_flag = 0;*/
+	unsigned long base = p_btif->base;
+	unsigned char reg_map[0xE0 / 4] = { 0 };
+	unsigned int lsr = 0x0;
+	unsigned int dma_en = 0;
+
+	/*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/
+#if defined(CONFIG_MTK_CLKMGR)
+	if (clock_is_on(MTK_BTIF_CG_BIT) == 0) {
+		/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/
+		BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n",
+			      __FILE__);
+		return i_ret;
+	}
+#endif
+	lsr = BTIF_READ32(BTIF_LSR(base));
+	dma_en = BTIF_READ32(BTIF_DMA_EN(base));
+	/*
+	 * here we omit 1st register which is THR/RBR register to avoid
+	 * Rx data read by this debug information accidently
+	 */
+	for (idx = 1; idx < sizeof(reg_map); idx++)
+		reg_map[idx] = BTIF_READ8(p_btif->base + (4 * idx));
+	/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/
+	BTIF_INFO_FUNC("BTIF's clock is on\n");
+	BTIF_INFO_FUNC("base address: 0x%lx\n", base);
+	switch (flag) {
+	case REG_BTIF_ALL:
+#if 0
+		BTIF_INFO_FUNC("BTIF_IER:0x%x\n", BTIF_READ32(BTIF_IER(base)));
+		BTIF_INFO_FUNC("BTIF_IIR:0x%x\n", BTIF_READ32(BTIF_IIR(base)));
+		BTIF_INFO_FUNC("BTIF_FAKELCR:0x%x\n",
+			       BTIF_READ32(BTIF_FAKELCR(base)));
+		BTIF_INFO_FUNC("BTIF_LSR:0x%x\n", BTIF_READ32(BTIF_LSR(base)));
+		BTIF_INFO_FUNC("BTIF_SLEEP_EN:0x%x\n",
+			       BTIF_READ32(BTIF_SLEEP_EN(base)));
+		BTIF_INFO_FUNC("BTIF_DMA_EN:0x%x\n",
+			       BTIF_READ32(BTIF_DMA_EN(base)));
+		BTIF_INFO_FUNC("BTIF_RTOCNT:0x%x\n",
+			       BTIF_READ32(BTIF_RTOCNT(base)));
+		BTIF_INFO_FUNC("BTIF_TRI_LVL:0x%x\n",
+			       BTIF_READ32(BTIF_TRI_LVL(base)));
+		BTIF_INFO_FUNC("BTIF_WAT_TIME:0x%x\n",
+			       BTIF_READ32(BTIF_WAT_TIME(base)));
+		BTIF_INFO_FUNC("BTIF_HANDSHAKE:0x%x\n",
+			       BTIF_READ32(BTIF_HANDSHAKE(base)));
+#endif
+		btif_dump_array("BTIF register", reg_map, sizeof(reg_map));
+		break;
+	default:
+		break;
+	}
+
+	BTIF_INFO_FUNC("Tx DMA %s\n",
+		       (dma_en & BTIF_DMA_EN_TX) ? "enabled" : "disabled");
+	BTIF_INFO_FUNC("Rx DMA %s\n",
+		       (dma_en & BTIF_DMA_EN_RX) ? "enabled" : "disabled");
+
+	BTIF_INFO_FUNC("Rx data is %s\n",
+		       (lsr & BTIF_LSR_DR_BIT) ? "not empty" : "empty");
+	BTIF_INFO_FUNC("Tx data is %s\n",
+		       (lsr & BTIF_LSR_TEMT_BIT) ? "empty" : "not empty");
+
+	return i_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_is_tx_complete
+* DESCRIPTION
+*  get tx complete flag
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  true means tx complete, false means tx in process
+*****************************************************************************/
+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif)
+{
+/*Chaozhong: To be implement*/
+	bool b_ret = false;
+	unsigned int lsr = 0;
+	unsigned long flags = 0;
+	unsigned long base = p_btif->base;
+	unsigned int tx_empty = 0;
+	unsigned int rx_dr = 0;
+	unsigned int tx_irq_disable = 0;
+
+/*
+ * 3 conditions allow clock to be disable
+ * 1. if TEMT is set or not
+ * 2. if DR is set or not
+ * 3. Tx IRQ is disabled or not
+ */
+	lsr = BTIF_READ32(BTIF_LSR(base));
+	tx_empty = lsr & BTIF_LSR_TEMT_BIT;
+	rx_dr = lsr & BTIF_LSR_DR_BIT;
+	tx_irq_disable = BTIF_READ32(BTIF_IER(base)) & BTIF_IER_TXEEN;
+
+	b_ret =
+	    (tx_empty && (tx_irq_disable == 0) && (rx_dr == 0)) ? true : false;
+	if (!b_ret) {
+		BTIF_DBG_FUNC
+		    ("BTIF flag, tx_empty:%d, rx_dr:%d, tx_irq_disable:%d\n",
+		     tx_empty, rx_dr, tx_irq_disable);
+	}
+#if NEW_TX_HANDLING_SUPPORT
+	spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags);
+/*clear Tx enable flag if necessary*/
+	if (!(kfifo_is_empty(p_btif->p_tx_fifo))) {
+		BTIF_DBG_FUNC("BTIF tx FIFO is not empty\n");
+		b_ret = false;
+	}
+	spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags);
+#endif
+	return b_ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_is_tx_allow
+* DESCRIPTION
+*  whether tx is allowed
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+* true if tx operation is allowed; false if tx is not allowed
+*****************************************************************************/
+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif)
+{
+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000)
+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000)
+
+/*Chaozhong: To be implement*/
+	bool b_ret = false;
+
+#if NEW_TX_HANDLING_SUPPORT
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags);
+/*clear Tx enable flag if necessary*/
+	if (kfifo_is_full(p_btif->p_tx_fifo)) {
+		BTIF_WARN_FUNC("BTIF tx FIFO is full\n");
+		b_ret = false;
+	} else {
+		b_ret = true;
+	}
+	spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags);
+#else
+	unsigned int lsr = 0;
+	unsigned long base = p_btif->base;
+	unsigned int wait_us = (BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE) / MIN_TX_MB; /*only ava length */
+
+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/
+	lsr = BTIF_READ32(BTIF_LSR(base));
+
+	if (!(lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT))) {
+		BTIF_DBG_FUNC("wait for %d ~ %d us\n", wait_us, 3 * wait_us);
+/* usleep_range(wait_us, 3 * 10 * wait_us); */
+		usleep_range(wait_us, 3 * wait_us);
+	}
+	lsr = BTIF_READ32(BTIF_LSR(base));
+	b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false;
+	if (!b_ret)
+		BTIF_DBG_FUNC(" tx is not allowed for the moment\n");
+	else
+		BTIF_DBG_FUNC(" tx is allowed\n");
+#endif
+	return b_ret;
+}
+
+#if !(NEW_TX_HANDLING_SUPPORT)
+
+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif)
+{
+/*Chaozhong: To be implement*/
+	bool b_ret = false;
+	unsigned long base = p_btif->base;
+	unsigned int lsr = 0;
+
+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/
+	lsr = BTIF_READ32(BTIF_LSR(base));
+	b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false;
+	return b_ret;
+}
+#endif
+
+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif_info, MTK_BTIF_PM_OPID opid)
+{
+	int i_ret = -1;
+
+	BTIF_DBG_FUNC("op id: %d\n", opid);
+	switch (opid) {
+	case BTIF_PM_DPIDLE_EN:
+		i_ret = 0;
+		break;
+	case BTIF_PM_DPIDLE_DIS:
+		i_ret = 0;
+		break;
+	case BTIF_PM_SUSPEND:
+		i_ret = 0;
+		break;
+	case BTIF_PM_RESUME:
+		i_ret = 0;
+		break;
+	case BTIF_PM_RESTORE_NOIRQ:{
+			unsigned int flag = 0;
+			P_MTK_BTIF_IRQ_STR p_irq = p_btif_info->p_irq;
+
+#ifdef CONFIG_OF
+			flag = p_irq->irq_flags;
+#else
+			switch (p_irq->sens_type) {
+			case IRQ_SENS_EDGE:
+				if (p_irq->edge_type == IRQ_EDGE_FALL)
+					flag = IRQF_TRIGGER_FALLING;
+				else if (p_irq->edge_type == IRQ_EDGE_RAISE)
+					flag = IRQF_TRIGGER_RISING;
+				else if (p_irq->edge_type == IRQ_EDGE_BOTH)
+					flag = IRQF_TRIGGER_RISING |
+					    IRQF_TRIGGER_FALLING;
+				else
+					flag = IRQF_TRIGGER_FALLING;	/*make this as default type */
+				break;
+			case IRQ_SENS_LVL:
+				if (p_irq->lvl_type == IRQ_LVL_LOW)
+					flag = IRQF_TRIGGER_LOW;
+				else if (p_irq->lvl_type == IRQ_LVL_HIGH)
+					flag = IRQF_TRIGGER_HIGH;
+				else
+					flag = IRQF_TRIGGER_LOW;	/*make this as default type */
+				break;
+			default:
+				flag = IRQF_TRIGGER_LOW;	/*make this as default type */
+				break;
+			}
+#endif
+/* irq_set_irq_type(p_irq->irq_id, flag); */
+			i_ret = 0;
+		}
+		break;
+	default:
+		i_ret = ERR_INVALID_PAR;
+		break;
+	}
+
+	return i_ret;
+}
+void mtk_btif_read_cpu_sw_rst_debug_plat(void)
+{
+#define CONSYS_AP2CONN_WAKEUP_OFFSET	0x00000064
+	BTIF_WARN_FUNC("+CONSYS_AP2CONN_WAKEUP_OFFSET(0x%x)\n",
+			   BTIF_READ32(mtk_btif.base + CONSYS_AP2CONN_WAKEUP_OFFSET));
+}
+
diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h
new file mode 100644
index 0000000000000..5e2f5a9857d91
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_BTIF_H_
+#define __MTK_BTIF_H_
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/atomic.h>
+#include <linux/list.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/sched/rt.h>
+#include <linux/kthread.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/string.h>
+#include <linux/time.h>		/* gettimeofday */
+#include <asm-generic/bug.h>
+
+#include "btif_pub.h"
+#include "btif_dma_pub.h"
+#include "mtk_btif_exp.h"
+
+#define BTIF_PORT_NR 1
+#define BTIF_USER_NAME_MAX_LEN 32
+
+/*-------------Register Defination Start ---------------*/
+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD))
+#define BTIF_RX_BUFFER_SIZE (1024 * 32)
+#else
+#define BTIF_RX_BUFFER_SIZE (1024 * 64)
+#endif
+#define BTIF_TX_FIFO_SIZE (1024 * 4)
+
+/*------------Register Defination End ----------------*/
+
+/*------------BTIF Module Clock and Power Control Defination---------------*/
+typedef enum _ENUM_BTIF_RX_TYPE_ {
+	BTIF_IRQ_CTX = 0,
+	BTIF_TASKLET_CTX = BTIF_IRQ_CTX + 1,
+	BTIF_THREAD_CTX = BTIF_TASKLET_CTX + 1,
+	BTIF_WQ_CTX = BTIF_THREAD_CTX + 1,
+	BTIF_RX_TYPE_MAX,
+} ENUM_BTIF_RX_TYPE;
+
+typedef enum _ENUM_BTIF_TX_TYPE_ {
+	BTIF_TX_USER_CTX = 0,
+	BTIF_TX_SINGLE_CTX = BTIF_TX_USER_CTX + 1,
+	BTIF_TX_TYPE_MAX,
+} ENUM_BTIF_TX_TYPE;
+
+typedef enum _ENUM_BTIF_STATE_ {
+	B_S_OFF = 0,
+	B_S_SUSPEND = B_S_OFF + 1,
+	B_S_DPIDLE = B_S_SUSPEND + 1,
+	B_S_ON = B_S_DPIDLE + 1,
+	B_S_MAX,
+} ENUM_BTIF_STATE;
+
+#define ENABLE_BTIF_RX_DMA 1
+#define ENABLE_BTIF_TX_DMA 1
+
+#if ENABLE_BTIF_TX_DMA
+#define BTIF_TX_MODE BTIF_MODE_DMA
+#else
+#define BTIF_TX_MODE BTIF_MODE_PIO
+#endif
+
+#if ENABLE_BTIF_RX_DMA
+#define BTIF_RX_MODE BTIF_MODE_DMA
+#else
+#define BTIF_RX_MODE BTIF_MODE_PIO
+#endif
+
+#define BTIF_RX_BTM_CTX BTIF_THREAD_CTX/*BTIF_WQ_CTX*//* BTIF_TASKLET_CTX */
+/*
+ * -- cannot be used because ,
+ * mtk_wcn_stp_parser data will call *(stp_if_tx) to send ack,
+ * in which context sleepable lock or usleep operation may be used,
+ * these operation is not allowed in tasklet, may cause schedule_bug
+ */
+
+#define BTIF_TX_CTX BTIF_TX_USER_CTX	/* BTIF_TX_SINGLE_CTX */
+
+#define ENABLE_BTIF_RX_THREAD_RT_SCHED 0
+#define MAX_BTIF_RXD_TIME_REC 3
+
+/*Structure Defination*/
+
+/*-----------------BTIF setting--------------*/
+typedef struct _mtk_btif_setting_ {
+	ENUM_BTIF_MODE tx_mode;	/*BTIF Tx Mode Setting */
+	ENUM_BTIF_MODE rx_mode;	/*BTIF Tx Mode Setting */
+	ENUM_BTIF_RX_TYPE rx_type;	/*rx handle type */
+	ENUM_BTIF_TX_TYPE tx_type;	/*tx type */
+} mtk_btif_setting, *p_mtk_btif_setting;
+/*---------------------------------------------------------------------------*/
+
+#if 0
+/*---------------------------------------------------------------------------*/
+typedef struct _mtk_btif_register_ {
+	unsigned int iir;	/*Interrupt Identification Register */
+	unsigned int lsr;	/*Line Status Register */
+	unsigned int fake_lcr;	/*Fake Lcr Regiseter */
+	unsigned int fifo_ctrl;	/*FIFO Control Register */
+	unsigned int ier;	/*Interrupt Enable Register */
+	unsigned int sleep_en;	/*Sleep Enable Register */
+	unsigned int rto_counter;	/*Rx Timeout Counter Register */
+	unsigned int dma_en;	/*DMA Enalbe Register */
+	unsigned int tri_lvl;	/*Tx/Rx Trigger Level Register */
+	unsigned int wat_time;	/*Async Wait Time Register */
+	unsigned int handshake;	/*New HandShake Mode Register */
+	unsigned int sleep_wak;	/*Sleep Wakeup Reigster */
+} mtk_btif_register, *p_mtk_btif_register;
+/*---------------------------------------------------------------------------*/
+
+#endif
+
+typedef struct _btif_buf_str_ {
+	unsigned int size;
+	unsigned char *p_buf;
+	/*
+	 * For Tx: next Tx data pointer to FIFO;
+	 * For Rx: next read data pointer from BTIF user
+	 */
+	unsigned int rd_idx;
+	/*
+	 * For Tx: next Tx data pointer from BTIF user;
+	 * For Rx: next write data(from FIFO) pointer
+	 */
+	unsigned int wr_idx;
+} btif_buf_str, *p_btif_buf_str;
+
+/*---------------------------------------------------------------------------*/
+typedef struct _mtk_btif_dma_ {
+					/*p_mtk_btif*/ void *p_btif;
+					/*BTIF pointer to which DMA belongs */
+
+#if 0
+	unsigned int channel;	/*DMA's channel */
+#endif
+
+	ENUM_BTIF_DIR dir;	/*DMA's direction: */
+	bool enable;		/*DMA enable or disable flag */
+
+	P_MTK_DMA_INFO_STR p_dma_info;	/*DMA's IRQ information */
+
+#if 0
+	mtk_dma_register register;	/*DMA's register */
+#endif
+
+	spinlock_t iolock;	/*io lock for DMA channel */
+	atomic_t entry;		/* entry count */
+} mtk_btif_dma, *p_mtk_btif_dma;
+
+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD))
+#define BTIF_LOG_ENTRY_NUM 10
+#else
+#define BTIF_LOG_ENTRY_NUM 30
+#endif
+
+#define BTIF_LOG_SZ  1536
+
+typedef void (*MTK_BTIF_RX_NOTIFY) (void);
+
+typedef struct _btif_log_buf_t_ {
+	unsigned int len;
+	struct timeval timer;
+	unsigned char buffer[BTIF_LOG_SZ];
+} BTIF_LOG_BUF_T, *P_BTIF_LOG_BUF_T;
+
+typedef struct _btif_log_queue_t_ {
+	ENUM_BTIF_DIR dir;
+	bool enable;
+	bool output_flag;
+	unsigned int in;
+	unsigned int out;
+	unsigned int size;
+	spinlock_t lock;
+	P_BTIF_LOG_BUF_T p_queue[BTIF_LOG_ENTRY_NUM];
+} BTIF_LOG_QUEUE_T, *P_BTIF_LOG_QUEUE_T;
+
+/*---------------------------------------------------------------------------*/
+typedef struct _mtk_btif_ {
+	unsigned int open_counter;	/*open counter */
+	bool enable;		/*BTIF module enable flag */
+	bool lpbk_flag;		/*BTIF module enable flag */
+#if 0
+	unsigned long base;	/* BTIF controller base address */
+#endif
+
+	ENUM_BTIF_STATE state;	/*BTIF state mechanism */
+	struct mutex state_mtx;	/*lock to BTIF state mechanism's state change */
+	struct mutex ops_mtx;	/*lock to BTIF's open and close */
+
+#if 0
+	mtk_btif_register register;	/*BTIF registers */
+#endif
+
+	ENUM_BTIF_MODE tx_mode;	/* BTIF Tx channel mode */
+	ENUM_BTIF_MODE rx_mode;	/* BTIF Rx channel mode */
+	struct mutex tx_mtx;	/*lock to BTIF's tx process */
+/*rx handling */
+	ENUM_BTIF_RX_TYPE btm_type;	/*BTIF Rx bottom half context */
+/*tx handling*/
+	ENUM_BTIF_TX_TYPE tx_ctx;	/*BTIF tx context */
+/* unsigned char rx_buf[BTIF_RX_BUFFER_SIZE]; */
+	btif_buf_str btif_buf;
+	spinlock_t rx_irq_spinlock;	/*lock for rx irq handling */
+
+/*rx workqueue information*/
+	/*lock to BTIF's rx bottom half when kernel thread is used */
+	struct mutex rx_mtx;
+	struct workqueue_struct *p_rx_wq;
+	struct work_struct rx_work;
+
+	struct workqueue_struct *p_tx_wq;
+	struct work_struct tx_work;
+	struct kfifo *p_tx_fifo;
+
+/*rx tasklet information*/
+	struct tasklet_struct rx_tasklet;
+	/*lock to BTIF's rx bottom half when tasklet is used */
+	spinlock_t rx_tasklet_spinlock;
+
+/*rx thread information*/
+	struct task_struct *p_task;
+	struct completion rx_comp;
+
+	mtk_btif_setting *setting;	/*BTIF setting */
+
+	p_mtk_btif_dma p_tx_dma;	/*BTIF Tx channel DMA */
+	p_mtk_btif_dma p_rx_dma;	/*BTIF Rx channel DMA */
+
+	MTK_WCN_BTIF_RX_CB rx_cb;	/*Rx callback function */
+	MTK_BTIF_RX_NOTIFY rx_notify;
+
+	P_MTK_BTIF_INFO_STR p_btif_info;	/*BTIF's information */
+
+/*Log Tx data to buffer*/
+	BTIF_LOG_QUEUE_T tx_log;
+
+/*Log Rx data to buffer*/
+	BTIF_LOG_QUEUE_T rx_log;
+
+/* struct list_head *p_user_list; */
+	struct list_head user_list;
+/* get btif dev pointer*/
+	void *private_data;
+} mtk_btif, *p_mtk_btif;
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+#if 0
+/*---------------------------------------------------------------------------*/
+typedef struct _mtk_dma_register_ {
+	unsigned int int_flag;	/*Tx offset:0x0     Rx offset:0x0 */
+	unsigned int int_enable;	/*Tx offset:0x4     Rx offset:0x4 */
+	unsigned int dma_enable;	/*Tx offset:0x8     Rx offset:0x8 */
+	unsigned int dma_reset;	/*Tx offset:0xc     Rx offset:0xc */
+	unsigned int dma_stop;	/*Tx offset:0x10     Rx offset:0x10 */
+	unsigned int dma_flush;	/*Tx offset:0x14     Rx offset:0x14 */
+	unsigned int vff_addr;	/*Tx offset:0x1c     Rx offset:0x1c */
+	unsigned int vff_len;	/*Tx offset:0x24     Rx offset:0x24 */
+	unsigned int vff_thr;	/*Tx offset:0x28     Rx offset:0x28 */
+	unsigned int vff_wpt;	/*Tx offset:0x2c     Rx offset:0x2c */
+	unsigned int vff_rpt;	/*Tx offset:0x30     Rx offset:0x30 */
+	unsigned int rx_fc_thr;	/*Tx:No this register     Rx offset:0x34 */
+	unsigned int int_buf_size;	/*Tx offset:0x38     Rx offset:0x38 */
+	unsigned int vff_valid_size;	/*Tx offset:0x3c     Rx offset:0x3c */
+	unsigned int vff_left_size;	/*Tx offset:0x40     Rx offset:0x40 */
+	unsigned int debug_status;	/*Tx offset:0x50     Rx offset:0x50 */
+} mtk_dma_register, *p_mtk_dma_register;
+/*---------------------------------------------------------------------------*/
+#endif
+
+/*---------------------------------------------------------------------------*/
+typedef struct _mtk_btif_user_ {
+	bool enable;		/*register its state */
+	struct list_head entry;	/*btif_user's bi-direction list table */
+	/*BTIF's user, static allocation */
+	char u_name[BTIF_USER_NAME_MAX_LEN];
+	unsigned long u_id;
+	p_mtk_btif p_btif;
+} mtk_btif_user, *p_mtk_btif_user;
+
+/*---------------------------------------------------------------------------*/
+#define BBS_PTR(ptr, idx) ((ptr->p_buf) + idx)
+
+#define BBS_SIZE(ptr) ((ptr)->size)
+#define BBS_MASK(ptr) (BBS_SIZE(ptr) - 1)
+#define BBS_COUNT(ptr) ((ptr)->wr_idx >= (ptr)->rd_idx ? (ptr)->wr_idx - \
+(ptr)->rd_idx : BBS_SIZE(ptr) - \
+((ptr)->rd_idx - (ptr)->wr_idx))
+#define BBS_COUNT_CUR(ptr, wr_idx) (wr_idx >= (ptr)->rd_idx ? wr_idx - \
+(ptr)->rd_idx : BBS_SIZE(ptr) - \
+((ptr)->rd_idx - wr_idx))
+
+#define BBS_LEFT(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr))
+
+#define BBS_AVL_SIZE(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr))
+#define BBS_FULL(ptr) (BBS_COUNT(ptr) - BBS_SIZE(ptr))
+#define BBS_EMPTY(ptr) ((ptr)->wr_idx == (ptr)->rd_idx)
+#define BBS_WRITE_MOVE_NEXT(ptr) ((ptr)->wr_idx = \
+((ptr)->wr_idx + 1) & BBS_MASK(ptr))
+#define BBS_READ_MOVE_NEXT(ptr) ((ptr)->rd_idx = \
+((ptr)->rd_idx + 1) & BBS_MASK(ptr))
+
+#define BBS_INIT(ptr) \
+{ \
+(ptr)->rd_idx = (ptr)->wr_idx = 0; \
+(ptr)->size = BTIF_RX_BUFFER_SIZE; \
+}
+
+
+#define BTIF_MUTEX_UNLOCK(x) mutex_unlock(x)
+
+extern mtk_btif g_btif[];
+
+int btif_open(p_mtk_btif p_btif);
+int btif_close(p_mtk_btif p_btif);
+int btif_send_data(p_mtk_btif p_btif,
+		   const unsigned char *p_buf, unsigned int buf_len);
+int btif_enter_dpidle(p_mtk_btif p_btif);
+int btif_exit_dpidle(p_mtk_btif p_btif);
+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb);
+
+/*for test purpose*/
+int _btif_suspend(p_mtk_btif p_btif);
+int _btif_resume(p_mtk_btif p_btif);
+int _btif_restore_noirq(p_mtk_btif p_btif);
+
+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag);
+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf,
+			int len);
+int btif_dump_data(char *p_buf, int len);
+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que);
+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que);
+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que);
+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que);
+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que);
+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que);
+int btif_log_buf_init(p_mtk_btif p_btif);
+int btif_dump_reg(p_mtk_btif p_btif);
+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify);
+int btif_raise_wak_signal(p_mtk_btif p_btif);
+int btif_clock_ctrl(p_mtk_btif p_btif, int en);
+bool btif_parser_wmt_evt(p_mtk_btif p_btif,
+				const char *sub_str,
+				unsigned int sub_len);
+void mtk_btif_read_cpu_sw_rst_debug(void);
+
+#endif /*__MTK_BTIF_H_*/
diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h
new file mode 100644
index 0000000000000..3752644fe0aae
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_BTIF_EXP_H_
+#define _MTK_BTIF_EXP_H_
+
+/*--------------marco defination---------------*/
+#define BTIF_MAX_LEN_PER_PKT 2048
+#define BTIF_RXD_BE_BLOCKED_DETECT 1
+/*--------------Enum Defination---------------*/
+typedef enum _ENUM_BTIF_DPIDLE_ {
+	BTIF_DPIDLE_DISABLE = 0,
+	BTIF_DPIDLE_ENABLE = BTIF_DPIDLE_DISABLE + 1,
+	BTIF_DPIDLE_MAX,
+} ENUM_BTIF_DPIDLE_CTRL;
+
+typedef enum _ENUM_BTIF_LPBK_MODE_ {
+	BTIF_LPBK_DISABLE = 0,
+	BTIF_LPBK_ENABLE = BTIF_LPBK_DISABLE + 1,
+	BTIF_LPBK_MAX,
+} ENUM_BTIF_LPBK_MODE;
+
+typedef enum _ENUM_BTIF_DBG_ID_ {
+	BTIF_DISABLE_LOGGER = 0,
+	BTIF_ENABLE_LOGGER = BTIF_DISABLE_LOGGER + 1,
+	BTIF_DUMP_LOG = BTIF_ENABLE_LOGGER + 1,
+	BTIF_CLR_LOG = BTIF_DUMP_LOG + 1,
+	BTIF_DUMP_BTIF_REG = BTIF_CLR_LOG + 1,
+	BTIF_ENABLE_RT_LOG = BTIF_DUMP_BTIF_REG + 1,
+	BTIF_DISABLE_RT_LOG = BTIF_ENABLE_RT_LOG + 1,
+	BTIF_DBG_MAX,
+} ENUM_BTIF_DBG_ID;
+
+typedef enum _ENUM_BTIF_OP_ERROR_CODE_ {
+	E_BTIF_AGAIN = 0,
+	E_BTIF_FAIL = -1,
+	E_BTIF_BAD_POINTER = -2,
+	E_BTIF_NO_SPACE = -3,
+	E_BTIF_INTR = -4,
+	E_BTIF_INVAL_PARAM = -5,
+	E_BTIF_ALREADY_OPEN = -6,
+	E_BTIF_NOT_OPEN = -7,
+	E_BTIF_INVAL_STATE = -8,
+} ENUM_BTIF_OP_ERROR_CODE;
+
+/*--------------End of Enum Defination---------------*/
+
+/*--------------Type Definition---------------*/
+
+typedef int (*MTK_WCN_BTIF_RX_CB) (const unsigned char *p_buf,
+				   unsigned int len);
+
+/*--------------End of Type Definition---------------*/
+
+/*--------------Normal Mode API declearation---------------*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_open
+* DESCRIPTION
+*  open BTIF interface, will do BTIF module HW and SW initialization
+* PARAMETERS
+*  p_owner      [IN] pointer to owner who call this API,
+*                    currently there are 2 owner ("stp" or "btif_tester")
+*                    may use this module
+*                    user's id string must be less than 32 bytes
+*  for "stp", BTIF will call rx callback function to route rx data to STP module
+*  for "stp_tester", BTIF will save rx data
+*  and wait for native process to access
+*  p_id            [IN] BTIF's user id will be put to this address
+* RETURNS
+*  int 0 = succeed; others = fail, for detailed information,
+*      please see ENUM_BTIF_OP_ERROR_CODE
+*      if open success, value p_id will be the only identifier for
+*      user to access BTIF's other operations
+*      including read/write/dpidle_ctrl/rx_cb_retister
+*      this user id is only an identifier used for owner identification
+*****************************************************************************/
+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id);
+//EXPORT_SYMBOL(mtk_wcn_btif_open)
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_close
+* DESCRIPTION
+*  close BTIF interface, will do BTIF module HW and SW de-initialization
+*  once this API is called, p_btif should never be used by BTIF's user again
+* PARAMETERS
+*  u_id        [IN] BTIF's user id
+* RETURNS
+*  int         0 = succeed;
+*  others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_close(unsigned long u_id);
+//EXPORT_SYMBOL(mtk_wcn_btif_close)
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_write
+* DESCRIPTION
+*  send data throuth BTIF module
+*  there's no internal buffer to cache STP data in BTIF driver,
+*  if in DMA mode
+*  btif driver will check if there's enough space
+*  in vFIFO for data to send in DMA mode
+*    if yes, put data to vFIFO and return corresponding data length to caller
+*    if no, corresponding error code will be returned to called
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  p_buf       [IN] pointer to target data to send
+*  len         [IN] data length (should be less than 2014 bytes per STP package)
+*
+*  if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller
+*      if btif driver detected that no space is available in Tx FIFO,
+*      will return E_BTIF_NO_SPACE,
+*      mostly something is wrong with BTIF or consys when this
+*       return value is returned
+* RETURNS
+*  int          positive: data length send through BTIF;
+*        negative: please see ENUM_BTIF_OP_ERROR_CODE
+*        E_BTIF_AGAIN (0) will be returned to caller if btif does not have
+*        enough vFIFO to send data, when caller get 0,
+*        he should wait for a moment (5~10ms maybe) and
+*        try a few times (maybe 10~20)
+*            if still get E_BTIF_AGAIN, should call BTIF's debug API and
+*        dump BTIF driver and BTIF/DMA register information to kernel log
+*        for debug
+*        E_BTIF_BAD_POINTER will be returned to caller if btif is not
+*        opened successfully before call this API
+*        E_BTIF_INVAL_PARAM will be returned if parameter is not valid
+
+*****************************************************************************/
+int mtk_wcn_btif_write(unsigned long u_id,
+		       const unsigned char *p_buf, unsigned int len);
+//EXPORT_SYMBOL(mtk_wcn_btif_write)
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_read
+* DESCRIPTION
+*  read data from BTIF module
+* PARAMETERS
+*  p_btif     [IN] pointer returned by mtk_wcn_btif_open
+*  p_buf      [IN/OUT] pointer to buffer where rx data will be put
+*  max_len    [IN] max buffer length
+* RETURNS
+*  int          positive: data length read from BTIF;
+*  negative: please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_read(unsigned long u_id,
+		      unsigned char *p_buf, unsigned int max_len);
+//EXPORT_SYMBOL(mtk_wcn_btif_read)
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_dpidle_ctrl
+* DESCRIPTION
+*  control if BTIF module allow system enter deepidle state or not
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  en_flag    [IN] one of ENUM_BTIF_DPIDLE_CTRL
+* RETURNS
+*  int          always return 0
+*****************************************************************************/
+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_rx_cb_register
+* DESCRIPTION
+*  register rx callback function to BTIF module by btif user
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  rx_cb       [IN] pointer to stp rx handler callback function,
+*  should be comply with MTK_WCN_BTIF_RX_CB
+* RETURNS
+*  int          0 = succeed;
+*  others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_wakeup_consys
+* DESCRIPTION
+*  once sleep command is sent to con sys,
+*  should call this API before send wakeup command to
+*  make con sys aware host want to send data to consys
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+* RETURNS
+*  int          0 = succeed;
+*  others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_wakeup_consys(unsigned long u_id);
+
+/*--------------End of Normal Mode API declearation----------------*/
+
+/*--------------Debug Purpose API declearation----------------*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_loopback_ctrl
+* DESCRIPTION
+*  enable/disable BTIF internal loopback function,
+*  when this function is enabled,
+*  data send to btif will be received by btif itself
+*  only for debug purpose, should never use this function in normal mode
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  enable     [IN] loopback mode control flag, enable or disable,
+*  shou be one of ENUM_BTIF_LPBK_MODE
+* RETURNS
+*  int          0 = succeed;
+*  others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable);
+//EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl)
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_logger_ctrl
+* DESCRIPTION
+*  control BTIF logger function's behavior
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  flag         [IN] should be one of ENUM_BTIF_DBG_ID
+*                      BTIF_DISABLE_LOGGER  - disable btif logger
+*                      BTIF_ENABLE_LOGGER   - enable btif logger
+*                      BTIF_DUMP_LOG           - dump log logged by btif
+*                      BTIF_CLR_LOG             - clear btif log buffer
+*                      BTIF_DUMP_BTIF_REG   - dump btif controller's register
+*                      BTIF_DUMP_DMA_REG   - dump DMA controller's register
+* RETURNS
+*  int   0 = succeed;
+*        others = fail, for detailed information,
+*        please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag);
+//EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl);
+/*-----------End of Debug Purpose API declearation------------*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_parser_wmt_evt
+* DESCRIPTION
+*  parser wmt sleep/wakeup evt in btif bbs buffer for debug
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  sub_str     [IN] the str to be parsered
+*  str_len     [IN] the length of sub_str
+* RETURNS
+*  bool  true = succeed;
+*        false = fail;
+*****************************************************************************/
+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id,
+	const char *sub_str, unsigned int str_len);
+
+int mtk_btif_exp_open_test(void);
+int mtk_btif_exp_close_test(void);
+int mtk_btif_exp_write_test(void);
+int mtk_btif_exp_suspend_test(void);
+int mtk_btif_exp_resume_test(void);
+int mtk_btif_exp_enter_dpidle_test(void);
+int mtk_btif_exp_exit_dpidle_test(void);
+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int loop);
+int mtk_btif_exp_log_debug_test(int flag);
+int mtk_btif_exp_restore_noirq_test(void);
+int btif_wakeup_consys_no_id(void);
+int mtk_btif_exp_clock_ctrl(int en);
+#if BTIF_RXD_BE_BLOCKED_DETECT
+int mtk_btif_rxd_be_blocked_flag_get(void);
+#endif
+void mtk_btif_read_cpu_sw_rst_debug_exp(void);
+#endif /*_MTK_BTIF_EXP_H_*/
diff --git a/drivers/misc/mediatek/btif/common/mtk_btif.c b/drivers/misc/mediatek/btif/common/mtk_btif.c
new file mode 100644
index 0000000000000..0212ad41049f0
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/mtk_btif.c
@@ -0,0 +1,3472 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*-----------linux system header files----------------*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/poll.h>
+
+/*#include <mach/eint.h>*/
+/*-----------driver own header files----------------*/
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG "MTK-BTIF"
+
+#define BTIF_CDEV_SUPPORT 1
+
+#include "btif_pub.h"
+#include "btif_dma_pub.h"
+#include "mtk_btif_exp.h"
+#include "mtk_btif.h"
+
+/*-----------static function declearation----------------*/
+static int mtk_btif_probe(struct platform_device *pdev);
+static int mtk_btif_remove(struct platform_device *pdev);
+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state);
+static int mtk_btif_resume(struct platform_device *pdev);
+static int mtk_btif_drv_resume(struct device *dev);
+static int mtk_btif_drv_suspend(struct device *pdev);
+
+static int mtk_btif_restore_noirq(struct device *device);
+static int btif_file_open(struct inode *pinode, struct file *pfile);
+static int btif_file_release(struct inode *pinode, struct file *pfile);
+static ssize_t btif_file_read(struct file *pfile,
+			      char __user *buf, size_t count, loff_t *f_ops);
+static unsigned int btif_poll(struct file *filp, poll_table *wait);
+static int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq,
+		  mtk_btif_irq_handler irq_handler, void *data);
+static int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data);
+static int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en);
+static int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en);
+static irqreturn_t btif_irq_handler(int irq, void *data);
+static unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info,
+				       unsigned char *p_buf,
+				       unsigned int buf_len);
+
+static irqreturn_t btif_tx_dma_irq_handler(int irq, void *data);
+static irqreturn_t btif_rx_dma_irq_handler(int irq, void *data);
+
+static unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info,
+				       unsigned char *p_buf,
+				       unsigned int buf_len);
+static int _btif_controller_tx_setup(p_mtk_btif p_btif);
+static int _btif_controller_tx_free(p_mtk_btif p_btif);
+static int _btif_controller_rx_setup(p_mtk_btif p_btif);
+static int _btif_controller_rx_free(p_mtk_btif p_btif);
+static int _btif_tx_pio_setup(p_mtk_btif p_btif);
+static int _btif_rx_pio_setup(p_mtk_btif p_btif);
+static int _btif_rx_dma_setup(p_mtk_btif p_btif);
+static int _btif_rx_dma_free(p_mtk_btif p_btif);
+static int _btif_tx_dma_setup(p_mtk_btif p_btif);
+static int _btif_tx_dma_free(p_mtk_btif p_btif);
+static int _btif_controller_setup(p_mtk_btif p_btif);
+static int _btif_controller_free(p_mtk_btif p_btif);
+
+static int _btif_pio_write(p_mtk_btif p_btif,
+		    const unsigned char *p_buf, unsigned int buf_len);
+static int _btif_dma_write(p_mtk_btif p_btif,
+		    const unsigned char *p_buf, unsigned int buf_len);
+
+static unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs,
+				unsigned char *p_buf, unsigned int buf_len);
+static unsigned int btif_bbs_read(p_btif_buf_str p_bbs,
+			   unsigned char *p_buf, unsigned int buf_len);
+static unsigned int btif_bbs_write(p_btif_buf_str p_bbs,
+			    unsigned char *p_buf, unsigned int buf_len);
+static void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs);
+static int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len);
+static int _btif_rx_btm_deinit(p_mtk_btif p_btif);
+static int _btif_rx_btm_sched(p_mtk_btif p_btif);
+static int _btif_rx_btm_init(p_mtk_btif p_btif);
+static void btif_rx_tasklet(unsigned long func_data);
+static void btif_rx_worker(struct work_struct *p_work);
+static int btif_rx_thread(void *p_data);
+static int btif_rx_data_consummer(p_mtk_btif p_btif);
+
+static int _btif_tx_ctx_init(p_mtk_btif p_btif);
+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif);
+static void btif_tx_worker(struct work_struct *p_work);
+
+static int _btif_state_deinit(p_mtk_btif p_btif);
+static int _btif_state_release(p_mtk_btif p_btif);
+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif);
+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state);
+static int _btif_state_hold(p_mtk_btif p_btif);
+static int _btif_state_init(p_mtk_btif p_btif);
+
+static int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif,
+				    ENUM_BTIF_DPIDLE_CTRL en_flag);
+static int _btif_enter_dpidle(p_mtk_btif p_btif);
+static int _btif_exit_dpidle(p_mtk_btif p_btif);
+static int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif);
+static int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif);
+static int _btif_enter_dpidle_from_on(p_mtk_btif p_btif);
+static int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif);
+
+#if ENABLE_BTIF_TX_DMA
+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma);
+static int _btif_vfifo_init(p_mtk_btif_dma p_dma);
+#endif
+
+static bool _btif_is_tx_complete(p_mtk_btif p_btif);
+static int _btif_init(p_mtk_btif p_btif);
+static int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag);
+static int btif_rx_dma_mode_set(int en);
+static int btif_tx_dma_mode_set(int en);
+
+static int _btif_send_data(p_mtk_btif p_btif,
+		    const unsigned char *p_buf, unsigned int buf_len);
+
+/*-----------end of static function declearation----------------*/
+
+static const char *g_state[B_S_MAX] = {
+	"OFF",
+	"SUSPEND",
+	"DPIDLE",
+	"ON",
+};
+
+/*-----------BTIF setting--------------*/
+mtk_btif_setting g_btif_setting[BTIF_PORT_NR] = {
+	{
+	 .tx_mode = BTIF_TX_MODE,
+	 .rx_mode = BTIF_RX_MODE,
+	 .rx_type = BTIF_RX_BTM_CTX,
+	 .tx_type = BTIF_TX_CTX,
+	 },
+};
+
+mtk_btif g_btif[BTIF_PORT_NR] = {
+	{
+	 .open_counter = 0,
+	 .state = B_S_OFF,
+	 .setting = &g_btif_setting[0],
+	 .p_tx_dma = NULL,
+	 .p_rx_dma = NULL,
+	 .rx_cb = NULL,
+	 .p_btif_info = NULL,
+	 },
+};
+
+mtk_btif_dma g_dma[BTIF_PORT_NR][BTIF_DIR_MAX] = {
+	{
+	 {
+	  .p_btif = NULL,
+	  .dir = BTIF_TX,
+	  .p_dma_info = NULL,
+	  .entry = ATOMIC_INIT(0),
+	  },
+	 {
+	  .p_btif = NULL,
+	  .dir = BTIF_RX,
+	  .p_dma_info = NULL,
+	  .entry = ATOMIC_INIT(0),
+	  },
+	 },
+};
+
+#define G_MAX_PKG_LEN (7 * 1024)
+static int g_max_pkg_len = G_MAX_PKG_LEN; /*DMA vFIFO is set to 8 * 1024, we set this to 7/8 * vFIFO size*/
+static int g_max_pding_data_size = BTIF_RX_BUFFER_SIZE * 3 / 4;
+
+
+static int mtk_btif_dbg_lvl = BTIF_LOG_ERR;
+
+#if BTIF_RXD_BE_BLOCKED_DETECT
+static struct timeval btif_rxd_time_stamp[MAX_BTIF_RXD_TIME_REC];
+#endif
+/*-----------Platform bus related structures----------------*/
+#define DRV_NAME "mtk_btif"
+
+#ifdef CONFIG_OF
+const struct of_device_id apbtif_of_ids[] = {
+	{ .compatible = "mediatek,mtk-btif", },
+	{}
+};
+#endif
+
+const struct dev_pm_ops mtk_btif_drv_pm_ops = {
+	.restore_noirq = mtk_btif_restore_noirq,
+	.suspend = mtk_btif_drv_suspend,
+	.resume = mtk_btif_drv_resume,
+};
+
+struct platform_driver mtk_btif_dev_drv = {
+	.probe = mtk_btif_probe,
+	.remove = mtk_btif_remove,
+#ifdef CONFIG_PM
+	.suspend = mtk_btif_suspend,
+	.resume = mtk_btif_resume,
+#endif
+	.driver = {
+			.name = DRV_NAME,
+			.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+			.pm = &mtk_btif_drv_pm_ops,
+#endif
+#ifdef CONFIG_OF
+			.of_match_table = apbtif_of_ids,
+#endif
+		   }
+};
+
+#define BTIF_STATE_RELEASE(x) _btif_state_release(x)
+
+/*-----------End of Platform bus related structures----------------*/
+
+/*-----------platform bus related operation APIs----------------*/
+
+static int mtk_btif_probe(struct platform_device *pdev)
+{
+/*Chaozhong: ToDo: to be implement*/
+/*register IRQ for BTIF and Tx Rx DMA and disable them by default*/
+	BTIF_INFO_FUNC("DO BTIF PROBE\n");
+	platform_set_drvdata(pdev, &g_btif[0]);
+	g_btif[0].private_data = (struct device *)&pdev->dev;
+
+#if !defined(CONFIG_MTK_CLKMGR)
+	hal_btif_clk_get_and_prepare(pdev);
+#endif
+
+	return 0;
+}
+
+static int mtk_btif_remove(struct platform_device *pdev)
+{
+/*Chaozhong: ToDo: to be implement*/
+	BTIF_INFO_FUNC("DO BTIF REMOVE\n");
+	platform_set_drvdata(pdev, NULL);
+	g_btif[0].private_data = NULL;
+	return 0;
+}
+
+int _btif_suspend(p_mtk_btif p_btif)
+{
+	int i_ret;
+
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+	if (p_btif != NULL) {
+		if (!(p_btif->enable))
+			i_ret = 0;
+		else {
+			if (_btif_state_get(p_btif) == B_S_ON) {
+				BTIF_ERR_FUNC("BTIF in ON state,",
+					"there are data need to be send or recev,suspend fail\n");
+				i_ret = -1;
+			} else {
+				/*
+				 * before disable BTIF controller and DMA controller
+				 * we need to set BTIF to ON state
+				 */
+				i_ret = _btif_exit_dpidle(p_btif);
+				if (i_ret == 0) {
+					i_ret += _btif_controller_free(p_btif);
+					i_ret = _btif_controller_tx_free(p_btif);
+					i_ret += _btif_controller_rx_free(p_btif);
+				}
+				if (i_ret != 0) {
+					BTIF_INFO_FUNC("failed\n");
+					/*Chaozhong: what if failed*/
+				} else {
+					BTIF_INFO_FUNC("succeed\n");
+					i_ret = _btif_state_set(p_btif, B_S_SUSPEND);
+					if (i_ret && _btif_init(p_btif)) {
+						/*Chaozhong:BTIF re-init failed? what to do*/
+						i_ret = _btif_state_set(p_btif,	B_S_OFF);
+					}
+				}
+			}
+		}
+	} else
+		i_ret = -1;
+	BTIF_STATE_RELEASE(p_btif);
+
+	return i_ret;
+}
+
+
+static int mtk_btif_drv_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	pm_message_t state = PMSG_SUSPEND;
+
+	return mtk_btif_suspend(pdev, state);
+}
+
+static int mtk_btif_drv_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	return mtk_btif_resume(pdev);
+}
+
+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = NULL;
+
+/*Chaozhong: ToDo: to be implement*/
+	BTIF_DBG_FUNC("++\n");
+	p_btif = platform_get_drvdata(pdev);
+	i_ret = _btif_suspend(p_btif);
+	BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret);
+	return i_ret;
+}
+
+int _btif_restore_noirq(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+/*BTIF IRQ restore no irq*/
+	i_ret = hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_RESTORE_NOIRQ);
+	if (i_ret == 0) {
+		BTIF_INFO_FUNC("BTIF HW IRQ restore succeed\n");
+	} else {
+		BTIF_INFO_FUNC("BTIF HW IRQ restore failed, i_ret:%d\n", i_ret);
+		return i_ret;
+	}
+/*BTIF DMA restore no irq*/
+	if (p_btif->tx_mode & BTIF_MODE_DMA) {
+		i_ret = hal_dma_pm_ops(p_btif->p_tx_dma->p_dma_info,
+				       BTIF_PM_RESTORE_NOIRQ);
+		if (i_ret == 0) {
+			BTIF_INFO_FUNC("BTIF Tx DMA IRQ restore succeed\n");
+		} else {
+			BTIF_INFO_FUNC
+			    ("BTIF Tx DMA IRQ restore failed, i_ret:%d\n",
+			     i_ret);
+			return i_ret;
+		}
+	}
+	if (p_btif->rx_mode & BTIF_MODE_DMA) {
+		i_ret = hal_dma_pm_ops(p_btif->p_rx_dma->p_dma_info,
+				       BTIF_PM_RESTORE_NOIRQ);
+		if (i_ret == 0) {
+			BTIF_INFO_FUNC("BTIF Rx DMA IRQ restore succeed\n");
+		} else {
+			BTIF_INFO_FUNC
+			    ("BTIF Rx DMA IRQ restore failed, i_ret:%d\n",
+			     i_ret);
+			return i_ret;
+		}
+	}
+	return i_ret;
+}
+
+static int mtk_btif_restore_noirq(struct device *dev)
+{
+	int i_ret = 0;
+	struct platform_device *pdev = to_platform_device(dev);
+	p_mtk_btif p_btif = platform_get_drvdata(pdev);
+
+	BTIF_INFO_FUNC("++\n");
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+	if (p_btif->enable)
+		BTIF_ERR_FUNC("!!!-----------------!BTIF is not closed before IPOH shutdown!!!---------------!\n");
+	WARN_ON(p_btif->enable);
+
+	i_ret = _btif_restore_noirq(p_btif);
+	BTIF_STATE_RELEASE(p_btif);
+	BTIF_INFO_FUNC("--\n");
+	return 0;
+}
+
+int _btif_resume(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+	ENUM_BTIF_STATE state = B_S_MAX;
+
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+	if (p_btif != NULL) {
+		state = _btif_state_get(p_btif);
+		if (!(p_btif->enable))
+			i_ret = 0;
+		else if (state == B_S_SUSPEND)
+			i_ret = _btif_enter_dpidle(p_btif);
+		else
+			BTIF_INFO_FUNC
+				("BTIF state: %s before resume, do nothing\n", g_state[state]);
+	} else
+		i_ret = -1;
+	BTIF_STATE_RELEASE(p_btif);
+
+	return i_ret;
+}
+
+static int mtk_btif_resume(struct platform_device *pdev)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = NULL;
+/*Chaozhong: ToDo: to be implement*/
+	BTIF_DBG_FUNC("++\n");
+	p_btif = platform_get_drvdata(pdev);
+	i_ret = _btif_resume(p_btif);
+	BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret);
+	return 0;
+}
+
+/*-----------device node----------------*/
+#if BTIF_CDEV_SUPPORT
+
+dev_t btif_dev;
+struct class *p_btif_class;
+struct device *p_btif_dev;
+const char *p_btif_dev_name = "btif";
+static struct semaphore wr_mtx;
+static struct semaphore rd_mtx;
+unsigned char wr_buf[2048];
+unsigned char rd_buf[2048];
+static int rx_notify_flag;
+static DECLARE_WAIT_QUEUE_HEAD(btif_wq);
+static int btif_file_open(struct inode *pinode, struct file *pfile);
+static int btif_file_release(struct inode *pinode, struct file *pfile);
+static ssize_t btif_file_read(struct file *pfile,
+			      char __user *buf, size_t count, loff_t *f_ops);
+
+static ssize_t btif_file_write(struct file *filp,
+			const char __user *buf, size_t count, loff_t *f_pos);
+static long btif_unlocked_ioctl(struct file *filp, unsigned int cmd,
+			 unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+#endif
+static struct cdev btif_dev_c;
+static wait_queue_head_t btif_read_inq;	/* read queues */
+
+const struct file_operations mtk_btif_fops = {
+	.owner = THIS_MODULE,
+	.open = btif_file_open,
+	.release = btif_file_release,
+	.read = btif_file_read,
+	.write = btif_file_write,
+	.unlocked_ioctl = btif_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = btif_compat_ioctl,
+#endif
+	.poll = btif_poll,
+};
+
+static int btif_chrdev_init(void)
+{
+	int i_ret;
+
+	int i_err;
+
+	/* alloc device number dynamically */
+	i_ret = alloc_chrdev_region(&btif_dev, 0, 1, p_btif_dev_name);
+	if (i_ret) {
+		BTIF_ERR_FUNC("devuce number allocation failed, i_ret:%d\n",
+			      i_ret);
+	} else {
+		BTIF_INFO_FUNC("devuce number allocation succeed\n");
+	}
+	cdev_init(&btif_dev_c, &mtk_btif_fops);
+	btif_dev_c.owner = THIS_MODULE;
+	i_err = cdev_add(&btif_dev_c, btif_dev, 1);
+	if (i_err) {
+		BTIF_ERR_FUNC("error add btif dev to kernel, error code:%d\n",
+			      i_err);
+		unregister_chrdev_region(btif_dev, 1);
+		btif_dev = 0;
+		return -1;
+	}
+	BTIF_INFO_FUNC("add btif dev to kernel succeed\n");
+
+	p_btif_class = class_create(THIS_MODULE, p_btif_dev_name);
+	if (IS_ERR(p_btif_class)) {
+		BTIF_ERR_FUNC("error happened when doing class_create\n");
+		unregister_chrdev_region(btif_dev, 1);
+		btif_dev = 0;
+		return -2;
+	}
+	BTIF_INFO_FUNC("create class for btif succeed\n");
+
+	p_btif_dev = device_create(p_btif_class,
+				   NULL, btif_dev, 0, p_btif_dev_name);
+	if (IS_ERR(p_btif_dev)) {
+		BTIF_ERR_FUNC("error happened when doing device_create\n");
+		class_destroy(p_btif_class);
+		p_btif_class = NULL;
+		unregister_chrdev_region(btif_dev, 1);
+		btif_dev = 0;
+		return -3;
+	}
+	BTIF_INFO_FUNC("create device for btif succeed\n");
+
+	return 0;
+}
+
+void btif_rx_notify_cb(void)
+{
+	BTIF_DBG_FUNC("++\n");
+	rx_notify_flag = 1;
+	wake_up(&btif_wq);
+	wake_up_interruptible(&btif_read_inq);
+	BTIF_DBG_FUNC("--\n");
+}
+
+unsigned int btif_poll(struct file *filp, poll_table *wait)
+{
+	unsigned int mask = 0;
+	unsigned int ava_len = 0;
+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */
+	unsigned int wr_idx = g_btif[0].btif_buf.wr_idx;
+
+/*    BTIF_Rx_IRQ_Disable(); */
+	ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx);
+	BTIF_INFO_FUNC("++\n");
+	if (ava_len == 0) {
+		poll_wait(filp, &btif_read_inq, wait);
+		wr_idx = g_btif[0].btif_buf.wr_idx;
+		ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx);
+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */
+		if (ava_len)
+			mask |= POLLIN | POLLRDNORM;	/* readable */
+	} else {
+		mask |= POLLIN | POLLRDNORM;	/* readable */
+	}
+/*make for writable*/
+	mask |= POLLOUT | POLLWRNORM;	/* writable */
+	BTIF_INFO_FUNC("--, mask:%d\n", mask);
+	return mask;
+}
+
+static int _btif_file_open(void)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	BTIF_INFO_FUNC("++\n");
+
+/*Chaozhong: ToDo: to be implement*/
+	i_ret = btif_open(p_btif);
+	if ((i_ret != 0) && (i_ret != E_BTIF_ALREADY_OPEN)) {
+		BTIF_ERR_FUNC("btif_open failed, error code:%d\n", i_ret);
+	} else {
+		BTIF_INFO_FUNC("btif_open succeed\n");
+		i_ret = 0;
+	}
+/*semaphore for read and write operation init*/
+	sema_init(&wr_mtx, 1);
+	sema_init(&rd_mtx, 1);
+
+/*buffer for read and write init*/
+	memset(wr_buf, 0, sizeof(wr_buf));
+	memset(rd_buf, 0, sizeof(rd_buf));
+	init_waitqueue_head(&(btif_read_inq));
+	btif_rx_notify_reg(p_btif, btif_rx_notify_cb);
+	BTIF_INFO_FUNC("--\n");
+	return i_ret;
+}
+
+static int _btif_file_close(void)
+{
+	int i_ret = -1;
+
+	BTIF_INFO_FUNC("++\n");
+/*Chaozhong: ToDo: to be implement*/
+	i_ret = btif_close(&g_btif[0]);
+	if (i_ret != 0)
+		BTIF_ERR_FUNC("btif_close failed, error code:%d\n", i_ret);
+	else
+		BTIF_INFO_FUNC("btif_close succeed\n");
+
+	BTIF_INFO_FUNC("--\n");
+	return i_ret;
+}
+
+static int btif_file_open(struct inode *pinode, struct file *pfile)
+{
+	int i_ret = -1;
+
+	BTIF_INFO_FUNC("pid:%d\n", current->pid);
+	i_ret = 0;
+	return i_ret;
+}
+
+static int btif_file_release(struct inode *pinode, struct file *pfile)
+{
+	int i_ret = -1;
+
+	BTIF_INFO_FUNC("pid:%d\n", current->pid);
+	i_ret = 0;
+	return i_ret;
+}
+
+static ssize_t btif_file_read(struct file *pfile,
+			      char __user *buf, size_t count, loff_t *f_ops)
+{
+	int i_ret = 0;
+	int rd_len = 0;
+
+	BTIF_INFO_FUNC("++\n");
+	down(&rd_mtx);
+	rd_len = btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf));
+	while (rd_len == 0) {
+		if (pfile->f_flags & O_NONBLOCK)
+			break;
+
+		wait_event(btif_wq, rx_notify_flag != 0);
+		rx_notify_flag = 0;
+		rd_len =
+		    btif_bbs_read(&(g_btif[0].btif_buf), rd_buf,
+				  sizeof(rd_buf));
+	}
+
+	if (rd_len == 0)
+		i_ret = 0;
+	else if ((rd_len > 0) && (copy_to_user(buf, rd_buf, rd_len) == 0))
+		i_ret = rd_len;
+	else
+		i_ret = -EFAULT;
+
+	up(&rd_mtx);
+	BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret);
+	return i_ret;
+}
+
+ssize_t btif_file_write(struct file *filp,
+			const char __user *buf, size_t count, loff_t *f_pos)
+{
+	int i_ret = 0;
+	int copy_size = 0;
+
+	copy_size = count > sizeof(wr_buf) ? sizeof(wr_buf) : count;
+
+	BTIF_INFO_FUNC("++\n");
+	down(&wr_mtx);
+	if (copy_from_user(&wr_buf[0], &buf[0], copy_size))
+		i_ret = -EFAULT;
+	else
+		i_ret = btif_send_data(&g_btif[0], wr_buf, copy_size);
+
+	up(&wr_mtx);
+	BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret);
+
+	return i_ret;
+}
+#ifdef CONFIG_COMPAT
+long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+
+	BTIF_INFO_FUNC("cmd[0x%x]\n", cmd);
+	ret = btif_unlocked_ioctl(filp, cmd, arg);
+	return ret;
+}
+#endif
+long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+#define BTIF_IOC_MAGIC        0xb0
+#define BTIF_IOCTL_OPEN     _IOW(BTIF_IOC_MAGIC, 1, int)
+#define BTIF_IOCTL_CLOSE    _IOW(BTIF_IOC_MAGIC, 2, int)
+#define BTIF_IOCTL_LPBK_CTRL    _IOWR(BTIF_IOC_MAGIC, 3, int)
+#define BTIF_IOCTL_LOG_FUNC_CTRL    _IOWR(BTIF_IOC_MAGIC, 4, int)
+#define BTIF_IOCTL_RT_LOG_CTRL  _IOWR(BTIF_IOC_MAGIC, 5, int)
+#define BTIF_IOCTL_LOG_DUMP _IOWR(BTIF_IOC_MAGIC, 6, int)
+#define BTIF_IOCTL_REG_DUMP _IOWR(BTIF_IOC_MAGIC, 7, int)
+#define BTIF_IOCTL_DMA_CTRL _IOWR(BTIF_IOC_MAGIC, 8, int)
+
+	long ret = 0;
+/* unsigned char p_buf[NAME_MAX + 1]; */
+	p_mtk_btif p_btif = &g_btif[0];
+
+	BTIF_INFO_FUNC("++\n");
+	BTIF_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg);
+
+	switch (cmd) {
+	case BTIF_IOCTL_OPEN:
+		ret = _btif_file_open();
+		break;
+	case BTIF_IOCTL_CLOSE:
+		ret = _btif_file_close();
+		break;
+	case BTIF_IOCTL_LPBK_CTRL:
+		ret = btif_lpbk_ctrl(p_btif, arg == 0 ? 0 : 1);
+		break;
+	case BTIF_IOCTL_LOG_FUNC_CTRL:
+		if (arg == 0) {
+			ret += btif_log_buf_disable(&p_btif->tx_log);
+			ret += btif_log_buf_disable(&p_btif->rx_log);
+		} else {
+			ret += btif_log_buf_enable(&p_btif->tx_log);
+			ret += btif_log_buf_enable(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_IOCTL_RT_LOG_CTRL:
+		if (arg == 0) {
+			ret += btif_log_output_disable(&p_btif->tx_log);
+			ret += btif_log_output_disable(&p_btif->rx_log);
+		} else {
+			ret += btif_log_output_enable(&p_btif->tx_log);
+			ret += btif_log_output_enable(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_IOCTL_LOG_DUMP:
+
+		ret += btif_log_buf_dmp_out(&p_btif->tx_log);
+		ret += btif_log_buf_dmp_out(&p_btif->rx_log);
+		break;
+	case BTIF_IOCTL_REG_DUMP:
+		ret += btif_dump_reg(p_btif);
+		break;
+	case BTIF_IOCTL_DMA_CTRL:
+		if (arg == 0) {
+			ret += btif_tx_dma_mode_set(0);
+			ret += btif_rx_dma_mode_set(0);
+		} else {
+			ret += btif_tx_dma_mode_set(1);
+			ret += btif_rx_dma_mode_set(1);
+		}
+		break;
+	default:
+		BTIF_INFO_FUNC("unknown cmd(%d)\n", cmd);
+		ret = -2;
+		break;
+	}
+	BTIF_INFO_FUNC("--\n");
+	return ret;
+}
+
+#endif
+
+/*-----------device property----------------*/
+//static ssize_t driver_flag_read(struct device_driver *drv, char *buf)
+static ssize_t flag_show(struct device_driver *drv, char *buf)
+{
+	return sprintf(buf, "btif driver debug level:%d\n", mtk_btif_dbg_lvl);
+}
+
+//static ssize_t driver_flag_set(struct device_driver *drv,
+static ssize_t flag_store(struct device_driver *drv,
+			       const char *buffer, size_t count)
+{
+	char buf[256];
+	char *p_buf;
+	unsigned long len = count;
+	long x = 0;
+	long y = 0;
+	long z = 0;
+	int result = 0;
+	char *p_token = NULL;
+	char *p_delimiter = " \t";
+
+	BTIF_INFO_FUNC("buffer = %s, count = %zd\n", buffer, count);
+	if (len >= sizeof(buf)) {
+		BTIF_ERR_FUNC("input handling fail!\n");
+		len = sizeof(buf) - 1;
+		return -1;
+	}
+
+	memcpy(buf, buffer, sizeof(buf));
+	p_buf = buf;
+
+	p_token = strsep(&p_buf, p_delimiter);
+	if (p_token != NULL) {
+		result = kstrtol(p_token, 16, &x);
+		BTIF_INFO_FUNC("x = 0x%08x\n\r", x);
+	} else
+		x = 0;
+/*	x = (NULL != p_token) ? kstrtol(p_token, 16, NULL) : 0;*/
+
+	p_token = strsep(&p_buf, "\t\n ");
+	if (p_token != NULL) {
+		result = kstrtol(p_token, 16, &y);
+		BTIF_INFO_FUNC("y = 0x%08x\n\r", y);
+	} else
+		y = 0;
+
+	p_token = strsep(&p_buf, "\t\n ");
+	if (p_token != NULL)
+		result = kstrtol(p_token, 16, &z);
+	else
+		z = 0;
+
+	BTIF_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);
+
+	switch (x) {
+	case 1:
+		mtk_btif_exp_open_test();
+		break;
+	case 2:
+		mtk_btif_exp_close_test();
+		break;
+	case 3:
+		mtk_btif_exp_write_test();
+		break;
+	case 4:
+		mtk_btif_exp_enter_dpidle_test();
+		break;
+	case 5:
+		mtk_btif_exp_exit_dpidle_test();
+		break;
+	case 6:
+		mtk_btif_exp_suspend_test();
+		break;
+	case 7:
+		mtk_btif_exp_resume_test();
+		break;
+	case 8:
+		if (y > BTIF_LOG_LOUD)
+			mtk_btif_dbg_lvl = BTIF_LOG_LOUD;
+		else if (y < BTIF_LOG_ERR)
+			mtk_btif_dbg_lvl = BTIF_LOG_WARN;
+		else
+			mtk_btif_dbg_lvl = y;
+		BTIF_ERR_FUNC("mtk_btif_dbg_lvl set to %d\n", mtk_btif_dbg_lvl);
+		break;
+	case 9:
+		mtk_btif_exp_open_test();
+		mtk_btif_exp_write_test();
+		mtk_btif_exp_close_test();
+		break;
+	case 0xa:
+		mtk_btif_exp_log_debug_test(y);
+		break;
+	case 0xb:
+		btif_tx_dma_mode_set(1);
+		btif_rx_dma_mode_set(1);
+		break;
+	case 0xc:
+		btif_tx_dma_mode_set(0);
+		btif_rx_dma_mode_set(0);
+		break;
+	case 0xd:
+		mtk_btif_exp_restore_noirq_test();
+		break;
+	case 0xe:
+		btif_wakeup_consys_no_id();
+		break;
+	case 0xf:
+		mtk_btif_exp_clock_ctrl(y);
+		break;
+	case 0x10:
+		y = y > G_MAX_PKG_LEN ? G_MAX_PKG_LEN : y;
+		y = y < 1024 ? 1024 : y;
+		BTIF_INFO_FUNC("g_max_pkg_len is set to %d\n", y);
+		g_max_pkg_len = y;
+		break;
+	case 0x11:
+		y = y > BTIF_RX_BUFFER_SIZE ? BTIF_RX_BUFFER_SIZE : y;
+		y = y < 1024 ? 1024 : y;
+		BTIF_INFO_FUNC("g_max_pding_data_size is set to %d\n", y);
+		g_max_pding_data_size = y;
+		break;
+	default:
+		mtk_btif_exp_open_test();
+		mtk_btif_exp_write_stress_test(3030, 1);
+		mtk_btif_exp_close_test();
+		BTIF_WARN_FUNC("not supported.\n");
+		break;
+	}
+
+	return count;
+}
+
+//FWU: driver_ATTR dropped in 4.14
+//static DRIVER_ATTR(flag, S_IRUGO | S_IWUSR, driver_flag_read, driver_flag_set);
+static DRIVER_ATTR_RW(flag);
+
+/*-----------End of platform bus related operation APIs------------*/
+
+/*-----------------------platform driver ----------------*/
+
+int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq,
+		  mtk_btif_irq_handler irq_handler, void *data)
+{
+	int i_ret = -1;
+	unsigned int irq_id;
+	unsigned int flag;
+
+	if ((p_irq == NULL) || (irq_handler == NULL))
+		return E_BTIF_INVAL_PARAM;
+
+	if (!(p_irq->is_irq_sup)) {
+		BTIF_WARN_FUNC("%s is not supported\n", p_irq->name);
+		return 0;
+	}
+
+	irq_id = p_irq->irq_id;
+
+#ifdef CONFIG_OF
+	flag = p_irq->irq_flags;
+#else
+	switch (p_irq->sens_type) {
+	case IRQ_SENS_EDGE:
+		if (p_irq->edge_type == IRQ_EDGE_FALL)
+			flag = IRQF_TRIGGER_FALLING;
+		else if (p_irq->edge_type == IRQ_EDGE_RAISE)
+			flag = IRQF_TRIGGER_RISING;
+		else if (p_irq->edge_type == IRQ_EDGE_BOTH)
+			flag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
+		else
+			/*make this as default type */
+			flag = IRQF_TRIGGER_FALLING;
+		break;
+	case IRQ_SENS_LVL:
+		if (p_irq->lvl_type == IRQ_LVL_LOW)
+			flag = IRQF_TRIGGER_LOW;
+		else if (p_irq->lvl_type == IRQ_LVL_HIGH)
+			flag = IRQF_TRIGGER_HIGH;
+		else
+			/*make this as default type */
+			flag = IRQF_TRIGGER_LOW;
+		break;
+	default:
+		/*make this as default type */
+		flag = IRQF_TRIGGER_LOW;
+		break;
+	}
+#endif
+
+	p_irq->p_irq_handler = irq_handler;
+	i_ret = request_irq(irq_id,
+			    (irq_handler_t) irq_handler,
+			    flag, p_irq->name, data);
+	if (i_ret)
+		return i_ret;
+
+	p_irq->reg_flag = true;
+	return 0;
+}
+
+int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data)
+{
+	int i_ret = 0;
+	unsigned int eint_num = p_irq->irq_id;
+
+	if ((p_irq->is_irq_sup) && (p_irq->reg_flag)) {
+		_btif_irq_ctrl(p_irq, false);
+		free_irq(eint_num, data);
+		p_irq->reg_flag = false;
+	}
+/*do nothing for this operation*/
+	return i_ret;
+}
+
+int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en)
+{
+	unsigned int eint_num = p_irq->irq_id;
+
+	if (en)
+		enable_irq(eint_num);
+	else
+		disable_irq_nosync(eint_num);
+
+	return 0;
+}
+
+int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en)
+{
+	unsigned int eint_num = p_irq->irq_id;
+
+	if (en)
+		enable_irq(eint_num);
+	else
+		disable_irq(eint_num);
+
+	return 0;
+}
+
+
+irqreturn_t btif_irq_handler(int irq, void *data)
+{
+/*search BTIF? just use index 0*/
+/*Chaozhong: do we need lock here?*/
+
+	p_mtk_btif p_btif = (p_mtk_btif) data;	/*&(g_btif[index]); */
+
+	BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data);
+
+	_btif_irq_ctrl(p_btif->p_btif_info->p_irq, false);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE);
+#endif
+
+	hal_btif_irq_handler(p_btif->p_btif_info, NULL, 0);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE);
+#endif
+
+	_btif_irq_ctrl(p_btif->p_btif_info->p_irq, true);
+	_btif_rx_btm_sched(p_btif);
+
+	BTIF_DBG_FUNC("--\n");
+	return IRQ_HANDLED;
+}
+
+irqreturn_t btif_tx_dma_irq_handler(int irq, void *data)
+{
+/*search BTIF? just use index 0*/
+
+	p_mtk_btif p_btif = (p_mtk_btif) data;	/*&(g_btif[index]); */
+	p_mtk_btif_dma p_tx_dma = p_btif->p_tx_dma;
+	P_MTK_DMA_INFO_STR p_dma_info = p_tx_dma->p_dma_info;
+
+	BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data);
+	_btif_irq_ctrl(p_dma_info->p_irq, false);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE);
+#endif
+
+	hal_tx_dma_irq_handler(p_dma_info);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE);
+#endif
+	_btif_irq_ctrl(p_dma_info->p_irq, true);
+	BTIF_DBG_FUNC("--\n");
+	return IRQ_HANDLED;
+}
+
+irqreturn_t btif_rx_dma_irq_handler(int irq, void *data)
+{
+/*search BTIF? just use index 0*/
+
+	p_mtk_btif p_btif = (p_mtk_btif) data;	/*&(g_btif[index]); */
+	p_mtk_btif_dma p_rx_dma = p_btif->p_rx_dma;
+	P_MTK_DMA_INFO_STR p_rx_dma_info = p_rx_dma->p_dma_info;
+
+	BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data);
+
+	_btif_irq_ctrl(p_rx_dma_info->p_irq, false);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE);
+	hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_ENABLE);
+#endif
+
+	hal_rx_dma_irq_handler(p_rx_dma_info, NULL, 0);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_DISABLE);
+	hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE);
+#endif
+
+	_btif_irq_ctrl(p_rx_dma_info->p_irq, true);
+
+	_btif_rx_btm_sched(p_btif);
+
+	BTIF_DBG_FUNC("--\n");
+
+	return IRQ_HANDLED;
+}
+
+unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info,
+				       unsigned char *p_buf,
+				       unsigned int buf_len)
+{
+	unsigned int index = 0;
+	p_mtk_btif p_btif = &(g_btif[index]);
+
+#if 0
+	_btif_dump_memory("<DMA Rx>", p_buf, buf_len);
+#endif
+
+	btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len);
+/*save DMA Rx packet here*/
+	if (buf_len > 0)
+		btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len);
+
+	return 0;
+}
+
+unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info,
+				       unsigned char *p_buf,
+				       unsigned int buf_len)
+{
+	unsigned int index = 0;
+	p_mtk_btif p_btif = &(g_btif[index]);
+
+#if 0
+	_btif_dump_memory("<PIO Rx>", p_buf, buf_len);
+#endif
+	btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len);
+
+/*save PIO Rx packet here*/
+	if (buf_len > 0)
+		btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len);
+
+	return 0;
+}
+
+bool btif_parser_wmt_evt(p_mtk_btif p_btif,
+				const char *sub_str,
+				unsigned int str_len)
+{
+	unsigned int data_cnt = 0;
+	unsigned int copy_cnt = 0;
+	char *local_buf = NULL;
+	bool b_ret = false;
+	p_btif_buf_str p_bbs = &(p_btif->btif_buf);
+	unsigned int wr_idx = p_bbs->wr_idx;
+	unsigned int rd_idx = p_bbs->rd_idx;
+
+	data_cnt = copy_cnt =  BBS_COUNT(p_bbs);
+
+	if (data_cnt < str_len) {
+		BTIF_WARN_FUNC("there is not enough data for parser,need(%d),have(%d)\n", str_len, data_cnt);
+		return false;
+	}
+	BTIF_INFO_FUNC("data count in bbs buffer:%d,wr_idx(%d),rd_idx(%d)\n", data_cnt, wr_idx, rd_idx);
+	local_buf = vmalloc((data_cnt + 3) & ~0x3UL);
+	if (!local_buf) {
+		BTIF_WARN_FUNC("vmalloc memory fail\n");
+		return false;
+	}
+
+	if (wr_idx >= rd_idx) {
+		memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), copy_cnt);
+	} else {
+		unsigned int tail_len = BBS_SIZE(p_bbs) - rd_idx;
+
+		BTIF_INFO_FUNC("tail_Len(%d)\n", tail_len);
+		memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), tail_len);
+		memcpy(local_buf + tail_len, BBS_PTR(p_bbs, 0), copy_cnt - tail_len);
+	}
+
+	do {
+		int i = 0;
+		int j = 0;
+		int k = 0;
+		int d = 0;
+
+		BTIF_INFO_FUNC("sub_str_len:%d\n", str_len);
+		for (i = 0; i < copy_cnt; i++) {
+			BTIF_DBG_FUNC("i:%d\n", i);
+			k = i;
+			while (1) {
+				if ((j >= str_len) || (k >= copy_cnt) || (sub_str[j++] != local_buf[k++]))
+					break;
+			}
+
+			if (j == str_len) {
+				for (d = i; d < (str_len + i); d++)
+					BTIF_INFO_FUNC("0x%2x", local_buf[d]);
+				BTIF_INFO_FUNC("find sub str index:%d\n", i);
+				b_ret = true;
+				break;
+			}
+			if (j < str_len)
+				j = 0;
+		}
+
+	} while (0);
+
+	vfree(local_buf);
+	return b_ret;
+}
+int _btif_controller_tx_setup(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+
+	if (p_btif->tx_mode == BTIF_MODE_DMA) {
+		i_ret = _btif_tx_dma_setup(p_btif);
+		if (i_ret) {
+			BTIF_ERR_FUNC("_btif_tx_dma_setup failed,i_ret(%d),",
+				"set tx to PIO mode\n", i_ret);
+			i_ret = _btif_tx_pio_setup(p_btif);
+		}
+	} else
+/*enable Tx PIO mode*/
+		i_ret = _btif_tx_pio_setup(p_btif);
+
+	return i_ret;
+}
+
+int _btif_controller_tx_free(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+
+	if (p_btif->tx_mode == BTIF_MODE_DMA) {
+		i_ret = _btif_tx_dma_free(p_btif);
+		if (i_ret) {
+			BTIF_ERR_FUNC("_btif_tx_dma_free failed, i_ret(%d)\n",
+				      i_ret);
+		}
+	} else {
+/*do nothing for Tx PIO mode*/
+	}
+	return i_ret;
+}
+
+int _btif_controller_rx_setup(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+
+	if (p_btif->rx_mode == BTIF_MODE_DMA) {
+		i_ret = _btif_rx_dma_setup(p_btif);
+		if (i_ret) {
+			BTIF_ERR_FUNC("_btif_tx_dma_setup failed, i_ret(%d),",
+				"set tx to PIO mode\n", i_ret);
+			i_ret = _btif_rx_pio_setup(p_btif);
+		}
+	} else {
+/*enable Tx PIO mode*/
+		i_ret = _btif_rx_pio_setup(p_btif);
+	}
+	return i_ret;
+}
+
+int _btif_controller_rx_free(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+
+	if (p_btif->rx_mode == BTIF_MODE_DMA) {
+		i_ret = _btif_rx_dma_free(p_btif);
+		if (i_ret) {
+			BTIF_ERR_FUNC("_btif_rx_dma_free failed, i_ret(%d)\n",
+				      i_ret);
+		}
+	} else {
+/*do nothing for Rx PIO mode*/
+	}
+	return i_ret;
+}
+
+int _btif_tx_pio_setup(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+	P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info;
+
+/*set Tx to PIO mode*/
+	p_btif->tx_mode = BTIF_MODE_PIO;
+/*enable Tx PIO mode*/
+	i_ret = hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_PIO);
+	return i_ret;
+}
+
+int _btif_rx_pio_setup(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+	P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info;
+	P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq;
+
+	p_btif->rx_mode = BTIF_MODE_PIO;
+/*Enable Rx IRQ*/
+	_btif_irq_ctrl(p_btif_irq, true);
+/*enable Rx PIO mode*/
+	i_ret = hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_PIO);
+	return i_ret;
+}
+
+int _btif_rx_dma_setup(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+	P_MTK_BTIF_INFO_STR p_btif_info = NULL;
+	P_MTK_BTIF_IRQ_STR p_btif_irq = NULL;
+	P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info;
+
+	p_btif_info = p_btif->p_btif_info;
+	p_btif_irq = p_dma_info->p_irq;
+
+/*vFIFO reset*/
+	hal_btif_vfifo_reset(p_dma_info);
+
+	i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE);
+	if (i_ret) {
+		BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d),",
+			"set rx to pio mode\n", i_ret);
+/*DMA control failed set Rx to PIO mode*/
+		return _btif_rx_pio_setup(p_btif);
+	}
+/*hardware init*/
+	hal_btif_dma_hw_init(p_dma_info);
+
+	hal_btif_dma_rx_cb_reg(p_dma_info,
+			       (dma_rx_buf_write) btif_dma_rx_data_receiver);
+
+/*DMA controller enable*/
+	i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE);
+	if (i_ret) {
+		BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),",
+			"set rx to pio mode\n", i_ret);
+		hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE);
+/*DMA control failed set Rx to PIO mode*/
+		i_ret = _btif_rx_pio_setup(p_btif);
+	} else {
+/*enable Rx DMA mode*/
+		hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_DMA);
+
+/*DMA Rx IRQ register*/
+		_btif_irq_reg(p_btif_irq, btif_rx_dma_irq_handler, p_btif);
+#if 0
+/*Enable DMA Rx IRQ*/
+		_btif_irq_ctrl(p_btif_irq, true);
+#endif
+		BTIF_DBG_FUNC("succeed\n");
+	}
+	return i_ret;
+}
+
+int _btif_rx_dma_free(p_mtk_btif p_btif)
+{
+	P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info;
+	P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_rx_dma->p_dma_info->p_irq;
+
+	hal_btif_dma_rx_cb_reg(p_dma_info, (dma_rx_buf_write) NULL);
+	_btif_irq_free(p_irq, p_btif);
+/*disable BTIF Rx DMA channel*/
+	hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE);
+/*disable clock output*/
+	return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE);
+}
+
+int _btif_tx_dma_setup(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+	P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info;
+	P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info;
+	P_MTK_BTIF_IRQ_STR p_btif_irq = p_dma_info->p_irq;
+
+/*vFIFO reset*/
+	hal_btif_vfifo_reset(p_dma_info);
+
+	i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE);
+	if (i_ret) {
+		BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d)\n",
+			      i_ret);
+		return i_ret;
+	}
+/*DMA controller setup*/
+	hal_btif_dma_hw_init(p_dma_info);
+
+/*DMA HW Enable*/
+	i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE);
+	if (i_ret) {
+		BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),",
+			"set tx to pio mode\n", i_ret);
+
+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER)
+		hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE);
+#endif
+
+		_btif_tx_pio_setup(p_btif);
+	} else {
+		hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_DMA);
+/*DMA Tx IRQ register*/
+		_btif_irq_reg(p_btif_irq, btif_tx_dma_irq_handler, p_btif);
+#if 0
+/*disable DMA Tx IRQ*/
+		_btif_irq_ctrl(p_btif_irq, false);
+#endif
+
+		BTIF_DBG_FUNC("succeed\n");
+	}
+	return i_ret;
+}
+
+int _btif_tx_dma_free(p_mtk_btif p_btif)
+{
+	P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info;
+	P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_tx_dma->p_dma_info->p_irq;
+
+	_btif_irq_free(p_irq, p_btif);
+/*disable BTIF Tx DMA channel*/
+	hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE);
+/*disable clock output*/
+	return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE);
+}
+
+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag)
+{
+	int i_ret = -1;
+
+/*hold state mechine lock*/
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+#if 0
+	state = _btif_state_get(p_btif);
+	if (p_btif->enable && B_S_ON == state)
+		i_ret = _btif_lpbk_ctrl(p_btif, flag);
+	else
+		i_ret = E_BTIF_INVAL_STATE;
+#endif
+	i_ret = _btif_exit_dpidle(p_btif);
+	if (i_ret == 0)
+		i_ret = _btif_lpbk_ctrl(p_btif, flag);
+	else
+		i_ret = E_BTIF_INVAL_STATE;
+
+	BTIF_STATE_RELEASE(p_btif);
+	return i_ret;
+}
+
+int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag)
+{
+	int i_ret = -1;
+
+	if (flag) {
+		i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, true);
+		BTIF_DBG_FUNC("loopback function enabled\n");
+	} else {
+		i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, false);
+		BTIF_DBG_FUNC("loopback function disabled\n");
+	}
+	if (i_ret == 0)
+		p_btif->lpbk_flag = flag;
+
+	return i_ret;
+}
+
+int btif_clock_ctrl(p_mtk_btif p_btif, int en)
+{
+	int i_ret = 0;
+	P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info;
+	ENUM_CLOCK_CTRL ctrl_flag = en == 0 ? CLK_OUT_DISABLE : CLK_OUT_ENABLE;
+
+	i_ret = hal_btif_clk_ctrl(p_btif_info, ctrl_flag);
+
+	if (p_btif->rx_mode == BTIF_MODE_DMA)
+		i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ctrl_flag);
+
+	if (p_btif->tx_mode == BTIF_MODE_DMA)
+		i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ctrl_flag);
+
+	return i_ret;
+}
+
+int _btif_controller_setup(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+	P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info;
+	P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq;
+
+/*BTIF rx buffer init*/
+/* memset(p_btif->rx_buf, 0, BTIF_RX_BUFFER_SIZE); */
+	BBS_INIT(&(p_btif->btif_buf));
+/************************************************/
+	hal_btif_rx_cb_reg(p_btif_info,
+			   (btif_rx_buf_write) btif_pio_rx_data_receiver);
+
+	i_ret = hal_btif_clk_ctrl(p_btif_info, CLK_OUT_ENABLE);
+	if (i_ret) {
+		BTIF_ERR_FUNC("hal_btif_clk_ctrl failed, i_ret(%d)\n", i_ret);
+		return i_ret;
+	}
+/*BTIF controller init*/
+	i_ret = hal_btif_hw_init(p_btif_info);
+	if (i_ret) {
+		hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE);
+		BTIF_ERR_FUNC("hal_btif_hw_init failed, i_ret(%d)\n", i_ret);
+		return i_ret;
+	}
+	_btif_lpbk_ctrl(p_btif, p_btif->lpbk_flag);
+/*BTIF IRQ register*/
+	i_ret = _btif_irq_reg(p_btif_irq, btif_irq_handler, p_btif);
+	if (i_ret) {
+		hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE);
+
+		BTIF_ERR_FUNC("_btif_irq_reg failed, i_ret(%d)\n", i_ret);
+		return i_ret;
+	}
+
+/*disable IRQ*/
+	_btif_irq_ctrl(p_btif_irq, false);
+	i_ret = 0;
+	BTIF_DBG_FUNC("succeed\n");
+	return i_ret;
+}
+
+int _btif_controller_free(p_mtk_btif p_btif)
+{
+/*No need to set BTIF to PIO mode, only enable BTIF CG*/
+	hal_btif_rx_cb_reg(p_btif->p_btif_info, (btif_rx_buf_write) NULL);
+	_btif_irq_free(p_btif->p_btif_info->p_irq, p_btif);
+	return hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE);
+}
+
+int _btif_init(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+	i_ret = _btif_controller_setup(p_btif);
+	if (i_ret) {
+		BTIF_ERR_FUNC("_btif_controller_init failed, i_ret(%d)\n",
+			      i_ret);
+		_btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE);
+		BTIF_STATE_RELEASE(p_btif);
+		return i_ret;
+	}
+
+	i_ret = _btif_controller_tx_setup(p_btif);
+	if (i_ret) {
+		BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n",
+			      i_ret);
+		_btif_controller_free(p_btif);
+		_btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE);
+		BTIF_STATE_RELEASE(p_btif);
+		return i_ret;
+	}
+
+	i_ret = _btif_controller_rx_setup(p_btif);
+	if (i_ret) {
+		BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n",
+			      i_ret);
+		_btif_controller_tx_free(p_btif);
+		_btif_controller_free(p_btif);
+		_btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE);
+		BTIF_STATE_RELEASE(p_btif);
+		return i_ret;
+	}
+	return i_ret;
+}
+
+int btif_open(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+
+	if (p_btif->enable)
+		return E_BTIF_ALREADY_OPEN;
+
+/*hold state mechine lock*/
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+/*disable deepidle*/
+	_btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE);
+
+	i_ret = _btif_init(p_btif);
+	if (i_ret == 0) {
+		/*set BTIF's enable flag*/
+		p_btif->enable = true;
+		_btif_state_set(p_btif, B_S_ON);
+	} else {
+		_btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE);
+	}
+	btif_log_buf_reset(&p_btif->tx_log);
+	btif_log_buf_reset(&p_btif->rx_log);
+
+	BTIF_STATE_RELEASE(p_btif);
+
+	BTIF_DBG_FUNC("BTIF's Tx Mode:%d, Rx Mode(%d)\n",
+		       p_btif->tx_mode, p_btif->rx_mode);
+	return i_ret;
+}
+
+int btif_close(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+	if (!(p_btif->enable))
+		return E_BTIF_NOT_OPEN;
+
+/*hold state mechine lock*/
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+/*always set state back to B_S_ON before do close operation*/
+	_btif_exit_dpidle(p_btif);
+/*set BTIF's state to disable state*/
+	p_btif->enable = false;
+
+	_btif_controller_free(p_btif);
+	_btif_controller_tx_free(p_btif);
+	_btif_controller_rx_free(p_btif);
+
+/*reset BTIF's rx_cb function*/
+	p_btif->rx_cb = NULL;
+	p_btif->rx_notify = NULL;
+	p_btif->lpbk_flag = false;
+
+/*set state mechine to B_S_OFF*/
+	_btif_state_set(p_btif, B_S_OFF);
+
+	btif_log_buf_disable(&p_btif->tx_log);
+	btif_log_buf_disable(&p_btif->rx_log);
+
+	BTIF_STATE_RELEASE(p_btif);
+
+	return i_ret;
+}
+
+int _btif_exit_dpidle(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+	ENUM_BTIF_STATE state = B_S_MAX;
+
+	state = _btif_state_get(p_btif);
+	switch (state) {
+	case B_S_DPIDLE:
+		i_ret = _btif_exit_dpidle_from_dpidle(p_btif);
+		break;
+	case B_S_SUSPEND:
+/*in suspend state, need to do reinit of btif*/
+		i_ret = _btif_exit_dpidle_from_sus(p_btif);
+		break;
+	case B_S_OFF:
+		i_ret = _btif_init(p_btif);
+		break;
+	case B_S_ON:
+		i_ret = 0;	/* for btif_close case */
+		break;
+	default:
+		i_ret = E_BTIF_INVAL_PARAM;
+		BTIF_INFO_FUNC("invalid state change:%d->\n", state, B_S_ON);
+		break;
+	}
+
+	if (i_ret == 0)
+		i_ret = _btif_state_set(p_btif, B_S_ON);
+	return i_ret;
+}
+
+int btif_exit_dpidle(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+/*hold state mechine lock*/
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+	i_ret = _btif_exit_dpidle(p_btif);
+	BTIF_STATE_RELEASE(p_btif);
+	return i_ret;
+}
+
+int _btif_enter_dpidle(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+	ENUM_BTIF_STATE state = B_S_MAX;
+
+	state = _btif_state_get(p_btif);
+	if (state == B_S_ON) {
+		i_ret = _btif_enter_dpidle_from_on(p_btif);
+	} else if (state == B_S_SUSPEND) {
+		/*do reinit and enter deepidle*/
+		i_ret = _btif_enter_dpidle_from_sus(p_btif);
+	} else if (state == B_S_DPIDLE) {
+		/*do nothing*/
+		i_ret = 0;
+	} else {
+		BTIF_WARN_FUNC("operation is not allowed, current state:%d\n",
+			       state);
+		i_ret = E_BTIF_INVAL_STATE;
+	}
+/*anyway, set to B_S_DPIDLE state*/
+	if (i_ret == 0)
+		i_ret = _btif_state_set(p_btif, B_S_DPIDLE);
+	return i_ret;
+}
+
+int btif_enter_dpidle(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+/*hold state mechine lock*/
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+	i_ret = _btif_enter_dpidle(p_btif);
+	BTIF_STATE_RELEASE(p_btif);
+	return i_ret;
+}
+
+int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+/*in dpidle state, only need to open related clock*/
+	if (p_btif->tx_mode == BTIF_MODE_DMA) {
+		/*enable BTIF Tx DMA's clock*/
+		i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info,
+					       CLK_OUT_ENABLE);
+	}
+	if (p_btif->rx_mode == BTIF_MODE_DMA) {
+		/*enable BTIF Rx DMA's clock*/
+		i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info,
+					       CLK_OUT_ENABLE);
+	}
+/*enable BTIF's clock*/
+	i_ret += hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE);
+
+	if (i_ret != 0)
+		BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret);
+	return i_ret;
+}
+
+int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif)
+{
+/*in suspend state, need to do driver re-init*/
+
+	int i_ret = _btif_init(p_btif);
+
+	return i_ret;
+}
+
+int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif)
+{
+/*do driiver reinit*/
+	int i_ret = _btif_init(p_btif);
+
+	if (i_ret == 0)
+		i_ret = _btif_enter_dpidle_from_on(p_btif);
+	return i_ret;
+}
+
+int _btif_enter_dpidle_from_on(p_mtk_btif p_btif)
+{
+#define MAX_WAIT_TIME_MS 5000
+/*
+ * this max wait time cannot exceed 12s,
+ * because dpm will monitor each device's
+ * resume/suspend process by start up a watch dog timer of 12s
+ * incase of one driver's suspend/resume process block other device's suspend/resume
+ */
+	int i_ret = 0;
+	unsigned int retry = 0;
+	unsigned int wait_period = 1;
+	unsigned int max_retry = MAX_WAIT_TIME_MS / wait_period;
+	struct timeval timer_start;
+	struct timeval timer_now;
+
+	do_gettimeofday(&timer_start);
+
+	while ((!_btif_is_tx_complete(p_btif)) && (retry < max_retry)) {
+		do_gettimeofday(&timer_now);
+		if ((MAX_WAIT_TIME_MS/1000) <= (timer_now.tv_sec - timer_start.tv_sec)) {
+			BTIF_WARN_FUNC("max retry timer expired, timer_start.tv_sec:%d, timer_now.tv_sec:%d,",
+				"retry:%d\n", timer_start.tv_sec, timer_now.tv_sec, retry);
+			break;
+		}
+		msleep(wait_period);
+		retry++;
+	}
+
+	if (retry < max_retry) {
+		if (p_btif->tx_mode == BTIF_MODE_DMA) {
+			/*disable BTIF Tx DMA's clock*/
+			i_ret +=
+			    hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info,
+						  CLK_OUT_DISABLE);
+		}
+		if (p_btif->rx_mode == BTIF_MODE_DMA) {
+			/*disable BTIF Rx DMA's clock*/
+			i_ret +=
+			    hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info,
+						  CLK_OUT_DISABLE);
+		}
+/*disable BTIF's clock*/
+		i_ret +=
+		    hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE);
+
+		if (i_ret)
+			BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret);
+	} else
+		i_ret = -1;
+
+	return i_ret;
+}
+
+int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ENUM_BTIF_DPIDLE_CTRL en_flag)
+{
+/*call WCP's API to control deepidle's enable/disable*/
+	if (en_flag == BTIF_DPIDLE_DISABLE)
+		hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_DIS);
+	else
+		hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_EN);
+
+	return 0;
+}
+
+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb)
+{
+	if (p_btif->rx_cb) {
+		BTIF_WARN_FUNC
+		    ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n",
+		     p_btif->rx_cb, rx_cb);
+	}
+	p_btif->rx_cb = rx_cb;
+
+	return 0;
+}
+
+int btif_raise_wak_signal(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+	P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info;
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE);
+#endif
+
+	i_ret = hal_btif_raise_wak_sig(p_btif_info);
+
+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER
+	hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE);
+#endif
+	return i_ret;
+}
+
+bool _btif_is_tx_complete(p_mtk_btif p_btif)
+{
+	bool b_ret = false;
+	ENUM_BTIF_MODE tx_mode = p_btif->tx_mode;
+
+/*
+ * make sure BTIF tx finished in PIO mode
+ * make sure BTIF tx finished and DMA tx finished in DMA mode
+ */
+	if (tx_mode == BTIF_MODE_DMA) {
+		b_ret = hal_dma_is_tx_complete(p_btif->p_tx_dma->p_dma_info);
+		if (b_ret == false) {
+			BTIF_DBG_FUNC("Tx DMA is not finished\n");
+			return b_ret;
+		}
+	}
+
+	b_ret = hal_btif_is_tx_complete(p_btif->p_btif_info);
+	if (b_ret == false) {
+		BTIF_DBG_FUNC("BTIF Tx is not finished\n");
+		return b_ret;
+	}
+	b_ret = true;
+	return b_ret;
+}
+
+/*--------------------------------Functions-------------------------------------------*/
+
+#if ENABLE_BTIF_TX_DMA
+static int _btif_vfifo_init(p_mtk_btif_dma p_dma)
+{
+	P_DMA_VFIFO p_vfifo = NULL;
+	struct device *dev = NULL;
+	p_mtk_btif p_btif = NULL;
+
+	if (p_dma == NULL) {
+		BTIF_ERR_FUNC("p_dma is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	p_btif = (p_mtk_btif)p_dma->p_btif;
+
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif);
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	dev = (struct device *)p_btif->private_data;
+	if (dev == NULL)
+		BTIF_WARN_FUNC("Null dev pointer!!!!\n");
+
+	p_vfifo = p_dma->p_dma_info->p_vfifo;
+	if (p_vfifo->p_vir_addr != NULL) {
+		BTIF_ERR_FUNC
+		    ("BTIF vFIFO memory already allocated, do nothing\n");
+		return E_BTIF_BAD_POINTER;
+	}
+
+/*vFIFO memory allocation*/
+	p_vfifo->p_vir_addr = dma_zalloc_coherent(dev,
+						  p_vfifo->vfifo_size,
+						  &p_vfifo->phy_addr, GFP_DMA | GFP_DMA32);
+	if (p_vfifo->p_vir_addr == NULL) {
+		BTIF_ERR_FUNC("alloc vFIFO memory for BTIF failed\n");
+		return E_BTIF_FAIL;
+	}
+
+	if (sizeof(dma_addr_t) == sizeof(unsigned long long))
+		BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch64,vir addr:0x%p,",
+		"phy addr:0x%llx\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr);
+	else
+		BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch32,vir addr:0x%p,",
+		"phy addr:0x%08x\n",	p_vfifo->p_vir_addr, p_vfifo->phy_addr);
+
+	return 0;
+}
+#endif
+#if ENABLE_BTIF_TX_DMA
+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma)
+{
+	P_DMA_VFIFO p_vfifo = NULL;
+	struct device *dev = NULL;
+	p_mtk_btif p_btif = NULL;
+
+	if (p_dma == NULL) {
+		BTIF_ERR_FUNC("p_dma is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+
+
+	p_btif = (p_mtk_btif)p_dma->p_btif;
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif);
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	dev = (struct device *)p_btif->private_data;
+	if (dev == NULL)
+		BTIF_WARN_FUNC("Null dev pointer!!!!\n");
+
+	p_vfifo = p_dma->p_dma_info->p_vfifo;
+
+/*free DMA memory if allocated successfully before*/
+	if (p_vfifo->p_vir_addr != NULL) {
+		dma_free_coherent(dev,
+				  p_vfifo->vfifo_size,
+				  p_vfifo->p_vir_addr, p_vfifo->phy_addr);
+		p_vfifo->p_vir_addr = NULL;
+	}
+
+	return 0;
+}
+#endif
+
+static int _btif_state_init(p_mtk_btif p_btif)
+{
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("p_btif is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+	p_btif->state = B_S_OFF;
+	mutex_init(&(p_btif->state_mtx));
+
+	return 0;
+}
+
+static int _btif_state_hold(p_mtk_btif p_btif)
+{
+	return mutex_lock_killable(&(p_btif->state_mtx));
+}
+
+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state)
+{
+/*chaozhong: To do: need to finished state mechine here*/
+	int i_ret = 0;
+	int ori_state = p_btif->state;
+
+	if (ori_state == state) {
+		BTIF_INFO_FUNC("already in %s state\n", g_state[state]);
+		return i_ret;
+	}
+	if ((state >= B_S_OFF) && (state < B_S_MAX)) {
+		BTIF_DBG_FUNC("%s->%s request\n", g_state[ori_state],
+			      g_state[state]);
+		if (state == B_S_ON)
+			_btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE);
+		switch (ori_state) {
+		case B_S_ON:
+/*B_S_ON can only be switched to B_S_OFF, B_S_SUSPEND and B_S_DPIDLE*/
+/*B_S_ON->B_S_OFF : do nothing here*/
+/*
+ * B_S_ON->B_S_DPLE : disable clock backup
+ * BTIF and DMA controller's register if necessary
+ */
+			if (state == B_S_DPIDLE) {
+				/*clock controlled id done in _btif_enter_dpidle*/
+				p_btif->state = state;
+				i_ret = 0;
+			} else if (state == B_S_OFF) {
+				/*clock controlled is done in btif_close*/
+				p_btif->state = state;
+				i_ret = 0;
+			} else if (state == B_S_SUSPEND) {
+				/*clock controlled is done in btif_close*/
+				p_btif->state = state;
+				i_ret = 0;
+			} else {
+				BTIF_ERR_FUNC("%s->%s is not allowed\n",
+					      g_state[ori_state],
+					      g_state[state]);
+				i_ret = E_BTIF_INVAL_STATE;
+			}
+			break;
+		case B_S_DPIDLE:
+/*B_S_DPIDLE can only be switched to B_S_ON and B_S_SUSPEND*/
+/*B_S_DPIDLE-> B_S_ON: do nothing for this moment*/
+/*
+ * B_S_DPIDLE-> B_S_SUSPEND:
+ * disable clock backup BTIF and DMA controller's register if necessary
+ */
+			if (state == B_S_ON) {
+				/*clock controlled id done in _btif_exit_dpidle*/
+				p_btif->state = state;
+				i_ret = 0;
+			} else if (state == B_S_SUSPEND) {
+				/*clock controlled is done in _btif_exit_dpidle*/
+				p_btif->state = state;
+				i_ret = 0;
+			} else {
+				BTIF_ERR_FUNC("%s->%s is not allowed\n",
+					      g_state[ori_state],
+					      g_state[state]);
+				i_ret = E_BTIF_INVAL_STATE;
+			}
+			break;
+
+		case B_S_SUSPEND:
+/*B_S_SUSPEND can be switched to B_S_IDLE and B_S_ON*/
+/*reinit BTIF controller and DMA controller*/
+			if (state == B_S_DPIDLE) {
+				/*
+				 * system call resume API, do resume operation,
+				 * change to deepidle state
+				 */
+				p_btif->state = state;
+				i_ret = 0;
+			} else if (state == B_S_ON) {
+				/*
+				 * when stp want to send data before
+				 * system do resume operation
+				 */
+				p_btif->state = state;
+				i_ret = 0;
+			} else {
+				BTIF_ERR_FUNC("%s->%s is not allowed\n",
+					      g_state[ori_state],
+					      g_state[state]);
+				i_ret = E_BTIF_INVAL_STATE;
+			}
+			break;
+
+		case B_S_OFF:{
+/*B_S_OFF can only be switched to B_S_ON*/
+				if (state == B_S_ON) {
+					/*clock controlled is done in btif_open*/
+					p_btif->state = state;
+					i_ret = 0;
+				} else {
+					BTIF_ERR_FUNC("%s->%s is not allowed\n",
+						      g_state[ori_state],
+						      g_state[state]);
+					i_ret = E_BTIF_INVAL_STATE;
+				}
+			}
+			break;
+		default:
+/*no this possibility*/
+			BTIF_ERR_FUNC
+			    ("state change request is not allowed, this should never happen\n");
+			break;
+		}
+
+		if (state != B_S_ON)
+			_btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE);
+
+	} else {
+		i_ret = E_BTIF_INVAL_PARAM;
+		BTIF_ERR_FUNC("invalid state:%d, do nothing\n", state);
+	}
+	return i_ret;
+}
+
+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif)
+{
+	return p_btif->state;
+}
+
+static int _btif_state_release(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+	BTIF_MUTEX_UNLOCK(&(p_btif->state_mtx));
+	return i_ret;
+}
+
+static int _btif_state_deinit(p_mtk_btif p_btif)
+{
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("p_btif is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+	p_btif->state = B_S_OFF;
+	mutex_destroy(&(p_btif->state_mtx));
+
+	return 0;
+}
+
+static int btif_rx_data_consummer(p_mtk_btif p_btif)
+{
+	unsigned int length = 0;
+	unsigned char *p_buf = NULL;
+/*get BTIF rx buffer's information*/
+	p_btif_buf_str p_bbs = &(p_btif->btif_buf);
+/*
+ * wr_idx of btif_buf may be modified in IRQ handler,
+ * in order not to be effected by case in which irq interrupt this operation,
+ * we record wr_idx here
+ */
+	unsigned int wr_idx = p_bbs->wr_idx;
+
+	length = BBS_COUNT_CUR(p_bbs, wr_idx);
+
+/*make sure length of rx buffer data > 0*/
+	do {
+		if (length > 0) {
+			/*
+			 * check if rx_cb empty or not, if registered ,
+			 * call user's rx callback to handle these data
+			 */
+			if (p_btif->rx_cb) {
+				if (p_bbs->rd_idx <= wr_idx) {
+					p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx);
+					/* p_buf = &(p_bbs->buf[p_bbs->rd_idx]); */
+					/* length = BBS_COUNT(p_bbs); */
+					length = (wr_idx >= (p_bbs)->rd_idx) ?
+					    (wr_idx - (p_bbs)->rd_idx) :
+					    BBS_SIZE(p_bbs) -
+					    ((p_bbs)->rd_idx - wr_idx);
+					if (p_btif->rx_cb)
+						(*(p_btif->rx_cb)) (p_buf, length);
+					else
+						BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n");
+					/*update rx data read index*/
+					p_bbs->rd_idx = wr_idx;
+				} else {
+					unsigned int len_tail =
+					    BBS_SIZE(p_bbs) - (p_bbs)->rd_idx;
+					/*p_buf = &(p_bbs->buf[p_bbs->->rd_idx]);*/
+					p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx);
+					if (p_btif->rx_cb)
+						(*(p_btif->rx_cb)) (p_buf, len_tail);
+					else
+						BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n");
+					length = BBS_COUNT_CUR(p_bbs, wr_idx);
+					length -= len_tail;
+					/*p_buf = &(p_bbs->buf[0]);*/
+					p_buf = BBS_PTR(p_bbs, 0);
+					if (p_btif->rx_cb)
+						(*(p_btif->rx_cb)) (p_buf, length);
+					else
+						BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n");
+					/*update rx data read index*/
+					p_bbs->rd_idx = wr_idx;
+				}
+			} else if (p_btif->rx_notify != NULL) {
+				(*p_btif->rx_notify) ();
+			} else {
+				BTIF_WARN_FUNC
+				    ("p_btif:0x%p, both rx_notify and rx_cb are NULL\n",
+				     p_btif);
+				break;
+			}
+		} else {
+			BTIF_DBG_FUNC("length:%d\n", length);
+			break;
+		}
+		wr_idx = p_bbs->wr_idx;
+		length = BBS_COUNT_CUR(p_bbs, wr_idx);
+	} while (1);
+	return length;
+}
+
+#if BTIF_RXD_BE_BLOCKED_DETECT
+static int mtk_btif_rxd_be_blocked_by_timer(void)
+{
+	int ret = 0;
+	int counter = 0;
+	unsigned int i;
+	struct timeval now;
+	int time_gap[MAX_BTIF_RXD_TIME_REC];
+
+	do_gettimeofday(&now);
+
+	for (i = 0; i < MAX_BTIF_RXD_TIME_REC; i++) {
+		BTIF_INFO_FUNC("btif_rxd_time_stamp[%d]=%d.%d\n", i,
+			btif_rxd_time_stamp[i].tv_sec, btif_rxd_time_stamp[i].tv_usec);
+		if (now.tv_sec >= btif_rxd_time_stamp[i].tv_sec) {
+			time_gap[i] = now.tv_sec - btif_rxd_time_stamp[i].tv_sec;
+			time_gap[i] *= 1000000; /*second*/
+			if (now.tv_usec >= btif_rxd_time_stamp[i].tv_usec)
+				time_gap[i] += now.tv_usec - btif_rxd_time_stamp[i].tv_usec;
+			else
+				time_gap[i] += 1000000 - now.tv_usec + btif_rxd_time_stamp[i].tv_usec;
+
+			if (time_gap[i] > 1000000)
+				counter++;
+			BTIF_INFO_FUNC("time_gap[%d]=%d,counter:%d\n", i, time_gap[i], counter);
+		} else {
+			time_gap[i] = 0;
+			BTIF_ERR_FUNC("abnormal case now:%d < time_stamp[%d]:%d\n", now.tv_sec,
+							i, btif_rxd_time_stamp[i].tv_usec);
+		}
+	}
+	if (counter > (MAX_BTIF_RXD_TIME_REC - 2))
+		ret = 1;
+	return ret;
+}
+static int mtk_btif_rxd_be_blocked_by_data(void)
+{
+	unsigned int out_index = 0;
+	unsigned int in_index = 0;
+	unsigned int dump_size = 0;
+	unsigned int len = 0;
+	unsigned long flags;
+	unsigned int sync_pkt_n = 0;
+	P_BTIF_LOG_BUF_T p_log_buf = NULL;
+	P_BTIF_LOG_QUEUE_T p_log_que = NULL;
+	p_mtk_btif p_btif = &(g_btif[0]);
+
+	p_log_que = &p_btif->rx_log;
+	spin_lock_irqsave(&p_log_que->lock, flags);
+	in_index = p_log_que->in;
+	dump_size = p_log_que->size;
+	out_index = p_log_que->size >=
+	BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM -
+					 p_log_que->size +
+					 in_index) % BTIF_LOG_ENTRY_NUM;
+	if (dump_size != 0) {
+		while (dump_size--) {
+			p_log_buf = p_log_que->p_queue[0] + out_index;
+			len = p_log_buf->len;
+			if (len > BTIF_LOG_SZ)
+				len = BTIF_LOG_SZ;
+			if ((0x7f == *(p_log_buf->buffer)) && (0x7f == *(p_log_buf->buffer + 1))) {
+				sync_pkt_n++;
+				BTIF_INFO_FUNC("tx pkt_count:%d is sync pkt\n", out_index);
+			}
+			out_index++;
+			out_index %= BTIF_LOG_ENTRY_NUM;
+		}
+	}
+	if (sync_pkt_n == 0)
+		BTIF_ERR_FUNC("there is no sync pkt in BTIF buffer\n");
+	else
+		BTIF_ERR_FUNC("there are %d sync pkt in BTIF buffer\n", sync_pkt_n);
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+	return sync_pkt_n;
+}
+
+int mtk_btif_rxd_be_blocked_flag_get(void)
+{
+	int ret = 0;
+	int condition1 = 0, condition2 = 0;
+
+	condition1 = mtk_btif_rxd_be_blocked_by_timer();
+	condition2 = mtk_btif_rxd_be_blocked_by_data();
+	if (condition1 && condition2) {
+		BTIF_ERR_FUNC("btif_rxd thread be blocked too long!\n");
+		ret = 1;
+	}
+	return ret;
+}
+#endif
+static int btif_rx_thread(void *p_data)
+{
+#if BTIF_RXD_BE_BLOCKED_DETECT
+	unsigned int i = 0;
+#endif
+	p_mtk_btif p_btif = (p_mtk_btif)p_data;
+
+
+	while (1) {
+		wait_for_completion_interruptible(&p_btif->rx_comp);
+
+		if (kthread_should_stop()) {
+			BTIF_WARN_FUNC("btif rx thread stoping ...\n");
+			break;
+		}
+#ifdef BTIF_RXD_BE_BLOCKED_DETECT
+		do_gettimeofday(&btif_rxd_time_stamp[i]);
+		i++;
+		if (i >= MAX_BTIF_RXD_TIME_REC)
+			i = 0;
+#endif
+		btif_rx_data_consummer(p_btif);
+	}
+	return 0;
+}
+
+static void btif_rx_worker(struct work_struct *p_work)
+{
+/*get mtk_btif's pointer*/
+	p_mtk_btif p_btif = container_of(p_work, mtk_btif, rx_work);
+
+	BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif);
+/*lock rx_mutex*/
+
+	if (mutex_lock_killable(&(p_btif->rx_mtx))) {
+		BTIF_ERR_FUNC("mutex_lock_killable return failed\n");
+		return;
+	}
+	btif_rx_data_consummer(p_btif);
+	BTIF_MUTEX_UNLOCK(&(p_btif->rx_mtx));
+}
+
+static void btif_tx_worker(struct work_struct *p_work)
+{
+	int i_ret = 0;
+	int leng_sent = 0;
+/*tx fifo out*/
+	int how_much_get = 0;
+	unsigned char local_buf[384];
+
+/*get mtk_btif's pointer*/
+	p_mtk_btif p_btif = container_of(p_work, mtk_btif, tx_work);
+
+	BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif);
+
+	if (mutex_lock_killable(&(p_btif->tx_mtx))) {
+		BTIF_ERR_FUNC("mutex_lock_killable return failed\n");
+		return;
+	}
+	how_much_get =
+	    kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf));
+	do {
+		while (leng_sent < how_much_get) {
+			i_ret = _btif_send_data(p_btif,
+						local_buf + leng_sent,
+						how_much_get - leng_sent);
+			if (i_ret > 0) {
+				leng_sent += i_ret;
+			} else if (i_ret == 0) {
+				BTIF_WARN_FUNC
+				    ("_btif_send_data return 0, retry\n");
+			} else {
+				BTIF_WARN_FUNC
+				    ("btif send data fail,reset tx fifo, i_ret(%d)\n",
+				     i_ret);
+				kfifo_reset(p_btif->p_tx_fifo);
+				break;
+			}
+		}
+		how_much_get =
+		    kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf));
+		leng_sent = 0;
+	} while (how_much_get > 0);
+	BTIF_MUTEX_UNLOCK(&(p_btif->tx_mtx));
+}
+
+static void btif_rx_tasklet(unsigned long func_data)
+{
+	unsigned long flags;
+/*get mtk_btif's pointer*/
+	p_mtk_btif p_btif = (p_mtk_btif) func_data;
+
+	BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif);
+/*lock rx_spinlock*/
+	spin_lock_irqsave(&p_btif->rx_tasklet_spinlock, flags);
+	btif_rx_data_consummer(p_btif);
+	spin_unlock_irqrestore(&p_btif->rx_tasklet_spinlock, flags);
+}
+
+static int _btif_tx_ctx_init(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("p_btif is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) {
+		p_btif->p_tx_wq = create_singlethread_workqueue("btif_txd");
+
+		if (!(p_btif->p_tx_wq)) {
+			BTIF_ERR_FUNC
+			    ("create_singlethread_workqueue for tx thread fail\n");
+			i_ret = -ENOMEM;
+			goto btm_init_err;
+		}
+		mutex_init(&(p_btif->tx_mtx));
+/* init btif tx work */
+		INIT_WORK(&(p_btif->tx_work), btif_tx_worker);
+		BTIF_INFO_FUNC("btif_tx_worker init succeed\n");
+
+		p_btif->p_tx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC);
+		if (p_btif->p_tx_fifo == NULL) {
+			i_ret = -ENOMEM;
+			BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n");
+			goto btm_init_err;
+		}
+
+		i_ret = kfifo_alloc(p_btif->p_tx_fifo,
+				    BTIF_TX_FIFO_SIZE, GFP_ATOMIC);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret);
+			i_ret = -ENOMEM;
+			goto btm_init_err;
+		}
+	} else if (p_btif->tx_ctx == BTIF_TX_USER_CTX) {
+		BTIF_INFO_FUNC
+		    ("nothing is done when btif tx in user's thread\n");
+	} else {
+		BTIF_ERR_FUNC("unsupported tx context type:%d\n",
+			      p_btif->tx_ctx);
+		goto btm_init_err;
+	}
+
+	BTIF_INFO_FUNC("succeed\n");
+
+	i_ret = 0;
+	return i_ret;
+btm_init_err:
+	if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) {
+		if (p_btif->p_tx_wq) {
+			destroy_workqueue(p_btif->p_tx_wq);
+			p_btif->p_tx_wq = NULL;
+			BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n");
+		}
+		kfree(p_btif->p_tx_fifo);
+	}
+	return i_ret;
+}
+
+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+
+	if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) {
+		if (p_btif->p_tx_wq) {
+			destroy_workqueue(p_btif->p_tx_wq);
+			p_btif->p_tx_wq = NULL;
+			BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n");
+		}
+		if (p_btif->p_tx_fifo) {
+			kfifo_free(p_btif->p_tx_fifo);
+			kfree(p_btif->p_tx_fifo);
+			p_btif->p_tx_fifo = NULL;
+		}
+	}
+	return i_ret;
+}
+
+static int _btif_rx_btm_init(p_mtk_btif p_btif)
+{
+	int i_ret = -1;
+
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("p_btif is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	if (p_btif->btm_type == BTIF_THREAD_CTX) {
+		init_completion(&p_btif->rx_comp);
+
+		/*create kernel thread for later rx data handle*/
+		p_btif->p_task = kthread_create(btif_rx_thread, p_btif, "btif_rxd");
+		if (p_btif->p_task == NULL) {
+			BTIF_ERR_FUNC("kthread_create fail\n");
+			i_ret = -ENOMEM;
+			goto btm_init_err;
+		}
+
+#if ENABLE_BTIF_RX_THREAD_RT_SCHED
+		{
+			int i_ret = -1;
+			int policy = SCHED_FIFO;
+			struct sched_param param;
+
+			param.sched_priority = MAX_RT_PRIO - 20;
+			i_ret = sched_setscheduler(p_btif->p_task, policy, &param);
+			if (i_ret != 0)
+				BTIF_WARN_FUNC("set RT to btif_rxd workqueue failed\n");
+			else
+				BTIF_INFO_FUNC("set RT to btif_rxd workqueue succeed\n");
+		}
+#endif
+
+		wake_up_process(p_btif->p_task);
+		BTIF_INFO_FUNC("btif_rxd start to work!\n");
+	} else if (p_btif->btm_type == BTIF_WQ_CTX) {
+		p_btif->p_rx_wq = create_singlethread_workqueue("btif_rxwq");
+		if (!(p_btif->p_rx_wq)) {
+			BTIF_ERR_FUNC("create_singlethread_workqueue fail\n");
+			i_ret = -ENOMEM;
+			goto btm_init_err;
+		}
+		mutex_init(&(p_btif->rx_mtx));
+		/* init btif rx work */
+		INIT_WORK(&(p_btif->rx_work), btif_rx_worker);
+		BTIF_INFO_FUNC("btif_rx_worker init succeed\n");
+	} else if (p_btif->btm_type == BTIF_TASKLET_CTX) {
+		/*init rx tasklet*/
+		tasklet_init(&(p_btif->rx_tasklet), btif_rx_tasklet,
+			     (unsigned long)p_btif);
+		spin_lock_init(&(p_btif->rx_tasklet_spinlock));
+		BTIF_INFO_FUNC("btif_rx_tasklet init succeed\n");
+	} else {
+		BTIF_ERR_FUNC("unsupported rx context type:%d\n",
+			      p_btif->btm_type);
+	}
+
+/*spinlock init*/
+	spin_lock_init(&(p_btif->rx_irq_spinlock));
+	BTIF_INFO_FUNC("rx_spin_lock init succeed\n");
+
+	i_ret = 0;
+	return i_ret;
+btm_init_err:
+	if (p_btif->btm_type == BTIF_THREAD_CTX) {
+		/*do nothing*/
+		BTIF_INFO_FUNC("failed\n");
+	} else if (p_btif->btm_type == BTIF_WQ_CTX) {
+		if (p_btif->p_rx_wq) {
+			destroy_workqueue(p_btif->p_rx_wq);
+			p_btif->p_rx_wq = NULL;
+			BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n");
+		}
+	}
+	return i_ret;
+}
+
+static int _btif_rx_btm_sched(p_mtk_btif p_btif)
+{
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("p_btif is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	if (p_btif->btm_type == BTIF_THREAD_CTX) {
+		complete(&p_btif->rx_comp);
+		BTIF_DBG_FUNC("schedule btif_rx_thread\n");
+	} else if (p_btif->btm_type == BTIF_WQ_CTX) {
+		queue_work(p_btif->p_rx_wq, &(p_btif->rx_work));
+		BTIF_DBG_FUNC("schedule btif_rx_worker\n");
+	} else if (p_btif->btm_type == BTIF_TASKLET_CTX) {
+		/*schedule it!*/
+		tasklet_schedule(&(p_btif->rx_tasklet));
+		BTIF_DBG_FUNC("schedule btif_rx_tasklet\n");
+	} else {
+		BTIF_ERR_FUNC("unsupported rx context type:%d\n",
+			      p_btif->btm_type);
+	}
+
+	return 0;
+}
+
+static int _btif_rx_btm_deinit(p_mtk_btif p_btif)
+{
+	if (p_btif == NULL) {
+		BTIF_ERR_FUNC("p_btif is NULL\n");
+		return E_BTIF_INVAL_PARAM;
+	}
+	if (p_btif->btm_type == BTIF_THREAD_CTX) {
+		if (p_btif->p_task != NULL) {
+			BTIF_INFO_FUNC("signaling btif rx thread to stop ...\n");
+			kthread_stop(p_btif->p_task);
+		}
+	} else if (p_btif->btm_type == BTIF_WQ_CTX) {
+		if (p_btif->p_rx_wq) {
+			cancel_work_sync(&(p_btif->rx_work));
+			BTIF_INFO_FUNC("btif_rx_worker cancelled\n");
+			destroy_workqueue(p_btif->p_rx_wq);
+			p_btif->p_rx_wq = NULL;
+			BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n");
+		}
+		mutex_destroy(&(p_btif->rx_mtx));
+	} else if (p_btif->btm_type == BTIF_TASKLET_CTX) {
+		tasklet_kill(&(p_btif->rx_tasklet));
+		BTIF_INFO_FUNC("rx_tasklet killed\n");
+	} else {
+		BTIF_ERR_FUNC("unsupported rx context type:%d\n",
+			      p_btif->btm_type);
+	}
+
+	spin_lock_init(&(p_btif->rx_irq_spinlock));
+
+	return 0;
+}
+
+
+void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs)
+{
+	BTIF_INFO_FUNC
+	    ("%s UBS:0x%p\n  Size:0x%p\n  read:0x%08x\n  write:0x%08x\n",
+	     p_str, p_bbs, p_bbs->size, p_bbs->rd_idx, p_bbs->wr_idx);
+}
+
+unsigned int btif_bbs_write(p_btif_buf_str p_bbs,
+			    unsigned char *p_buf, unsigned int buf_len)
+{
+/*in IRQ context, so read operation won't interrupt this operation*/
+
+	unsigned int wr_len = 0;
+
+	unsigned int emp_len = BBS_LEFT(p_bbs);
+	unsigned int ava_len = emp_len - 1;
+	p_mtk_btif p_btif = container_of(p_bbs, mtk_btif, btif_buf);
+
+	if (ava_len <= 0) {
+		BTIF_ERR_FUNC
+		    ("no empty space left for write, (%d)ava_len, (%d)to write\n",
+		     ava_len, buf_len);
+		hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL);
+		hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL);
+		return 0;
+	}
+
+	if (ava_len < buf_len) {
+		BTIF_ERR_FUNC("BTIF overrun, (%d)empty, (%d)needed\n",
+			      emp_len, buf_len);
+		hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL);
+		hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL);
+		_btif_dump_memory("<DMA Rx vFIFO>", p_buf, buf_len);
+	}
+
+	if (buf_len >= g_max_pkg_len) {
+		BTIF_WARN_FUNC("buf_len too long, (%d)ava_len, (%d)to write\n",
+			       ava_len, buf_len);
+		hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL);
+		hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL);
+		_btif_dump_memory("<DMA Rx vFIFO>", p_buf, buf_len);
+	}
+
+	wr_len = min(buf_len, ava_len);
+	btif_bbs_wr_direct(p_bbs, p_buf, wr_len);
+
+	if (BBS_COUNT(p_bbs) >= g_max_pding_data_size) {
+		BTIF_WARN_FUNC("Rx buf_len too long, size(%d)\n",
+			       BBS_COUNT(p_bbs));
+		btif_dump_bbs_str("Rx buffer tooo long", p_bbs);
+		hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL);
+		hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL);
+		_btif_dump_memory("<DMA Rx vFIFO>", p_buf, buf_len);
+		BBS_INIT(p_bbs);
+	}
+
+	return wr_len;
+}
+
+unsigned int btif_bbs_read(p_btif_buf_str p_bbs,
+			   unsigned char *p_buf, unsigned int buf_len)
+{
+	unsigned int rd_len = 0;
+	unsigned int ava_len = 0;
+	unsigned int wr_idx = p_bbs->wr_idx;
+
+	ava_len = BBS_COUNT_CUR(p_bbs, wr_idx);
+	if (ava_len >= 4096) {
+		BTIF_WARN_FUNC("ava_len too long, size(%d)\n", ava_len);
+		btif_dump_bbs_str("Rx buffer tooo long", p_bbs);
+	}
+	if (ava_len != 0) {
+		if (buf_len >= ava_len) {
+			rd_len = ava_len;
+			if (wr_idx >= (p_bbs)->rd_idx) {
+				memcpy(p_buf, BBS_PTR(p_bbs,
+						      p_bbs->rd_idx),
+				       ava_len);
+				(p_bbs)->rd_idx = wr_idx;
+			} else {
+				unsigned int tail_len = BBS_SIZE(p_bbs) -
+				    (p_bbs)->rd_idx;
+				memcpy(p_buf, BBS_PTR(p_bbs,
+						      p_bbs->rd_idx),
+				       tail_len);
+				memcpy(p_buf + tail_len, BBS_PTR(p_bbs,
+								 0), ava_len - tail_len);
+				(p_bbs)->rd_idx = wr_idx;
+			}
+		} else {
+			rd_len = buf_len;
+			if (wr_idx >= (p_bbs)->rd_idx) {
+				memcpy(p_buf, BBS_PTR(p_bbs,
+						      p_bbs->rd_idx),
+				       rd_len);
+				(p_bbs)->rd_idx = (p_bbs)->rd_idx + rd_len;
+			} else {
+				unsigned int tail_len = BBS_SIZE(p_bbs) -
+				    (p_bbs)->rd_idx;
+				if (tail_len >= rd_len) {
+					memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx),
+					       rd_len);
+					(p_bbs)->rd_idx =
+					    ((p_bbs)->rd_idx + rd_len) & (BBS_MASK(p_bbs));
+				} else {
+					memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), tail_len);
+					memcpy(p_buf + tail_len,
+					       (p_bbs)->p_buf, rd_len - tail_len);
+					(p_bbs)->rd_idx = rd_len - tail_len;
+				}
+			}
+		}
+	}
+	mb();
+	return rd_len;
+}
+
+unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs,
+				unsigned char *p_buf, unsigned int buf_len)
+{
+	unsigned int tail_len = 0;
+	unsigned int l = 0;
+	unsigned int tmp_wr_idx = p_bbs->wr_idx;
+
+	tail_len = BBS_SIZE(p_bbs) - (tmp_wr_idx & BBS_MASK(p_bbs));
+
+	l = min(tail_len, buf_len);
+
+	memcpy((p_bbs->p_buf) + (tmp_wr_idx & BBS_MASK(p_bbs)), p_buf, l);
+	memcpy(p_bbs->p_buf, p_buf + l, buf_len - l);
+
+	mb();
+
+	tmp_wr_idx += buf_len;
+	tmp_wr_idx &= BBS_MASK(p_bbs);
+	p_bbs->wr_idx = tmp_wr_idx;
+
+	mb();
+	return buf_len;
+}
+
+int _btif_dma_write(p_mtk_btif p_btif,
+		    const unsigned char *p_buf, unsigned int buf_len)
+{
+	unsigned int i_ret = 0;
+	unsigned int retry = 0;
+	unsigned int max_tx_retry = 10;
+
+	P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info;
+
+	_btif_irq_ctrl_sync(p_dma_info->p_irq, false);
+	do {
+		/*wait until tx is allowed*/
+		while (!hal_dma_is_tx_allow(p_dma_info) &&
+		       (retry < max_tx_retry)) {
+			retry++;
+			if (retry >= max_tx_retry) {
+				BTIF_ERR_FUNC("wait for tx allowed timeout\n");
+				break;
+			}
+		}
+		if (retry >= max_tx_retry)
+			break;
+
+		if (buf_len <= hal_dma_get_ava_room(p_dma_info))
+			i_ret = hal_dma_send_data(p_dma_info, p_buf, buf_len);
+		else
+			i_ret = 0;
+	} while (0);
+	_btif_irq_ctrl_sync(p_dma_info->p_irq, true);
+	return i_ret;
+}
+
+int _btif_pio_write(p_mtk_btif p_btif,
+		    const unsigned char *p_buf, unsigned int buf_len)
+{
+	unsigned int i_ret = 0;
+	unsigned int sent_len = 0;
+	unsigned int retry = 0;
+	unsigned int max_tx_retry = 10;
+	P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info;
+
+	while ((sent_len < buf_len)) {
+		if (hal_btif_is_tx_allow(p_btif_info)) {
+			i_ret = hal_btif_send_data(p_btif_info,
+						   p_buf + sent_len,
+						   buf_len - sent_len);
+			if (i_ret > 0) {
+				sent_len += i_ret;
+				BTIF_DBG_FUNC("lent sent:%d, total sent:%d\n",
+					      i_ret, sent_len);
+				retry = 0;
+			}
+		}
+		if ((++retry > max_tx_retry) || (i_ret < 0)) {
+			BTIF_INFO_FUNC("exceed retry times limit :%d\n", retry);
+			break;
+		}
+	}
+	i_ret = sent_len;
+	return i_ret;
+}
+
+int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len)
+{
+	unsigned int idx = 0;
+
+	pr_debug("%s:, length:%d\n", str, buf_len);
+	for (idx = 0; idx < buf_len;) {
+		pr_debug("%02x ", p_buf[idx]);
+		idx++;
+		if (idx % 8 == 0)
+			pr_debug("\n");
+	}
+	return 0;
+}
+
+int btif_send_data(p_mtk_btif p_btif,
+		   const unsigned char *p_buf, unsigned int buf_len)
+{
+	int i_ret = 0;
+
+	if (p_btif->tx_ctx == BTIF_TX_USER_CTX) {
+		i_ret = _btif_send_data(p_btif, p_buf, buf_len);
+	} else if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) {
+		int length = 0;
+/*tx fifo in*/
+		length = kfifo_in(p_btif->p_tx_fifo,
+				  (unsigned char *)p_buf, buf_len);
+		if (length == buf_len) {
+			queue_work(p_btif->p_tx_wq, &(p_btif->tx_work));
+			BTIF_DBG_FUNC("schedule btif_tx_worker\n");
+			i_ret = length;
+		} else {
+			i_ret = 0;
+			BTIF_ERR_FUNC("fifo in failed, target len(%d),in len(%d),",
+				"don't schedule btif_tx_worker\n", buf_len, length);
+		}
+	} else {
+		BTIF_ERR_FUNC("invalid btif tx context:%d\n", p_btif->tx_ctx);
+		i_ret = 0;
+	}
+
+	return i_ret;
+}
+
+int _btif_send_data(p_mtk_btif p_btif,
+		    const unsigned char *p_buf, unsigned int buf_len)
+{
+	int i_ret = 0;
+	unsigned int state = 0;
+
+/*make sure BTIF in ON state before doing tx operation*/
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+	state = _btif_state_get(p_btif);
+
+	if (state != B_S_ON)
+		i_ret = _btif_exit_dpidle(p_btif);
+
+	if (i_ret != 0) {
+		i_ret = E_BTIF_INVAL_STATE;
+	} else if (p_btif->tx_mode == BTIF_MODE_DMA) {
+		/*_btif_dump_memory("tx data:", p_buf, buf_len);*/
+		i_ret = _btif_dma_write(p_btif, p_buf, buf_len);
+	} else if (p_btif->tx_mode == BTIF_MODE_PIO) {
+		/*_btif_dump_memory("tx data:", p_buf, buf_len);*/
+		i_ret = _btif_pio_write(p_btif, p_buf, buf_len);
+	} else {
+		BTIF_ERR_FUNC("invalid tx mode:%d\n", p_btif->tx_mode);
+		i_ret = 0;
+	}
+
+/*save Tx packet here*/
+	if (i_ret > 0)
+		btif_log_buf_dmp_in(&p_btif->tx_log, p_buf, i_ret);
+
+	BTIF_STATE_RELEASE(p_btif);
+	return i_ret;
+}
+
+int btif_dump_reg(p_mtk_btif p_btif)
+{
+	int i_ret = 0;
+	unsigned int ori_state = 0;
+
+/*make sure BTIF in ON state before doing tx operation*/
+	if (_btif_state_hold(p_btif))
+		return E_BTIF_INTR;
+	ori_state = _btif_state_get(p_btif);
+
+	if (ori_state == B_S_OFF) {
+		i_ret = E_BTIF_INVAL_STATE;
+		BTIF_ERR_FUNC
+		    ("BTIF in OFF state, ",
+		     "should no need to dump register, ",
+		     "please check wmt's operation is okay or not.\n");
+		goto dmp_reg_err;
+	}
+
+	if ((ori_state != B_S_ON) && (ori_state < B_S_MAX)) {
+		BTIF_ERR_FUNC("BTIF's original state is %s, not B_S_ON\n", g_state[ori_state]);
+		BTIF_ERR_FUNC("!!!!---<<<This should never happen in normal mode>>>---!!!");
+		i_ret = _btif_exit_dpidle(p_btif);
+	}
+
+	if (i_ret != 0) {
+		i_ret = E_BTIF_INVAL_STATE;
+		BTIF_ERR_FUNC("switch to B_S_ON failed\n");
+		goto dmp_reg_err;
+	}
+
+/*dump BTIF register*/
+	hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL);
+
+/*dump BTIF Tx DMA channel register if in DMA mode*/
+	if (p_btif->tx_mode == BTIF_MODE_DMA)
+		hal_dma_dump_reg(p_btif->p_tx_dma->p_dma_info, REG_TX_DMA_ALL);
+	else
+		BTIF_INFO_FUNC("BTIF Tx in PIO mode,no need to dump Tx DMA's register\n");
+
+/*dump BTIF Rx DMA channel register if in DMA mode*/
+	if (p_btif->rx_mode == BTIF_MODE_DMA)
+		hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL);
+	else
+		BTIF_INFO_FUNC("BTIF Rx in PIO mode,no need to dump Rx DMA's register\n");
+
+	switch (ori_state) {
+	case B_S_SUSPEND:
+/*return to dpidle state*/
+/* break; */
+	case B_S_DPIDLE:
+/*return to dpidle state*/
+		_btif_enter_dpidle(p_btif);
+		break;
+	case B_S_ON:
+/*nothing needs to be done*/
+		break;
+	default:
+		break;
+	}
+
+dmp_reg_err:
+
+	BTIF_STATE_RELEASE(p_btif);
+	return i_ret;
+}
+
+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify)
+{
+	if (p_btif->rx_notify) {
+		BTIF_WARN_FUNC
+		    ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n",
+		     p_btif->rx_notify, rx_notify);
+	}
+	p_btif->rx_notify = rx_notify;
+
+	return 0;
+}
+
+int btif_dump_data(char *p_buf, int len)
+{
+	unsigned int idx = 0;
+	unsigned char str[30];
+	unsigned char *p_str;
+
+	p_str = &str[0];
+	for (idx = 0; idx < len; idx++, p_buf++) {
+		sprintf(p_str, "%02x ", *p_buf);
+		p_str += 3;
+		if (7 == (idx % 8)) {
+			*p_str++ = '\n';
+			*p_str = '\0';
+			pr_debug("%s", str);
+			p_str = &str[0];
+		}
+	}
+	if (len % 8) {
+		*p_str++ = '\n';
+		*p_str = '\0';
+		pr_debug("%s", str);
+	}
+	return 0;
+}
+
+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf,
+			int len)
+{
+	P_BTIF_LOG_BUF_T p_log_buf = NULL;
+	char *dir = NULL;
+	struct timeval *p_timer = NULL;
+	unsigned long flags;
+	bool output_flag = false;
+
+	BTIF_DBG_FUNC("++\n");
+
+	if ((p_log_que == NULL) || (p_buf == NULL) || (len == 0)) {
+		BTIF_ERR_FUNC("invalid parameter, p_log_que(0x%x), buf(0x%x), ",
+			"len(%d)\n", p_log_que, p_buf, len);
+		return 0;
+	}
+	if (!(p_log_que->enable))
+		return 0;
+
+	dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx";
+	output_flag = p_log_que->output_flag;
+
+	spin_lock_irqsave(&(p_log_que->lock), flags);
+
+/*get next log buffer for record usage*/
+	p_log_buf = p_log_que->p_queue[0] + p_log_que->in;
+	p_timer = &p_log_buf->timer;
+
+/*log time stamp*/
+	do_gettimeofday(p_timer);
+
+/*record data information including length and content*/
+	p_log_buf->len = len;
+	memcpy(p_log_buf->buffer, p_buf, len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len);
+
+/*update log queue size information*/
+	p_log_que->size++;
+	p_log_que->size = p_log_que->size >
+	    BTIF_LOG_ENTRY_NUM ? BTIF_LOG_ENTRY_NUM : p_log_que->size;
+
+/*update log queue index information*/
+	p_log_que->in++;
+	p_log_que->in %= BTIF_LOG_ENTRY_NUM;
+
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+
+/*check if log dynamic output function is enabled or not*/
+	if (output_flag) {
+		pr_debug("BTIF-DBG, dir:%s, %d.%ds len:%d\n",
+		       dir, (int)p_timer->tv_sec, (int)p_timer->tv_usec, len);
+/*output buffer content*/
+		btif_dump_data((char *)p_buf, len);
+	}
+	BTIF_DBG_FUNC("--\n");
+
+	return 0;
+}
+
+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que)
+{
+	P_BTIF_LOG_BUF_T p_log_buf = NULL;
+	unsigned int out_index = 0;
+	unsigned int in_index = 0;
+	unsigned int dump_size = 0;
+	unsigned char *p_buf = NULL;
+	unsigned int len = 0;
+	unsigned int pkt_count = 0;
+	unsigned char *p_dir = NULL;
+	struct timeval *p_timer = NULL;
+	unsigned long flags;
+
+#if 0				/* no matter enable or not, we allowed output */
+	if (!(p_log_que->enable))
+		return;
+#endif
+	BTIF_DBG_FUNC("++\n");
+
+	spin_lock_irqsave(&p_log_que->lock, flags);
+	in_index = p_log_que->in;
+	dump_size = p_log_que->size;
+	out_index = p_log_que->size >=
+	    BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM -
+					     p_log_que->size +
+					     in_index) % BTIF_LOG_ENTRY_NUM;
+	p_dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx";
+
+	BTIF_INFO_FUNC("btif %s log buffer size:%d\n", p_dir, dump_size);
+
+	if (dump_size != 0) {
+		while (dump_size--) {
+			p_log_buf = p_log_que->p_queue[0] + out_index;
+
+			len = p_log_buf->len;
+			p_buf = p_log_buf->buffer;
+			p_timer = &p_log_buf->timer;
+
+			len = len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len;
+
+			BTIF_INFO_FUNC("dir:%s, pkt_count:%d, %d.%ds len:%d\n",
+			       p_dir,
+			       pkt_count++,
+			       (int)p_timer->tv_sec,
+			       (int)p_timer->tv_usec, len);
+/*output buffer content*/
+			btif_dump_data(p_log_buf->buffer, len);
+			out_index++;
+			out_index %= BTIF_LOG_ENTRY_NUM;
+		}
+	}
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+	BTIF_DBG_FUNC("--\n");
+
+	return 0;
+}
+
+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&p_log_que->lock, flags);
+	p_log_que->enable = true;
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+	BTIF_INFO_FUNC("enable %s log function\n",
+		       p_log_que->dir == BTIF_TX ? "Tx" : "Rx");
+	return 0;
+}
+
+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&p_log_que->lock, flags);
+	p_log_que->enable = false;
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+	BTIF_INFO_FUNC("disable %s log function\n",
+		       p_log_que->dir == BTIF_TX ? "Tx" : "Rx");
+	return 0;
+}
+
+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&p_log_que->lock, flags);
+	p_log_que->output_flag = true;
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+	BTIF_INFO_FUNC("%s log rt output enabled\n",
+		       p_log_que->dir == BTIF_TX ? "Tx" : "Rx");
+	return 0;
+}
+
+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&p_log_que->lock, flags);
+	p_log_que->output_flag = false;
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+	BTIF_INFO_FUNC("%s log rt output disabled\n",
+		       p_log_que->dir == BTIF_TX ? "Tx" : "Rx");
+	return 0;
+}
+
+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&p_log_que->lock, flags);
+
+/*tx log buffer init*/
+	p_log_que->in = 0;
+	p_log_que->out = 0;
+	p_log_que->size = 0;
+	p_log_que->enable = true;
+	memset((p_log_que->p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T));
+
+	spin_unlock_irqrestore(&p_log_que->lock, flags);
+	BTIF_DBG_FUNC("reset %s log buffer\n",
+		       p_log_que->dir == BTIF_TX ? "Tx" : "Rx");
+	return 0;
+}
+
+int btif_log_buf_init(p_mtk_btif p_btif)
+{
+/*tx log buffer init*/
+	p_btif->tx_log.dir = BTIF_TX;
+	p_btif->tx_log.in = 0;
+	p_btif->tx_log.out = 0;
+	p_btif->tx_log.size = 0;
+	p_btif->tx_log.output_flag = false;
+	p_btif->tx_log.enable = true;
+	spin_lock_init(&(p_btif->tx_log.lock));
+	BTIF_DBG_FUNC("tx_log.p_queue:0x%p\n", p_btif->tx_log.p_queue[0]);
+	memset((p_btif->tx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T));
+
+/*rx log buffer init*/
+	p_btif->rx_log.dir = BTIF_RX;
+	p_btif->rx_log.in = 0;
+	p_btif->rx_log.out = 0;
+	p_btif->rx_log.size = 0;
+	p_btif->rx_log.output_flag = false;
+	p_btif->rx_log.enable = true;
+	spin_lock_init(&(p_btif->rx_log.lock));
+	BTIF_DBG_FUNC("rx_log.p_queue:0x%p\n", p_btif->rx_log.p_queue[0]);
+	memset((p_btif->rx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T));
+
+	return 0;
+}
+
+int btif_tx_dma_mode_set(int en)
+{
+	int index = 0;
+	ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO;
+
+	for (index = 0; index < BTIF_PORT_NR; index++)
+		g_btif[index].tx_mode = mode;
+
+	return 0;
+}
+
+int btif_rx_dma_mode_set(int en)
+{
+	int index = 0;
+	ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO;
+
+	for (index = 0; index < BTIF_PORT_NR; index++)
+		g_btif[index].rx_mode = mode;
+
+	return 0;
+}
+
+static int BTIF_init(void)
+{
+	int i_ret = -1;
+	int index = 0;
+	p_mtk_btif_dma p_tx_dma = NULL;
+	p_mtk_btif_dma p_rx_dma = NULL;
+	unsigned char *p_btif_buffer = NULL;
+	unsigned char *p_tx_queue = NULL;
+	unsigned char *p_rx_queue = NULL;
+
+	BTIF_DBG_FUNC("++\n");
+
+/*Platform Driver initialization*/
+	i_ret = platform_driver_register(&mtk_btif_dev_drv);
+	if (i_ret) {
+		BTIF_ERR_FUNC("BTIF platform driver registered failed, ret(%d)\n", i_ret);
+		goto err_exit1;
+	}
+
+	i_ret = driver_create_file(&mtk_btif_dev_drv.driver, &driver_attr_flag);
+	if (i_ret)
+		BTIF_ERR_FUNC("BTIF pdriver_create_file failed, ret(%d)\n", i_ret);
+
+/*SW init*/
+	for (index = 0; index < BTIF_PORT_NR; index++) {
+		p_btif_buffer = kmalloc(BTIF_RX_BUFFER_SIZE, GFP_ATOMIC);
+		if (!p_btif_buffer) {
+			BTIF_ERR_FUNC("p_btif_buffer kmalloc memory fail\n");
+			return -1;
+		}
+		BTIF_INFO_FUNC("p_btif_buffer get memory 0x%p\n", p_btif_buffer);
+		p_tx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC);
+		if (!p_tx_queue) {
+			BTIF_ERR_FUNC("p_tx_queue kmalloc memory fail\n");
+			kfree(p_btif_buffer);
+			return -1;
+		}
+		BTIF_INFO_FUNC("p_tx_queue get memory 0x%p\n", p_tx_queue);
+		p_rx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC);
+		if (!p_rx_queue) {
+			BTIF_ERR_FUNC("p_rx_queue kmalloc memory fail\n");
+			kfree(p_btif_buffer);
+			kfree(p_tx_queue);
+			return -1;
+		}
+		BTIF_INFO_FUNC("p_rx_queue get memory 0x%p\n", p_rx_queue);
+
+		INIT_LIST_HEAD(&(g_btif[index].user_list));
+		BBS_INIT(&(g_btif[index].btif_buf));
+		g_btif[index].enable = false;
+		g_btif[index].open_counter = 0;
+		g_btif[index].setting = &g_btif_setting[index];
+		g_btif[index].p_btif_info = hal_btif_info_get();
+		g_btif[index].tx_mode = g_btif_setting[index].tx_mode;
+		g_btif[index].rx_mode = g_btif_setting[index].rx_mode;
+		g_btif[index].btm_type = g_btif_setting[index].rx_type;
+		g_btif[index].tx_ctx = g_btif_setting[index].tx_type;
+		g_btif[index].lpbk_flag = false;
+		g_btif[index].rx_cb = NULL;
+		g_btif[index].rx_notify = NULL;
+		g_btif[index].btif_buf.p_buf = p_btif_buffer;
+		g_btif[index].tx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_tx_queue;
+		g_btif[index].rx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_rx_queue;
+		btif_log_buf_init(&g_btif[index]);
+
+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER)
+/*enable BTIF clock gating by default*/
+		i_ret = hal_btif_clk_ctrl(g_btif[index].p_btif_info,
+					  CLK_OUT_DISABLE);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF controller CG failed\n");
+			goto err_exit2;
+		}
+#endif
+
+/*
+ * viftual FIFO memory must be physical continious,
+ * because DMA will access it directly without MMU
+ */
+#if ENABLE_BTIF_TX_DMA
+		p_tx_dma = &g_dma[index][BTIF_TX];
+		g_btif[index].p_tx_dma = p_tx_dma;
+		p_tx_dma->dir = BTIF_TX;
+		p_tx_dma->p_btif = &(g_btif[index]);
+
+/*DMA Tx vFIFO initialization*/
+		p_tx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_TX);
+/*spinlock init*/
+		spin_lock_init(&(p_tx_dma->iolock));
+/*entry setup*/
+		atomic_set(&(p_tx_dma->entry), 0);
+/*vFIFO initialization*/
+		i_ret = _btif_vfifo_init(p_tx_dma);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF Tx vFIFO allocation failed\n");
+			goto err_exit2;
+		}
+
+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER)
+/*enable BTIF Tx DMA channel's clock gating by default*/
+		i_ret = hal_btif_dma_clk_ctrl(p_tx_dma->p_dma_info,
+					      CLK_OUT_DISABLE);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF Tx DMA's CG failed\n");
+			goto err_exit2;
+		}
+#endif
+
+#else
+		g_btif[index].p_tx_dma = NULL;
+/*force tx mode to DMA no matter what it is in default setting*/
+		g_btif[index].tx_mode = BTIF_MODE_PIO;
+#endif
+
+#if ENABLE_BTIF_RX_DMA
+		p_rx_dma = &g_dma[index][BTIF_RX];
+		g_btif[index].p_rx_dma = p_rx_dma;
+		p_rx_dma->p_btif = &(g_btif[index]);
+		p_rx_dma->dir = BTIF_RX;
+
+/*DMA Tx vFIFO initialization*/
+		p_rx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_RX);
+/*spinlock init*/
+		spin_lock_init(&(p_rx_dma->iolock));
+/*entry setup*/
+		atomic_set(&(p_rx_dma->entry), 0);
+/*vFIFO initialization*/
+		i_ret = _btif_vfifo_init(p_rx_dma);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF Rx vFIFO allocation failed\n");
+			goto err_exit2;
+		}
+
+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER)
+/*enable BTIF Tx DMA channel's clock gating by default*/
+		i_ret = hal_btif_dma_clk_ctrl(p_rx_dma->p_dma_info,
+					      CLK_OUT_DISABLE);
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF Rx DMA's CG failed\n");
+			goto err_exit2;
+		}
+#endif
+
+#else
+		g_btif[index].p_rx_dma = NULL;
+/*force rx mode to DMA no matter what it is in default setting*/
+		g_btif[index].rx_mode = BTIF_MODE_PIO;
+
+#endif
+/*PM state mechine initialization*/
+		i_ret = _btif_state_init(&(g_btif[index]));
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF state mechanism init failed\n");
+			goto err_exit2;
+		}
+
+/*Rx bottom half initialization*/
+		i_ret = _btif_rx_btm_init(&(g_btif[index]));
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF Rx btm init failed\n");
+			goto err_exit3;
+		}
+		i_ret = _btif_tx_ctx_init(&(g_btif[index]));
+		if (i_ret != 0) {
+			BTIF_ERR_FUNC("BTIF Tx context init failed\n");
+			goto err_exit4;
+		}
+/*Character Device initialization*/
+/*Chaozhong: ToDo: to be initialized*/
+
+		mutex_init(&g_btif[index].ops_mtx);
+	}
+
+/*Debug purpose initialization*/
+
+#if BTIF_CDEV_SUPPORT
+	btif_chrdev_init();
+#endif
+
+	return 0;
+
+err_exit4:
+	for (index = 0; index < BTIF_PORT_NR; index++)
+		_btif_tx_ctx_deinit(&(g_btif[index]));
+
+err_exit3:
+	for (index = 0; index < BTIF_PORT_NR; index++) {
+		_btif_rx_btm_deinit(&(g_btif[index]));
+
+		_btif_state_deinit(&(g_btif[index]));
+	}
+
+err_exit2:
+	for (index = 0; index < BTIF_PORT_NR; index++) {
+		p_tx_dma = &g_dma[index][BTIF_TX];
+		p_rx_dma = &g_dma[index][BTIF_RX];
+#if ENABLE_BTIF_TX_DMA
+		_btif_vfifo_deinit(p_tx_dma);
+#endif
+
+#if ENABLE_BTIF_RX_DMA
+		_btif_vfifo_deinit(p_rx_dma);
+#endif
+		g_btif[index].open_counter = 0;
+		g_btif[index].enable = false;
+	}
+	driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag);
+	platform_driver_unregister(&mtk_btif_dev_drv);
+
+err_exit1:
+	i_ret = -1;
+	BTIF_DBG_FUNC("--\n");
+	return i_ret;
+}
+
+static void BTIF_exit(void)
+{
+	unsigned int index = 0;
+	p_mtk_btif_dma p_tx_dma = NULL;
+	p_mtk_btif_dma p_rx_dma = NULL;
+
+	BTIF_DBG_FUNC("++\n");
+
+	for (index = 0; index < BTIF_PORT_NR; index++) {
+		g_btif[index].open_counter = 0;
+		g_btif[index].enable = false;
+		p_tx_dma = &g_dma[index][BTIF_TX];
+		p_rx_dma = &g_dma[index][BTIF_RX];
+#if ENABLE_BTIF_TX_DMA
+		_btif_vfifo_deinit(p_tx_dma);
+#endif
+
+#if ENABLE_BTIF_RX_DMA
+		_btif_vfifo_deinit(p_rx_dma);
+#endif
+		_btif_state_deinit(&(g_btif[index]));
+
+		_btif_rx_btm_deinit(&(g_btif[index]));
+
+		mutex_destroy(&g_btif[index].ops_mtx);
+	}
+
+#if !defined(CONFIG_MTK_CLKMGR)
+		hal_btif_clk_unprepare();
+#endif
+
+	driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag);
+	platform_driver_unregister(&mtk_btif_dev_drv);
+	BTIF_DBG_FUNC("--\n");
+}
+
+int mtk_btif_hal_get_log_lvl(void)
+{
+	return mtk_btif_dbg_lvl;
+}
+
+void mtk_btif_read_cpu_sw_rst_debug(void)
+{
+	mtk_btif_read_cpu_sw_rst_debug_plat();
+}
+
+/*---------------------------------------------------------------------------*/
+
+module_init(BTIF_init);
+module_exit(BTIF_exit);
+
+/*---------------------------------------------------------------------------*/
+
+MODULE_AUTHOR("MBJ/WCN/SE/SS1/Chaozhong.Liang");
+MODULE_DESCRIPTION("MTK BTIF Driver$1.0$");
+MODULE_LICENSE("GPL");
+
+/*---------------------------------------------------------------------------*/
diff --git a/drivers/misc/mediatek/btif/common/mtk_btif_exp.c b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c
new file mode 100644
index 0000000000000..c0df44558357b
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c
@@ -0,0 +1,786 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG "MTK-BTIF-EXP"
+
+/*#include "mtk_btif_exp.h"*/
+#include "mtk_btif.h"
+
+/*---------------------------------Function----------------------------------*/
+
+p_mtk_btif btif_exp_srh_id(unsigned long u_id)
+{
+	int index = 0;
+	p_mtk_btif p_btif = NULL;
+	struct list_head *p_list = NULL;
+	struct list_head *tmp = NULL;
+	p_mtk_btif_user p_user = NULL;
+
+	for (index = 0; (index < BTIF_PORT_NR) && (p_btif == NULL); index++) {
+		p_list = &(g_btif[index].user_list);
+		list_for_each(tmp, p_list) {
+			p_user = container_of(tmp, mtk_btif_user, entry);
+			if (u_id == p_user->u_id) {
+				p_btif = p_user->p_btif;
+				BTIF_DBG_FUNC
+				    ("BTIF's user id(0x%p), p_btif(0x%p)\n",
+				     p_user->u_id, p_btif);
+				break;
+			}
+		}
+	}
+	if (p_btif == NULL) {
+		BTIF_INFO_FUNC
+		    ("no btif structure found for BTIF's user id(0x%lx)\n",
+		     u_id);
+	}
+	return p_btif;
+}
+
+/*-----Normal Mode API declearation-------*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_open
+* DESCRIPTION
+*  open BTIF interface, will do BTIF module HW and SW initialization
+* PARAMETERS
+*  p_owner      [IN] pointer to owner who call this API,
+*                    currently there are 2 owner ("stp" or "btif_tester")
+*                    may use this module
+*  for "stp", BTIF will call rx callback function to route rx data to STP module
+*  for "stp_tester", BTIF will save rx data and wait for native process to access
+*  p_id            [IN] BTIF's user id will be put to this address
+* RETURNS
+*  int  0 = BTIF module initialization fail; negative = BTIF module initialization success
+*       if open success, value p_id will be the only identifier
+*       for user to access BTIF's other operations
+*       including read/write/dpidle_ctrl/rx_cb_retister
+*       this user id is only an identifier used for owner identification
+*****************************************************************************/
+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id)
+{
+	int i_ret = -1;
+	unsigned int index = 0;
+	p_mtk_btif_user p_new_user = NULL;
+	p_mtk_btif p_btif = &g_btif[index];
+	struct list_head *p_user_list = &(p_btif->user_list);
+
+	BTIF_DBG_FUNC("++");
+	BTIF_DBG_FUNC("p_btif(0x%p)\n", p_btif);
+
+	if (mutex_lock_killable(&(p_btif->ops_mtx))) {
+		BTIF_ERR_FUNC("mutex_lock_killable return failed\n");
+		return E_BTIF_INTR;
+	}
+	if ((p_owner == NULL) || (p_id == NULL)) {
+		if (p_id)
+			*p_id = 0;
+		BTIF_ERR_FUNC("parameter invalid, p_owner(0x%p), p_id(0x%p)\n",
+			      p_owner, p_id);
+		BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx));
+		return E_BTIF_INVAL_PARAM;
+	}
+
+/*check if btif is already opened or not, if yes, just return fail*/
+	if (!list_empty(p_user_list)) {
+		struct list_head *pos;
+		p_mtk_btif_user p_user;
+
+		BTIF_ERR_FUNC("BTIF's user list is not empty\n");
+		list_for_each(pos, p_user_list) {
+			p_user = container_of(pos, mtk_btif_user, entry);
+			BTIF_INFO_FUNC("BTIF's user id(0x%lx), name(%s)\n",
+				       p_user->u_id, p_user->u_name);
+		}
+/*leave p_id alone*/
+		BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx));
+		return E_BTIF_ALREADY_OPEN;
+	}
+	p_new_user = vmalloc(sizeof(mtk_btif_user));
+
+	if (p_new_user != NULL) {
+		INIT_LIST_HEAD(&(p_new_user->entry));
+		p_new_user->enable = false;
+		p_new_user->p_btif = p_btif;
+		p_new_user->u_id = (unsigned long)p_new_user;
+		strncpy(p_new_user->u_name, p_owner, sizeof(p_new_user->u_name) - 1);
+		p_new_user->u_name[sizeof(p_new_user->u_name) - 1] = '\0';
+		BTIF_DBG_FUNC("owner name:%s, recorded name:%s\n",
+			       p_owner, p_new_user->u_name);
+
+		i_ret = btif_open(p_btif);
+		if (i_ret) {
+			BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret);
+			*p_id = 0;
+/*free btif new user's structure*/
+			vfree(p_new_user);
+			p_new_user = NULL;
+		} else {
+			BTIF_INFO_FUNC("btif_open succeed\n");
+			*p_id = p_new_user->u_id;
+/*mark enable flag to true*/
+			p_new_user->enable = true;
+/*add to uer lsit*/
+			list_add_tail(&(p_new_user->entry), p_user_list);
+		}
+	} else {
+		*p_id = 0;
+		i_ret = -ENOMEM;
+		BTIF_ERR_FUNC("allocate memory for mtk_btif_user failed\n");
+	}
+	BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx));
+	BTIF_DBG_FUNC("--");
+	return i_ret;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_open);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_close
+* DESCRIPTION
+*  close BTIF interface, will do BTIF module HW and SW de-initialization
+*  once this API is called, p_btif should never be used by BTIF's user again
+* PARAMETERS
+*  u_id        [IN] BTIF's user id
+* RETURNS
+*  int     0 = succeed;
+*          others = fail,
+*          for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_close(unsigned long u_id)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = NULL;
+	struct list_head *pos = NULL;
+	struct list_head *p_user_list = NULL;
+
+	BTIF_DBG_FUNC("++");
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+
+	if (mutex_lock_killable(&(p_btif->ops_mtx))) {
+		BTIF_ERR_FUNC("mutex_lock_killable return failed\n");
+		return E_BTIF_INTR;
+	}
+	p_user_list = &(p_btif->user_list);
+	list_for_each(pos, p_user_list) {
+		p_mtk_btif_user p_user =
+		    container_of(pos, mtk_btif_user, entry);
+
+		if (p_user->u_id == u_id) {
+			BTIF_INFO_FUNC
+			    ("user who's id is 0x%lx deleted from user list\n",
+			     u_id);
+			list_del(pos);
+			vfree(p_user);
+			i_ret = btif_close(p_btif);
+			if (i_ret)
+				BTIF_WARN_FUNC("BTIF close failed");
+			break;
+		}
+	}
+	BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx));
+	BTIF_DBG_FUNC("--");
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_close);
+
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_write
+* DESCRIPTION
+*  send data throuth BTIF module
+*  there's no internal buffer to cache STP data in BTIF driver,
+*  if in DMA mode
+*  btif driver will check if there's enough space in vFIFO for data to send in DMA mode
+*    if yes, put data to vFIFO and return corresponding data length to caller
+*    if no, corresponding error code will be returned to called
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  p_buf       [IN] pointer to target data to send
+*  len         [IN] data length (should be less than 2014 bytes per STP package)
+*
+*  if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller
+*  if btif driver detected that no space is available in Tx FIFO,
+*  will return E_BTIF_NO_SPACE, mostly something is wrong with BTIF or
+*  consys when this return value is returned
+* RETURNS
+*  int  positive: data length send through BTIF;
+*       negative: please see ENUM_BTIF_OP_ERROR_CODE
+*       E_BTIF_AGAIN (0) will be returned to caller
+*       if btif does not have enough vFIFO to send data,
+*       when caller get 0, he should wait for a moment
+*       (5~10ms maybe) and try a few times (maybe 10~20)
+*        if still get E_BTIF_AGAIN,
+*        should call BTIF's debug API and dump BTIF driver
+*        and BTIF/DMA register information to kernel log for debug
+*        E_BTIF_BAD_POINTER will be returned to caller
+*        if btif is not opened successfully before call this API
+*        E_BTIF_INVAL_PARAM will be returned if parameter is not valid
+
+*****************************************************************************/
+int mtk_wcn_btif_write(unsigned long u_id,
+		       const unsigned char *p_buf, unsigned int len)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = NULL;
+
+	BTIF_DBG_FUNC("++");
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+	if (p_buf == NULL) {
+		BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf);
+		return E_BTIF_INVAL_PARAM;
+	}
+	if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) {
+		BTIF_ERR_FUNC("invalid buffer length(%d)\n", len);
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	i_ret = btif_send_data(p_btif, p_buf, len);
+	BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret);
+	return i_ret;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_write);
+
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_read
+* DESCRIPTION
+*  read data from BTIF module
+* PARAMETERS
+*  p_btif     [IN] pointer returned by mtk_wcn_btif_open
+*  p_buf      [IN/OUT] pointer to buffer where rx data will be put
+*  max_len    [IN] max buffer length
+* RETURNS
+*  int   positive: data length read from BTIF;
+*        negative: please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_read(unsigned long u_id,
+		      unsigned char *p_buf, unsigned int max_len)
+{
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_dpidle_ctrl
+* DESCRIPTION
+*  control if BTIF module allow system enter deepidle state or not
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  en_flag    [IN] one of ENUM_BTIF_DPIDLE_CTRL
+* RETURNS
+*  int          always return 0
+*****************************************************************************/
+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = NULL;
+
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+
+	if (en_flag == BTIF_DPIDLE_DISABLE)
+		i_ret = btif_exit_dpidle(p_btif);
+	else
+		i_ret = btif_enter_dpidle(p_btif);
+
+	return i_ret;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_dpidle_ctrl);
+
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_rx_cb_register
+* DESCRIPTION
+*  register rx callback function to BTIF module by btif user
+* PARAMETERS
+*  p_btif  [IN] pointer returned by mtk_wcn_btif_open
+*  rx_cb  [IN] pointer to stp rx handler callback function,
+*            should be comply with MTK_WCN_BTIF_RX_CB
+* RETURNS
+*  int      0 = succeed;
+*           others = fail, for detailed information,
+*           please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = NULL;
+
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+
+	i_ret = btif_rx_cb_reg(p_btif, rx_cb);
+
+	return i_ret;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_rx_cb_register);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_wakeup_consys
+* DESCRIPTION
+*  once sleep command is sent to con sys,
+*  should call this API before send wakeup command
+*  to make con sys aware host want to send data to consys
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+* RETURNS
+*  int          0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_wakeup_consys(unsigned long u_id)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = NULL;
+
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+
+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/
+	i_ret = btif_raise_wak_signal(p_btif);
+
+	return i_ret;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_wakeup_consys);
+
+
+/***************End of Normal Mode API declearation**********/
+
+/***************Debug Purpose API declearation**********/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_loopback_ctrl
+* DESCRIPTION
+*  enable/disable BTIF internal loopback function,
+*  when this function is enabled data send to btif
+*  will be received by btif itself
+*  only for debug purpose, should never use this function in normal mode
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  enable     [IN] loopback mode control flag, enable or disable,
+*  shou be one of ENUM_BTIF_LPBK_MODE
+* RETURNS
+*  int          0 = succeed;
+*  others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = NULL;
+
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+	i_ret =
+	    btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false);
+
+	return i_ret;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_btif_logger_ctrl
+* DESCRIPTION
+*  control BTIF logger function's behavior
+* PARAMETERS
+*  p_btif      [IN] pointer returned by mtk_wcn_btif_open
+*  flag         [IN] should be one of ENUM_BTIF_DBG_ID
+*                      BTIF_DISABLE_LOGGER  - disable btif logger
+*                      BTIF_ENABLE_LOGGER   - enable btif logger
+*                      BTIF_DUMP_LOG           - dump log logged by btif
+*                      BTIF_CLR_LOG             - clear btif log buffer
+*                      BTIF_DUMP_BTIF_REG   - dump btif controller's register
+*                      BTIF_DUMP_DMA_REG   - dump DMA controller's register
+* RETURNS
+*  int          0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE
+*****************************************************************************/
+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = NULL;
+
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+
+	i_ret = 0;
+	switch (flag) {
+	case BTIF_DISABLE_LOGGER:{
+			BTIF_INFO_FUNC
+			    ("disable btif log function for both Tx and Rx\n");
+			btif_log_buf_disable(&p_btif->tx_log);
+			btif_log_buf_disable(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_ENABLE_LOGGER:{
+			BTIF_INFO_FUNC
+			    ("enable btif log function for both Tx and Rx\n");
+			btif_log_buf_enable(&p_btif->tx_log);
+			btif_log_buf_enable(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_DUMP_LOG:{
+			BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n");
+			btif_log_buf_dmp_out(&p_btif->tx_log);
+			btif_log_buf_dmp_out(&p_btif->rx_log);
+		}
+		break;
+
+	case BTIF_CLR_LOG:{
+			BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n");
+			btif_log_buf_reset(&p_btif->tx_log);
+			btif_log_buf_reset(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_DUMP_BTIF_REG:
+		 /*TBD*/ btif_dump_reg(p_btif);
+		break;
+	case BTIF_ENABLE_RT_LOG:
+		BTIF_INFO_FUNC
+		    ("enable btif real time log for both Tx and Rx\n");
+		btif_log_output_enable(&p_btif->tx_log);
+		btif_log_output_enable(&p_btif->rx_log);
+		break;
+	case BTIF_DISABLE_RT_LOG:
+		BTIF_INFO_FUNC
+		    ("disable btif real time log for both Tx and Rx\n");
+		btif_log_output_disable(&p_btif->tx_log);
+		btif_log_output_disable(&p_btif->rx_log);
+		break;
+	default:
+		BTIF_INFO_FUNC("not supported flag:%d\n", flag);
+		i_ret = -2;
+		break;
+	}
+
+	return i_ret;
+}
+EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl);
+
+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id,
+	const char *sub_str, unsigned int str_len)
+{
+	bool b_ret = false;
+	p_mtk_btif p_btif = NULL;
+
+	p_btif = btif_exp_srh_id(u_id);
+
+	if (p_btif == NULL)
+		return E_BTIF_INVAL_PARAM;
+	b_ret = btif_parser_wmt_evt(p_btif, sub_str, str_len);
+	BTIF_INFO_FUNC("parser wmt evt %s\n", b_ret ? "ok" : "fail");
+
+	return b_ret;
+}
+
+/**********End of Debug Purpose API declearation**********/
+
+int btif_open_no_id(void)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret = btif_open(p_btif);
+
+	if (i_ret)
+		BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret);
+	else
+		BTIF_INFO_FUNC("btif_open succeed\n");
+
+	return i_ret;
+}
+
+int btif_close_no_id(void)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret = btif_close(p_btif);
+
+	if (i_ret)
+		BTIF_ERR_FUNC("btif_close failed, i_ret(%d)\n", i_ret);
+	else
+		BTIF_INFO_FUNC("btif_close succeed\n");
+	return i_ret;
+}
+
+int btif_write_no_id(const unsigned char *p_buf, unsigned int len)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	BTIF_DBG_FUNC("++");
+
+	if (p_buf == NULL) {
+		BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf);
+		return E_BTIF_INVAL_PARAM;
+	}
+	if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) {
+		BTIF_ERR_FUNC("invalid buffer length(%d)\n", len);
+		return E_BTIF_INVAL_PARAM;
+	}
+
+	i_ret = btif_send_data(p_btif, p_buf, len);
+	BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret);
+	return i_ret;
+}
+
+int btif_dpidle_ctrl_no_id(ENUM_BTIF_DPIDLE_CTRL en_flag)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	if (en_flag == BTIF_DPIDLE_DISABLE)
+		i_ret = btif_exit_dpidle(p_btif);
+	else
+		i_ret = btif_enter_dpidle(p_btif);
+
+	return i_ret;
+}
+
+int btif_wakeup_consys_no_id(void)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = &g_btif[0];
+
+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/
+	i_ret = btif_raise_wak_signal(p_btif);
+
+	return i_ret;
+}
+
+int btif_loopback_ctrl_no_id(ENUM_BTIF_LPBK_MODE enable)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret =
+	    btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false);
+
+	return i_ret;
+}
+
+int btif_dbg_ctrl_no_id(ENUM_BTIF_DBG_ID flag)
+{
+	int i_ret = -1;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret = 0;
+	switch (flag) {
+	case BTIF_DISABLE_LOGGER:{
+			BTIF_INFO_FUNC
+			    ("disable btif log function for both Tx and Rx\n");
+			btif_log_buf_disable(&p_btif->tx_log);
+			btif_log_buf_disable(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_ENABLE_LOGGER:{
+			BTIF_INFO_FUNC
+			    ("enable btif log function for both Tx and Rx\n");
+			btif_log_buf_enable(&p_btif->tx_log);
+			btif_log_buf_enable(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_DUMP_LOG:{
+			BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n");
+			btif_log_buf_dmp_out(&p_btif->tx_log);
+			btif_log_buf_dmp_out(&p_btif->rx_log);
+		}
+		break;
+
+	case BTIF_CLR_LOG:{
+			BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n");
+			btif_log_buf_reset(&p_btif->tx_log);
+			btif_log_buf_reset(&p_btif->rx_log);
+		}
+		break;
+	case BTIF_DUMP_BTIF_REG:
+		 /*TBD*/ btif_dump_reg(p_btif);
+		break;
+	case BTIF_ENABLE_RT_LOG:
+		BTIF_INFO_FUNC
+		    ("enable btif real time log for both Tx and Rx\n");
+		btif_log_output_enable(&p_btif->tx_log);
+		btif_log_output_enable(&p_btif->rx_log);
+		break;
+	case BTIF_DISABLE_RT_LOG:
+		BTIF_INFO_FUNC
+		    ("disable btif real time log for both Tx and Rx\n");
+		btif_log_output_disable(&p_btif->tx_log);
+		btif_log_output_disable(&p_btif->rx_log);
+		break;
+	default:
+		BTIF_INFO_FUNC("not supported flag:%d\n", flag);
+		i_ret = -2;
+		break;
+	}
+
+	return i_ret;
+}
+
+int mtk_btif_exp_open_test(void)
+{
+	int i_ret = 0;
+
+	i_ret = btif_open_no_id();
+	if (i_ret < 0) {
+		BTIF_INFO_FUNC("mtk_wcn_btif_open failed\n");
+		return -1;
+	}
+
+	BTIF_INFO_FUNC("mtk_wcn_btif_open succeed\n");
+
+	return i_ret;
+}
+
+int mtk_btif_exp_close_test(void)
+{
+	int i_ret = 0;
+
+	i_ret = btif_close_no_id();
+	if (i_ret < 0) {
+		BTIF_INFO_FUNC("mtk_wcn_btif_close failed\n");
+		return -1;
+	}
+
+	BTIF_INFO_FUNC("mtk_wcn_btif_close succeed\n");
+
+	return i_ret;
+}
+
+int mtk_btif_exp_write_test(void)
+{
+	return mtk_btif_exp_write_stress_test(100, 10);
+}
+
+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int max_loop)
+{
+#define BUF_LEN 1024
+	int i_ret = 0;
+	int idx = 0;
+	int buf_len = length > BUF_LEN ? BUF_LEN : length;
+	int loop = max_loop > 1000000 ? 1000000 : max_loop;
+	unsigned char *buffer;
+
+	buffer = kmalloc(BUF_LEN, GFP_KERNEL);
+	if (!buffer) {
+		BTIF_ERR_FUNC("btif tester kmalloc failed\n");
+		return -1;
+	}
+
+	for (idx = 0; idx < buf_len; idx++)
+		/* btif_stress_test_buf[idx] = BUF_LEN -idx; */
+		*(buffer + idx) = idx % 255;
+	i_ret = btif_loopback_ctrl_no_id(BTIF_LPBK_ENABLE);
+	BTIF_INFO_FUNC("mtk_wcn_btif_loopback_ctrl returned %d\n", i_ret);
+	while (loop--) {
+		i_ret = btif_write_no_id(buffer, buf_len);
+		BTIF_INFO_FUNC("mtk_wcn_btif_write left loop:%d, i_ret:%d\n",
+				   loop, i_ret);
+		if (i_ret != buf_len) {
+			BTIF_INFO_FUNC
+				("mtk_wcn_btif_write failed, target len %d, sent len: %d\n",
+				 buf_len, i_ret);
+			break;
+		}
+		buf_len--;
+		if (buf_len <= 0)
+			buf_len = length > BUF_LEN ? BUF_LEN : length;
+	}
+	kfree(buffer);
+	return i_ret;
+}
+
+int mtk_btif_exp_suspend_test(void)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret = _btif_suspend(p_btif);
+	return i_ret;
+}
+
+int mtk_btif_exp_restore_noirq_test(void)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret = _btif_restore_noirq(p_btif);
+	return i_ret;
+}
+
+int mtk_btif_exp_clock_ctrl(int en)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret = btif_clock_ctrl(p_btif, en);
+	return i_ret;
+}
+
+int mtk_btif_exp_resume_test(void)
+{
+	int i_ret = 0;
+	p_mtk_btif p_btif = &g_btif[0];
+
+	i_ret = _btif_resume(p_btif);
+	return i_ret;
+}
+
+int mtk_btif_exp_enter_dpidle_test(void)
+{
+	return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_ENABLE);
+}
+
+int mtk_btif_exp_exit_dpidle_test(void)
+{
+	return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_DISABLE);
+}
+
+int mtk_btif_exp_log_debug_test(int flag)
+{
+	int i_ret = 0;
+
+	i_ret = btif_dbg_ctrl_no_id(flag);
+	return i_ret;
+}
+
+void mtk_btif_read_cpu_sw_rst_debug_exp(void)
+{
+	mtk_btif_read_cpu_sw_rst_debug();
+}
+
+/************End of Function**********/
diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h
new file mode 100644
index 0000000000000..97756f684ab40
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __HAL_BTIF_DMA_H_
+#define __HAL_BTIF_DMA_H_
+
+#include <linux/io.h>
+#include "btif_dma_pub.h"
+
+#if defined(CONFIG_MTK_CLKMGR)
+#if defined(CONFIG_ARCH_MT6580)
+#define MTK_BTIF_APDMA_CLK_CG MT_CG_APDMA_SW_CG
+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753)
+#define MTK_BTIF_APDMA_CLK_CG MT_CG_PERI_APDMA
+#endif
+#else
+extern struct clk *clk_btif_apdma; /*btif apdma clock*/
+#endif /* !defined(CONFIG_MTK_CLKMGR) */
+
+#define TX_DMA_VFF_SIZE (1024 * 8)	/*Tx vFIFO Len must be 8 Byte allignment */
+#define RX_DMA_VFF_SIZE (1024 * 8)	/*Rx vFIFO Len must be 8 Byte allignment */
+
+#define DMA_TX_THRE(n) (n - 7)	/*Tx Trigger Level */
+#define DMA_RX_THRE(n) ((n) * 3 / 4)	/*Rx Trigger Level */
+
+/**********************************Hardware related defination**************************/
+#ifndef CONFIG_OF
+/*DMA channel's offset refer to AP_DMA's base address*/
+#define BTIF_TX_DMA_OFFSET 0x880
+#define BTIF_RX_DMA_OFFSET 0x900
+#endif
+
+/*Register Address Mapping*/
+#define DMA_INT_FLAG_OFFSET  0x00
+#define DMA_INT_EN_OFFSET  0x04
+#define DMA_EN_OFFSET  0x08
+#define DMA_RST_OFFSET  0x0C
+#define DMA_STOP_OFFSET  0x10
+#define DMA_FLUSH_OFFSET  0x14
+
+#define DMA_BASE_OFFSET  0x1C
+#define DMA_LEN_OFFSET  0x24
+
+#define DMA_THRE_OFFSET  0x28
+#define DMA_WPT_OFFSET  0x2C
+#define DMA_RPT_OFFSET  0x30
+#define DMA_VALID_OFFSET  0x3C
+#define DMA_LEFT_OFFSET  0x40
+#define DMA_VFF_BIT29_OFFSET  0x01
+
+#define TX_DMA_INT_FLAG(base)       (unsigned long)(base + 0x0)	/*BTIF Tx Virtual FIFO Interrupt Flag Register */
+#define TX_DMA_INT_EN(base)         (unsigned long)(base + 0x4)	/*BTIF Tx Virtual FIFO Interrupt Enable Register */
+#define TX_DMA_EN(base)             (unsigned long)(base + DMA_EN_OFFSET)/*BTIF Tx Virtual FIFO Enable Register */
+#define TX_DMA_RST(base)            (unsigned long)(base + DMA_RST_OFFSET)/*BTIF Tx Virtual FIFO  Reset Register */
+#define TX_DMA_STOP(base)           (unsigned long)(base + DMA_STOP_OFFSET)/*BTIF Tx Virtual FIFO STOP  Register */
+#define TX_DMA_FLUSH(base)          (unsigned long)(base + DMA_FLUSH_OFFSET)/*BTIF Tx Virtual FIFO Flush Register */
+#define TX_DMA_VFF_ADDR(base)       (unsigned long)(base + 0x1C) /*BTIF Tx Virtual FIFO Base Address Register */
+#define TX_DMA_VFF_LEN(base)        (unsigned long)(base + 0x24) /*BTIF Tx Virtual FIFO Length Register */
+#define TX_DMA_VFF_THRE(base)       (unsigned long)(base + 0x28) /*BTIF Tx Virtual FIFO Threshold Register */
+#define TX_DMA_VFF_WPT(base)        (unsigned long)(base + 0x2C) /*BTIF Tx Virtual FIFO Write Pointer Register */
+#define TX_DMA_VFF_RPT(base)        (unsigned long)(base + 0x30) /*BTIF Tx Virtual FIFO Read Pointer  Register */
+#define TX_DMA_W_INT_BUF_SIZE(base) (unsigned long)(base + 0x34)
+/*BTIF Tx Virtual FIFO Internal Tx Write Buffer Size Register */
+#define TX_DMA_INT_BUF_SIZE(base)   (unsigned long)(base + 0x38)
+/*BTIF Tx Virtual FIFO Internal Tx Buffer Size Register */
+
+#define TX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Tx Virtual FIFO Valid Size Register */
+#define TX_DMA_VFF_LEFT_SIZE(base)  (unsigned long)(base + 0x40) /*BTIF Tx Virtual FIFO Left Size Register */
+#define TX_DMA_DEBUG_STATUS(base)   (unsigned long)(base + 0x50) /*BTIF Tx Virtual FIFO Debug Status Register */
+#define TX_DMA_VFF_ADDR_H(base)     (unsigned long)(base + 0x54) /*BTIF Tx Virtual FIFO Base High Address Register */
+
+/*Rx Register Address Mapping*/
+#define RX_DMA_INT_FLAG(base)       (unsigned long)(base + 0x0)	/*BTIF Rx Virtual FIFO Interrupt Flag Register */
+#define RX_DMA_INT_EN(base)         (unsigned long)(base + 0x4)	/*BTIF Rx Virtual FIFO Interrupt Enable Register */
+#define RX_DMA_EN(base)             (unsigned long)(base + DMA_EN_OFFSET) /*BTIF Rx Virtual FIFO Enable Register */
+#define RX_DMA_RST(base)            (unsigned long)(base + DMA_RST_OFFSET) /*BTIF Rx Virtual FIFO Reset Register */
+#define RX_DMA_STOP(base)           (unsigned long)(base + DMA_STOP_OFFSET) /*BTIF Rx Virtual FIFO Stop Register */
+#define RX_DMA_FLUSH(base)          (unsigned long)(base + DMA_FLUSH_OFFSET) /*BTIF Rx Virtual FIFO Flush Register */
+#define RX_DMA_VFF_ADDR(base)       (unsigned long)(base + 0x1C) /*BTIF Rx Virtual FIFO Base Address Register */
+#define RX_DMA_VFF_LEN(base)        (unsigned long)(base + 0x24) /*BTIF Rx Virtual FIFO Length Register */
+#define RX_DMA_VFF_THRE(base)       (unsigned long)(base + 0x28) /*BTIF Rx Virtual FIFO Threshold Register */
+#define RX_DMA_VFF_WPT(base)        (unsigned long)(base + 0x2C) /*BTIF Rx Virtual FIFO Write Pointer Register */
+#define RX_DMA_VFF_RPT(base)        (unsigned long)(base + 0x30) /*BTIF Rx Virtual FIFO Read Pointer Register */
+#define RX_DMA_FLOW_CTRL_THRE(base) (unsigned long)(base + 0x34) /*BTIF Rx Virtual FIFO Flow Control  Register */
+#define RX_DMA_INT_BUF_SIZE(base)   (unsigned long)(base + 0x38) /*BTIF Rx Virtual FIFO Internal Buffer Register */
+#define RX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Rx Virtual FIFO Valid Size Register */
+#define RX_DMA_VFF_LEFT_SIZE(base)  (unsigned long)(base + 0x40) /*BTIF Rx Virtual FIFO Left Size  Register */
+#define RX_DMA_DEBUG_STATUS(base)   (unsigned long)(base + 0x50) /*BTIF Rx Virtual FIFO Debug Status Register */
+#define RX_DMA_VFF_ADDR_H(base)     (unsigned long)(base + 0x54) /*BTIF Rx Virtual FIFO Base High Address Register */
+
+#define DMA_EN_BIT (0x1)
+#define DMA_STOP_BIT (0x1)
+#define DMA_RST_BIT (0x1)
+#define DMA_FLUSH_BIT (0x1)
+
+#define DMA_WARM_RST (0x1 << 0)
+#define DMA_HARD_RST (0x1 << 1)
+
+#define DMA_WPT_MASK (0x0000FFFF)
+#define DMA_WPT_WRAP (0x00010000)
+
+#define DMA_RPT_MASK (0x0000FFFF)
+#define DMA_RPT_WRAP (0x00010000)
+
+/*APDMA BTIF Tx Reg Ctrl Bit*/
+#define TX_DMA_INT_FLAG_MASK (0x1)
+
+#define TX_DMA_INTEN_BIT (0x1)
+
+#define TX_DMA_ADDR_MASK (0xFFFFFFF8)
+#define TX_DMA_LEN_MASK (0x0000FFF8)
+
+#define TX_DMA_THRE_MASK (0x0000FFFF)
+
+#define TX_DMA_W_INT_BUF_MASK (0x000000FF)
+
+#define TX_DMA_VFF_VALID_MASK (0x0000FFFF)
+#define TX_DMA_VFF_LEFT_MASK (0x0000FFFF)
+
+/*APDMA BTIF Rx Reg Ctrl Bit*/
+#define RX_DMA_INT_THRE (0x1 << 0)
+#define RX_DMA_INT_DONE (0x1 << 1)
+
+#define RX_DMA_INT_THRE_EN (0x1 << 0)
+#define RX_DMA_INT_DONE_EN (0x1 << 1)
+
+#define RX_DMA_ADDR_MASK (0xFFFFFFF8)
+#define RX_DMA_LEN_MASK (0x0000FFF8)
+
+#define RX_DMA_THRE_MASK (0x0000FFFF)
+
+#define RX_DMA_FLOW_CTRL_THRE_MASK (0x000000FF)
+
+#define RX_DMA_INT_BUF_SIZE_MASK (0x0000001F)
+
+#define RX_DMA_VFF_VALID_MASK (0x0000001F)
+
+#define RX_DMA_VFF_LEFT_MASK (0x0000FFFF)
+
+typedef struct _MTK_BTIF_DMA_VFIFO_ {
+	DMA_VFIFO vfifo;
+	unsigned int wpt;	/*DMA's write pointer, which is maintained by SW for Tx DMA and HW for Rx DMA */
+	unsigned int last_wpt_wrap;	/*last wrap bit for wpt */
+	unsigned int rpt;	/*DMA's read pointer, which is maintained by HW for Tx DMA and SW for Rx DMA */
+	unsigned int last_rpt_wrap;	/*last wrap bit for rpt */
+} MTK_BTIF_DMA_VFIFO, *P_MTK_BTIF_DMA_VFIFO;
+
+/*for DMA debug purpose*/
+typedef struct _MTK_BTIF_DMA_REG_DMP_DBG_ {
+	unsigned long reg_addr;
+	unsigned int reg_val;
+} MTK_BTIF_DMA_REG_DMP_DBG, *P_MTK_BTIF_DMA_REG_DMP_DBG;
+
+#endif /*__HAL_BTIF_DMA_H_*/
diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h
new file mode 100644
index 0000000000000..0773f2ce387ac
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __HAL_BTIFD_DMA_PUB_H_
+#define __HAL_BTIFD_DMA_PUB_H_
+
+#include <linux/dma-mapping.h>
+
+#include "plat_common.h"
+
+typedef enum _ENUM_DMA_CTRL_ {
+	DMA_CTRL_DISABLE = 0,
+	DMA_CTRL_ENABLE = DMA_CTRL_DISABLE + 1,
+	DMA_CTRL_BOTH,
+} ENUM_DMA_CTRL;
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_info_get
+* DESCRIPTION
+*  get btif tx dma channel's information
+* PARAMETERS
+* dma_dir        [IN]         DMA's direction
+* RETURNS
+*  pointer to btif dma's information structure
+*****************************************************************************/
+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_dma_hw_init
+* DESCRIPTION
+*  control clock output enable/disable of DMA module
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_ctrl
+* DESCRIPTION
+*  control clock output enable/disable of DMA module
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_ctrl
+* DESCRIPTION
+* enable/disable Tx DMA channel
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* ctrl_id          [IN]        enable/disable ID
+* dma_dir        [IN]         DMA's direction
+* RETURNS
+*  0 means success; negative means fail
+*****************************************************************************/
+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_dma_rx_cb_reg
+* DESCRIPTION
+* register rx callback function to dma module
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* rx_cb           [IN]        function pointer to btif
+* RETURNS
+*  0 means success; negative means fail
+*****************************************************************************/
+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info,
+			   dma_rx_buf_write rx_cb);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_vfifo_reset
+* DESCRIPTION
+*  reset tx virtual fifo information, except memory information
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* dma_dir  [IN]         DMA's direction
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_tx_dma_irq_handler
+* DESCRIPTION
+*  lower level tx interrupt handler
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_send_data
+* DESCRIPTION
+*  send data through btif in DMA mode
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* p_buf     [IN]        pointer to rx data buffer
+* max_len  [IN]        tx buffer length
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info,
+		      const unsigned char *p_buf, const unsigned int buf_len);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_is_tx_complete
+* DESCRIPTION
+*  get tx complete flag
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  true means tx complete, false means tx in process
+*****************************************************************************/
+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_get_ava_room
+* DESCRIPTION
+*  get tx available room
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  available room  size
+*****************************************************************************/
+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_is_tx_allow
+* DESCRIPTION
+*  is tx operation allowed by DMA
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* RETURNS
+*  true if tx operation is allowed; false if tx is not allowed
+*****************************************************************************/
+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_rx_dma_irq_handler
+* DESCRIPTION
+*  lower level rx interrupt handler
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info,
+			   unsigned char *p_buf, const unsigned int max_len);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_dma_dump_reg
+* DESCRIPTION
+*  dump BTIF module's information when needed
+* PARAMETERS
+* p_dma_info   [IN]        pointer to BTIF dma channel's information
+* flag             [IN]        register id flag
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag);
+
+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid);
+
+#endif /*__HAL_BTIFD_DMA_PUB_H_*/
diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h
new file mode 100644
index 0000000000000..51fe58a82b49c
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __HAL_BTIF_H_
+#define __HAL_BTIF_H_
+
+#ifndef CONFIG_OF
+#define MTK_BTIF_REG_BASE BTIF_BASE
+#endif
+
+#if defined(CONFIG_MTK_CLKMGR)
+#if defined(CONFIG_ARCH_MT6580)
+#define MTK_BTIF_CG_BIT MT_CG_BTIF_SW_CG
+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753)
+#define MTK_BTIF_CG_BIT MT_CG_PERI_BTIF
+#endif
+#else
+struct clk *clk_btif_apdma; /*btif apdma clock*/
+struct clk *clk_btif; /*btif  clock*/
+#endif /* !defined(CONFIG_MTK_CLKMGR) */
+
+#define BTIF_RBR(base)         (unsigned long)(base + 0x0)	/*RX Buffer Register: read only */
+#define BTIF_THR(base)         (unsigned long)(base + 0x0) /*Rx Holding Register: write only */
+#define BTIF_IER(base)         (unsigned long)(base + 0x4) /*Interrupt Enable Register: read/write */
+#define BTIF_IIR(base)         (unsigned long)(base + 0x8)	/*Interrupt Identification Register: read only */
+#define BTIF_FIFOCTRL(base)    (unsigned long)(base + 0x8)	/*FIFO Control Register: write only */
+#define BTIF_FAKELCR(base)     (unsigned long)(base + 0xC)	/*FAKE LCR Register: read/write */
+#define BTIF_LSR(base)         (unsigned long)(base + 0x14)	/*Line Status Register: read only */
+#define BTIF_SLEEP_EN(base)    (unsigned long)(base + 0x48)	/*Sleep Enable Register: read/write */
+#define BTIF_DMA_EN(base)      (unsigned long)(base + 0x4C)	/*DMA Enable Register: read/write */
+#define BTIF_RTOCNT(base)      (unsigned long)(base + 0x54)	/*Rx Timeout Count Register: read/write */
+#define BTIF_TRI_LVL(base)     (unsigned long)(base + 0x60)	/*Tx/Rx Trigger Level Control Register: read/write */
+#define BTIF_WAK(base)         (unsigned long)(base + 0x64)	/*BTIF module wakeup Register: write only */
+#define BTIF_WAT_TIME(base)    (unsigned long)(base + 0x68)	/*BTIF ASYNC Wait Time Control Register: read/write */
+#define BTIF_HANDSHAKE(base)   (unsigned long)(base + 0x6C)	/*BTIF New Handshake Control Register: read/write */
+
+/*BTIF_IER bits*/
+#define BTIF_IER_TXEEN (0x1 << 1)	/*1: Tx holding register is empty */
+#define BTIF_IER_RXFEN (0x1 << 0)	/*1: Rx buffer contains data */
+
+/*BTIF_IIR bits*/
+#define BTIF_IIR_NINT        (0x1 << 0)	/*No INT Pending */
+#define BTIF_IIR_TX_EMPTY    (0x1 << 1)	/*Tx Holding Register empty */
+#define BTIF_IIR_RX          (0x1 << 2)	/*Rx data received */
+#define BTIF_IIR_RX_TIMEOUT  (0x11 << 2)	/*Rx data received */
+
+/*BTIF_LSR bits*/
+#define BTIF_LSR_DR_BIT (0x1 << 0)
+#define BTIF_LSR_THRE_BIT (0x1 << 5)
+#define BTIF_LSR_TEMT_BIT (0x1 << 6)
+
+/*BTIF_FIFOCTRL bits*/
+#define BTIF_FIFOCTRL_CLR_TX (0x1 << 2)	/*Clear Tx FIRO */
+#define BTIF_FIFOCTRL_CLR_RX (0x1 << 1)	/*Clear Rx FIRO */
+
+/*BTIF_FAKELCR bits*/
+#define BTIF_FAKELCR_NORMAL_MODE 0x0
+
+/*BTIF_SLEEP_EN bits*/
+#define BTIF_SLEEP_EN_BIT (0x1 << 0)	/*enable Sleep mode */
+#define BTIF_SLEEP_DIS_BIT (0x0)	/*disable sleep mode */
+
+/*BTIF_DMA_EN bits*/
+#define BTIF_DMA_EN_RX  (0x1 << 0)	/*Enable Rx DMA */
+#define BTIF_DMA_EN_TX  (0x1 << 1)	/*Enable Tx DMA */
+#define BTIF_DMA_EN_AUTORST_EN  (0x1 << 2)	/*1: timeout counter will be auto reset */
+#define BTIF_DMA_EN_AUTORST_DIS  (0x0 << 2)	/*
+						 * 0: after Rx timeout happens,
+						 * SW shall reset the interrupt by reading BTIF 0x4C
+						 */
+
+/*BTIF_TRI_LVL bits*/
+#define BTIF_TRI_LVL_TX_MASK ((0xf) << 0)
+#define BTIF_TRI_LVL_RX_MASK ((0x7) << 4)
+
+#define BTIF_TRI_LVL_TX(x) ((x & 0xf) << 0)
+#define BTIF_TRI_LVL_RX(x) ((x & 0x7) << 4)
+
+#define BTIF_TRI_LOOP_EN (0x1 << 7)
+#define BTIF_TRI_LOOP_DIS (0x0 << 7)
+
+/*BTIF_WAK bits*/
+#define BTIF_WAK_BIT (0x1 << 0)
+
+/*BTIF_HANDSHAKE bits*/
+#define BTIF_HANDSHAKE_EN_HANDSHAKE 1
+#define BTIF_HANDSHAKE_DIS_HANDSHAKE 0
+
+#define BTIF_TX_FIFO_SIZE 16
+#define BTIF_RX_FIFO_SIZE 8
+
+#define BTIF_TX_FIFO_THRE (BTIF_TX_FIFO_SIZE / 2)
+#define BTIF_RX_FIFO_THRE 0x1	/* 0x5 */
+
+#endif /*__HAL_BTIF_H_*/
diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h
new file mode 100644
index 0000000000000..1555d5a50c384
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __HAL_BTIF_PUB_H_
+#define __HAL_BTIF_PUB_H_
+
+#include "plat_common.h"
+
+/*Enum Defination*/
+/*BTIF Mode Enum */
+typedef enum _ENUM_BTIF_MODE_ {
+	BTIF_MODE_PIO = 0,
+	BTIF_MODE_DMA = BTIF_MODE_PIO + 1,
+	BTIF_MODE_MAX,
+} ENUM_BTIF_MODE;
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_info_get
+* DESCRIPTION
+*  get btif's information included base address , irq related information
+* PARAMETERS
+* RETURNS
+*  BTIF's information
+*****************************************************************************/
+P_MTK_BTIF_INFO_STR hal_btif_info_get(void);
+
+#if 0				/*included in hal_btif_info_get */
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_get_irq
+* DESCRIPTION
+*  get BTIF module's IRQ information
+* PARAMETERS
+* RETURNS
+*  pointer to BTIF's irq structure
+*****************************************************************************/
+P_MTK_BTIF_IRQ_STR hal_btif_get_irq(void);
+#endif
+
+#if !defined(CONFIG_MTK_CLKMGR)
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_get_and_prepare
+* DESCRIPTION
+*  get clock from device tree and prepare for enable/disable control
+* PARAMETERS
+* pdev  device pointer
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_clk_get_and_prepare(struct platform_device *pdev);
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_unprepare
+* DESCRIPTION
+*  unprepare btif clock and apdma clock
+* PARAMETERS
+* none
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_clk_unprepare(void);
+#endif
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_clk_ctrl
+* DESCRIPTION
+*  control clock output enable/disable of BTIF module
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_hw_init
+* DESCRIPTION
+*  BTIF module init, after this step, BTIF should enable to do tx/rx with PIO
+*  mode
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_rx_cb_reg
+* DESCRIPTION
+*  BTIF rx callback register API
+* PARAMETERS
+* p_btif_info   [IN]        pointer to BTIF's information
+* rx_cb          [IN]        rx callback function
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info,
+		       btif_rx_buf_write rx_cb);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_loopback_ctrl
+* DESCRIPTION
+*  BTIF Tx/Rx loopback mode set, this operation can only be done
+*  after set BTIF to normal mode
+* PARAMETERS
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_rx_handler
+* DESCRIPTION
+*  lower level interrupt handler
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* p_buf     [IN/OUT] pointer to rx data buffer
+* max_len  [IN]        max length of rx buffer
+* RETURNS
+*  0 means success; negative means fail; positive means rx data length
+*****************************************************************************/
+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif,
+			 unsigned char *p_buf, const unsigned int max_len);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_tx_mode_ctrl
+* DESCRIPTION
+*  set BTIF tx to corresponding mode (PIO/DMA)
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* mode     [IN]        rx mode <PIO/DMA>
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_rx_mode_ctrl
+* DESCRIPTION
+*  set BTIF rx to corresponding mode (PIO/DMA)
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* mode     [IN]        rx mode <PIO/DMA>
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_send_data
+* DESCRIPTION
+*  send data through btif in FIFO mode
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* p_buf     [IN]        pointer to rx data buffer
+* max_len  [IN]        tx buffer length
+* RETURNS
+*  positive means number of data sent;
+*  0 means no data put to FIFO;
+*  negative means error happens
+*****************************************************************************/
+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif,
+		       const unsigned char *p_buf, const unsigned int buf_len);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_raise_wak_sig
+* DESCRIPTION
+*  raise wakeup signal to counterpart
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_dump_reg
+* DESCRIPTION
+*  dump BTIF module's information when needed
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* flag        [IN]        register id flag
+* RETURNS
+*  0 means success, negative means fail
+*****************************************************************************/
+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_is_tx_complete
+* DESCRIPTION
+*  get tx complete flag
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+*  true means tx complete, false means tx in process
+*****************************************************************************/
+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif);
+
+/*****************************************************************************
+* FUNCTION
+*  hal_btif_is_tx_allow
+* DESCRIPTION
+*  whether tx is allowed
+* PARAMETERS
+* p_base   [IN]        BTIF module's base address
+* RETURNS
+* true if tx operation is allowed; false if tx is not allowed
+*****************************************************************************/
+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif);
+
+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif, MTK_BTIF_PM_OPID opid);
+
+void mtk_btif_read_cpu_sw_rst_debug_plat(void);
+
+#endif /*__HAL_BTIF_PUB_H_*/
diff --git a/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h
new file mode 100644
index 0000000000000..2a1462cb32ff4
--- /dev/null
+++ b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __HAL_PUB_H_
+#define __HAL_PUB_H_
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/sched/rt.h>
+#include <mtk_io.h>
+
+#ifdef CONFIG_OF
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#else
+#include <mach/mt_reg_base.h>
+#include <mach/mt_irq.h>
+#endif
+#if defined(CONFIG_MTK_CLKMGR)
+#include <mach/mt_clkmgr.h>
+#else
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+#include <sync_write.h>
+
+extern int mtk_btif_hal_get_log_lvl(void);
+
+#define MTK_BTIF_MARK_UNUSED_API
+
+typedef irq_handler_t mtk_btif_irq_handler;
+
+#define MTK_BTIF_ENABLE_CLK_CTL 1
+#define MTK_BTIF_ENABLE_CLK_REF_COUNTER 1
+
+#define DBG_LOG_STR_SIZE 256
+
+/*Log defination*/
+static int hal_log_print(const char *str, ...)
+{
+	va_list args;
+	char temp_sring[DBG_LOG_STR_SIZE];
+
+	va_start(args, str);
+	vsnprintf(temp_sring, DBG_LOG_STR_SIZE, str, args);
+	va_end(args);
+
+	pr_err("%s", temp_sring);
+
+	return 0;
+}
+
+#define BTIF_LOG_LOUD    4
+#define BTIF_LOG_DBG     3
+#define BTIF_LOG_INFO    2
+#define BTIF_LOG_WARN    1
+#define BTIF_LOG_ERR     0
+
+#ifndef DFT_TAG
+#define DFT_TAG         "[BTIF-DFT]"
+#endif
+
+#define BTIF_LOUD_FUNC(fmt, arg ...) \
+do { \
+	if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_LOUD) \
+		hal_log_print(DFT_TAG "[L]%s:"  fmt, \
+		__func__, ## arg); \
+} while (0)
+
+#define BTIF_INFO_FUNC(fmt, arg ...) \
+do { \
+	if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_INFO)\
+		hal_log_print(DFT_TAG "[I]%s:"  fmt, \
+		__func__, ## arg); \
+} while (0)
+
+#define BTIF_WARN_FUNC(fmt, arg ...) \
+do { \
+	if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_WARN)\
+		hal_log_print(DFT_TAG "[W]%s:"  fmt, \
+		__func__, ## arg); \
+} while (0)
+
+#define BTIF_ERR_FUNC(fmt, arg ...)\
+do {\
+	if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_ERR)\
+		hal_log_print(DFT_TAG "[E]%s(%d):"  fmt,\
+		__func__, __LINE__, ## arg);\
+} while (0)
+
+#define BTIF_DBG_FUNC(fmt, arg ...) \
+do { \
+	if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \
+		hal_log_print(DFT_TAG "[D]%s:"  fmt, \
+		__func__, ## arg); \
+} while (0)
+
+#define BTIF_TRC_FUNC(f) \
+do { \
+	if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \
+		hal_log_print(DFT_TAG "<%s> <%d>\n", \
+		__func__, __LINE__); \
+} while (0)
+
+/*-----------------------------------Enum Defination--------------------------------*/
+/*IRQ sensetive type */
+typedef enum _ENUM_IRQ_SENS_TYPE_ {
+	IRQ_SENS_EDGE = 0,
+	IRQ_SENS_LVL = IRQ_SENS_EDGE + 1,
+	IRQ_SENS_TYPE_MAX
+} ENUM_IRQ_SENS_TYPE;
+
+/*IRQ level trigger type */
+typedef enum _ENUM_IRQ_LVL_TYPE_ {
+	IRQ_LVL_LOW = 0,
+	IRQ_LVL_HIGH = IRQ_LVL_LOW + 1,
+	IRQ_LVL_MAX
+} ENUM_IRQ_LVL;
+
+/*IRQ edge trigger type */
+typedef enum _ENUM_IRQ_EDGE_TYPE_ {
+	IRQ_EDGE_FALL = 0,
+	IRQ_EDGE_RAISE = IRQ_EDGE_FALL + 1,
+	IRQ_EDGE_BOTH = IRQ_EDGE_RAISE + 1,
+	IRQ_EDGE_MAX
+} ENUM_IRQ_EDGE;
+
+typedef enum _ENUM_CLOCK_CTRL_ {
+	CLK_OUT_DISABLE = 0,
+	CLK_OUT_ENABLE = CLK_OUT_DISABLE + 1,
+	CLK_OUT_MAX
+} ENUM_CLOCK_CTRL;
+
+/*Error No. table */
+typedef enum _ENUM_ERROR_CODE_ {
+	ERR_NO_ERROR = 0,
+	ERR_INVALID_PAR = ERR_NO_ERROR - 1,
+	ERR_MAX = ERR_INVALID_PAR - 1,
+} ENUM_ERROR_CODE;
+
+typedef enum _ENUM_BTIF_DIR_ {
+	BTIF_TX = 0,
+	BTIF_RX = BTIF_TX + 1,
+	BTIF_DIR_MAX,
+} ENUM_BTIF_DIR;
+
+typedef enum _ENUM_DMA_DIR_ {
+	DMA_DIR_RX = 0,
+	DMA_DIR_TX = DMA_DIR_RX + 1,
+	DMA_DIR_BOTH,
+} ENUM_DMA_DIR;
+
+typedef enum _ENUM_BTIF_REG_ID_ {
+	REG_IIR = 0,		/*Interrupt Identification Register */
+	REG_LSR = 1,		/*Line Status Register */
+	REG_FAKE_LCR = 2,	/*Fake Lcr Regiseter */
+	REG_FIFO_CTRL = 3,	/*FIFO Control Register */
+	REG_IER = 4,		/*Interrupt Enable Register */
+	REG_SLEEP_EN = 5,	/*Sleep Enable Register */
+	REG_RTO_COUNTER = 6,	/*Rx Timeout Counter Register */
+	REG_DMA_EN = 7,		/*DMA Enalbe Register */
+	REG_TRIG_LVL = 8,	/*Tx/Rx Trigger Level Register */
+	REG_WAT_TIME = 9,	/*Async Wait Time Register */
+	REG_HANDSHAKE = 10,	/*New HandShake Mode Register */
+	REG_SLP_WAK = 11,	/*Sleep Wakeup Reigster */
+	REG_BTIF_ALL = 12,	/*all btif controller's registers */
+	REG_TX_DMA_ALL = 13,
+	REG_RX_DMA_ALL = 14,
+	REG_MAX
+} ENUM_BTIF_REG_ID;
+
+typedef enum _MTK_BTIF_PM_OPID_ {
+	BTIF_PM_DPIDLE_EN,
+	BTIF_PM_DPIDLE_DIS,
+	BTIF_PM_SUSPEND,
+	BTIF_PM_RESUME,
+	BTIF_PM_RESTORE_NOIRQ,
+} MTK_BTIF_PM_OPID;
+
+#define BTIF_HAL_TX_FIFO_SIZE (1024 * 4)
+
+/*-----------------------------------Enum Defination End--------------------------------*/
+
+/*****************************structure definition***************************/
+/*IRQ related information*/
+typedef struct _MTK_BTIF_IRQ_STR_ {
+	const char *name;
+	bool is_irq_sup;
+	unsigned int irq_id;
+#ifdef CONFIG_OF
+	unsigned int irq_flags;
+#else
+	ENUM_IRQ_SENS_TYPE sens_type;
+	union {
+		ENUM_IRQ_LVL lvl_type;
+		ENUM_IRQ_EDGE edge_type;
+	};
+#endif
+	bool reg_flag;
+	irq_handler_t p_irq_handler;
+} MTK_BTIF_IRQ_STR, *P_MTK_BTIF_IRQ_STR;
+
+typedef struct _DMA_VFIFO_ {
+	/*[Driver Access] vFIFO memory'svirtual address */
+	unsigned char *p_vir_addr;
+	/*[HW Access] dma handle , physically address, set to DMA's HW Register */
+	dma_addr_t phy_addr;
+	/*DMA's vFIFO size */
+	unsigned int vfifo_size;
+	/*DMA's threshold value */
+	unsigned int thre;
+} DMA_VFIFO, *P_DMA_VFIFO;
+
+typedef unsigned int (*dma_rx_buf_write) (void *p_dma_info,
+					  unsigned char *p_buf,
+					  unsigned int buf_len);
+typedef unsigned int (*btif_rx_buf_write) (void *p_btif_info,
+					   unsigned char *p_buf,
+					   unsigned int buf_len);
+
+/*DMA related information*/
+typedef struct _MTK_DMA_INFO_STR_ {
+	unsigned long base;
+	ENUM_DMA_DIR dir;
+	P_MTK_BTIF_IRQ_STR p_irq;
+	dma_rx_buf_write rx_cb;
+	P_DMA_VFIFO p_vfifo;
+} MTK_DMA_INFO_STR, *P_MTK_DMA_INFO_STR;
+
+/*DMA related information*/
+typedef struct _MTK_BTIF_INFO_STR_ {
+	unsigned long base;	/*base address */
+	P_MTK_BTIF_IRQ_STR p_irq;	/*irq related information */
+
+	unsigned int tx_fifo_size;	/*BTIF tx FIFO size */
+	unsigned int rx_fifo_size;	/*BTIF rx FIFO size */
+
+	unsigned int tx_tri_lvl;	/*BTIFtx trigger level in FIFO mode */
+	unsigned int rx_tri_lvl;	/*BTIFrx trigger level in FIFO mode */
+
+	unsigned int clk_gat_addr;	/*clock gating address */
+	unsigned int set_bit;	/*enable clock gating bit */
+	unsigned int clr_bit;	/*clear clock gating bit */
+
+	unsigned int rx_data_len;	/*rx data length */
+
+	btif_rx_buf_write rx_cb;
+
+	struct kfifo *p_tx_fifo;	/*tx fifo */
+	spinlock_t tx_fifo_spinlock;	/*tx fifo spinlock */
+} MTK_BTIF_INFO_STR, *P_MTK_BTIF_INFO_STR;
+
+/**********End of Structure Definition***********/
+
+/***********register operation***********/
+#ifdef __KERNEL__
+/*byte write  <1 byte> */
+#define btif_reg_sync_writeb(v, a)    mt_reg_sync_writeb(v, a)
+/*word write  <2 byte> */
+#define btif_reg_sync_writew(v, a)    mt_reg_sync_writew(v, a)
+/*long write   <4 byte> */
+#define btif_reg_sync_writel(v, a)    mt_reg_sync_writel(v, a)
+#else
+/*byte write  <1 byte> */
+#define btif_reg_sync_writeb(v, a)    mt65xx_reg_sync_writeb(v, a)
+/*word write  <2 byte> */
+#define btif_reg_sync_writew(v, a)    mt65xx_reg_sync_writew(v, a)
+/*long write   <4 byte> */
+#define btif_reg_sync_writel(v, a)    mt65xx_reg_sync_writel(v, a)
+#endif
+#define BTIF_READ8(REG)               __raw_readb((unsigned char *)(REG))
+#define BTIF_READ16(REG)              __raw_readw((unsigned short *)(REG))
+#define BTIF_READ32(REG)              __raw_readl((unsigned int *)(REG))
+
+#define BTIF_SET_BIT(REG, BITVAL)    do { \
+*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL)); \
+mb(); /**/ \
+} \
+while (0)
+#define BTIF_CLR_BIT(REG, BITVAL)    do { \
+(*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL)); \
+mb(); /**/\
+} \
+while (0)
+
+/***********end of register operation *********/
+
+#endif /*__HAL_PUB_H_*/
diff --git a/drivers/misc/mediatek/connectivity/Kconfig b/drivers/misc/mediatek/connectivity/Kconfig
new file mode 100644
index 0000000000000..4a944b1f0ebe5
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/Kconfig
@@ -0,0 +1,299 @@
+config MTK_COMBO
+	tristate "MediaTek Connectivity Combo Chip Support"
+	help
+	  MTK connectivity combo chip driver for MT66xx
+
+#
+# MTK Combo Chip Selection
+#
+
+choice
+	prompt "Select Chip"
+	depends on MTK_COMBO
+
+config MTK_COMBO_CHIP_MT6620
+	bool "MT6620"
+	help
+	  this config is used to decided combo chip version
+	  in current platform
+	  is
+	  MT6620
+
+config MTK_COMBO_CHIP_MT6628
+	bool "MT6628"
+	help
+	  this config is used to decided combo chip version
+	  in current platform
+	  is
+	  MT6628
+
+config MTK_COMBO_CHIP_MT6630
+	bool "MT6630"
+	help
+	  this config is used to decided combo chip version
+	  in current platform
+	  is
+	  MT6630
+
+config MTK_COMBO_CHIP_CONSYS_6572
+	bool "CONSYS_6572"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6572
+
+config MTK_COMBO_CHIP_CONSYS_6582
+	bool "CONSYS_6582"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6582
+
+config MTK_COMBO_CHIP_CONSYS_8127
+	bool "CONSYS_8127"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6572
+
+config MTK_COMBO_CHIP_CONSYS_7623
+	bool "CONSYS_7623"
+	#select MTK_PLATFORM::="mt7623"
+	help
+	  this config is used to decide SOC consys version
+	  in current platform is MT7623 and prepare proper
+	  system services like radio power on/off and firmware
+	  download for the Bluetotoh and Wifi.
+
+
+config MTK_COMBO_CHIP_CONSYS_6752
+	bool "CONSYS_6752"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6752
+
+config MTK_COMBO_CHIP_CONSYS_6592
+	bool "CONSYS_6592"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6592
+
+config MTK_COMBO_CHIP_CONSYS_8163
+	bool "CONSYS_8163"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT8163
+
+config MTK_COMBO_CHIP_CONSYS_6735
+	bool "CONSYS_6735"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6735
+
+config MTK_COMBO_CHIP_CONSYS_6755
+	bool "CONSYS_6755"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6755
+
+config MTK_COMBO_CHIP_CONSYS_6580
+	bool "CONSYS_6580"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6580
+
+config MTK_COMBO_CHIP_CONSYS_6797
+	bool "CONSYS_6797"
+	help
+	  this config is used to decided SOC consys version
+	  in current platform
+	  is
+	  MT6797
+endchoice
+
+config MTK_COMBO_CHIP
+	string
+	default "MT6620" if MTK_COMBO_CHIP_MT6620
+	default "MT6628" if MTK_COMBO_CHIP_MT6628
+	default "MT6630" if MTK_COMBO_CHIP_MT6630
+	default "CONSYS_6572" if MTK_COMBO_CHIP_CONSYS_6572
+	default "CONSYS_6582" if MTK_COMBO_CHIP_CONSYS_6582
+	default "CONSYS_8127" if MTK_COMBO_CHIP_CONSYS_8127
+	default "CONSYS_7623" if MTK_COMBO_CHIP_CONSYS_7623
+	default "CONSYS_6752" if MTK_COMBO_CHIP_CONSYS_6752
+	default "CONSYS_6755" if MTK_COMBO_CHIP_CONSYS_6755
+	default "CONSYS_6592" if MTK_COMBO_CHIP_CONSYS_6592
+	default "CONSYS_8163" if MTK_COMBO_CHIP_CONSYS_8163
+	default "CONSYS_6735" if MTK_COMBO_CHIP_CONSYS_6735
+	default "CONSYS_6580" if MTK_COMBO_CHIP_CONSYS_6580
+	default "CONSYS_6797" if MTK_COMBO_CHIP_CONSYS_6797
+	help
+	  this feature is used to identify combo chip version or SOC chip
+	  consys version.
+
+#
+# Target Platform Selection
+#
+config MTK_COMBO_PLAT_PATH
+	string "Platform folder name"
+	depends on MTK_COMBO
+	default "sample" if MTK_COMBO_PLAT_SAMPLE
+	help
+	  Specify platform folder under common driver platform folder:
+	  mtk_wcn_combo/common/platform/*
+
+#
+# MTK COMBO Chip Configuration
+#
+config MTK_COMBO_COMM
+	depends on MTK_COMBO
+	tristate "MediaTek Combo Chip Common part driver"
+	help
+	  MediaTek combo chip common part driver
+
+#config MTK_COMBO_COMM_PS
+#	depends on MTK_COMBO_COMM
+#	bool "Enable PS support"
+#	default n
+#	help
+#	  Enable PS support of common UART interface
+
+config MTK_COMBO_COMM_UART
+	depends on MTK_COMBO_COMM
+	tristate "Common interface UART"
+	help
+	  Use UART for common part interface type
+
+config MTK_COMBO_COMM_SDIO
+	depends on MTK_COMBO_COMM
+	tristate "Common interface SDIO"
+	help
+	  Use SDIO for common part interface type
+
+config MTK_COMBO_COMM_NPWR
+	depends on MTK_COMBO_COMM
+	bool "Enable NPWR support"
+	default n
+	help
+	  Enable NPWR support of new power on swquence
+
+config MTK_COMBO_COMM_APO
+	depends on MTK_COMBO_COMM
+	bool "Enable always power on support"
+	#default y
+	help
+	  Enable chip will always power on
+
+config MTK_COMBO_BT
+	tristate "MediaTek Combo Chip BT driver"
+	depends on BT && MTK_COMBO
+	select MTK_BTIF
+	help
+	  MTK BT /dev/stpbt driver for Bluedroid
+
+config MTK_COMBO_BT_HCI
+	tristate "MediaTek Combo Chip BlueZ driver"
+	depends on BT && MTK_COMBO
+	select MTK_BTIF
+	help
+	  MTK BT driver for BlueZ
+
+config MTK_COMBO_WIFI
+	tristate "MediaTek combo chip Wi-Fi support"
+	depends on MTK_COMBO
+	select MTK_BTIF
+	select WIRELESS_EXT
+	select WEXT_PRIV
+
+config MTK_WAPI_SUPPORT
+	bool "MTK_WAPI_SUPPORT"
+	depends on MTK_COMBO_WIFI
+	#default y
+	help
+	  if it is set to TRUE: Support WAPI (WLAN Authentication and
+	  Privacy Infrastructure)
+
+config MTK_PASSPOINT_R1_SUPPORT
+	bool "MTK_PASSPOINT_R1_SUPPORT"
+	depends on MTK_COMBO_WIFI
+	help
+	  Support Passpoint R1 (Hotspot 2.0 R1)
+
+config MTK_PASSPOINT_R2_SUPPORT
+	bool "MTK_PASSPOINT_R2_SUPPORT"
+	depends on MTK_COMBO_WIFI
+	help
+	   Support Passpoint R2
+
+config MTK_WIFI_MCC_SUPPORT
+	bool "MTK_WIFI_MCC_SUPPORT"
+	depends on MTK_COMBO_WIFI
+	#default y
+	help
+	   if it is set to TRUE, wlan will support Multi-Channel Concurrency,
+	   otherwise, only support Single Channel Concurrency
+
+config MTK_DHCPV6C_WIFI
+	bool "MTK_DHCPV6C_WIFI"
+	help
+	  no: disable this feature
+
+config MTK_CONN_LTE_IDC_SUPPORT
+	bool "MediaTek CONN LTE IDC support"
+	select MTK_CONN_MD
+	#default y
+	help
+	  This option enables CONN LTE IDC support
+
+menuconfig GPS
+        tristate "GPS drivers"
+        #default y
+        ---help---
+          Say Y here for supporting GPS.
+
+if GPS
+config MTK_GPS
+        tristate "MediaTek GPS driver"
+        #default y
+        ---help---
+          MTK GPS driver
+          To switch gps nmea port driver.
+          Set "yes" to turn on.
+          Set "no" to turn off.
+endif # GPS
+
+config MTK_GPS_SUPPORT
+        tristate "MediaTek GPS driver"
+        select MTK_GPS
+        help
+          to switch GPS feature on the platform.
+          Set "yes" to turn on and set "no"
+          (with MTK_AGPS_APP=no at the same time)
+          to turn off.
+
+config MTK_GPS_REGISTER_SETTING
+	tristate "MediaTek GPS Register Setting"
+	depends on MTK_COMBO_GPS
+	help
+	   GPS register settings.
+
+config MTK_GPS_EMI
+	tristate "MediaTek GPS EMI Driver"
+	depends on MTK_COMBO_GPS
+	help
+	   GPS EMI driver is for MNL OFFLOAD feature.
diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile
new file mode 100644
index 0000000000000..0947788d189a8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/Makefile
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+# Connectivity combo driver
+# If KERNELRELEASE is defined, we've been invoked from the
+# kernel build system and can use its language.
+ifneq ($(KERNELRELEASE),)
+subdir-ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE
+ifeq ($(CONFIG_ARM64), y)
+subdir-ccflags-y += -D CONFIG_MTK_WCN_ARM64
+endif
+
+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y)
+    subdir-ccflags-y += -D WMT_IDC_SUPPORT=1
+else
+    subdir-ccflags-y += -D WMT_IDC_SUPPORT=0
+endif
+    subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+
+    obj-y += common/
+    obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/
+	obj-n := dummy.o
+
+# Otherwise we were called directly from the command line;
+# invoke the kernel build system.
+else
+    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+    PWD  := $(shell pwd)
+default:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+endif
diff --git a/drivers/misc/mediatek/connectivity/common/Makefile b/drivers/misc/mediatek/connectivity/common/Makefile
new file mode 100644
index 0000000000000..622b74430e132
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/Makefile
@@ -0,0 +1,23 @@
+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include
+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat
+
+#ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),)
+#	obj-y   +=  combo/
+#endif
+#ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),)
+#	subdir-ccflags-y += -D MT6628
+#	subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT
+#	obj-y   +=  combo/
+#endif
+#ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),)
+#	subdir-ccflags-y += -D MT6630
+#ifneq ($(CONFIG_ARCH_MT2601),y)
+#	subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT
+#endif
+#	obj-y   +=  combo/
+#endif
+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),)
+	obj-y   +=  conn_soc/
+endif
+
+obj-y   +=  common_detect/
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile
new file mode 100644
index 0000000000000..8d7dc690affd2
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile
@@ -0,0 +1,47 @@
+subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/dct/dct
+subdir-ccflags-y += -DWMT_PLAT_ALPS=1
+
+COMBO_CHIP_SUPPORT := false
+ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),)
+	COMBO_CHIP_SUPPORT := true
+endif
+ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),)
+	COMBO_CHIP_SUPPORT := true
+endif
+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),)
+	COMBO_CHIP_SUPPORT := true
+endif
+ifeq ($(COMBO_CHIP_SUPPORT), true)
+	subdir-ccflags-y += -D MTK_WCN_COMBO_CHIP_SUPPORT
+	ccflags-y += -I$(src)/../combo/linux/include
+endif
+
+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),)
+	subdir-ccflags-y += -D MTK_WCN_SOC_CHIP_SUPPORT
+	ccflags-y += -I$(src)/../conn_soc/linux/include
+endif
+
+
+ifeq ($(CONFIG_MTK_COMBO),y)
+	ccflags-y += -I$(src)/drv_init/inc
+	obj-y += mtk_wcn_stub_alps.o
+	obj-y += wmt_stp_exp.o
+	obj-y += wmt_gpio.o
+
+	obj-y += wmt_detect.o
+	obj-y += sdio_detect.o
+	obj-y += wmt_detect_pwr.o
+
+	obj-y += drv_init/
+endif
+
+ifeq ($(CONFIG_MTK_COMBO),m)
+	obj-y += mtk_wcn_stub_alps.o
+	obj-y += wmt_stp_exp.o
+	obj-y += wmt_gpio.o
+
+	obj-$(CONFIG_MTK_COMBO) += mtk_wmt_detect.o
+	mtk_wmt_detect-objs := wmt_detect.o
+	mtk_wmt_detect-objs += sdio_detect.o
+	mtk_wmt_detect-objs += wmt_detect_pwr.o
+endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile
new file mode 100644
index 0000000000000..bb84384b9a24f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile
@@ -0,0 +1,22 @@
+ifeq ($(CONFIG_MTK_COMBO),y)
+	ccflags-y += -I$(src)/inc/
+	ccflags-y += -I$(src)/../
+
+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),)
+	ccflags-y += -D MTK_WCN_WLAN_GEN3
+endif
+ifneq ($(filter "CONSYS_6797",$(CONFIG_MTK_COMBO_CHIP)),)
+	ccflags-y += -D MTK_WCN_WLAN_GEN3
+else ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),)
+	ccflags-y += -D MTK_WCN_WLAN_GEN2
+endif
+
+	obj-y += conn_drv_init.o
+	obj-y += common_drv_init.o
+	obj-y += bluetooth_drv_init.o
+	obj-y += gps_drv_init.o
+	obj-y += fm_drv_init.o
+	obj-y += wlan_drv_init.o
+	obj-($(CONFIG_MTK_COMBO_ANT)) += ant_drv_init.o
+
+endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c
new file mode 100644
index 0000000000000..aa453f9397a47
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c
@@ -0,0 +1,38 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[ANT-MOD-INIT]"
+
+#include "wmt_detect.h"
+#include "ant_drv_init.h"
+
+int do_ant_drv_init(int chip_id)
+{
+	int i_ret = -1;
+
+	WMT_DETECT_INFO_FUNC("start to do ANT driver init\n");
+	switch (chip_id) {
+	case 0x6630:
+	case 0x6797:
+		i_ret = mtk_wcn_stpant_drv_init();
+		WMT_DETECT_INFO_FUNC("finish ANT driver init, i_ret:%d\n", i_ret);
+		break;
+	default:
+		WMT_DETECT_ERR_FUNC("chipid is not 6630,ANT is not supported!\n");
+	}
+	return i_ret;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c
new file mode 100644
index 0000000000000..47b0554334433
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[BT-MOD-INIT]"
+
+#include "wmt_detect.h"
+#include "bluetooth_drv_init.h"
+
+int do_bluetooth_drv_init(int chip_id)
+{
+	int i_ret = -1;
+
+#if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI)
+	WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n");
+	i_ret = mtk_wcn_stpbt_drv_init();
+	WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret);
+#else
+	WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n");
+#endif
+	return i_ret;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c
new file mode 100644
index 0000000000000..f9c332ea266b9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c
@@ -0,0 +1,103 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-MOD-INIT]"
+
+#include "wmt_detect.h"
+#include "common_drv_init.h"
+
+static int do_combo_common_drv_init(int chip_id)
+{
+	int i_ret = 0;
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+	int i_ret_tmp = 0;
+
+	WMT_DETECT_DBG_FUNC("start to do combo driver init, chipid:0x%08x\n", chip_id);
+
+	/* HIF-SDIO driver init */
+	i_ret_tmp = mtk_wcn_hif_sdio_drv_init();
+	i_ret += i_ret_tmp;
+	WMT_DETECT_DBG_FUNC("HIF-SDIO driver init, i_ret:%d\n", i_ret);
+
+	/* WMT driver init */
+	i_ret_tmp = mtk_wcn_combo_common_drv_init();
+	i_ret += i_ret_tmp;
+	WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret);
+
+	/* STP-UART driver init */
+	i_ret_tmp = mtk_wcn_stp_uart_drv_init();
+	i_ret += i_ret_tmp;
+	WMT_DETECT_DBG_FUNC("STP-UART driver init, i_ret:%d\n", i_ret);
+
+	/* STP-SDIO driver init */
+	i_ret_tmp = mtk_wcn_stp_sdio_drv_init();
+	i_ret += i_ret_tmp;
+	WMT_DETECT_DBG_FUNC("STP-SDIO driver init, i_ret:%d\n", i_ret);
+
+#else
+	i_ret = -1;
+	WMT_DETECT_ERR_FUNC("COMBO chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n");
+#endif
+	WMT_DETECT_DBG_FUNC("finish combo driver init\n");
+	return i_ret;
+}
+
+static int do_soc_common_drv_init(int chip_id)
+{
+	int i_ret = 0;
+
+#ifdef MTK_WCN_SOC_CHIP_SUPPORT
+	int i_ret_tmp = 0;
+
+	WMT_DETECT_DBG_FUNC("start to do soc common driver init, chipid:0x%08x\n", chip_id);
+
+	/* WMT driver init */
+	i_ret_tmp = mtk_wcn_soc_common_drv_init();
+	i_ret += i_ret_tmp;
+	WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret);
+
+#else
+	i_ret = -1;
+	WMT_DETECT_ERR_FUNC("SOC chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n");
+#endif
+
+	WMT_DETECT_DBG_FUNC("TBD........\n");
+	return i_ret;
+}
+
+int do_common_drv_init(int chip_id)
+{
+	int i_ret = 0;
+
+	WMT_DETECT_INFO_FUNC("start to do common driver init, chipid:0x%08x\n", chip_id);
+
+	switch (chip_id) {
+	case 0x6620:
+	case 0x6628:
+	case 0x6630:
+		i_ret = do_combo_common_drv_init(chip_id);
+		break;
+	default:
+		i_ret = do_soc_common_drv_init(chip_id);
+		break;
+	}
+
+	WMT_DETECT_INFO_FUNC("finish common driver init\n");
+
+	return i_ret;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c
new file mode 100644
index 0000000000000..8112d2a1d95e2
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c
@@ -0,0 +1,80 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WCN-MOD-INIT]"
+
+#include "wmt_detect.h"
+#include "conn_drv_init.h"
+#include "common_drv_init.h"
+#include "fm_drv_init.h"
+#include "wlan_drv_init.h"
+#include "bluetooth_drv_init.h"
+#include "gps_drv_init.h"
+#include "ant_drv_init.h"
+
+int __weak do_wlan_drv_init(int chip_id)
+{
+	WMT_DETECT_ERR_FUNC("Can not find wlan module for chip: %d !\n", chip_id);
+	return 0;
+}
+
+int __weak do_ant_drv_init(int chip_id)
+{
+	WMT_DETECT_DBG_FUNC("Chip: %d can not support ANT !\n", chip_id);
+	return 0;
+}
+
+int do_connectivity_driver_init(int chip_id)
+{
+	int i_ret = 0;
+	int tmp_ret = 0;
+
+	tmp_ret = do_common_drv_init(chip_id);
+	i_ret += tmp_ret;
+	if (tmp_ret) {
+		WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret);
+		WMT_DETECT_ERR_FUNC("abort connectivity driver init, because common part is not ready\n");
+		return i_ret;
+	}
+
+	tmp_ret = do_bluetooth_drv_init(chip_id);
+	i_ret += tmp_ret;
+	if (tmp_ret)
+		WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret);
+
+	tmp_ret = do_gps_drv_init(chip_id);
+	i_ret += tmp_ret;
+	if (tmp_ret)
+		WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret);
+
+	tmp_ret = do_fm_drv_init(chip_id);
+	i_ret += tmp_ret;
+	if (tmp_ret)
+		WMT_DETECT_ERR_FUNC("do fm module init failed, ret:%d\n", tmp_ret);
+
+	tmp_ret = do_wlan_drv_init(chip_id);
+	i_ret += tmp_ret;
+	if (tmp_ret)
+		WMT_DETECT_ERR_FUNC("do wlan module init failed, ret:%d\n", tmp_ret);
+
+	tmp_ret = do_ant_drv_init(chip_id);
+	i_ret += tmp_ret;
+	if (tmp_ret)
+		WMT_DETECT_ERR_FUNC("do ANT module init failed, ret:%d\n", tmp_ret);
+
+	return i_ret;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c
new file mode 100644
index 0000000000000..069c1cf13bbaf
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c
@@ -0,0 +1,33 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[FM-MOD-INIT]"
+
+#include "wmt_detect.h"
+#include "fm_drv_init.h"
+
+int do_fm_drv_init(int chip_id)
+{
+	WMT_DETECT_INFO_FUNC("start to do fm module init\n");
+
+#ifdef CONFIG_MTK_FMRADIO
+	mtk_wcn_fm_init();
+#endif
+
+	WMT_DETECT_INFO_FUNC("finish fm module init\n");
+	return 0;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c
new file mode 100644
index 0000000000000..6da1d70a3ca65
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[GPS-MOD-INIT]"
+
+#include "wmt_detect.h"
+#include "gps_drv_init.h"
+
+int do_gps_drv_init(int chip_id)
+{
+	int i_ret = -1;
+#ifdef CONFIG_MTK_COMBO_GPS
+	WMT_DETECT_INFO_FUNC("start to do gps driver init\n");
+	i_ret = mtk_wcn_stpgps_drv_init();
+	WMT_DETECT_INFO_FUNC("finish gps driver init, i_ret:%d\n", i_ret);
+#else
+	WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_GPS is not defined\n");
+#endif
+	return i_ret;
+
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h
new file mode 100644
index 0000000000000..4a436a2362900
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h
@@ -0,0 +1,20 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _ANT_DRIVER_INIT_H_
+#define _ANT_DRIVER_INIT_H_
+
+extern int do_ant_drv_init(int chip_id);
+extern int mtk_wcn_stpant_drv_init(void);
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h
new file mode 100644
index 0000000000000..8a847d361fc8c
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h
@@ -0,0 +1,20 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _BLUETOOTH_DRIVER_INIT_H_
+#define _BLUETOOTH_DRIVER_INIT_H_
+
+extern int do_bluetooth_drv_init(int chip_id);
+extern int mtk_wcn_stpbt_drv_init(void);
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h
new file mode 100644
index 0000000000000..ea01bd633c3c4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h
@@ -0,0 +1,31 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _COMMON_DRV_INIT_H_
+#define _COMMON_DRV_INIT_H_
+extern int do_common_drv_init(int chip_id);
+
+/*defined in common part driver*/
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+extern int mtk_wcn_combo_common_drv_init(void);
+extern int mtk_wcn_hif_sdio_drv_init(void);
+extern int mtk_wcn_stp_uart_drv_init(void);
+extern int mtk_wcn_stp_sdio_drv_init(void);
+#endif
+
+#ifdef MTK_WCN_SOC_CHIP_SUPPORT
+extern int mtk_wcn_soc_common_drv_init(void);
+#endif
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h
new file mode 100644
index 0000000000000..971193eade9e9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h
@@ -0,0 +1,18 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONNECTIVITY_DRV_INIT_H_
+#define _CONNECTIVITY_DRV_INIT_H_
+extern int do_connectivity_driver_init(int chip_id);
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h
new file mode 100644
index 0000000000000..f6ea30addc5da
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h
@@ -0,0 +1,20 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _FM_DRV_INIT_H_
+#define _FM_DRV_INIT_H_
+extern int do_fm_drv_init(int chip_id);
+extern int mtk_wcn_fm_init(void);
+extern void mtk_wcn_fm_exit(void);
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h
new file mode 100644
index 0000000000000..006ce072c53b6
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h
@@ -0,0 +1,19 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _GPS_DRIVER_INIT_H_
+#define _GPS_DRIVER_INIT_H_
+extern int do_gps_drv_init(int chip_id);
+extern int mtk_wcn_stpgps_drv_init(void);
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h
new file mode 100644
index 0000000000000..cb71b50bf950d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h
@@ -0,0 +1,30 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WLAN_DRV_INIT_H_
+#define _WLAN_DRV_INIT_H_
+
+
+extern int do_wlan_drv_init(int chip_id);
+
+extern int mtk_wcn_wmt_wifi_init(void);
+
+#ifdef MTK_WCN_WLAN_GEN2
+extern int mtk_wcn_wlan_gen2_init(void);
+#endif
+#ifdef MTK_WCN_WLAN_GEN3
+extern int mtk_wcn_wlan_gen3_init(void);
+#endif
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c
new file mode 100644
index 0000000000000..5b0d039a4a425
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c
@@ -0,0 +1,74 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WLAN-MOD-INIT]"
+
+#include "wmt_detect.h"
+#include "wlan_drv_init.h"
+
+
+int do_wlan_drv_init(int chip_id)
+{
+	int i_ret = 0;
+
+#ifdef CONFIG_MTK_COMBO_WIFI
+	int ret = 0;
+
+	WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id);
+
+	/* WMT-WIFI char dev init */
+	ret = mtk_wcn_wmt_wifi_init();
+	WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret);
+	i_ret += ret;
+
+	switch (chip_id) {
+	case 0x6630:
+	case 0x6797:
+#ifdef MTK_WCN_WLAN_GEN3
+		/* WLAN driver init */
+		ret = mtk_wcn_wlan_gen3_init();
+		WMT_DETECT_INFO_FUNC("WLAN-GEN3 driver init, ret:%d\n", ret);
+		i_ret += ret;
+#else
+		WMT_DETECT_ERR_FUNC("WLAN-GEN3 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n");
+		i_ret = -1;
+#endif
+		break;
+
+	default:
+#ifdef MTK_WCN_WLAN_GEN2
+		/* WLAN driver init */
+		ret = mtk_wcn_wlan_gen2_init();
+		WMT_DETECT_INFO_FUNC("WLAN-GEN2 driver init, ret:%d\n", ret);
+		i_ret += ret;
+#else
+		WMT_DETECT_ERR_FUNC("WLAN-GEN2 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n");
+		i_ret = -1;
+#endif
+		break;
+	}
+
+	WMT_DETECT_INFO_FUNC("finish wlan module init\n");
+
+#else
+
+	WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n");
+
+#endif
+
+	return i_ret;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c
new file mode 100644
index 0000000000000..fa8d437686f2d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c
@@ -0,0 +1,605 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define CMB_STUB_DBG_LOG                  3
+#define CMB_STUB_INFO_LOG                 2
+#define CMB_STUB_WARN_LOG                 1
+
+int gCmbStubLogLevel = CMB_STUB_INFO_LOG;
+
+#define CMB_STUB_LOG_INFO(fmt, arg...) \
+do { \
+	if (gCmbStubLogLevel >= CMB_STUB_INFO_LOG) \
+		pr_warn(fmt, ##arg); \
+} while (0)
+#define CMB_STUB_LOG_WARN(fmt, arg...) \
+do { \
+	if (gCmbStubLogLevel >= CMB_STUB_WARN_LOG) \
+		pr_warn(fmt, ##arg); \
+} while (0)
+#define CMB_STUB_LOG_DBG(fmt, arg...) \
+do { \
+	if (gCmbStubLogLevel >= CMB_STUB_DBG_LOG) \
+		pr_debug(fmt, ##arg); \
+} while (0)
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <mtk_wcn_cmb_stub.h>
+#include "wmt_detect.h"
+
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0
+#endif
+
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+struct work_struct *g_sdio_1v_autok_wk = NULL;
+#endif
+int gConnectivityChipId = -1;
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+/*
+* current used uart port name, default is "ttyMT2",
+* will be changed when wmt driver init
+*/
+char *wmt_uart_port_desc = "ttyMT2";
+EXPORT_SYMBOL(wmt_uart_port_desc);
+#endif
+
+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data);
+static void mtk_wcn_cmb_sdio_enable_eirq(void);
+static void mtk_wcn_cmb_sdio_disable_eirq(void);
+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data);
+
+struct sdio_ops mt_sdio_ops[4] = {
+	{NULL, NULL, NULL, NULL},
+	{NULL, NULL, NULL, NULL},
+	{mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq,
+		mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm},
+	{mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq,
+		mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm}
+};
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb;
+static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb;
+static wmt_thermal_query_cb cmb_stub_thermal_ctrl_cb;
+static CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0;
+static wmt_deep_idle_ctrl_cb cmb_stub_deep_idle_ctrl_cb;
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+static wmt_get_drv_status cmb_stub_drv_status_ctrl_cb;
+#endif
+static wmt_func_do_reset cmb_stub_do_reset_cb;
+/* A temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X.
+ * This is used for ALPS backward compatible ONLY!!! Remove this table, related
+ * functions, and type definition after modifying other kernel built-in modules,
+ * such as AUDIO. [FixMe][GeorgeKuo]
+ */
+#if 0
+static CMB_STUB_AIF_X audio2aif[] = {
+	[COMBO_AUDIO_STATE_0] = CMB_STUB_AIF_0,
+	[COMBO_AUDIO_STATE_1] = CMB_STUB_AIF_1,
+	[COMBO_AUDIO_STATE_2] = CMB_STUB_AIF_2,
+	[COMBO_AUDIO_STATE_3] = CMB_STUB_AIF_3,
+};
+#endif
+static msdc_sdio_irq_handler_t mtk_wcn_cmb_sdio_eirq_handler;
+static atomic_t sdio_claim_irq_enable_flag;
+static atomic_t irq_enable_flag;
+static pm_callback_t mtk_wcn_cmb_sdio_pm_cb;
+static void *mtk_wcn_cmb_sdio_pm_data;
+static void *mtk_wcn_cmb_sdio_eirq_data;
+
+static u32 wifi_irq = 0xffffffff;
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+static void mtk_wcn_cmb_stub_1v_autok_work(struct work_struct *work)
+{
+	CMB_STUB_LOG_WARN("++enter++\n");
+	mtk_wcn_cmb_stub_func_ctrl(11, 1);
+	mtk_wcn_cmb_stub_func_ctrl(11, 0);
+	CMB_STUB_LOG_WARN("--exit--\n");
+}
+
+/*!
+ * \brief A function for Getting current driver status:on/off
+ *
+ * \param driver type:0/bt,1/fm,2/gps,3/wifi,11/autok->run wmt turn on/off wifi flow
+ *
+ * \retval 0/off,2/on,-1/null pointer
+ */
+static int mtk_wcn_cmb_stub_drv_status(unsigned int type)
+{
+	int ret = -1;
+
+	if (cmb_stub_drv_status_ctrl_cb)
+		ret = (*cmb_stub_drv_status_ctrl_cb) (type);
+	else
+		CMB_STUB_LOG_WARN("cmb_stub_drv_status_ctrl_cb is NULL\n");
+	return ret;
+}
+
+/*!
+ * \brief A 1v AutoK function for kernel DVFS driver calling when screen off
+ *
+ * \param void
+ *
+ * \retval int,mt6630 state:0/off,1/power on,2/func on, -1/null
+ */
+int mtk_wcn_cmb_stub_1vautok_for_dvfs(void)
+{
+	int wmt_status;
+
+	CMB_STUB_LOG_WARN("DVFS driver call sdio 1v autok\n");
+
+	wmt_status = mtk_wcn_cmb_stub_drv_status(4);
+	CMB_STUB_LOG_WARN("current mt6630 status is %d\n", wmt_status);
+	if (0 == wmt_status) {
+		if (g_sdio_1v_autok_wk)
+			schedule_work(g_sdio_1v_autok_wk);
+		else
+			CMB_STUB_LOG_WARN("g_sdio_1v_autok_wk is NULL\n");
+	} else if ((2 == wmt_status) || (1 == wmt_status)) {
+		CMB_STUB_LOG_WARN("mt6630 is on state,skip AUTOK\n");
+	} else {
+		CMB_STUB_LOG_WARN("mt6630 is unknown state(%d)\n", wmt_status);
+	}
+
+	return wmt_status;
+
+}
+#endif
+/*!
+ * \brief A registration function for WMT-PLAT to register itself to CMB-STUB.
+ *
+ * An MTK-WCN-CMB-STUB registration function provided to WMT-PLAT to register
+ * itself and related callback functions when driver being loaded into kernel.
+ *
+ * \param p_stub_cb a pointer carrying CMB_STUB_CB information
+ *
+ * \retval 0 operation success
+ * \retval -1 invalid parameters
+ */
+int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb)
+{
+	if ((!p_stub_cb)
+	    || (p_stub_cb->size != sizeof(CMB_STUB_CB))) {
+		CMB_STUB_LOG_WARN("[cmb_stub] invalid p_stub_cb:0x%p size(%d)\n",
+				  p_stub_cb, (p_stub_cb) ? p_stub_cb->size : 0);
+		return -1;
+	}
+
+	CMB_STUB_LOG_DBG("[cmb_stub] registered, p_stub_cb:0x%p size(%d)\n", p_stub_cb, p_stub_cb->size);
+
+	cmb_stub_aif_ctrl_cb = p_stub_cb->aif_ctrl_cb;
+	cmb_stub_func_ctrl_cb = p_stub_cb->func_ctrl_cb;
+	cmb_stub_thermal_ctrl_cb = p_stub_cb->thermal_query_cb;
+	cmb_stub_deep_idle_ctrl_cb = p_stub_cb->deep_idle_ctrl_cb;
+	cmb_stub_do_reset_cb = p_stub_cb->wmt_do_reset_cb;
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+	cmb_stub_drv_status_ctrl_cb = p_stub_cb->get_drv_status_cb;
+	g_sdio_1v_autok_wk = vmalloc(sizeof(struct work_struct));
+	if (!g_sdio_1v_autok_wk)
+		CMB_STUB_LOG_WARN("vmalloc work_struct(%zd) fail\n", sizeof(struct work_struct));
+	else
+		INIT_WORK(g_sdio_1v_autok_wk, mtk_wcn_cmb_stub_1v_autok_work);
+
+#endif
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_cmb_stub_reg);
+/*!
+ * \brief A unregistration function for WMT-PLAT to unregister from CMB-STUB.
+ *
+ * An MTK-WCN-CMB-STUB unregistration function provided to WMT-PLAT to
+ * unregister itself and clear callback function references.
+ *
+ * \retval 0 operation success
+ */
+int mtk_wcn_cmb_stub_unreg(void)
+{
+	cmb_stub_aif_ctrl_cb = NULL;
+	cmb_stub_func_ctrl_cb = NULL;
+	cmb_stub_thermal_ctrl_cb = NULL;
+	cmb_stub_deep_idle_ctrl_cb = NULL;
+	cmb_stub_do_reset_cb = NULL;
+	CMB_STUB_LOG_INFO("[cmb_stub] unregistered\n");	/* KERN_DEBUG */
+
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+	if (g_sdio_1v_autok_wk) {
+		vfree(g_sdio_1v_autok_wk);
+		g_sdio_1v_autok_wk = NULL;
+	}
+#endif
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_cmb_stub_unreg);
+
+/* stub functions for kernel to control audio path pin mux */
+int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl)
+{
+	int ret;
+
+	if ((CMB_STUB_AIF_MAX <= state)
+	    || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) {
+
+		CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl invalid (%d, %d)\n", state, ctrl);
+		return -1;
+	}
+
+	/* avoid the early interrupt before we register the eirq_handler */
+	if (cmb_stub_aif_ctrl_cb) {
+		ret = (*cmb_stub_aif_ctrl_cb) (state, ctrl);
+		CMB_STUB_LOG_INFO("[cmb_stub] aif_ctrl_cb state(%d->%d) ctrl(%d) ret(%d)\n",
+		cmb_stub_aif_stat, state, ctrl, ret);	/* KERN_DEBUG */
+
+		cmb_stub_aif_stat = state;
+	} else {
+		CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl_cb null\n");
+		ret = -2;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_cmb_stub_aif_ctrl);
+
+/* Use a temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X
+ * for ALPS backward compatible ONLY!!! Remove this table, related functions,
+ * and type definition after modifying other kernel built-in modules, such as
+ * AUDIO. [FixMe][GeorgeKuo]
+ */
+
+void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on)
+{
+	if (cmb_stub_func_ctrl_cb)
+		(*cmb_stub_func_ctrl_cb) (type, on);
+	else
+		CMB_STUB_LOG_WARN("[cmb_stub] func_ctrl_cb null\n");
+}
+EXPORT_SYMBOL(mtk_wcn_cmb_stub_func_ctrl);
+
+int mtk_wcn_cmb_stub_query_ctrl(void)
+{
+	signed long temp = 0;
+
+	if (cmb_stub_thermal_ctrl_cb)
+		temp = (*cmb_stub_thermal_ctrl_cb) ();
+	else
+		CMB_STUB_LOG_WARN("[cmb_stub] thermal_ctrl_cb null\n");
+
+	return temp;
+}
+
+/*platform-related APIs*/
+/* void clr_device_working_ability(UINT32 clockId, MT6573_STATE state); */
+/* void set_device_working_ability(UINT32 clockId, MT6573_STATE state); */
+
+static int _mt_combo_plt_do_deep_idle(COMBO_IF src, int enter)
+{
+	int ret = -1;
+
+#if 0
+	if (src != COMBO_IF_UART && src != COMBO_IF_MSDC && src != COMBO_IF_BTIF) {
+		CMB_STUB_LOG_WARN("src = %d is error\n", src);
+		return ret;
+	}
+	if (src >= 0 && src < COMBO_IF_MAX)
+		CMB_STUB_LOG_INFO("src = %s, to enter deep idle? %d\n", combo_if_name[src], enter);
+#endif
+	/*TODO: For Common SDIO configuration, we need to do some judgement between STP and WIFI
+	   to decide if the msdc will enter deep idle safely */
+
+	switch (src) {
+	case COMBO_IF_UART:
+		if (enter == 0) {
+			/* clr_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */
+			/* disable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+#if 0
+			ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 0);
+			if (ret < 0)
+				CMB_STUB_LOG_WARN("[CMB] %s exit deep idle failed\n", wmt_uart_port_desc);
+#endif
+#endif
+		} else {
+			/* set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */
+			/* enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+#if 0
+			ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 1);
+			if (ret < 0)
+				CMB_STUB_LOG_WARN("[CMB] %s enter deep idle failed\n", wmt_uart_port_desc);
+#endif
+#endif
+		}
+		ret = 0;
+		break;
+
+	case COMBO_IF_MSDC:
+		if (enter == 0) {
+			/* for common sdio hif */
+			/* clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */
+		} else {
+			/* for common sdio hif */
+			/* set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */
+		}
+		ret = 0;
+		break;
+
+	case COMBO_IF_BTIF:
+		if (cmb_stub_deep_idle_ctrl_cb)
+			ret = (*cmb_stub_deep_idle_ctrl_cb) (enter);
+		else
+			CMB_STUB_LOG_WARN("NULL function pointer\n");
+
+		if (ret)
+			CMB_STUB_LOG_WARN("%s deep idle fail(%d)\n", enter == 1 ? "enter" : "exit", ret);
+		else
+			CMB_STUB_LOG_DBG("%s deep idle ok(%d)\n", enter == 1 ? "enter" : "exit", ret);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int mt_combo_plt_enter_deep_idle(COMBO_IF src)
+{
+	/* return 0; */
+	/* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */
+	return _mt_combo_plt_do_deep_idle(src, 1);
+}
+EXPORT_SYMBOL(mt_combo_plt_enter_deep_idle);
+
+int mt_combo_plt_exit_deep_idle(COMBO_IF src)
+{
+	/* return 0; */
+	/* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */
+	return _mt_combo_plt_do_deep_idle(src, 0);
+}
+EXPORT_SYMBOL(mt_combo_plt_exit_deep_idle);
+
+int mtk_wcn_wmt_chipid_query(void)
+{
+	return gConnectivityChipId;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query);
+
+void mtk_wcn_wmt_set_chipid(int chipid)
+{
+	CMB_STUB_LOG_INFO("set current consys chipid (0x%x)\n", chipid);
+	gConnectivityChipId = chipid;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_set_chipid);
+
+int mtk_wcn_cmb_stub_do_reset(unsigned int type)
+{
+	if (cmb_stub_do_reset_cb)
+		return (*cmb_stub_do_reset_cb) (type);
+	else
+		return -1;
+}
+EXPORT_SYMBOL(mtk_wcn_cmb_stub_do_reset);
+
+static void mtk_wcn_cmb_sdio_enable_eirq(void)
+{
+	if (atomic_read(&irq_enable_flag))
+		CMB_STUB_LOG_DBG("wifi eint has been enabled\n");
+	else {
+		atomic_set(&irq_enable_flag, 1);
+		if (wifi_irq != 0xfffffff) {
+			enable_irq(wifi_irq);
+			CMB_STUB_LOG_DBG(" enable WIFI EINT irq %d !!\n", wifi_irq);
+		}
+	}
+}
+
+static void mtk_wcn_cmb_sdio_disable_eirq(void)
+{
+	if (!atomic_read(&irq_enable_flag))
+		CMB_STUB_LOG_DBG("wifi eint has been disabled!\n");
+	else {
+		if (wifi_irq != 0xfffffff) {
+			disable_irq_nosync(wifi_irq);
+			CMB_STUB_LOG_DBG("disable WIFI EINT irq %d !!\n", wifi_irq);
+		}
+		atomic_set(&irq_enable_flag, 0);
+	}
+}
+
+irqreturn_t mtk_wcn_cmb_sdio_eirq_handler_stub(int irq, void *data)
+{
+	if ((NULL != mtk_wcn_cmb_sdio_eirq_handler)&&(0 != atomic_read(&sdio_claim_irq_enable_flag)))
+		mtk_wcn_cmb_sdio_eirq_handler(mtk_wcn_cmb_sdio_eirq_data);
+	return IRQ_HANDLED;
+}
+
+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data)
+{
+	struct device_node *node;
+	int ret = -EINVAL;
+#if 0
+	unsigned int gpio_wifi_eint_pin;
+#endif
+
+	CMB_STUB_LOG_INFO("enter %s\n", __func__);
+	mtk_wcn_sdio_irq_flag_set(0);
+	atomic_set(&irq_enable_flag, 0);
+	mtk_wcn_cmb_sdio_eirq_data = data;
+	mtk_wcn_cmb_sdio_eirq_handler = irq_handler;
+
+	node = (struct device_node *)of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo");
+	if (node) {
+#if 0
+		gpio_wifi_eint_pin = of_get_gpio(node, 5);
+		CMB_STUB_LOG_INFO("WIFI EINT pin %d !!\n", gpio_wifi_eint_pin);
+		wifi_irq = gpio_to_irq(gpio_wifi_eint_pin);
+#else
+		wifi_irq = irq_of_parse_and_map(node, 0);/* get wifi eint num */
+#endif
+#if 1
+		ret = request_irq(wifi_irq, mtk_wcn_cmb_sdio_eirq_handler_stub, IRQF_TRIGGER_LOW,
+				"WIFI-eint", NULL);
+		CMB_STUB_LOG_DBG("WIFI EINT irq %d !!\n", wifi_irq);
+#endif
+
+		if (ret)
+			CMB_STUB_LOG_WARN("WIFI EINT IRQ LINE NOT AVAILABLE!!\n");
+		else
+			mtk_wcn_cmb_sdio_disable_eirq();/*not ,chip state is power off*/
+	} else
+		CMB_STUB_LOG_WARN("[%s] can't find connectivity compatible node\n", __func__);
+
+	CMB_STUB_LOG_INFO("exit %s\n", __func__);
+}
+
+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data)
+{
+	CMB_STUB_LOG_DBG("mtk_wcn_cmb_sdio_register_pm (0x%p, 0x%p)\n", pm_cb, data);
+	/* register pm change callback */
+	mtk_wcn_cmb_sdio_pm_cb = pm_cb;
+	mtk_wcn_cmb_sdio_pm_data = data;
+}
+
+static void mtk_wcn_cmb_sdio_on(int sdio_port_num)
+{
+	pm_message_t state = {.event = PM_EVENT_USER_RESUME };
+
+	CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_on (%d)\n", sdio_port_num);
+
+	/* 1. disable sdio eirq */
+	mtk_wcn_cmb_sdio_disable_eirq();
+
+	/* 2. call sd callback */
+	if (mtk_wcn_cmb_sdio_pm_cb) {
+		/* pr_warn("mtk_wcn_cmb_sdio_pm_cb(PM_EVENT_USER_RESUME, 0x%p, 0x%p)\n",
+		 * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */
+		mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data);
+	} else
+		CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_on no sd callback!!\n");
+}
+
+static void mtk_wcn_cmb_sdio_off(int sdio_port_num)
+{
+	pm_message_t state = {.event = PM_EVENT_USER_SUSPEND };
+
+	CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_off (%d)\n", sdio_port_num);
+
+	/* 1. call sd callback */
+	if (mtk_wcn_cmb_sdio_pm_cb) {
+		/* pr_warn("mtk_wcn_cmb_sdio_off(PM_EVENT_USER_SUSPEND, 0x%p, 0x%p)\n",
+		 * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */
+		mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data);
+	} else
+		CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_off no sd callback!!\n");
+
+	/* 2. disable sdio eirq */
+	mtk_wcn_cmb_sdio_disable_eirq();
+}
+
+int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on)
+{
+	CMB_STUB_LOG_DBG("mt_mtk_wcn_cmb_sdio_ctrl (%d, %d)\n", sdio_port_num, on);
+	if (on) {
+#if 1
+		CMB_STUB_LOG_DBG("board_sdio_ctrl force off before on\n");
+		mtk_wcn_cmb_sdio_off(sdio_port_num);
+#else
+		CMB_STUB_LOG_WARN("skip sdio off before on\n");
+#endif
+		/* off -> on */
+		mtk_wcn_cmb_sdio_on(sdio_port_num);
+		if (wifi_irq != 0xfffffff)
+			irq_set_irq_wake(wifi_irq, 1);
+		else
+			CMB_STUB_LOG_WARN("wifi_irq is not available\n");
+	} else {
+			if (wifi_irq != 0xfffffff)
+				irq_set_irq_wake(wifi_irq, 0);
+			else
+				CMB_STUB_LOG_WARN("wifi_irq is not available\n");
+			/* on -> off */
+			mtk_wcn_cmb_sdio_off(sdio_port_num);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(board_sdio_ctrl);
+
+int mtk_wcn_sdio_irq_flag_set(int flag)
+{
+	if (0 != flag)
+		atomic_set(&sdio_claim_irq_enable_flag, 1);
+	else
+		atomic_set(&sdio_claim_irq_enable_flag, 0);
+
+	CMB_STUB_LOG_DBG("sdio_claim_irq_enable_flag:%d\n", atomic_read(&sdio_claim_irq_enable_flag));
+
+	return atomic_read(&sdio_claim_irq_enable_flag);
+}
+EXPORT_SYMBOL(mtk_wcn_sdio_irq_flag_set);
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c
new file mode 100644
index 0000000000000..7ac5ac73ef5d8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c
@@ -0,0 +1,269 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[SDIO-DETECT]"
+
+#include "wmt_detect.h"
+
+#if MTK_HIF_SDIO_AUTOK_ENABLED
+#include <mt_boot.h>
+#endif
+
+unsigned int gComboChipId = -1;
+struct sdio_func *g_func = NULL;
+
+MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = {
+	/* MT6620 *//* Not an SDIO standard class device */
+	{{SDIO_DEVICE(0x037A, 0x020A)}, 0x6620},	/* SDIO1:FUNC1:WIFI */
+	{{SDIO_DEVICE(0x037A, 0x020B)}, 0x6620},	/* SDIO2:FUNC1:BT+FM+GPS */
+	{{SDIO_DEVICE(0x037A, 0x020C)}, 0x6620},	/* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */
+
+	/* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */
+	{{SDIO_DEVICE(0x037A, 0x6628)}, 0x6628},
+
+	/* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */
+	{{SDIO_DEVICE(0x037A, 0x6630)}, 0x6630},
+
+};
+
+/* Supported SDIO device table */
+static const struct sdio_device_id mtk_sdio_id_tbl[] = {
+	/* MT6618 *//* Not an SDIO standard class device */
+	{SDIO_DEVICE(0x037A, 0x018A)},	/* SDIO1:WIFI */
+	{SDIO_DEVICE(0x037A, 0x018B)},	/* SDIO2:FUNC1:BT+FM */
+	{SDIO_DEVICE(0x037A, 0x018C)},	/* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */
+
+	/* MT6619 *//* Not an SDIO standard class device */
+	{SDIO_DEVICE(0x037A, 0x6619)},	/* SDIO2:FUNC1:BT+FM+GPS */
+
+	/* MT6620 *//* Not an SDIO standard class device */
+	{SDIO_DEVICE(0x037A, 0x020A)},	/* SDIO1:FUNC1:WIFI */
+	{SDIO_DEVICE(0x037A, 0x020B)},	/* SDIO2:FUNC1:BT+FM+GPS */
+	{SDIO_DEVICE(0x037A, 0x020C)},	/* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */
+
+	/* MT5921 *//* Not an SDIO standard class device */
+	{SDIO_DEVICE(0x037A, 0x5921)},
+
+	/* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */
+	{SDIO_DEVICE(0x037A, 0x6628)},
+
+	/* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */
+	{SDIO_DEVICE(0x037A, 0x6630)},
+	{ /* end: all zeroes */ },
+};
+
+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id);
+
+static void sdio_detect_remove(struct sdio_func *func);
+
+static struct sdio_driver mtk_sdio_client_drv = {
+	.name = "mtk_sdio_client",	/* MTK SDIO Client Driver */
+	.id_table = mtk_sdio_id_tbl,	/* all supported struct sdio_device_id table */
+	.probe = sdio_detect_probe,
+	.remove = sdio_detect_remove,
+};
+
+static int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id);
+
+int hif_sdio_is_chipid_valid(int chipId)
+{
+	int index = -1;
+
+	int left = 0;
+	int middle = 0;
+	int right = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]) - 1;
+
+	if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId))
+		return index;
+
+	middle = (left + right) / 2;
+
+	while (left <= right) {
+		if (chipId > gChipInfoArray[middle].chipId) {
+			left = middle + 1;
+		} else if (chipId < gChipInfoArray[middle].chipId) {
+			right = middle - 1;
+		} else {
+			index = middle;
+			break;
+		}
+		middle = (left + right) / 2;
+	}
+
+	if (0 > index)
+		WMT_DETECT_ERR_FUNC("no supported chipid found\n");
+	else
+		WMT_DETECT_INFO_FUNC("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId);
+
+	return index;
+}
+
+int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id)
+{
+	int maxIndex = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]);
+	int index = 0;
+	struct sdio_device_id *localId = NULL;
+	int chipId = -1;
+
+	for (index = 0; index < maxIndex; index++) {
+		localId = &(gChipInfoArray[index].deviceId);
+		if ((localId->vendor == id->vendor) && (localId->device == id->device)) {
+			chipId = gChipInfoArray[index].chipId;
+			WMT_DETECT_INFO_FUNC
+			    ("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index,
+			     localId->vendor, localId->device, chipId);
+			gComboChipId = chipId;
+			mtk_wcn_wmt_set_chipid(gComboChipId);
+			break;
+		}
+	}
+	if (0 > chipId) {
+		WMT_DETECT_ERR_FUNC("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor,
+				    id->device);
+	}
+
+	return chipId;
+}
+
+int sdio_detect_query_chipid(int waitFlag)
+{
+	unsigned int timeSlotMs = 200;
+	unsigned int maxTimeSlot = 15;
+	unsigned int counter = 0;
+	/* gComboChipId = 0x6628; */
+	if (0 == waitFlag)
+		return gComboChipId;
+	if (0 <= hif_sdio_is_chipid_valid(gComboChipId))
+		return gComboChipId;
+
+	while (counter < maxTimeSlot) {
+		if (0 <= hif_sdio_is_chipid_valid(gComboChipId))
+			break;
+		msleep(timeSlotMs);
+		counter++;
+	}
+
+	return gComboChipId;
+}
+
+int sdio_detect_do_autok(int chipId)
+{
+	int i_ret = 0;
+
+#if MTK_HIF_SDIO_AUTOK_ENABLED
+#if 0
+	BOOTMODE boot_mode;
+
+	boot_mode = get_boot_mode();
+
+	if (boot_mode == META_BOOT) {
+		WMT_DETECT_INFO_FUNC("omit autok in meta mode\n");
+		return 0;
+	}
+#endif
+	if (0x6630 == chipId) {
+#ifdef CONFIG_SDIOAUTOK_SUPPORT
+		if (NULL != g_func) {
+			WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready++\n");
+			i_ret = wait_sdio_autok_ready(g_func->card->host);
+			WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready--\n");
+			if (0 == i_ret) {
+				WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return success\n");
+			} else {
+				WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return fail, i_ret:%d\n", i_ret);
+				gComboChipId = -1;
+			}
+		} else {
+			WMT_DETECT_INFO_FUNC("g_func NULL, omit autok\n");
+		}
+#else
+		i_ret = 0;
+		WMT_DETECT_INFO_FUNC("MTK_SDIOAUTOK_SUPPORT not defined\n");
+#endif
+	} else {
+		WMT_DETECT_INFO_FUNC("MT%x does not support SDIO3.0 autoK is not needed\n", chipId);
+	}
+#else
+	i_ret = 0;
+	WMT_DETECT_INFO_FUNC("MTK_HIF_SDIO_AUTOK_ENABLED is not defined\n");
+#endif
+	return i_ret;
+}
+
+/*!
+ * \brief hif_sdio probe function
+ *
+ * hif_sdio probe function called by mmc driver when any matched SDIO function
+ * is detected by it.
+ *
+ * \param func
+ * \param id
+ *
+ * \retval 0    register successfully
+ * \retval < 0  list error code here
+ */
+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id)
+{
+	int chipId = 0;
+
+	WMT_DETECT_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num);
+	chipId = hif_sdio_match_chipid_by_dev_id(id);
+
+	if ((0x6630 == chipId) && (1 == func->num)) {
+		int ret = 0;
+
+		g_func = func;
+		WMT_DETECT_INFO_FUNC("autok function detected, func:0x%p\n", g_func);
+
+		sdio_claim_host(func);
+		ret = sdio_enable_func(func);
+		sdio_release_host(func);
+		if (ret)
+			WMT_DETECT_ERR_FUNC("sdio_enable_func failed!\n");
+	}
+
+	return 0;
+}
+
+static void sdio_detect_remove(struct sdio_func *func)
+{
+	if (g_func == func) {
+		sdio_claim_host(func);
+		sdio_disable_func(func);
+		sdio_release_host(func);
+		g_func = NULL;
+	}
+	WMT_DETECT_INFO_FUNC("do sdio remove\n");
+}
+
+int sdio_detect_init(void)
+{
+	int ret = -1;
+	/* register to mmc driver */
+	ret = sdio_register_driver(&mtk_sdio_client_drv);
+	WMT_DETECT_INFO_FUNC("sdio_register_driver() ret=%d\n", ret);
+	return 0;
+}
+
+int sdio_detect_exit(void)
+{
+	g_func = NULL;
+	/* register to mmc driver */
+	sdio_unregister_driver(&mtk_sdio_client_drv);
+	WMT_DETECT_INFO_FUNC("sdio_unregister_driver\n");
+	return 0;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h
new file mode 100644
index 0000000000000..3a0bff9def1b1
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h
@@ -0,0 +1,43 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SDIO_DETECT_H_
+#define _SDIO_DETECT_H_
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/module.h>
+
+#ifdef CONFIG_SDIOAUTOK_SUPPORT
+#define MTK_HIF_SDIO_AUTOK_ENABLED 1
+extern int wait_sdio_autok_ready(void *);
+#else
+#define MTK_HIF_SDIO_AUTOK_ENABLED 0
+#endif
+
+typedef struct _MTK_WCN_HIF_SDIO_CHIP_INFO_ {
+	struct sdio_device_id deviceId;
+	unsigned int chipId;
+} MTK_WCN_HIF_SDIO_CHIP_INFO, *P_MTK_WCN_HIF_SDIO_CHIP_INFO;
+
+extern int sdio_detect_exit(void);
+extern int sdio_detect_init(void);
+extern int sdio_detect_query_chipid(int waitFlag);
+extern int hif_sdio_is_chipid_valid(int chipId);
+
+extern int sdio_detect_do_autok(int chipId);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c
new file mode 100644
index 0000000000000..487852df8f20f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c
@@ -0,0 +1,380 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <mtk_wcn_cmb_stub.h>
+#include <linux/platform_device.h>
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-DETECT]"
+
+#include "wmt_detect.h"
+#include "wmt_gpio.h"
+
+#if MTK_WCN_REMOVE_KO
+#include "conn_drv_init.h"
+#endif
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+
+#define WMT_DETECT_MAJOR 154
+#define WMT_DETECT_DEV_NUM 1
+#define WMT_DETECT_DRVIER_NAME "mtk_wcn_detect"
+#define WMT_DETECT_DEVICE_NAME "wmtdetect"
+
+struct class *pDetectClass = NULL;
+struct device *pDetectDev = NULL;
+static int gWmtDetectMajor = WMT_DETECT_MAJOR;
+static struct cdev gWmtDetectCdev;
+unsigned int gWmtDetectDbgLvl = WMT_DETECT_LOG_INFO;
+
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+inline unsigned int wmt_plat_get_soc_chipid(void)
+{
+	WMT_DETECT_INFO_FUNC("no soc chip supported, due to MTK_WCN_SOC_CHIP_SUPPORT is not set.\n");
+	return -1;
+}
+#endif
+
+static int wmt_detect_open(struct inode *inode, struct file *file)
+{
+	WMT_DETECT_INFO_FUNC("open major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid);
+
+	return 0;
+}
+
+static int wmt_detect_close(struct inode *inode, struct file *file)
+{
+	WMT_DETECT_INFO_FUNC("close major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid);
+
+	return 0;
+}
+
+static ssize_t wmt_detect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	WMT_DETECT_INFO_FUNC(" ++\n");
+	WMT_DETECT_INFO_FUNC(" --\n");
+
+	return 0;
+}
+
+ssize_t wmt_detect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+	WMT_DETECT_INFO_FUNC(" ++\n");
+	WMT_DETECT_INFO_FUNC(" --\n");
+
+	return 0;
+}
+
+static long wmt_detect_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int retval = 0;
+
+	WMT_DETECT_INFO_FUNC("cmd (%d),arg(%ld)\n", cmd, arg);
+
+	switch (cmd) {
+	case COMBO_IOCTL_GET_CHIP_ID:
+		/*just get chipid from sdio-detect module */
+		/*check if external combo chip exists or not */
+		/*if yes, just return combo chip id */
+		/*if no, get soc chipid */
+		retval = mtk_wcn_wmt_chipid_query();
+		break;
+
+	case COMBO_IOCTL_SET_CHIP_ID:
+		mtk_wcn_wmt_set_chipid(arg);
+
+		break;
+
+	case COMBO_IOCTL_EXT_CHIP_PWR_ON:
+		retval = wmt_detect_ext_chip_pwr_on();
+		break;
+
+	case COMBO_IOCTL_EXT_CHIP_DETECT:
+		retval = wmt_detect_ext_chip_detect();
+		break;
+
+	case COMBO_IOCTL_EXT_CHIP_PWR_OFF:
+		retval = wmt_detect_ext_chip_pwr_off();
+		break;
+
+	case COMBO_IOCTL_DO_SDIO_AUDOK:
+		retval = sdio_detect_do_autok(arg);
+		break;
+
+	case COMBO_IOCTL_GET_SOC_CHIP_ID:
+		retval = wmt_plat_get_soc_chipid();
+		/*get soc chipid by HAL interface */
+		break;
+
+	case COMBO_IOCTL_MODULE_CLEANUP:
+#if (MTK_WCN_REMOVE_KO)
+		/*deinit SDIO-DETECT module */
+		retval = sdio_detect_exit();
+#else
+		WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n");
+#endif
+		break;
+
+	case COMBO_IOCTL_DO_MODULE_INIT:
+#if (MTK_WCN_REMOVE_KO)
+		/*deinit SDIO-DETECT module */
+		retval = do_connectivity_driver_init(arg);
+#else
+		WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n");
+#endif
+		break;
+
+	default:
+		WMT_DETECT_WARN_FUNC("unknown cmd (%d)\n", cmd);
+		retval = 0;
+		break;
+	}
+	return retval;
+}
+#ifdef CONFIG_COMPAT
+static long WMT_compat_detect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+
+	WMT_DETECT_INFO_FUNC("cmd (%d)\n", cmd);
+	ret = wmt_detect_unlocked_ioctl(filp, cmd, arg);
+	return ret;
+}
+#endif
+const struct file_operations gWmtDetectFops = {
+	.open = wmt_detect_open,
+	.release = wmt_detect_close,
+	.read = wmt_detect_read,
+	.write = wmt_detect_write,
+	.unlocked_ioctl = wmt_detect_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = WMT_compat_detect_ioctl,
+#endif
+};
+
+int wmt_detect_ext_chip_pwr_on(void)
+{
+	/*pre power on external chip */
+	/* wmt_plat_pwr_ctrl(FUNC_ON); */
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+	WMT_DETECT_INFO_FUNC("++\n");
+	if (0 != wmt_detect_chip_pwr_ctrl(1))
+		return -1;
+	if (0 != wmt_detect_sdio_pwr_ctrl(1))
+		return -2;
+	return 0;
+#else
+	WMT_DETECT_INFO_FUNC("combo chip is not supported\n");
+	return -1;
+#endif
+}
+
+int wmt_detect_ext_chip_pwr_off(void)
+{
+	/*pre power off external chip */
+	/* wmt_plat_pwr_ctrl(FUNC_OFF); */
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+	WMT_DETECT_INFO_FUNC("--\n");
+	wmt_detect_sdio_pwr_ctrl(0);
+	return wmt_detect_chip_pwr_ctrl(0);
+#else
+	WMT_DETECT_INFO_FUNC("combo chip is not supported\n");
+	return 0;
+#endif
+}
+
+int wmt_detect_ext_chip_detect(void)
+{
+	int iRet = -1;
+	unsigned int chipId = -1;
+	/*if there is no external combo chip, return -1 */
+	int bgfEintStatus = -1;
+
+	WMT_DETECT_INFO_FUNC("++\n");
+	/*wait for a stable time */
+	msleep(20);
+
+	/*read BGF_EINT_PIN status */
+	bgfEintStatus = wmt_detect_read_ext_cmb_status();
+
+	if (0 == bgfEintStatus) {
+		/*external chip does not exist */
+		WMT_DETECT_INFO_FUNC("external combo chip not detected\n");
+	} else if (1 == bgfEintStatus) {
+		/*combo chip exists */
+		WMT_DETECT_INFO_FUNC("external combo chip detected\n");
+
+		/*detect chipid by sdio_detect module */
+		chipId = sdio_detect_query_chipid(1);
+		if (0 <= hif_sdio_is_chipid_valid(chipId))
+			WMT_DETECT_INFO_FUNC("valid external combo chip id (0x%x)\n", chipId);
+		else
+			WMT_DETECT_INFO_FUNC("invalid external combo chip id (0x%x)\n", chipId);
+		iRet = 0;
+	} else {
+		/*Error exists */
+		WMT_DETECT_ERR_FUNC("error happens when detecting combo chip\n");
+	}
+	WMT_DETECT_INFO_FUNC("--\n");
+	/*return 0 */
+	return iRet;
+	/*todo: if there is external combo chip, power on chip return 0 */
+}
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+static int wmt_detect_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	WMT_DETECT_ERR_FUNC("platform name: %s\n", pdev->name);
+	ret = wmt_gpio_init(pdev);
+	if (-1 == ret)
+		WMT_DETECT_ERR_FUNC("gpio init fail ret:%d\n", ret);
+	return ret;
+}
+
+static int wmt_detect_remove(struct platform_device *pdev)
+{
+	wmt_gpio_deinit();
+	return 0;
+}
+#endif
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+static struct of_device_id wmt_detect_match[] = {
+	{ .compatible = "mediatek,connectivity-combo", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, wmt_detect_match);
+
+static struct platform_driver wmt_detect_driver = {
+	.probe = wmt_detect_probe,
+	.remove = wmt_detect_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "mediatek,connectivity-combo",
+		.of_match_table = wmt_detect_match,
+	},
+};
+#endif
+
+/*module_platform_driver(wmt_detect_driver);*/
+static int wmt_detect_driver_init(void)
+{
+	dev_t devID = MKDEV(gWmtDetectMajor, 0);
+	int cdevErr = -1;
+	int ret = -1;
+
+	ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME);
+	if (ret) {
+		WMT_DETECT_ERR_FUNC("fail to register chrdev\n");
+		return ret;
+	}
+
+	cdev_init(&gWmtDetectCdev, &gWmtDetectFops);
+	gWmtDetectCdev.owner = THIS_MODULE;
+
+	cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM);
+	if (cdevErr) {
+		WMT_DETECT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr);
+		goto err1;
+	}
+
+	pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME);
+	if (IS_ERR(pDetectClass)) {
+		WMT_DETECT_ERR_FUNC("class create fail, error code(%ld)\n", PTR_ERR(pDetectClass));
+		goto err1;
+	}
+
+	pDetectDev = device_create(pDetectClass, NULL, devID, NULL, WMT_DETECT_DEVICE_NAME);
+	if (IS_ERR(pDetectDev)) {
+		WMT_DETECT_ERR_FUNC("device create fail, error code(%ld)\n", PTR_ERR(pDetectDev));
+		goto err2;
+	}
+
+	WMT_DETECT_INFO_FUNC("driver(major %d) installed success\n", gWmtDetectMajor);
+
+	/*init SDIO-DETECT module */
+	sdio_detect_init();
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+	ret = platform_driver_register(&wmt_detect_driver);
+	if (ret)
+		WMT_DETECT_ERR_FUNC("platform driver register fail ret:%d\n", ret);
+#endif
+
+	return 0;
+
+err2:
+
+	if (pDetectClass) {
+		class_destroy(pDetectClass);
+		pDetectClass = NULL;
+	}
+
+err1:
+
+	if (cdevErr == 0)
+		cdev_del(&gWmtDetectCdev);
+
+	if (ret == 0) {
+		unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM);
+		gWmtDetectMajor = -1;
+	}
+
+	WMT_DETECT_ERR_FUNC("fail\n");
+
+	return -1;
+}
+
+static void wmt_detect_driver_exit(void)
+{
+	dev_t dev = MKDEV(gWmtDetectMajor, 0);
+
+	if (pDetectDev) {
+		device_destroy(pDetectClass, dev);
+		pDetectDev = NULL;
+	}
+
+	if (pDetectClass) {
+		class_destroy(pDetectClass);
+		pDetectClass = NULL;
+	}
+
+	cdev_del(&gWmtDetectCdev);
+	unregister_chrdev_region(dev, WMT_DETECT_DEV_NUM);
+
+#if !(MTK_WCN_REMOVE_KO)
+/*deinit SDIO-DETECT module*/
+	sdio_detect_exit();
+#endif
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+	platform_driver_unregister(&wmt_detect_driver);
+#endif
+
+	WMT_DETECT_INFO_FUNC("done\n");
+}
+
+module_init(wmt_detect_driver_init);
+module_exit(wmt_detect_driver_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Zhiguo.Niu & Chaozhong.Liang @ MBJ/WCNSE/SS1");
+
+module_param(gWmtDetectMajor, uint, 0);
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h
new file mode 100644
index 0000000000000..7e152bfd39ec9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h
@@ -0,0 +1,114 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WMT_DETECT_H_
+#define _WMT_DETECT_H_
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE
+#define MTK_WCN_REMOVE_KO 1
+#else
+#define MTK_WCN_REMOVE_KO 0
+#endif
+
+#include "sdio_detect.h"
+#include "wmt_detect_pwr.h"
+#include <mtk_wcn_cmb_stub.h>
+
+#define WMT_DETECT_LOG_LOUD    4
+#define WMT_DETECT_LOG_DBG     3
+#define WMT_DETECT_LOG_INFO    2
+#define WMT_DETECT_LOG_WARN    1
+#define WMT_DETECT_LOG_ERR     0
+
+extern unsigned int gWmtDetectDbgLvl;
+
+#define WMT_DETECT_LOUD_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_LOUD) \
+		pr_debug(DFT_TAG"[L]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_DETECT_DBG_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_DBG) \
+		pr_debug(DFT_TAG"[D]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_DETECT_INFO_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_INFO) \
+		pr_err(DFT_TAG"[I]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_DETECT_WARN_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_WARN) \
+		pr_warn(DFT_TAG"[W]%s(%d):"  fmt, __func__ , __LINE__, ##arg); \
+} while (0)
+#define WMT_DETECT_ERR_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_ERR) \
+		pr_err(DFT_TAG"[E]%s(%d):"  fmt, __func__ , __LINE__, ##arg); \
+} while (0)
+
+#define WMT_IOC_MAGIC			'w'
+#define COMBO_IOCTL_GET_CHIP_ID		  _IOR(WMT_IOC_MAGIC, 0, int)
+#define COMBO_IOCTL_SET_CHIP_ID		  _IOW(WMT_IOC_MAGIC, 1, int)
+#define COMBO_IOCTL_EXT_CHIP_DETECT   _IOR(WMT_IOC_MAGIC, 2, int)
+#define COMBO_IOCTL_GET_SOC_CHIP_ID   _IOR(WMT_IOC_MAGIC, 3, int)
+#define COMBO_IOCTL_DO_MODULE_INIT    _IOR(WMT_IOC_MAGIC, 4, int)
+#define COMBO_IOCTL_MODULE_CLEANUP    _IOR(WMT_IOC_MAGIC, 5, int)
+#define COMBO_IOCTL_EXT_CHIP_PWR_ON   _IOR(WMT_IOC_MAGIC, 6, int)
+#define COMBO_IOCTL_EXT_CHIP_PWR_OFF  _IOR(WMT_IOC_MAGIC, 7, int)
+#define COMBO_IOCTL_DO_SDIO_AUDOK     _IOR(WMT_IOC_MAGIC, 8, int)
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************/
+extern int wmt_detect_ext_chip_detect(void);
+extern int wmt_detect_ext_chip_pwr_on(void);
+extern int wmt_detect_ext_chip_pwr_off(void);
+
+#ifdef MTK_WCN_SOC_CHIP_SUPPORT
+extern unsigned int wmt_plat_get_soc_chipid(void);
+#endif
+
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver
+ *
+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2"
+ * @ enable - "1", enable deep idle; "0", disable deep idle
+ *
+ * Return 0 if success, else -1
+ */
+extern unsigned int mtk_uart_pdn_enable(char *port, int enable);
+#endif
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c
new file mode 100644
index 0000000000000..1dcb7ed358bcf
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c
@@ -0,0 +1,232 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <mtk_rtc.h>
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-DETECT]"
+
+#include "wmt_detect.h"
+#include "wmt_gpio.h"
+
+#define INVALID_PIN_ID (0xFFFFFFFF)
+
+/*copied form WMT module*/
+static int wmt_detect_dump_pin_conf(void)
+{
+	WMT_DETECT_DBG_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n");
+
+	WMT_DETECT_INFO_FUNC("LDO(GPIO%d), PMU(GPIO%d), PMUV28(GPIO%d)\n",
+			gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num,
+			gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num,
+			gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num);
+
+	WMT_DETECT_INFO_FUNC("RST(GPIO%d), BGF_EINT(GPIO%d), BGF_EINT_NUM(%d)\n",
+			gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num,
+			gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num,
+			gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num));
+
+	WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d), WIFI_EINT_NUM(%d)\n",
+			gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num,
+			gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num));
+
+	WMT_DETECT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration ends<=\n");
+
+	return 0;
+}
+
+int _wmt_detect_output_low(unsigned int id)
+{
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
+		gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0);
+		WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n",
+				gpio_ctrl_info.gpio_ctrl_state[id].gpio_num,
+				gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num));
+	}
+
+	return 0;
+}
+
+int _wmt_detect_output_high(unsigned int id)
+{
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
+		gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1);
+		WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n",
+				gpio_ctrl_info.gpio_ctrl_state[id].gpio_num,
+				gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num));
+	}
+
+	return 0;
+}
+
+int _wmt_detect_read_gpio_input(unsigned int id)
+{
+	int retval = 0;
+
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
+		retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num);
+		WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n",
+				gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval);
+	}
+
+	return retval;
+}
+
+/*This power on sequence must support all combo chip's basic power on sequence
+ * 1. LDO control is a must, if external LDO exist
+ * 2. PMU control is a must
+ * 3. RST control is a must
+ * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup
+ * 5. RTC32k clock control is a must
+ * */
+static int wmt_detect_chip_pwr_on(void)
+{
+	int retval = -1;
+	/*setting validiation check*/
+	if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) ||
+		(INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) ||
+		(INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) {
+		WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n",
+				gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num,
+				gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num,
+				gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num);
+
+		return retval;
+	}
+	/*set LDO/PMU/RST to output 0, no pull*/
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
+		_wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN);
+	if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) {
+		pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+				gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]);
+		WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n");
+	} else
+		WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+	_wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN);
+	if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) {
+		pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+				gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]);
+		WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n");
+	} else
+		WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+	_wmt_detect_output_low(GPIO_COMBO_RST_PIN);
+
+#if 0
+	_wmt_detect_output_high(GPIO_WIFI_EINT_PIN);
+#endif
+
+	/*pull high LDO*/
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
+		_wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN);
+	/*sleep for LDO stable time*/
+	msleep(MAX_LDO_STABLE_TIME);
+
+	/*export RTC clock, sleep for RTC stable time*/
+	rtc_gpio_enable_32k(RTC_GPIO_USER_GPS);
+	msleep(MAX_RTC_STABLE_TIME);
+	/*PMU output low, RST output low, to make chip power off completely*/
+	/*always done*/
+	/*sleep for power off stable time*/
+	msleep(MAX_OFF_STABLE_TIME);
+	/*PMU output high, and sleep for reset stable time*/
+	_wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN);
+#ifdef CONFIG_MTK_COMBO_COMM_NPWR
+	if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) &&
+		(gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) {
+		msleep(20);
+		_wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN);
+
+		msleep(20);
+		_wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN);
+
+		msleep(20);
+		_wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN);
+
+		msleep(20);
+		_wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN);
+
+		msleep(20);
+	}
+#endif
+	msleep(MAX_RST_STABLE_TIME);
+	/*RST output high, and sleep for power on stable time */
+	_wmt_detect_output_high(GPIO_COMBO_RST_PIN);
+	msleep(MAX_ON_STABLE_TIME);
+
+	retval = 0;
+	return retval;
+}
+
+static int wmt_detect_chip_pwr_off(void)
+{
+
+	/*set RST pin to input low status*/
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
+		_wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN);
+	/*set RST pin to input low status*/
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)
+		_wmt_detect_output_low(GPIO_COMBO_RST_PIN);
+	/*set PMU pin to input low status*/
+	if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)
+		_wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN);
+	return 0;
+}
+
+int wmt_detect_read_ext_cmb_status(void)
+{
+	int retval = 0;
+	/*read WIFI_EINT pin status*/
+	if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) {
+		retval = 0;
+		WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n");
+	} else {
+		retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN);
+		WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval);
+	}
+	return retval;
+}
+
+int wmt_detect_chip_pwr_ctrl(int on)
+{
+	int retval = -1;
+
+	if (0 == on) {
+		/*power off combo chip */
+		retval = wmt_detect_chip_pwr_off();
+	} else {
+		wmt_detect_dump_pin_conf();
+		/*power on combo chip */
+		retval = wmt_detect_chip_pwr_on();
+	}
+	return retval;
+}
+
+int wmt_detect_sdio_pwr_ctrl(int on)
+{
+	int retval = -1;
+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT
+	if (0 == on) {
+		/*power off SDIO slot */
+		retval = board_sdio_ctrl(1, 0);
+	} else {
+		/*power on SDIO slot */
+		retval = board_sdio_ctrl(1, 1);
+	}
+#else
+	WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n");
+#endif
+	return retval;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h
new file mode 100644
index 0000000000000..32e661520fd0d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __WMT_DETECT_PWR_H_
+#define __WMT_DETECT_PWR_H_
+
+#define MAX_RTC_STABLE_TIME 100
+#define MAX_LDO_STABLE_TIME 100
+#define MAX_RST_STABLE_TIME 30
+#define MAX_OFF_STABLE_TIME 10
+#define MAX_ON_STABLE_TIME 30
+
+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on);
+extern int wmt_detect_chip_pwr_ctrl(int on);
+extern int wmt_detect_sdio_pwr_ctrl(int on);
+extern int wmt_detect_read_ext_cmb_status(void);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c
new file mode 100644
index 0000000000000..3a79e1e9d15a9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c
@@ -0,0 +1,371 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "wmt_gpio.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX] = {{"gpio_ldo_en_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"gpio_ldo_en_in_pulldown",
+		""},
+	{"gpio_pmuv28_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"gpio_pmuv28_in_pulldown",
+		""},
+	{"gpio_pmu_en_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"gpio_pmu_en_in_pulldown",
+		""},
+	{"gpio_rst_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"gpio_bgf_eint_in_pulldown",
+		"gpio_bgf_eint_in_pullup"},
+	{"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"gpio_wifi_eint_in_pull_dis",
+		"",
+		"gpio_wifi_eint_in_pullup"},
+	{"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"gpio_all_eint_in_pulldown",
+		"gpio_all_eint_in_pullup"},
+	{"gpio_urxd_uart_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"gpio_urxd_gpio_in_pull_dis",
+		"",
+		"gpio_urxd_gpio_in_pullup"},
+	{"gpio_utxd_uart_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_pcm_daiclk_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_pcm_daipcmin_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_pcm_daipcmout_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_pcm_daisync_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_i2s_ck_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_i2s_ws_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_i2s_dat_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_gps_sync_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""},
+	{"gpio_gps_lna_pull_dis",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		""}
+};
+
+const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX] = {"gpio_combo_ldo_en_pin",
+					"gpio_combo_pmuv28_en_pin",
+					"gpio_combo_pmu_en_pin",
+					"gpio_combo_rst_pin",
+					"gpio_combo_bgf_eint_pin",
+					"gpio_wifi_eint_pin",
+					"gpio_all_eint_pin",
+					"gpio_combo_urxd_pin",
+					"gpio_combo_utxd_pin",
+					"gpio_pcm_daiclk_pin",
+					"gpio_pcm_daipcmin_pin",
+					"gpio_pcm_daipcmout_pin",
+					"gpio_pcm_daisync_pin",
+					"gpio_combo_i2s_ck_pin",
+					"gpio_combo_i2s_ws_pin",
+					"gpio_combo_i2s_dat_pin",
+					"gpio_gps_sync_pin",
+					"gpio_gps_lna_pin"};
+
+GPIO_CTRL_INFO gpio_ctrl_info;
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+INT32 wmt_gpio_init(struct platform_device *pdev)
+{
+	INT32 iret = 0;
+	UINT32 i, j;
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo");
+	if (!node) {
+		for (i = 0; i < GPIO_PIN_ID_MAX; i++)
+			gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID;
+		pr_err("wmt_gpio:can't find device tree node!\n");
+		iret = -1;
+		goto err;
+	}
+
+	gpio_ctrl_info.pinctrl_info = devm_pinctrl_get(&pdev->dev);
+	if (gpio_ctrl_info.pinctrl_info) {
+		for (i = 0; i < GPIO_PIN_ID_MAX; i++) {
+			gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = of_get_named_gpio(node,
+					gpio_pin_name[i], 0);
+			if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num < 0)
+				gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID;
+			if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) {
+				for (j = 0; j < GPIO_STATE_MAX; j++) {
+					if (0 != strlen(gpio_state_name[i][j])) {
+						gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] =
+							pinctrl_lookup_state(gpio_ctrl_info.pinctrl_info,
+									gpio_state_name[i][j]);
+					} else
+						gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL;
+				}
+			}
+		}
+
+		pr_err("wmt_gpio: gpio init start!\n");
+
+		if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) {
+			pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+					gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].
+					gpio_state[GPIO_PULL_DIS]);
+			pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n");
+		} else
+			pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+
+		if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) {
+			gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num,
+					0);
+			pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN out to 0: %d!\n",
+					gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num));
+		}
+
+		if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) {
+			pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+					gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]);
+			pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n");
+		} else
+			pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+
+		if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) {
+			gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num,
+					0);
+			pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN out to 0: %d!\n",
+					gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num));
+		}
+
+		if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]) {
+			pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+					gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]);
+			pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP done!\n");
+		} else
+			pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP fail, is NULL!\n");
+
+		if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]) {
+			pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+					gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]);
+			pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS done!\n");
+		} else
+			pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+
+		if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]) {
+			pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+					gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].
+					gpio_state[GPIO_PULL_DIS]);
+			pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS done!\n");
+		} else
+			pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+
+		if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]) {
+			pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+					gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].
+					gpio_state[GPIO_PULL_DIS]);
+			pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS done!\n");
+		} else
+			pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+
+		if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]) {
+			pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
+					gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].
+					gpio_state[GPIO_PULL_DIS]);
+			pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS done!\n");
+		} else
+			pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS fail, is NULL!\n");
+
+		pr_err("wmt_gpio: gpio init done!\n");
+	} else {
+		pr_err("wmt_gpio:can't find pinctrl dev!\n");
+		iret = -1;
+	}
+err:
+	return iret;
+}
+
+INT32 wmt_gpio_deinit(VOID)
+{
+	INT32 iret = 0;
+	UINT32 i;
+	UINT32 j;
+
+	for (i = 0; i < GPIO_PIN_ID_MAX; i++) {
+		gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID;
+		if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) {
+			for (j = 0; j < GPIO_STATE_MAX; j++) {
+				if (0 != strlen(gpio_state_name[i][j]))
+					gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL;
+			}
+		}
+	}
+	if (gpio_ctrl_info.pinctrl_info) {
+		devm_pinctrl_put(gpio_ctrl_info.pinctrl_info);
+		gpio_ctrl_info.pinctrl_info = NULL;
+	}
+
+	return iret;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h
new file mode 100644
index 0000000000000..cd935bfddd994
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h
@@ -0,0 +1,103 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WMT_GPIO_H_
+#define _WMT_GPIO_H_
+
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include "osal.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define DEFAULT_PIN_ID (0xffffffff)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_GPIO_PIN_ID {
+	GPIO_COMBO_LDO_EN_PIN = 0,
+	GPIO_COMBO_PMUV28_EN_PIN,
+	GPIO_COMBO_PMU_EN_PIN,
+	GPIO_COMBO_RST_PIN,
+	GPIO_COMBO_BGF_EINT_PIN,
+	GPIO_WIFI_EINT_PIN,
+	GPIO_COMBO_ALL_EINT_PIN,
+	GPIO_COMBO_URXD_PIN,
+	GPIO_COMBO_UTXD_PIN,
+	GPIO_PCM_DAICLK_PIN,
+	GPIO_PCM_DAIPCMIN_PIN,
+	GPIO_PCM_DAIPCMOUT_PIN,
+	GPIO_PCM_DAISYNC_PIN,
+	GPIO_COMBO_I2S_CK_PIN,
+	GPIO_COMBO_I2S_WS_PIN,
+	GPIO_COMBO_I2S_DAT_PIN,
+	GPIO_GPS_SYNC_PIN,
+	GPIO_GPS_LNA_PIN,
+	GPIO_PIN_ID_MAX
+} ENUM_GPIO_PIN_ID, *P_ENUM_GPIO_PIN_ID;
+
+typedef enum _ENUM_GPIO_STATE_ID {
+	GPIO_PULL_DIS = 0,
+	GPIO_PULL_DOWN,
+	GPIO_PULL_UP,
+	GPIO_OUT_LOW,
+	GPIO_OUT_HIGH,
+	GPIO_IN_DIS,
+	GPIO_IN_EN,
+	GPIO_IN_PULL_DIS,
+	GPIO_IN_PULLDOWN,
+	GPIO_IN_PULLUP,
+	GPIO_STATE_MAX,
+} ENUM_GPIO_STATE_ID, *P_ENUM_GPIO_STATE_ID;
+
+typedef struct _GPIO_CTRL_STATE {
+	INT32 gpio_num;
+	struct pinctrl_state *gpio_state[GPIO_STATE_MAX];
+} GPIO_CTRL_STATE, *P_GPIO_CTRL_STATE;
+
+typedef struct _GPIO_CTRL_INFO {
+	struct pinctrl *pinctrl_info;
+	GPIO_CTRL_STATE gpio_ctrl_state[GPIO_PIN_ID_MAX];
+} GPIO_CTRL_INFO, *P_GPIO_CTRL_INFO;
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+extern const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX];
+extern const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX];
+extern GPIO_CTRL_INFO gpio_ctrl_info;
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+INT32 wmt_gpio_init(struct platform_device *pdev);
+
+INT32 wmt_gpio_deinit(VOID);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c
new file mode 100644
index 0000000000000..4fc3144b3ba6c
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c
@@ -0,0 +1,480 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "osal_typedef.h"
+#include "wmt_stp_exp.h"
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-STP-EXP]"
+
+#define WMT_STP_EXP_INFO_FUNC(fmt, arg...)   pr_debug(DFT_TAG "[I]%s: "  fmt, __func__ , ##arg)
+#define WMT_STP_EXP_WARN_FUNC(fmt, arg...)   pr_warn(DFT_TAG "[W]%s: "  fmt, __func__ , ##arg)
+#define WMT_STP_EXP_ERR_FUNC(fmt, arg...)    pr_err(DFT_TAG "[E]%s(%d):ERROR! "   fmt, __func__ , __LINE__, ##arg)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+/*STP exp*/
+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_f = NULL;
+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_raw_f = NULL;
+MTK_WCN_STP_PARSER_DATA mtk_wcn_stp_parser_data_f = NULL;
+MTK_WCN_STP_RECV_DATA mtk_wcn_stp_receive_data_f = NULL;
+MTK_WCN_STP_IS_RXQ_EMPTY mtk_wcn_stp_is_rxqueue_empty_f = NULL;
+MTK_WCN_STP_IS_RDY mtk_wcn_stp_is_ready_f = NULL;
+MTK_WCN_STP_SET_BLUEZ mtk_wcn_stp_set_bluez_f = NULL;
+MTK_WCN_STP_REG_IF_TX mtk_wcn_stp_if_tx_f = NULL;
+MTK_WCN_STP_REG_IF_RX mtk_wcn_stp_if_rx_f = NULL;
+MTK_WCN_STP_REG_EVENT_CB mtk_wcn_stp_reg_event_cb_f = NULL;
+MTK_WCN_STP_RGE_TX_EVENT_CB mtk_wcn_stp_reg_tx_event_cb_f = NULL;
+MTK_WCN_STP_COREDUMP_START_GET mtk_wcn_stp_coredump_start_get_f = NULL;
+
+/*WMT exp*/
+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_on_f = NULL;
+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_off_f = NULL;
+MTK_WCN_WMT_THERM_CTRL mtk_wcn_wmt_therm_ctrl_f = NULL;
+MTK_WCN_WMT_HWVER_GET mtk_wcn_wmt_hwver_get_f = NULL;
+MTK_WCN_WMT_DSNS_CTRL mtk_wcn_wmt_dsns_ctrl_f = NULL;
+MTK_WCN_WMT_MSGCB_REG mtk_wcn_wmt_msgcb_reg_f = NULL;
+MTK_WCN_WMT_MSGCB_UNREG mtk_wcn_wmt_msgcb_unreg_f = NULL;
+MTK_WCN_WMT_SDIO_OP_REG mtk_wcn_wmt_sdio_op_reg_f = NULL;
+MTK_WCN_WMT_SDIO_HOST_AWAKE mtk_wcn_wmt_sdio_host_awake_f = NULL;
+MTK_WCN_WMT_ASSERT mtk_wcn_wmt_assert_f = NULL;
+MTK_WCN_WMT_ASSERT_TIMEOUT mtk_wcn_wmt_assert_timeout_f = NULL;
+MTK_WCN_WMT_IC_INFO_GET mtk_wcn_wmt_ic_info_get_f = NULL;
+MTK_WCN_WMT_PSM_CTRL mtk_wcn_wmt_psm_ctrl_f = NULL;
+
+/*******************************************************************************
+*                          F U N C T I O N S
+********************************************************************************
+*/
+
+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb)
+{
+	WMT_STP_EXP_INFO_FUNC("call stp exp cb reg\n");
+
+	mtk_wcn_stp_send_data_f = pStpExpCb->stp_send_data_cb;
+	mtk_wcn_stp_send_data_raw_f = pStpExpCb->stp_send_data_raw_cb;
+	mtk_wcn_stp_parser_data_f = pStpExpCb->stp_parser_data_cb;
+	mtk_wcn_stp_receive_data_f = pStpExpCb->stp_receive_data_cb;
+	mtk_wcn_stp_is_rxqueue_empty_f = pStpExpCb->stp_is_rxqueue_empty_cb;
+	mtk_wcn_stp_is_ready_f = pStpExpCb->stp_is_ready_cb;
+	mtk_wcn_stp_set_bluez_f = pStpExpCb->stp_set_bluez_cb;
+	mtk_wcn_stp_if_tx_f = pStpExpCb->stp_if_tx_cb;
+	mtk_wcn_stp_if_rx_f = pStpExpCb->stp_if_rx_cb;
+	mtk_wcn_stp_reg_event_cb_f = pStpExpCb->stp_reg_event_cb;
+	mtk_wcn_stp_reg_tx_event_cb_f = pStpExpCb->stp_reg_tx_event_cb;
+	mtk_wcn_stp_coredump_start_get_f = pStpExpCb->stp_coredump_start_get_cb;
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_reg);
+
+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID)
+{
+	WMT_STP_EXP_INFO_FUNC("call stp exp cb unreg\n");
+
+	mtk_wcn_stp_send_data_f = NULL;
+	mtk_wcn_stp_send_data_raw_f = NULL;
+	mtk_wcn_stp_parser_data_f = NULL;
+	mtk_wcn_stp_receive_data_f = NULL;
+	mtk_wcn_stp_is_rxqueue_empty_f = NULL;
+	mtk_wcn_stp_is_ready_f = NULL;
+	mtk_wcn_stp_set_bluez_f = NULL;
+	mtk_wcn_stp_if_tx_f = NULL;
+	mtk_wcn_stp_if_rx_f = NULL;
+	mtk_wcn_stp_reg_event_cb_f = NULL;
+	mtk_wcn_stp_reg_tx_event_cb_f = NULL;
+	mtk_wcn_stp_coredump_start_get_f = NULL;
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_unreg);
+
+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_send_data_f) {
+		ret = (*mtk_wcn_stp_send_data_f) (buffer, length, type);
+		/* WMT_STP_EXP_INFO_FUNC("mtk_wcn_stp_send_data_f send data(%d)\n",ret); */
+	} else {
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_f cb is null\n");
+	}
+
+	return ret;
+
+}
+EXPORT_SYMBOL(mtk_wcn_stp_send_data);
+
+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_send_data_raw_f)
+		ret = (*mtk_wcn_stp_send_data_raw_f) (buffer, length, type);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_raw_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw);
+
+INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_parser_data_f)
+		ret = (*mtk_wcn_stp_parser_data_f) (buffer, length);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_parser_data_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_parser_data);
+
+INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_receive_data_f)
+		ret = (*mtk_wcn_stp_receive_data_f) (buffer, length, type);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_receive_data_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_receive_data);
+
+MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type)
+{
+	MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_wcn_stp_is_rxqueue_empty_f)
+		ret = (*mtk_wcn_stp_is_rxqueue_empty_f) (type);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_rxqueue_empty_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty);
+
+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void)
+{
+	MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_wcn_stp_is_ready_f)
+		ret = (*mtk_wcn_stp_is_ready_f) ();
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_ready_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_is_ready);
+
+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags)
+{
+
+	if (mtk_wcn_stp_set_bluez_f)
+		(*mtk_wcn_stp_set_bluez_f) (flags);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_set_bluez_f cb is null\n");
+
+}
+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez);
+
+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_if_tx_f)
+		ret = (*mtk_wcn_stp_if_tx_f) (stp_if, func);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_tx_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx);
+
+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_if_rx_f)
+		ret = (*mtk_wcn_stp_if_rx_f) (func);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_rx_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx);
+
+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_reg_event_cb_f)
+		ret = (*mtk_wcn_stp_reg_event_cb_f) (type, func);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_event_cb_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb);
+
+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_reg_tx_event_cb_f)
+		ret = (*mtk_wcn_stp_reg_tx_event_cb_f) (type, func);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_tx_event_cb_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb);
+
+INT32 mtk_wcn_stp_coredump_start_get(VOID)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_coredump_start_get_f)
+		ret = (*mtk_wcn_stp_coredump_start_get_f) ();
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_coredump_start_get_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_coredump_start_get);
+
+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb)
+{
+	WMT_STP_EXP_INFO_FUNC("call wmt exp cb reg\n");
+
+	mtk_wcn_wmt_func_on_f = pWmtExpCb->wmt_func_on_cb;
+	mtk_wcn_wmt_func_off_f = pWmtExpCb->wmt_func_off_cb;
+	mtk_wcn_wmt_therm_ctrl_f = pWmtExpCb->wmt_therm_ctrl_cb;
+	mtk_wcn_wmt_hwver_get_f = pWmtExpCb->wmt_hwver_get_cb;
+	mtk_wcn_wmt_dsns_ctrl_f = pWmtExpCb->wmt_dsns_ctrl_cb;
+	mtk_wcn_wmt_msgcb_reg_f = pWmtExpCb->wmt_msgcb_reg_cb;
+	mtk_wcn_wmt_msgcb_unreg_f = pWmtExpCb->wmt_msgcb_unreg_cb;
+	mtk_wcn_wmt_sdio_op_reg_f = pWmtExpCb->wmt_sdio_op_reg_cb;
+	mtk_wcn_wmt_sdio_host_awake_f = pWmtExpCb->wmt_sdio_host_awake_cb;
+	mtk_wcn_wmt_assert_f = pWmtExpCb->wmt_assert_cb;
+	mtk_wcn_wmt_assert_timeout_f = pWmtExpCb->wmt_assert_timeout_cb;
+	mtk_wcn_wmt_ic_info_get_f = pWmtExpCb->wmt_ic_info_get_cb;
+	mtk_wcn_wmt_psm_ctrl_f = pWmtExpCb->wmt_psm_ctrl_cb;
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_reg);
+
+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID)
+{
+	WMT_STP_EXP_INFO_FUNC("call wmt exp cb unreg\n");
+
+	mtk_wcn_wmt_func_on_f = NULL;
+	mtk_wcn_wmt_func_off_f = NULL;
+	mtk_wcn_wmt_therm_ctrl_f = NULL;
+	mtk_wcn_wmt_hwver_get_f = NULL;
+	mtk_wcn_wmt_dsns_ctrl_f = NULL;
+	mtk_wcn_wmt_msgcb_reg_f = NULL;
+	mtk_wcn_wmt_msgcb_unreg_f = NULL;
+	mtk_wcn_wmt_sdio_op_reg_f = NULL;
+	mtk_wcn_wmt_sdio_host_awake_f = NULL;
+	mtk_wcn_wmt_assert_f = NULL;
+	mtk_wcn_wmt_assert_timeout_f = NULL;
+	mtk_wcn_wmt_ic_info_get_f = NULL;
+	mtk_wcn_wmt_psm_ctrl_f = NULL;
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_unreg);
+
+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type)
+{
+	MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_wcn_wmt_func_off_f)
+		ret = (*mtk_wcn_wmt_func_off_f) (type);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_off_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_func_off);
+
+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type)
+{
+	MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_wcn_wmt_func_on_f) {
+		ret = (*mtk_wcn_wmt_func_on_f) (type);
+		WMT_STP_EXP_INFO_FUNC("mtk_wcn_wmt_func_on_f type(%d)\n", type);
+	} else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_on_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_func_on);
+
+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_wmt_therm_ctrl_f)
+		ret = (*mtk_wcn_wmt_therm_ctrl_f) (eType);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_therm_ctrl_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl);
+
+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID)
+{
+	ENUM_WMTHWVER_TYPE_T ret = WMTHWVER_INVALID;
+
+	if (mtk_wcn_wmt_hwver_get_f)
+		ret = (*mtk_wcn_wmt_hwver_get_f) ();
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_hwver_get_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get);
+
+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType)
+{
+	MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_wcn_wmt_dsns_ctrl_f)
+		ret = (*mtk_wcn_wmt_dsns_ctrl_f) (eType);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_dsns_ctrl_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl);
+
+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb)
+{
+	INT32 ret = 0;
+
+	if (mtk_wcn_wmt_msgcb_reg_f)
+		ret = (*mtk_wcn_wmt_msgcb_reg_f) (eType, pCb);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_reg_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg);
+
+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType)
+{
+	INT32 ret = 0;
+
+	if (mtk_wcn_wmt_msgcb_unreg_f)
+		ret = (*mtk_wcn_wmt_msgcb_unreg_f) (eType);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_unreg_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg);
+
+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_wmt_sdio_op_reg_f)
+		ret = (*mtk_wcn_wmt_sdio_op_reg_f) (own_cb);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_op_reg_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg);
+
+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_wmt_sdio_host_awake_f)
+		ret = (*mtk_wcn_wmt_sdio_host_awake_f) ();
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_host_awake_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake);
+
+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason)
+{
+	MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_wcn_wmt_assert_f)
+		ret = (*mtk_wcn_wmt_assert_f) (type, reason);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_assert);
+
+MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout)
+{
+	MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_wcn_wmt_assert_timeout_f)
+		ret = (*mtk_wcn_wmt_assert_timeout_f)(type, reason, timeout);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_timeout_f cb is null\n");
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_assert_timeout);
+
+UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type)
+{
+	UINT32 ret = 0;
+
+	if (mtk_wcn_wmt_ic_info_get_f)
+		ret = (*mtk_wcn_wmt_ic_info_get_f) (type);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_ic_info_get_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_ic_info_get);
+
+INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag)
+{
+	UINT32 ret = 0;
+
+	if (mtk_wcn_wmt_psm_ctrl_f)
+		ret = (*mtk_wcn_wmt_psm_ctrl_f)(flag);
+	else
+		WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_psm_ctrl_f cb is null\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_psm_ctrl);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h
new file mode 100644
index 0000000000000..1c3dc89652981
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h
@@ -0,0 +1,610 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WMT_STP_EXP_H_
+#define _WMT_STP_EXP_H_
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/workqueue.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/kthread.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <mtk_wcn_cmb_stub.h>
+#include "osal_typedef.h"
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0
+#endif
+
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+
+#if (WMT_IDC_SUPPORT)
+#define CFG_WMT_LTE_COEX_HANDLING 1
+#define CFG_WMT_LTE_ENABLE_MSGID_MAPPING 0
+#else
+#define CFG_WMT_LTE_COEX_HANDLING 0
+#endif
+
+/*from stp_exp.h*/
+#define BT_TASK_INDX        (0)
+#define FM_TASK_INDX        (1)
+#define GPS_TASK_INDX       (2)
+#define WIFI_TASK_INDX      (3)
+#define WMT_TASK_INDX       (4)
+#define STP_TASK_INDX       (5)
+#define INFO_TASK_INDX      (6)
+#define ANT_TASK_INDX       (7)
+#if CFG_WMT_LTE_COEX_HANDLING
+#define COEX_TASK_INDX		(8)
+#define MTKSTP_MAX_TASK_NUM (9)
+#else
+#define MTKSTP_MAX_TASK_NUM	(8)
+#endif
+
+#define MTKSTP_BUFFER_SIZE  (16384)	/* Size of RX Queue */
+/*end from stp_exp.h*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************/
+
+/*moved from stp_exp.h*/
+typedef void (*MTK_WCN_STP_EVENT_CB) (void);
+typedef INT32(*MTK_WCN_STP_IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size);
+/* export for HIF driver */
+typedef void (*MTK_WCN_STP_IF_RX) (const PUINT8 data, INT32 size);
+
+typedef enum {
+	STP_UART_IF_TX = 0,
+	STP_SDIO_IF_TX = 1,
+	STP_BTIF_IF_TX = 2,
+	STP_MAX_IF_TX
+} ENUM_STP_TX_IF_TYPE;
+
+/*end moved from stp_exp.h*/
+
+typedef INT32(*MTK_WCN_STP_SEND_DATA) (const PUINT8 buffer, const UINT32 length, const UINT8 type);
+typedef INT32(*MTK_WCN_STP_PARSER_DATA) (PUINT8 buffer, UINT32 length);
+typedef INT32(*MTK_WCN_STP_RECV_DATA) (PUINT8 buffer, UINT32 length, UINT8 type);
+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RXQ_EMPTY) (UINT8 type);
+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RDY) (VOID);
+typedef VOID(*MTK_WCN_STP_SET_BLUEZ) (MTK_WCN_BOOL flags);
+typedef INT32(*MTK_WCN_STP_REG_IF_TX) (ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func);
+typedef INT32(*MTK_WCN_STP_REG_IF_RX) (MTK_WCN_STP_IF_RX func);
+typedef INT32(*MTK_WCN_STP_REG_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func);
+typedef INT32(*MTK_WCN_STP_RGE_TX_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func);
+typedef INT32(*MTK_WCN_STP_COREDUMP_START_GET)(VOID);
+
+typedef struct _MTK_WCN_STP_EXP_CB_INFO_ {
+	MTK_WCN_STP_SEND_DATA stp_send_data_cb;
+	MTK_WCN_STP_SEND_DATA stp_send_data_raw_cb;
+	MTK_WCN_STP_PARSER_DATA stp_parser_data_cb;
+	MTK_WCN_STP_RECV_DATA stp_receive_data_cb;
+	MTK_WCN_STP_IS_RXQ_EMPTY stp_is_rxqueue_empty_cb;
+	MTK_WCN_STP_IS_RDY stp_is_ready_cb;
+	MTK_WCN_STP_SET_BLUEZ stp_set_bluez_cb;
+	MTK_WCN_STP_REG_IF_TX stp_if_tx_cb;
+	MTK_WCN_STP_REG_IF_RX stp_if_rx_cb;
+	MTK_WCN_STP_REG_EVENT_CB stp_reg_event_cb;
+	MTK_WCN_STP_RGE_TX_EVENT_CB stp_reg_tx_event_cb;
+	MTK_WCN_STP_COREDUMP_START_GET stp_coredump_start_get_cb;
+} MTK_WCN_STP_EXP_CB_INFO, *P_MTK_WCN_STP_EXP_CB_INFO;
+
+/*moved from wmt_exp.h*/
+
+typedef enum _ENUM_WMTDRV_TYPE_T {
+	WMTDRV_TYPE_BT = 0,
+	WMTDRV_TYPE_FM = 1,
+	WMTDRV_TYPE_GPS = 2,
+	WMTDRV_TYPE_WIFI = 3,
+	WMTDRV_TYPE_WMT = 4,
+	WMTDRV_TYPE_ANT = 5,
+	WMTDRV_TYPE_STP = 6,
+	WMTDRV_TYPE_SDIO1 = 7,
+	WMTDRV_TYPE_SDIO2 = 8,
+	WMTDRV_TYPE_LPBK = 9,
+	WMTDRV_TYPE_COREDUMP = 10,
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+	WMTDRV_TYPE_AUTOK = 11,
+#endif
+	WMTDRV_TYPE_MAX
+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T;
+
+typedef enum _ENUM_WMTDSNS_TYPE_T {
+	WMTDSNS_FM_DISABLE = 0,
+	WMTDSNS_FM_ENABLE = 1,
+	WMTDSNS_FM_GPS_DISABLE = 2,
+	WMTDSNS_FM_GPS_ENABLE = 3,
+	WMTDSNS_MAX
+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T;
+
+typedef enum _ENUM_WMTHWVER_TYPE_T {
+	WMTHWVER_E1 = 0x0,
+	WMTHWVER_E2 = 0x1,
+	WMTHWVER_E3 = 0x2,
+	WMTHWVER_E4 = 0x3,
+	WMTHWVER_E5 = 0x4,
+	WMTHWVER_E6 = 0x5,
+	WMTHWVER_E7 = 0x6,
+	WMTHWVER_MAX,
+	WMTHWVER_INVALID = 0xff
+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T;
+
+typedef enum _ENUM_WMTTHERM_TYPE_T {
+	WMTTHERM_ZERO = 0,
+	WMTTHERM_ENABLE = WMTTHERM_ZERO + 1,
+	WMTTHERM_READ = WMTTHERM_ENABLE + 1,
+	WMTTHERM_DISABLE = WMTTHERM_READ + 1,
+	WMTTHERM_MAX
+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T;
+
+typedef enum _ENUM_WMTMSG_TYPE_T {
+	WMTMSG_TYPE_POWER_ON = 0,
+	WMTMSG_TYPE_POWER_OFF = 1,
+	WMTMSG_TYPE_RESET = 2,
+	WMTMSG_TYPE_STP_RDY = 3,
+	WMTMSG_TYPE_HW_FUNC_ON = 4,
+	WMTMSG_TYPE_MAX
+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T;
+
+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T,	/* Source driver type */
+			   ENUM_WMTDRV_TYPE_T,	/* Destination driver type */
+			   ENUM_WMTMSG_TYPE_T,	/* Message type */
+			   VOID *,	/* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client
+					   can't touch this buffer after this function return. */
+			   UINT32	/* Buffer size in unit of byte */
+);
+
+typedef enum _SDIO_PS_OP {
+	OWN_SET = 0,
+	OWN_CLR = 1,
+	OWN_STATE = 2,
+} SDIO_PS_OP;
+
+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP);
+
+typedef enum _ENUM_WMTCHIN_TYPE_T {
+	WMTCHIN_CHIPID = 0x0,
+	WMTCHIN_HWVER = WMTCHIN_CHIPID + 1,
+	WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1,
+	WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1,
+	WMTCHIN_MAX,
+
+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T;
+
+/*end moved from wmt_exp.h*/
+
+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_FUNC_CTRL) (ENUM_WMTDRV_TYPE_T type);
+typedef INT8(*MTK_WCN_WMT_THERM_CTRL) (ENUM_WMTTHERM_TYPE_T eType);
+typedef ENUM_WMTHWVER_TYPE_T(*MTK_WCN_WMT_HWVER_GET) (VOID);
+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_DSNS_CTRL) (ENUM_WMTDSNS_TYPE_T eType);
+typedef INT32(*MTK_WCN_WMT_MSGCB_REG) (ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb);
+typedef INT32(*MTK_WCN_WMT_MSGCB_UNREG) (ENUM_WMTDRV_TYPE_T eType);
+typedef INT32(*MTK_WCN_WMT_SDIO_OP_REG) (PF_WMT_SDIO_PSOP own_cb);
+typedef INT32(*MTK_WCN_WMT_SDIO_HOST_AWAKE) (VOID);
+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT) (ENUM_WMTDRV_TYPE_T type, UINT32 reason);
+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT_TIMEOUT)(ENUM_WMTDRV_TYPE_T type,
+		UINT32 reason, INT32 timeout);
+typedef UINT32(*MTK_WCN_WMT_IC_INFO_GET) (ENUM_WMT_CHIPINFO_TYPE_T type);
+typedef INT32 (*MTK_WCN_WMT_PSM_CTRL)(MTK_WCN_BOOL flag);
+
+typedef struct _MTK_WCN_WMT_EXP_CB_INFO_ {
+	MTK_WCN_WMT_FUNC_CTRL wmt_func_on_cb;
+	MTK_WCN_WMT_FUNC_CTRL wmt_func_off_cb;
+	MTK_WCN_WMT_THERM_CTRL wmt_therm_ctrl_cb;
+	MTK_WCN_WMT_HWVER_GET wmt_hwver_get_cb;
+	MTK_WCN_WMT_DSNS_CTRL wmt_dsns_ctrl_cb;
+	MTK_WCN_WMT_MSGCB_REG wmt_msgcb_reg_cb;
+	MTK_WCN_WMT_MSGCB_UNREG wmt_msgcb_unreg_cb;
+	MTK_WCN_WMT_SDIO_OP_REG wmt_sdio_op_reg_cb;
+	MTK_WCN_WMT_SDIO_HOST_AWAKE wmt_sdio_host_awake_cb;
+	MTK_WCN_WMT_ASSERT wmt_assert_cb;
+	MTK_WCN_WMT_ASSERT_TIMEOUT wmt_assert_timeout_cb;
+	MTK_WCN_WMT_IC_INFO_GET wmt_ic_info_get_cb;
+	MTK_WCN_WMT_PSM_CTRL wmt_psm_ctrl_cb;
+} MTK_WCN_WMT_EXP_CB_INFO, *P_MTK_WCN_WMT_EXP_CB_INFO;
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*exp for WMT/STP register callback*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_exp_cb_reg
+* DESCRIPTION
+*  stp driver reigster exp symbols
+* PARAMETERS
+*  pStpExpCb      [IN]        stp callback structure pointer
+* RETURNS
+*  UINT32    = 0: OK
+*****************************************************************************/
+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_exp_cb_unreg
+* DESCRIPTION
+*  stp driver unreigster exp symbols
+* PARAMETERS
+*  VOID
+* RETURNS
+*  UINT32    = 0: OK
+*****************************************************************************/
+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_exp_cb_reg
+* DESCRIPTION
+*  WMT driver reigster exp symbols
+* PARAMETERS
+*  pStpExpCb      [IN]       wmt callback structure pointer
+* RETURNS
+*  UINT32    = 0: OK
+*****************************************************************************/
+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_exp_cb_unreg
+* DESCRIPTION
+*  wmt driver unreigster exp symbols
+* PARAMETERS
+*  VOID
+* RETURNS
+*  UINT32    = 0: OK
+*****************************************************************************/
+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID);
+
+/*stp exp symbols*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_send_data
+* DESCRIPTION
+*  subfunction send data through STP
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    >= 0: length transmitted; < 0: error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_send_data_raw
+* DESCRIPTION
+*  subfunction send data through STP without seq/ack
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    >= 0: length transmitted; < 0: error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_parser_data
+* DESCRIPTION
+*  push data to serial transport protocol parser engine
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  void
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_receive_data
+* DESCRIPTION
+*  receive data from serial protocol engine
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  INT32    >= 0: size of data received; < 0: error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_rxqueue_empty
+* DESCRIPTION
+*  Is certain rx queue empty?
+* PARAMETERS
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    0: queue is NOT empyt; !0: queue is empty
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_enable
+* DESCRIPTION
+*  Is STP ready?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:ready, FALSE:not ready
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void);
+
+/*****************************************************************************
+* FUNCTION
+*  set_bluetooth_rx_interface
+* DESCRIPTION
+*  Set bluetooth rx interface
+* PARAMETERS
+*  rx interface type
+* RETURNS
+*  void
+*****************************************************************************/
+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_if_tx
+* DESCRIPTION
+*  regiter Tx event callback function
+* PARAMETERS
+*  stp_if: SDIO or UART, fnnc: Call back function
+* RETURNS
+*  INT32: 0:successful , -1: fail
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_if_rx
+* DESCRIPTION
+*  regiter Rx event callback function
+* PARAMETERS
+*  stp_if: SDIO or UART, fnnc: Call back function
+* RETURNS
+*  INT32: 0:successful , -1: fail
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_event_cb
+* DESCRIPTION
+*  regiter Rx event callback function
+* PARAMETERS
+*  func
+* RETURNS
+*  INT32: 0:successful , -1: fail
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_tx_event_cb
+* DESCRIPTION
+*  regiter Tx event callback function
+* PARAMETERS
+*  func
+* RETURNS
+*  INT32: 0:successful , -1: fail
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_coredump_start_get
+* DESCRIPTION
+*  get coredump flag is set or not
+* PARAMETERS
+*  VOID
+* RETURNS
+*  INT32: 0:coredump flag is not set , 1: coredump flag is set
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_coredump_start_get(VOID);
+
+/*wmt exp symbols*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_func_off
+* DESCRIPTION
+*  wmt turn off subsystem
+* PARAMETERS
+*  type [IN] subsystem type
+* RETURNS
+*  MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_func_on
+* DESCRIPTION
+*  wmt turn on subsystem
+* PARAMETERS
+*  type [IN] subsystem type
+* RETURNS
+*  MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_therm_ctrl
+* DESCRIPTION
+*  query chip temperature by WMT CMD
+* PARAMETERS
+*  eType [IN] thermal ctrl type
+* RETURNS
+*  >=0: chip temperature; 0xff:error
+*****************************************************************************/
+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_hwver_get
+* DESCRIPTION
+*  get chip hardware version
+* PARAMETERS
+*  VOID
+* RETURNS
+*  >=0: chip hw version; 0xff:error
+*****************************************************************************/
+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_ic_info_get
+* DESCRIPTION
+*  get chip hardware version or f/w version
+* PARAMETERS
+*  type : which kind of information is needed
+* RETURNS
+*  f/w version or hw version information
+*****************************************************************************/
+extern UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_dsns_ctrl
+* DESCRIPTION
+*  fm dsns cmd ctrl
+* PARAMETERS
+*  eType [IN] fm dsns ctrl type
+* RETURNS
+*  MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_msgcb_reg
+* DESCRIPTION
+*  used for subsystem register chip reset callback for received wmt reset msg.
+* PARAMETERS
+*  eType [IN] subsystem type
+*  pCb   [IN] rst callback
+* RETURNS
+*  1: OK; 0:error
+*****************************************************************************/
+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_msgcb_unreg
+* DESCRIPTION
+*  used for subsystem unregister chip reset callback for received wmt reset msg.
+* PARAMETERS
+*  eType [IN] subsystem type
+* RETURNS
+*  1: OK; 0:error
+*****************************************************************************/
+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_wmt_sdio_op_reg
+* DESCRIPTION
+*  used to register callback for set sdio ownership.
+* PARAMETERS
+*  own_cb [IN] set owner ship callback
+* RETURNS
+*  always return 0;
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_wmt_sdio_host_awake
+* DESCRIPTION
+*  handing host awake when link is stp sdio?
+* PARAMETERS
+*  VOID
+* RETURNS
+*  always return 0;
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_assert
+* DESCRIPTION
+*  host trigger firmware assert
+* PARAMETERS
+*  type   [IN] subsystem driver type
+*  reason [IN] trigger assert reason
+* RETURNS
+*  MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason);
+
+/*****************************************************************************
+ * * FUNCTION
+ * *  mtk_wcn_wmt_assert_timeout
+ * * DESCRIPTION
+ * *  host trigger firmware assert
+ * * PARAMETERS
+ * *  type   [IN] subsystem driver type
+ * *  reason [IN] trigger assert reason
+ * *  timeout [IN] trigger assert timeout data
+ * * RETURNS
+ * *  MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error
+ * *****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type,
+		UINT32 reason, INT32 timeout);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmt_psm_ctrl
+* DESCRIPTION
+*  disable/enable psm
+* PARAMETERS
+*  flag [IN] disable:0, enable:1
+* RETURNS
+*  always return 0;
+*****************************************************************************/
+extern INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag);
+
+#endif
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile
new file mode 100644
index 0000000000000..286bfd4bfed36
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile
@@ -0,0 +1,65 @@
+subdir-ccflags-y += \
+	-I$(src)/linux/include \
+	-I$(src)/linux/pri/include \
+	-I$(src)/core/include \
+	-I$(src)/include \
+	-I$(src)/../common_detect \
+	-I$(srctree)/drivers/misc/mediatek/btif/common/inc
+
+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/
+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM)
+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs/
+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/conn_md/include
+
+EXT_FLAG=_soc
+COMMON_SRC_PATH := $(src)
+COMMON_OBJ_PATH := $(src)
+
+ifeq ($(CONFIG_ARCH_MT6580), y)
+subdir-ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33
+endif
+
+ifeq ($(CONFIG_MTK_COMBO), m)
+# WMT DRIVER
+obj-$(CONFIG_MTK_COMBO) += mtk_stp_wmt$(EXT_FLAG).o
+# WMT DRIVER-core part
+mtk_stp_wmt$(EXT_FLAG)-objs	:= core/wmt_core.o core/wmt_ctrl.o core/wmt_func.o core/wmt_ic_soc.o core/wmt_lib.o core/wmt_conf.o
+
+
+# WMT DRIVER-linux private part
+mtk_stp_wmt$(EXT_FLAG)-objs	+= linux/pri/wmt_dev.o linux/pri/wmt_exp.o
+mtk_stp_wmt$(EXT_FLAG)-objs	+= linux/pri/stp_btif.o
+
+
+# WMT DRIVER-OSAL
+mtk_stp_wmt$(EXT_FLAG)-objs	+= linux/pub/osal.o linux/pub/bgw_desense.o
+# WMT DRIVER-platform implementation
+# ccflags-y += -D WMT_PLAT_ALPS
+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/wmt_plat_alps.o
+
+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/mtk_wcn_consys_hw.o
+
+
+mtk_stp_wmt$(EXT_FLAG)-objs	+= linux/pri/stp_exp.o core/stp_core.o core/psm_core.o core/btm_core.o linux/pri/stp_dbg.o
+
+# WMT stub part (built-in kernel image)
+# obj-y			+= platform/alps/mtk_wcn_consys_stub_alps.o
+
+
+
+obj-$(CONFIG_MTK_COMBO_BT) 	+= mtk_stp_bt$(EXT_FLAG).o
+mtk_stp_bt$(EXT_FLAG)-objs	:= linux/pub/stp_chrdev_bt.o
+
+
+obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi$(EXT_FLAG).o
+mtk_wmt_wifi$(EXT_FLAG)-objs := linux/pub/wmt_chrdev_wifi.o
+
+endif
+
+ifeq ($(CONFIG_MTK_COMBO), y)
+# subdir-ccflags-y += -D WMT_PLAT_ALPS
+obj-y += core/
+obj-y += linux/
+#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-y += mt7623/
+endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile
new file mode 100644
index 0000000000000..9df71b9e163ea
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile
@@ -0,0 +1,22 @@
+ifeq ($(CONFIG_MTK_COMBO), y)
+
+ccflags-y += \
+	-I$(src)/../linux/include \
+	-I$(src)/../linux/pri/include \
+	-I$(src)/../core/include \
+	-I$(src)/../include \
+	-I$(src)/../../common_detect \
+	-I$(srctree)/drivers/misc/mediatek/btif/common/inc \
+
+obj-y += wmt_core.o \
+         wmt_ctrl.o \
+         wmt_func.o \
+         wmt_ic_soc.o \
+         wmt_lib.o \
+         wmt_conf.o \
+         btm_core.o \
+         dbg_core.o \
+         psm_core.o \
+         stp_core.o
+
+endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c
new file mode 100644
index 0000000000000..4946b682d8266
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c
@@ -0,0 +1,1376 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <asm/atomic.h>
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "stp_dbg.h"
+#include "stp_core.h"
+#include "btm_core.h"
+#include "wmt_plat.h"
+
+#define PFX_BTM                         "[STP-BTM] "
+#define STP_BTM_LOG_LOUD                 4
+#define STP_BTM_LOG_DBG                  3
+#define STP_BTM_LOG_INFO                 2
+#define STP_BTM_LOG_WARN                 1
+#define STP_BTM_LOG_ERR                  0
+
+INT32 gBtmDbgLevel = STP_BTM_LOG_INFO;
+
+#define STP_BTM_LOUD_FUNC(fmt, arg...) \
+do { \
+	if (gBtmDbgLevel >= STP_BTM_LOG_LOUD) \
+		pr_debug(PFX_BTM "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_BTM_DBG_FUNC(fmt, arg...) \
+do { \
+	if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \
+		pr_debug(PFX_BTM "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_BTM_INFO_FUNC(fmt, arg...) \
+do { \
+	if (gBtmDbgLevel >= STP_BTM_LOG_INFO) \
+		pr_debug(PFX_BTM "[I]%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_BTM_WARN_FUNC(fmt, arg...) \
+do { \
+	if (gBtmDbgLevel >= STP_BTM_LOG_WARN) \
+		pr_warn(PFX_BTM "[W]%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_BTM_ERR_FUNC(fmt, arg...) \
+do { \
+	if (gBtmDbgLevel >= STP_BTM_LOG_ERR) \
+		pr_err(PFX_BTM "[E]%s(%d):ERROR! "   fmt, __func__ , __LINE__, ##arg); \
+} while (0)
+#define STP_BTM_TRC_FUNC(f) \
+do { \
+	if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \
+		pr_debug(PFX_BTM "<%s> <%d>\n", __func__, __LINE__); \
+} while (0)
+
+#define ASSERT(expr)
+
+MTKSTP_BTM_T stp_btm_i;
+MTKSTP_BTM_T *stp_btm = &stp_btm_i;
+
+const char *g_btm_op_name[] = {
+	"STP_OPID_BTM_RETRY",
+	"STP_OPID_BTM_RST",
+	"STP_OPID_BTM_DBG_DUMP",
+	"STP_OPID_BTM_DUMP_TIMEOUT",
+	"STP_OPID_BTM_POLL_CPUPCR",
+	"STP_OPID_BTM_PAGED_DUMP",
+	"STP_OPID_BTM_FULL_DUMP",
+	"STP_OPID_BTM_PAGED_TRACE",
+	"STP_OPID_BTM_FORCE_FW_ASSERT",
+#if CFG_WMT_LTE_COEX_HANDLING
+	"STP_OPID_BTM_WMT_LTE_COEX",
+#endif
+	"STP_OPID_BTM_EXIT"
+};
+
+#if 0
+static char *_stp_pkt_type(int type)
+{
+
+	static char s[10];
+
+	switch (type) {
+	case WMT_TASK_INDX:
+		osal_memcpy(s, "WMT", strlen("WMT") + 1);
+		break;
+	case BT_TASK_INDX:
+		osal_memcpy(s, "BT", strlen("BT") + 1);
+		break;
+	case GPS_TASK_INDX:
+		osal_memcpy(s, "GPS", strlen("GPS") + 1);
+		break;
+	case FM_TASK_INDX:
+		osal_memcpy(s, "FM", strlen("FM") + 1);
+		break;
+	default:
+		osal_memcpy(s, "UNKNOWN", strlen("UNKNOWN") + 1);
+		break;
+	}
+
+	return s;
+}
+#endif
+
+static INT32 _stp_btm_put_dump_to_nl(void)
+{
+#define NUM_FETCH_ENTRY 8
+
+	static UINT8 buf[2048];
+	static UINT8 tmp[2048];
+
+	UINT32 buf_len;
+	STP_PACKET_T *pkt;
+	STP_DBG_HDR_T *hdr;
+	INT32 len;
+	INT32 remain = 0, index = 0;
+	INT32 retry = 0, rc = 0, nl_retry = 0;
+
+	STP_BTM_INFO_FUNC("Enter..\n");
+
+	index = 0;
+	tmp[index++] = '[';
+	tmp[index++] = 'M';
+	tmp[index++] = ']';
+
+	do {
+		index = 3;
+		remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len);
+		if (buf_len > 0) {
+			pkt = (STP_PACKET_T *) buf;
+			hdr = &pkt->hdr;
+			len = pkt->hdr.len;
+			osal_memcpy(&tmp[index], &len, 2);
+			index += 2;
+			if (hdr->dbg_type == STP_DBG_FW_DMP) {
+					osal_memcpy(&tmp[index], pkt->raw, len);
+
+				if (len <= 1500) {
+					/* pr_warn("\n%s\n+++\n", tmp); */
+					/* pr_warn("send coredump len:%d\n", len); */
+					/* pr_warn("send coredump:%s\n", tmp); */
+					rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5);
+
+					while (rc) {
+						nl_retry++;
+					if (nl_retry > 1000)
+							break;
+						STP_BTM_WARN_FUNC
+							("**dump send fails, and retry again.**\n");
+						osal_sleep_ms(3);
+						rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5);
+					if (!rc)
+							STP_BTM_WARN_FUNC("****retry again ok!**\n");
+						}
+					/* schedule(); */
+				} else {
+						STP_BTM_INFO_FUNC("dump entry length is over long\n");
+						BUG_ON(0);
+				}
+				retry = 0;
+			}
+		} else {
+			retry++;
+			osal_sleep_ms(100);
+		}
+	} while ((remain > 0) || (retry < 2));
+
+	STP_BTM_INFO_FUNC("Exit..\n");
+	return 0;
+}
+
+#define SUB_PKT_SIZE 1024
+#define SUB_PKT_HEADER 5	/*'[M]',3Bytes; len,2Bytes*/
+
+INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len)
+{
+	static UINT8  tmp[SUB_PKT_SIZE + SUB_PKT_HEADER];
+
+	INT32 remain = dump_len, index = 0;
+	INT32 rc = 0, nl_retry = 0;
+	INT32 len;
+	INT32 offset = 0;
+
+	STP_BTM_INFO_FUNC("Enter..\n");
+
+	if (dump_len > 0) {
+		index = 0;
+		tmp[index++] = '[';
+		tmp[index++] = 'M';
+		tmp[index++] = ']';
+
+		do {
+			index = 3;
+			if (remain >= SUB_PKT_SIZE)
+				len = SUB_PKT_SIZE;
+			else
+				len = remain;
+			remain -= len;
+
+			osal_memcpy(&tmp[index], &len, 2);
+			index += 2;
+			osal_memcpy(&tmp[index], data_buf + offset, len);
+			offset += len;
+			STP_BTM_DBG_FUNC
+				("send %d remain %d\n", len, remain);
+
+			rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER);
+			while (rc) {
+				nl_retry++;
+				if (nl_retry > 1000)
+					break;
+				STP_BTM_WARN_FUNC
+								("**dump send fails, and retry again.**\n");
+					osal_sleep_ms(3);
+					rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER);
+					if (!rc) {
+						STP_BTM_WARN_FUNC
+							("****retry again ok!**\n");
+					}
+				}
+			/* schedule(); */
+		} while (remain > 0);
+	} else
+		STP_BTM_INFO_FUNC("dump entry length is 0\n");
+
+	STP_BTM_INFO_FUNC("Exit..\n");
+	return 0;
+}
+
+static INT32 _stp_btm_put_dump_to_aee(void)
+{
+	static UINT8 buf[2048];
+	static UINT8 tmp[2048];
+
+	UINT32 buf_len;
+	STP_PACKET_T *pkt;
+	STP_DBG_HDR_T *hdr;
+	INT32 remain = 0;
+	INT32 retry = 0;
+	INT32 ret = 0;
+
+	STP_BTM_INFO_FUNC("Enter..\n");
+
+	do {
+		remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len);
+		if (buf_len > 0) {
+			pkt = (STP_PACKET_T *) buf;
+			hdr = &pkt->hdr;
+			if (hdr->dbg_type == STP_DBG_FW_DMP) {
+				memcpy(&tmp[0], pkt->raw, pkt->hdr.len);
+
+				if (pkt->hdr.len <= 1500) {
+					tmp[pkt->hdr.len] = '\n';
+					tmp[pkt->hdr.len + 1] = '\0';
+
+					ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0);
+				} else {
+					STP_BTM_INFO_FUNC("dump entry length is over long\n");
+					BUG_ON(0);
+				}
+				retry = 0;
+			}
+		} else {
+			retry++;
+			msleep(100);
+		}
+	} while ((remain > 0) || (retry < 2));
+
+	STP_BTM_INFO_FUNC("Exit..\n");
+	return ret;
+}
+
+#if 0
+INT32 _stp_trigger_firmware_assert_via_emi(VOID)
+{
+	PUINT8 p_virtual_addr = NULL;
+	INT32 status = -1;
+	INT32 i = 0, j = 0;
+
+	do {
+		STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n");
+		p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1);
+		if (!p_virtual_addr) {
+			STP_BTM_ERR_FUNC("get virtual address fail\n");
+			return -1;
+		}
+
+		CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1);
+		STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n");
+#if 1
+		/* wait for firmware assert */
+		osal_sleep_ms(50);
+		/* if firmware is not assert self, host driver helps it. */
+		do {
+			if (0 != mtk_wcn_stp_coredump_start_get()) {
+				status = 0;
+				break;
+			}
+
+			mtk_wcn_stp_wakeup_consys();
+			STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i);
+			stp_dbg_poll_cpupcr(5, 1, 1);
+			osal_sleep_ms(5);
+
+			i++;
+			if (i > 20) {
+				i = 0;
+				break;
+			}
+		} while (1);
+#endif
+
+		if (0 != mtk_wcn_stp_coredump_start_get()) {
+			status = 0;
+			break;
+		}
+
+		j++;
+		if (j > 8) {
+			j = 0;
+			break;
+		}
+	} while (1);
+
+	return status;
+}
+#else
+INT32 _stp_trigger_firmware_assert_via_emi(VOID)
+{
+	INT32 status = -1;
+	INT32 j = 0;
+
+	wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN);
+
+	do {
+		if (0 != mtk_wcn_stp_coredump_start_get()) {
+			status = 0;
+			break;
+		}
+
+		stp_dbg_poll_cpupcr(5, 1, 1);
+		stp_dbg_poll_dmaregs(5, 1);
+		j++;
+		STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j);
+		osal_sleep_ms(20);
+		if (j > 49) {	/* wait for 1 second */
+			stp_dbg_set_fw_info("host trigger fw assert timeout",
+					    osal_strlen("host trigger fw assert timeout"),
+					    STP_HOST_TRIGGER_ASSERT_TIMEOUT);
+			wcn_core_dump_timeout();	/* trigger collect SYS_FTRACE */
+			break;
+		}
+	} while (1);
+
+	return status;
+}
+#endif
+
+#define COMBO_DUMP2AEE
+#if 1
+#define STP_DBG_PAGED_DUMP_BUFFER_SIZE (32*1024*sizeof(char))
+UINT8 g_paged_dump_buffer[STP_DBG_PAGED_DUMP_BUFFER_SIZE] = { 0 };
+
+#define STP_DBG_PAGED_TRACE_SIZE (2048*sizeof(char))
+UINT8 g_paged_trace_buffer[STP_DBG_PAGED_TRACE_SIZE] = { 0 };
+
+UINT32 g_paged_dump_len = 0;
+UINT32 g_paged_trace_len = 0;
+VOID _stp_dump_emi_dump_buffer(UINT8 *buffer, UINT32 len)
+{
+	UINT32 i = 0;
+
+	if (len > 16)
+		len = 16;
+	for (i = 0; i < len; i++) {
+		if (i % 16 == 0 && i != 0)
+			pr_cont("\n    ");
+
+		if (buffer[i] == ']' || buffer[i] == '[' || buffer[i] == ',')
+			pr_cont("%c", buffer[i]);
+		else
+			pr_cont("0x%02x ", buffer[i]);
+	}
+}
+#endif
+static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp)
+{
+	INT32 ret = -1;
+	INT32 dump_sink = 1;	/* core dump target, 0: aee; 1: netlink */
+	INT32 Ret = 0;
+	static UINT32 counter;
+	UINT32 full_dump_left = STP_FULL_DUMP_TIME;
+	UINT32 page_counter = 0;
+	UINT32 packet_num = STP_PAGED_DUMP_TIME_LIMIT/100;
+	UINT32 dump_num = 0;
+	ENUM_STP_FW_ISSUE_TYPE issue_type;
+	P_CONSYS_EMI_ADDR_INFO p_ecsi;
+
+	p_ecsi = wmt_plat_get_emi_phy_add();
+	osal_assert(p_ecsi);
+	if (NULL == pStpOp)
+		return -1;
+
+	switch (pStpOp->opId) {
+	case STP_OPID_BTM_EXIT:
+		/* TODO: clean all up? */
+		ret = 0;
+		break;
+
+		/*tx timeout retry */
+	case STP_OPID_BTM_RETRY:
+		stp_do_tx_timeout();
+		ret = 0;
+
+		break;
+
+		/*whole chip reset */
+	case STP_OPID_BTM_RST:
+		STP_BTM_INFO_FUNC("whole chip reset start!\n");
+		STP_BTM_INFO_FUNC("....+\n");
+		if (stp_btm->wmt_notify) {
+			stp_btm->wmt_notify(BTM_RST_OP);
+			ret = 0;
+		} else {
+			STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL.");
+			ret = -1;
+		}
+
+		STP_BTM_INFO_FUNC("whole chip reset end!\n");
+
+		break;
+
+	case STP_OPID_BTM_DBG_DUMP:
+		/*Notify the wmt to get dump data */
+		STP_BTM_DBG_FUNC("wmt dmp notification\n");
+		dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1);
+
+		if (dump_sink == 0)
+			_stp_btm_put_dump_to_aee();
+		else if (dump_sink == 1)
+			_stp_btm_put_dump_to_nl();
+		else
+			STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink);
+
+		break;
+
+	case STP_OPID_BTM_DUMP_TIMEOUT:
+		/* Flush dump data, and reset compressor */
+		STP_BTM_INFO_FUNC("Flush dump data\n");
+		wcn_core_dump_flush(0, MTK_WCN_BOOL_TRUE);
+		break;
+
+	case STP_OPID_BTM_POLL_CPUPCR:
+		do {
+			UINT32 times;
+			UINT32 sleep;
+
+			times = pStpOp->au4OpData[0];
+			sleep = pStpOp->au4OpData[1];
+
+			ret = stp_dbg_poll_cpupcr(times, sleep, 0);
+			ret += stp_dbg_poll_dmaregs(times, sleep);
+		} while (0);
+		break;
+
+	case STP_OPID_BTM_PAGED_DUMP:
+		g_paged_dump_len = 0;
+		issue_type = STP_FW_ASSERT_ISSUE;
+		/*packet number depend on dump_num get from register:0xf0080044 ,support jade*/
+		wcn_core_dump_deinit_gcoredump();
+		dump_num = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_page_dump_num);
+		if (dump_num != 0) {
+				packet_num = dump_num;
+				STP_BTM_WARN_FUNC("get consys dump num packet_num(%d)\n", packet_num);
+		} else {
+			STP_BTM_ERR_FUNC("can not get consys dump num and default num is 35\n");
+		}
+		Ret = wcn_core_dump_init_gcoredump(packet_num, STP_CORE_DUMP_TIMEOUT);
+		if (Ret) {
+			STP_BTM_ERR_FUNC("core dump init fail\n");
+			break;
+		}
+		wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
+		page_counter = 0;
+		do {
+			UINT32 loop_cnt1 = 0;
+			UINT32 loop_cnt2 = 0;
+			ENUM_HOST_DUMP_STATE host_state;
+			ENUM_CHIP_DUMP_STATE chip_state;
+			UINT32 dump_phy_addr = 0;
+			UINT8 *dump_vir_addr = NULL;
+			UINT32 dump_len = 0;
+			UINT32 isEnd = 0;
+
+			host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info(
+				p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_state);
+			if (STP_HOST_DUMP_NOT_START == host_state) {
+				counter++;
+				STP_BTM_INFO_FUNC("counter(%d)\n", counter);
+				osal_sleep_ms(100);
+			} else {
+				counter = 0;
+			}
+			while (1) {
+				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(
+					p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state);
+				if (STP_CHIP_DUMP_PUT_DONE == chip_state) {
+					STP_BTM_INFO_FUNC("chip put done\n");
+					break;
+				}
+				STP_BTM_INFO_FUNC("waiting chip put done\n");
+				STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state);
+				loop_cnt1++;
+				osal_sleep_ms(5);
+
+				if (loop_cnt1 > 10)
+					goto paged_dump_end;
+
+			}
+
+			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET);
+
+			dump_phy_addr = wmt_plat_get_dump_info(
+				p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr);
+
+			if (!dump_phy_addr) {
+				STP_BTM_ERR_FUNC("get paged dump phy address fail\n");
+				ret = -1;
+				break;
+			}
+
+			dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr);
+			if (!dump_vir_addr) {
+				STP_BTM_ERR_FUNC("get paged dump phy address fail\n");
+				ret = -2;
+				break;
+			}
+			dump_len = wmt_plat_get_dump_info(
+				p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len);
+			STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n",
+				dump_phy_addr, dump_vir_addr, dump_len);
+
+			/*move dump info according to dump_addr & dump_len */
+#if 1
+			osal_memcpy(&g_paged_dump_buffer[0], dump_vir_addr, dump_len);
+			_stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], dump_len);
+
+			if (0 == page_counter) {	/* do fw assert infor paser in first paged dump */
+				if (1 == stp_dbg_get_host_trigger_assert())
+					issue_type = STP_HOST_TRIGGER_FW_ASSERT;
+
+				ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0], 512, issue_type);
+				if (ret) {
+					STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n", ret);
+					stp_dbg_set_fw_info("Fw Warm reset", osal_strlen("Fw Warm reset"),
+							    STP_FW_WARM_RST_ISSUE);
+				}
+			}
+
+			if (dump_len <= 32 * 1024) {
+				pr_err("g_coredump_mode: %d!\n", g_coredump_mode);
+				if (1 == g_coredump_mode)
+					ret = stp_dbg_aee_send(&g_paged_dump_buffer[0], dump_len, 0);
+				else if	(2 == g_coredump_mode)
+					ret = _stp_btm_put_emi_dump_to_nl(&g_paged_dump_buffer[0], dump_len);
+				else{
+					STP_BTM_INFO_FUNC("coredump is disabled!\n");
+					return 0;
+				}
+				if (ret == 0)
+					STP_BTM_INFO_FUNC("aee send ok!\n");
+				else if (ret == 1)
+					STP_BTM_INFO_FUNC("aee send fisish!\n");
+				else
+					STP_BTM_ERR_FUNC("aee send error!\n");
+			} else
+				STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n", dump_len);
+
+			g_paged_dump_len += dump_len;
+			STP_BTM_INFO_FUNC("dump len update(%d)\n", g_paged_dump_len);
+#endif
+			wmt_plat_update_host_sync_num();
+			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE);
+
+			STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n",
+					  wmt_plat_get_dump_info(
+						p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num),
+					  wmt_plat_get_dump_info(
+						p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num));
+
+			page_counter++;
+			STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n", page_counter);
+
+			while (1) {
+				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(
+					p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state);
+				if (STP_CHIP_DUMP_END == chip_state) {
+					STP_BTM_INFO_FUNC("chip put end\n");
+					wmt_plat_set_host_dump_state(STP_HOST_DUMP_END);
+					break;
+				}
+				STP_BTM_INFO_FUNC("waiting chip put end\n");
+
+				loop_cnt2++;
+				osal_sleep_ms(10);
+
+				if (loop_cnt2 > 10)
+					goto paged_dump_end;
+			}
+
+paged_dump_end:
+			wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
+
+			if (counter > packet_num) {
+				isEnd = wmt_plat_get_dump_info(
+					p_ecsi->p_ecso->emi_apmem_ctrl_chip_paded_dump_end);
+
+				if (isEnd) {
+					STP_BTM_INFO_FUNC("paged dump end\n");
+
+					STP_BTM_INFO_FUNC("\n\n paged dump print  ++\n\n");
+					_stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], g_paged_dump_len);
+					STP_BTM_INFO_FUNC("\n\n paged dump print  --\n\n");
+					STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d\n\n",
+							  g_paged_dump_len, page_counter);
+					counter = 0;
+					ret = 0;
+				} else {
+					STP_BTM_ERR_FUNC("paged dump fail\n");
+					wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
+					stp_dbg_poll_cpupcr(5, 5, 0);
+					stp_dbg_poll_dmaregs(5, 1);
+					counter = 0;
+					ret = -1;
+				}
+				break;
+			}
+
+		} while (1);
+
+		break;
+
+	case STP_OPID_BTM_FULL_DUMP:
+
+		wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
+		do {
+			UINT32 loop_cnt1 = 0;
+			UINT32 loop_cnt2 = 0;
+			ENUM_CHIP_DUMP_STATE chip_state;
+			UINT32 dump_phy_addr = 0;
+			UINT8 *dump_vir_addr = NULL;
+			UINT32 dump_len = 0;
+			UINT32 isFail = 0;
+
+			while (1) {
+				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(
+						p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state);
+				if (STP_CHIP_DUMP_PUT_DONE == chip_state)
+					break;
+
+				loop_cnt1++;
+				osal_sleep_ms(10);
+
+				if (loop_cnt1 > 10) {
+					isFail = 1;
+					goto full_dump_end;
+				}
+			}
+
+			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET);
+
+			dump_phy_addr = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr);
+			if (!dump_phy_addr) {
+				STP_BTM_ERR_FUNC("get phy dump address fail\n");
+				ret = -1;
+				break;
+			}
+
+			dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr);
+			if (!dump_vir_addr) {
+				STP_BTM_ERR_FUNC("get vir dump address fail\n");
+				ret = -2;
+				break;
+			}
+			dump_len = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len);
+			/*move dump info according to dump_addr & dump_len */
+			wmt_plat_update_host_sync_num();
+			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE);
+
+			STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n",
+					  wmt_plat_get_dump_info(
+						p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num),
+					  wmt_plat_get_dump_info(
+						p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num));
+
+			while (1) {
+				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(
+							p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state);
+				if (STP_CHIP_DUMP_END == chip_state) {
+					wmt_plat_set_host_dump_state(STP_HOST_DUMP_END);
+					break;
+				}
+				loop_cnt2++;
+				osal_sleep_ms(10);
+
+				if (loop_cnt2 > 10) {
+					isFail = 1;
+					goto full_dump_end;
+				}
+			}
+			wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
+full_dump_end:
+			if (isFail) {
+				STP_BTM_ERR_FUNC("full dump fail\n");
+				wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
+				ret = -1;
+				break;
+			}
+		} while (--full_dump_left > 0);
+		if (0 == full_dump_left) {
+			STP_BTM_INFO_FUNC("full dump end\n");
+			ret = 0;
+		}
+		break;
+	case STP_OPID_BTM_PAGED_TRACE:
+		g_paged_trace_len = 0;
+		do {
+			UINT32 ctrl_val = 0;
+			UINT32 loop_cnt1 = 0;
+			UINT32 buffer_start = 0;
+			UINT32 buffer_idx = 0;
+			UINT8 *dump_vir_addr = NULL;
+
+			while (loop_cnt1 < 10) {
+				ctrl_val = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state);
+				if (0x8 == ctrl_val)
+					break;
+				osal_sleep_ms(10);
+				loop_cnt1++;
+			}
+
+			if (loop_cnt1 >= 10) {
+				STP_BTM_ERR_FUNC("polling CTRL STATE fail\n");
+				ret = -1;
+				break;
+			}
+
+			buffer_start = wmt_plat_get_dump_info(
+							p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_start);
+			buffer_idx = wmt_plat_get_dump_info(
+							p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_idx);
+			/* buffer_len = buffer_idx - buffer_start; */
+			g_paged_trace_len = buffer_idx;
+			STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n", buffer_start, buffer_idx);
+			dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_ecsi->emi_phy_addr);
+			if (!dump_vir_addr) {
+				STP_BTM_ERR_FUNC("get vir dump address fail\n");
+				ret = -2;
+				break;
+			}
+			osal_memcpy(&g_paged_trace_buffer[0], dump_vir_addr,
+				    buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE);
+			/*moving paged trace according to buffer_start & buffer_len */
+			do {
+				int i = 0;
+				int dump_len = 0;
+
+				dump_len =
+				    buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE;
+				pr_warn("\n\n -- paged trace hex output --\n\n");
+				for (i = 0; i < dump_len; i++) {
+					if (i % 16 == 0)
+						pr_cont("\n");
+
+					pr_cont("%02x ", g_paged_trace_buffer[i]);
+				}
+				pr_warn("\n\n -- paged trace ascii output --\n\n");
+				for (i = 0; i < dump_len; i++) {
+					if (i % 64 == 0)
+						pr_cont("\n");
+					pr_cont("%c", g_paged_trace_buffer[i]);
+				}
+			} while (0);
+			/*move parser fw assert infor to paged dump in the one paged dump */
+			/* ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type); */
+			ret = 0;
+
+		} while (0);
+		mtk_wcn_stp_ctx_restore();
+		break;
+
+#if CFG_WMT_LTE_COEX_HANDLING
+	case STP_OPID_BTM_WMT_LTE_COEX:
+		ret = wmt_idc_msg_to_lte_handing();
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ)
+{
+	P_OSAL_OP pOp;
+	/* INT32 ret = 0; */
+
+	if (!pOpQ) {
+		STP_BTM_WARN_FUNC("!pOpQ\n");
+		return NULL;
+	}
+
+	osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
+	/* acquire lock success */
+	RB_GET(pOpQ, pOp);
+	osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
+
+	if (!pOp)
+		STP_BTM_WARN_FUNC("RB_GET fail\n");
+
+	return pOp;
+}
+
+static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp)
+{
+	INT32 ret;
+
+	if (!pOpQ || !pOp) {
+		STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp);
+		return 0;	/* ;MTK_WCN_BOOL_FALSE; */
+	}
+
+	ret = 0;
+
+	osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
+	/* acquire lock success */
+	if (!RB_FULL(pOpQ))
+		RB_PUT(pOpQ, pOp);
+	else
+		ret = -1;
+
+	osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
+
+	if (ret) {
+		STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n",
+			pOpQ,
+			RB_COUNT(pOpQ),
+			&stp_btm->rFreeOpQ,
+			&stp_btm->rActiveOpQ);
+		return 0;
+	}
+	/* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */
+	return 1;
+
+}
+
+P_OSAL_OP _stp_btm_get_free_op(MTKSTP_BTM_T *stp_btm)
+{
+	P_OSAL_OP pOp;
+
+	if (stp_btm) {
+		pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ);
+		if (pOp)
+			osal_memset(&pOp->op, 0, sizeof(pOp->op));
+
+		return pOp;
+	} else
+		return NULL;
+}
+
+INT32 _stp_btm_put_act_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp)
+{
+	INT32 bRet = 0;
+	INT32 bCleanup = 0;
+	long wait_ret = -1;
+
+	P_OSAL_SIGNAL pSignal = NULL;
+
+	if (!stp_btm || !pOp) {
+		STP_BTM_ERR_FUNC("Input NULL pointer\n");
+		return bRet;
+	}
+	do {
+		pSignal = &pOp->signal;
+
+		if (pSignal->timeoutValue) {
+			pOp->result = -9;
+			osal_signal_init(&pOp->signal);
+		}
+
+		/* put to active Q */
+		bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp);
+		if (0 == bRet) {
+			STP_BTM_WARN_FUNC("put active queue fail\n");
+			bCleanup = 1;	/* MTK_WCN_BOOL_TRUE; */
+			break;
+		}
+
+		/* wake up wmtd */
+		osal_trigger_event(&stp_btm->STPd_event);
+
+		if (pSignal->timeoutValue == 0) {
+			bRet = 1;	/* MTK_WCN_BOOL_TRUE; */
+			/* clean it in wmtd */
+			break;
+		}
+
+		/* wait result, clean it here */
+		bCleanup = 1;	/* MTK_WCN_BOOL_TRUE; */
+
+		/* check result */
+		wait_ret = osal_wait_for_signal_timeout(&pOp->signal);
+
+		STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret);
+		if (!wait_ret) {
+			STP_BTM_ERR_FUNC("wait completion timeout\n");
+			/* TODO: how to handle it? retry? */
+		} else {
+			if (pOp->result)
+				STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result);
+
+			bRet = (pOp->result) ? 0 : 1;
+		}
+	} while (0);
+
+	if (bCleanup) {
+		/* put Op back to freeQ */
+		_stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp);
+	}
+	bRet = (pOp->result) ? 0 : 1;
+	return bRet;
+}
+
+static INT32 _stp_btm_wait_for_msg(void *pvData)
+{
+	MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData;
+
+	return (!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd);
+}
+
+static INT32 _stp_btm_proc(void *pvData)
+{
+	MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData;
+	P_OSAL_OP pOp;
+	INT32 id;
+	INT32 result;
+
+	if (!stp_btm) {
+		STP_BTM_WARN_FUNC("!stp_btm\n");
+		return -1;
+	}
+
+	for (;;) {
+		pOp = NULL;
+
+		osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm);
+
+		if (osal_thread_should_stop(&stp_btm->BTMd)) {
+			STP_BTM_INFO_FUNC("should stop now...\n");
+			/* TODO: clean up active opQ */
+			break;
+		}
+
+		/* get Op from activeQ */
+		pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ);
+
+		if (!pOp) {
+			STP_BTM_WARN_FUNC("get_lxop activeQ fail\n");
+			continue;
+		}
+
+		id = osal_op_get_id(pOp);
+
+		STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n",
+				 id, (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]),
+				 RB_COUNT(&stp_btm->rActiveOpQ));
+
+		if (id >= STP_OPID_BTM_NUM) {
+			STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id);
+			result = -1;
+			goto handler_done;
+		}
+
+		result = _stp_btm_handler(stp_btm, &pOp->op);
+
+handler_done:
+
+		if (result) {
+			STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id,
+					  (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]),
+					  result);
+		}
+
+		if (osal_op_is_wait_for_signal(pOp)) {
+			osal_op_raise_signal(pOp, result);
+		} else {
+			/* put Op back to freeQ */
+			_stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp);
+		}
+
+		if (STP_OPID_BTM_EXIT == id) {
+			break;
+		} else if (STP_OPID_BTM_RST == id) {
+			/* prevent multi reset case */
+			stp_btm_reset_btm_wq(stp_btm);
+			mtk_wcn_stp_coredump_start_ctrl(0);
+		}
+	}
+
+	STP_BTM_INFO_FUNC("exits\n");
+
+	return 0;
+};
+
+static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm)
+{
+
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_btm == NULL)
+		return STP_BTM_OPERATION_FAIL;
+
+	pOp = _stp_btm_get_free_op(stp_btm);
+	if (!pOp) {
+		STP_BTM_WARN_FUNC("get_free_lxop fail\n");
+		return -1;	/* break; */
+	}
+	pOp->op.opId = STP_OPID_BTM_RST;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_btm_put_act_op(stp_btm, pOp);
+	STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+	retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm)
+{
+
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_btm == NULL)
+		return STP_BTM_OPERATION_FAIL;
+
+	pOp = _stp_btm_get_free_op(stp_btm);
+	if (!pOp) {
+		STP_BTM_WARN_FUNC("get_free_lxop fail\n");
+		return -1;	/* break; */
+	}
+	pOp->op.opId = STP_OPID_BTM_RETRY;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_btm_put_act_op(stp_btm, pOp);
+	STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+	retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm)
+{
+
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (!stp_btm)
+		return STP_BTM_OPERATION_FAIL;
+
+	pOp = _stp_btm_get_free_op(stp_btm);
+	if (!pOp) {
+		STP_BTM_WARN_FUNC("get_free_lxop fail\n");
+		return -1;	/* break; */
+	}
+	pOp->op.opId = STP_OPID_BTM_DUMP_TIMEOUT;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_btm_put_act_op(stp_btm, pOp);
+	STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+	retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+static inline INT32 _stp_btm_dump_type(MTKSTP_BTM_T *stp_btm, ENUM_STP_BTM_OPID_T opid)
+{
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	pOp = _stp_btm_get_free_op(stp_btm);
+	if (!pOp) {
+		STP_BTM_WARN_FUNC("get_free_lxop fail\n");
+		return -1;	/* break; */
+	}
+
+	pOp->op.opId = opid;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_btm_put_act_op(stp_btm, pOp);
+	STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+	retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm)
+{
+
+	INT32 retval;
+#if 0
+	UINT32 dump_type;
+	UINT8 *virtual_addr = NULL;
+#endif
+	if (stp_btm == NULL)
+		return STP_BTM_OPERATION_FAIL;
+
+#if 1				/* Paged dump */
+	STP_BTM_INFO_FUNC("paged dump start++\n");
+	retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP);
+	if (retval)
+		STP_BTM_ERR_FUNC("paged dump fail\n");
+#else
+	virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR);
+	if (!virtual_addr) {
+		STP_BTM_ERR_FUNC("get dump type virtual addr fail\n");
+		return -1;
+	}
+	dump_type = CONSYS_REG_READ(virtual_addr);
+	STP_BTM_INFO_FUNC("dump type:%08x\n", dump_type);
+
+	if ((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff)) {
+		STP_BTM_INFO_FUNC("do paged dump\n");
+		retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP);
+		if (retval) {
+			STP_BTM_ERR_FUNC("paged dump fail,do full dump\n");
+			_stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP);
+		}
+	} else if ((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff)) {
+		STP_BTM_INFO_FUNC("do full dump\n");
+		retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP);
+	} else {
+		STP_BTM_INFO_FUNC("do normal dump\n");
+		retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DBG_DUMP);
+	}
+#endif
+
+	return retval;
+}
+
+static inline INT32 _stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep)
+{
+
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_btm == NULL)
+		return STP_BTM_OPERATION_FAIL;
+
+	pOp = _stp_btm_get_free_op(stp_btm);
+	if (!pOp) {
+		/* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */
+		return -1;	/* break; */
+	}
+	pOp->op.opId = STP_OPID_BTM_POLL_CPUPCR;
+	pOp->signal.timeoutValue = 0;
+	pOp->op.au4OpData[0] = times;
+	pOp->op.au4OpData[1] = sleep;
+	bRet = _stp_btm_put_act_op(stp_btm, pOp);
+	STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+	retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+static inline INT32 _stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm)
+{
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_btm == NULL)
+		return STP_BTM_OPERATION_FAIL;
+
+	pOp = _stp_btm_get_free_op(stp_btm);
+	if (!pOp) {
+		/* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */
+		return -1;	/* break; */
+	}
+	pOp->op.opId = STP_OPID_BTM_PAGED_TRACE;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_btm_put_act_op(stp_btm, pOp);
+	STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+	retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+static inline INT32 _stp_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm)
+{
+	INT32 ret = -1;
+
+	ret = _stp_trigger_firmware_assert_via_emi();
+
+	return ret;
+
+}
+
+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm)
+{
+	return _stp_btm_notify_wmt_rst_wq(stp_btm);
+}
+
+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm)
+{
+	return _stp_btm_notify_stp_retry_wq(stp_btm);
+}
+
+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm)
+{
+	return _stp_btm_notify_coredump_timeout_wq(stp_btm);
+}
+
+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm)
+{
+	return _stp_btm_notify_wmt_dmp_wq(stp_btm);
+}
+
+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm)
+{
+	return _stp_btm_notify_wmt_trace_wq(stp_btm);
+}
+
+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep)
+{
+	return _stp_notify_btm_poll_cpupcr(stp_btm, times, sleep);
+}
+
+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en)
+{
+	return stp_dbg_poll_cuppcr_ctrl(en);
+}
+
+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm)
+{
+	INT32 ret = -1;
+#if BTIF_RXD_BE_BLOCKED_DETECT
+	if (is_btif_rxd_be_blocked())
+		ret = wcn_btif_rxd_blocked_collect_ftrace();	/* trigger collect SYS_FTRACE */
+	else
+#endif
+		ret = _stp_btm_do_fw_assert_via_emi(stp_btm);
+	return ret;
+}
+
+#if CFG_WMT_LTE_COEX_HANDLING
+
+static inline INT32 _stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm)
+{
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_btm == NULL)
+		return STP_BTM_OPERATION_FAIL;
+
+	pOp = _stp_btm_get_free_op(stp_btm);
+	if (!pOp) {
+		/* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */
+		return -1;	/* break; */
+	}
+	pOp->op.opId = STP_OPID_BTM_WMT_LTE_COEX;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_btm_put_act_op(stp_btm, pOp);
+	STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+	retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm)
+{
+	return _stp_notify_btm_handle_wmt_lte_coex(stp_btm);
+}
+
+#endif
+MTKSTP_BTM_T *stp_btm_init(void)
+{
+	INT32 i = 0x0;
+	INT32 ret = -1;
+
+	osal_unsleepable_lock_init(&stp_btm->wq_spinlock);
+	osal_event_init(&stp_btm->STPd_event);
+	stp_btm->wmt_notify = wmt_lib_btm_cb;
+
+	RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE);
+	RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE);
+
+	/* Put all to free Q */
+	for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) {
+		osal_signal_init(&(stp_btm->arQue[i].signal));
+		_stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i]));
+	}
+
+	/*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving */
+	stp_btm->BTMd.pThreadData = (VOID *) stp_btm;
+	stp_btm->BTMd.pThreadFunc = (VOID *) _stp_btm_proc;
+	osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME, osal_strlen(BTM_THREAD_NAME));
+
+	ret = osal_thread_create(&stp_btm->BTMd);
+	if (ret < 0) {
+		STP_BTM_ERR_FUNC("osal_thread_create fail...\n");
+		goto ERR_EXIT1;
+	}
+
+	/* Start STPd thread */
+	ret = osal_thread_run(&stp_btm->BTMd);
+	if (ret < 0) {
+		STP_BTM_ERR_FUNC("osal_thread_run FAILS\n");
+		goto ERR_EXIT1;
+	}
+
+	return stp_btm;
+
+ERR_EXIT1:
+
+	return NULL;
+
+}
+
+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm)
+{
+
+	INT32 ret = -1;
+
+	STP_BTM_INFO_FUNC("btm deinit\n");
+
+	if (!stp_btm)
+		return STP_BTM_OPERATION_FAIL;
+
+	ret = osal_thread_destroy(&stp_btm->BTMd);
+	if (ret < 0) {
+		STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n");
+		return STP_BTM_OPERATION_FAIL;
+	}
+
+	return STP_BTM_OPERATION_SUCCESS;
+}
+
+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm)
+{
+	UINT32 i = 0;
+
+	osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
+	RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE);
+	RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE);
+	osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
+	/* Put all to free Q */
+	for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) {
+		osal_signal_init(&(stp_btm->arQue[i].signal));
+		_stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i]));
+	}
+
+	return 0;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c
new file mode 100644
index 0000000000000..246448b38b315
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c
@@ -0,0 +1,13 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h
new file mode 100644
index 0000000000000..9a429b4af1e30
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h
@@ -0,0 +1,133 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _BTM_CORE_H
+#define _BTM_CORE_H
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "stp_wmt.h"
+#include "wmt_plat.h"
+#include "wmt_idc.h"
+#include "mtk_btif_exp.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define STP_BTM_OPERATION_FAIL    (-1)
+#define STP_BTM_OPERATION_SUCCESS (0)
+
+#define STP_BTM_OP_BUF_SIZE (64)
+
+#define BTM_THREAD_NAME "mtk_stp_btm"
+
+#define STP_PAGED_DUMP_TIME_LIMIT 3500
+#define STP_FULL_DUMP_TIME 3
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_STP_BTM_OPID_T {
+	STP_OPID_BTM_RETRY = 0x0,
+	STP_OPID_BTM_RST = 0x1,
+	STP_OPID_BTM_DBG_DUMP = 0x2,
+	STP_OPID_BTM_DUMP_TIMEOUT = 0x3,
+	STP_OPID_BTM_POLL_CPUPCR = 0x4,
+	STP_OPID_BTM_PAGED_DUMP = 0x5,
+	STP_OPID_BTM_FULL_DUMP = 0x6,
+	STP_OPID_BTM_PAGED_TRACE = 0x7,
+	STP_OPID_BTM_FORCE_FW_ASSERT = 0x8,
+#if CFG_WMT_LTE_COEX_HANDLING
+	STP_OPID_BTM_WMT_LTE_COEX = 0x9,
+#endif
+	STP_OPID_BTM_EXIT,
+	STP_OPID_BTM_NUM
+} ENUM_STP_BTM_OPID_T, *P_ENUM_STP_BTM_OPID_T;
+
+typedef OSAL_OP_DAT STP_BTM_OP;
+typedef P_OSAL_OP_DAT P_STP_BTM_OP;
+
+typedef struct mtk_stp_btm {
+	OSAL_THREAD BTMd;	/* main thread (wmtd) handle */
+	OSAL_EVENT STPd_event;
+	OSAL_UNSLEEPABLE_LOCK wq_spinlock;
+
+	OSAL_OP_Q rFreeOpQ;	/* free op queue */
+	OSAL_OP_Q rActiveOpQ;	/* active op queue */
+	OSAL_OP arQue[STP_BTM_OP_BUF_SIZE];	/* real op instances */
+
+	/*wmt_notify */
+	INT32 (*wmt_notify)(MTKSTP_BTM_WMT_OP_T);
+} MTKSTP_BTM_T;
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm);
+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm);
+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm);
+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm);
+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm);
+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm);
+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep);
+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en);
+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm);
+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm);
+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm);
+INT32 wcn_psm_flag_trigger_collect_ftrace(void);
+#if BTIF_RXD_BE_BLOCKED_DETECT
+INT32 wcn_btif_rxd_blocked_collect_ftrace(void);
+MTK_WCN_BOOL is_btif_rxd_be_blocked(void);
+#endif
+MTKSTP_BTM_T *stp_btm_init(void);
+extern unsigned int g_coredump_mode;
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h
new file mode 100644
index 0000000000000..d8c6ebe9c4b06
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h
@@ -0,0 +1,69 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _DBG_CORE_H
+#define _DBG_CORE_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h
new file mode 100644
index 0000000000000..fe92f25e92c18
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h
@@ -0,0 +1,251 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PSM_CORE_H
+#define _PSM_CORE_H
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "stp_wmt.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define PFX_PSM                         "[STP-PSM] "
+#define STP_PSM_LOG_LOUD                 4
+#define STP_PSM_LOG_DBG                  3
+#define STP_PSM_LOG_INFO                 2
+#define STP_PSM_LOG_WARN                 1
+#define STP_PSM_LOG_ERR                  0
+
+#define ASSERT(expr)
+#define STP_PSM_FIFO_SIZE  0x2000	/* 8kbytes */
+#define STP_PSM_TX_SIZE    0x800	/* 2kbytes */
+
+#define STP_PSM_OPERATION_FAIL    (-1)
+#define STP_PSM_OPERATION_SUCCESS (0)
+
+#define STP_PSM_PACKET_SIZE_MAX (2000)
+
+#define PSM_HANDLING 127
+
+#define STP_PSM_WMT_PS_TASK_HANDLING_TIME  30	/* 20 milli-seconds */
+#define STP_PSM_IDLE_TIME_SLEEP           30	/* temporary for stress testing */
+#define STP_PSM_IDLE_TIME_SLEEP_1000           1000	/* for high speed transmission e.g. BT OPP*/
+#define STP_PSM_SDIO_IDLE_TIME_SLEEP           100	/* temporary for SDIO stress testing */
+#define STP_PSM_WAIT_EVENT_TIMEOUT        6000
+#if 0
+#define STP_PSM_WMT_EVENT_SLEEP_EN                    (0x1UL << 0)
+#define STP_PSM_WMT_EVENT_WAKEUP_EN                   (0x1UL << 1)
+#define STP_PSM_BLOCK_DATA_EN                         (0x1UL << 2)
+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR             (0x1UL << 3)
+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN                (0x1UL << 4)
+#define STP_PSM_RESET_EN                              (0x1UL << 5)
+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN                    (0x1UL << 6)
+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY   (0x1UL << 7)
+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY   (0x1UL << 8)
+#endif
+
+#define STP_PSM_WMT_EVENT_SLEEP_EN                    (0)
+#define STP_PSM_WMT_EVENT_WAKEUP_EN                   (1)
+#define STP_PSM_BLOCK_DATA_EN                         (2)
+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR             (3)
+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN                (4)
+#define STP_PSM_RESET_EN                              (5)
+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN                    (6)
+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY   (7)
+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY   (8)
+
+#define STP_PSM_DBG_SIZE (16)
+
+/* OP command ring buffer : must be power of 2 */
+#define STP_OP_BUF_SIZE (16)
+
+#define PSM_THREAD_NAME "mtk_stp_psm"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum {
+	ACT = 0,
+	ACT_INACT,
+	INACT,
+	INACT_ACT,
+	STP_PSM_MAX_STATE,
+} MTKSTP_PSM_STATE_T;
+
+typedef enum _ENUM_STP_OPID_T {
+	STP_OPID_PSM_SLEEP = 0,
+	STP_OPID_PSM_WAKEUP,
+	STP_OPID_PSM_HOST_AWAKE,
+	STP_OPID_PSM_EXIT,
+	STP_OPID_PSM_NUM,
+	STP_OPID_PSM_INALID = STP_OPID_PSM_NUM,
+} ENUM_STP_OPID_T, *P_ENUM_STP_OPID_T;
+
+typedef enum {
+	MON = 0,
+	UNMON,
+} MTKSTP_PSM_MONSTATE_T;
+
+typedef INT32(*wmt_notify_t) (MTKSTP_PSM_ACTION_T action);
+typedef INT32(*stp_tx_cb_t) (unsigned char *buffer, UINT32 length, UINT8 type);
+
+typedef OSAL_OP_DAT STP_OP;
+typedef P_OSAL_OP_DAT P_STP_OP;
+
+typedef struct mtk_stp_psm {
+	OSAL_THREAD PSMd;	/* main thread (wmtd) handle */
+	OSAL_EVENT STPd_event;
+
+	OSAL_OP_Q rFreeOpQ;	/* free op queue */
+	OSAL_OP_Q rActiveOpQ;	/* active op queue */
+	OSAL_OP arQue[STP_OP_BUF_SIZE];	/* real op instances */
+
+	/* OSAL_OP                 current_active_op; */
+	/* P_OSAL_OP               current_active_op; */
+	UINT32 last_active_opId;
+	MTKSTP_PSM_STATE_T work_state;	/*working state */
+	OSAL_BIT_OP_VAR flag;
+
+	/* in normal cases, sleep op is always enabled;
+	* but in error cases, we can't execute sleep cmd,
+	* Eg: FW assert, core dump
+	*/
+	INT32 sleep_en;
+
+/* OSAL_UNSLEEPABLE_LOCK   flagSpinlock; */
+	INT32 idle_time_to_sleep;
+	OSAL_WAKE_LOCK wake_lock;
+	OSAL_TIMER psm_timer;	/*monitor if active */
+	OSAL_EVENT wait_wmt_q;
+	OSAL_FIFO hold_fifo;
+	OSAL_SLEEPABLE_LOCK hold_fifo_spinlock_global;
+	OSAL_UNSLEEPABLE_LOCK wq_spinlock;
+	OSAL_SLEEPABLE_LOCK stp_psm_lock;
+	INT32 (*wmt_notify)(MTKSTP_PSM_ACTION_T action);
+	INT32 (*stp_tx_cb)(unsigned char *buffer, UINT32 length, UINT8 type);
+
+	MTK_WCN_BOOL (*is_wmt_quick_ps_support)(VOID);
+	UINT8 out_buf[STP_PSM_TX_SIZE];
+} MTKSTP_PSM_T;
+
+typedef struct {
+	UINT32 prev_flag;
+	UINT32 cur_flag;
+	UINT32 line_num;
+	UINT32 package_no;
+	UINT32 sec;
+	UINT32 usec;
+	UINT32 pid;
+} STP_PSM_ENTRY_T;
+
+typedef struct stp_psm_record {
+	STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE];
+	UINT32 in;
+	UINT32 out;
+	UINT32 size;
+	OSAL_UNSLEEPABLE_LOCK lock;
+} STP_PSM_RECORD_T;
+
+typedef struct stp_psm_opid_record {
+	STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE];
+	UINT32 in;
+	UINT32 out;
+	UINT32 size;
+	OSAL_UNSLEEPABLE_LOCK lock;
+} STP_PSM_OPID_RECORD, *P_STP_PSM_OPID_RECORD;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#define PSM_USE_COUNT_PACKAGE 0
+
+#if PSM_USE_COUNT_PACKAGE
+#define MTK_COMBO_PSM_RX_TH_DEFAULT (1600)
+#define MTK_COMBO_PSM_TX_TH_DEFAULT (300)
+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir);
+#else
+#define SAMPLE_DURATION 1	/*1 second */
+#define RTX_SPEED_THRESHOLD     50000	/*50KB/s */
+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length);
+#endif
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*stp-psm external function*/
+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action);
+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm);
+
+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type);
+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep);
+struct mtk_stp_psm *stp_psm_init(void);
+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm);
+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel);
+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state);
+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID);
+
+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm);
+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h
new file mode 100644
index 0000000000000..eaa5ce773e332
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h
@@ -0,0 +1,629 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _STP_CORE_H
+#define _STP_CORE_H
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "stp_exp.h"
+#include "psm_core.h"
+#include "btm_core.h"
+#include "stp_btif.h"
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+#define CFG_STP_CORE_CTX_SPIN_LOCK (0)
+
+#define WMT_LTE_COEX_FLAG (0x16)
+
+/*configure using SPINLOCK or just mutex for STP-CORE tx*/
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define CONFIG_POWER_SAVING_SUPPORT
+
+#ifdef PFX
+#undef PFX
+#endif
+#define PFX                         "[STP] "
+
+#define STP_LOG_DBG                  4
+#define STP_LOG_PKHEAD               3
+#define STP_LOG_INFO                 2
+#define STP_LOG_WARN                 1
+#define STP_LOG_ERR                  0
+
+extern unsigned int gStpDbgLvl;
+
+#define STP_DBG_FUNC(fmt, arg...)\
+do { \
+	if (gStpDbgLvl >= STP_LOG_DBG) \
+		osal_dbg_print(PFX "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_INFO_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgLvl >= STP_LOG_INFO) \
+		osal_dbg_print(PFX "%s:[I] "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_WARN_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgLvl >= STP_LOG_WARN) \
+		osal_warn_print(PFX "%s:[W] "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_ERR_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgLvl >= STP_LOG_ERR) \
+		osal_err_print(PFX "%s:[E] "   fmt, __func__ , ##arg); \
+} while (0)
+#define STP_TRC_FUNC(f) \
+do { \
+	if (gStpDbgLvl >= STP_LOG_DBG) \
+		osal_dbg_print(PFX "<%s> <%d>\n", __func__, __LINE__); \
+} while (0)
+
+#define STP_DUMP_PACKET_HEAD(a, b, c) \
+do { \
+	if (gStpDbgLvl >= STP_LOG_PKHEAD) \
+		stp_dump_data(a, b, c); \
+} while (0)
+#define STP_TRACE_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgLvl >= STP_LOG_DBG) \
+		osal_dbg_print(PFX "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+
+#define STP_MODE_BIT(x) (0x1UL << x)
+#define MTKSTP_UART_FULL_MODE	  STP_MODE_BIT(0)
+#define MTKSTP_UART_MAND_MODE	  STP_MODE_BIT(1)
+#define MTKSTP_BTIF_FULL_MODE	  STP_MODE_BIT(2)
+#define MTKSTP_BTIF_MAND_MODE	  STP_MODE_BIT(3)
+#define MTKSTP_SDIO_MODE          STP_MODE_BIT(4)
+
+#define MTKSTP_BUFFER_SIZE  (16384)
+
+/*To check function driver's status by the the interface*/
+/*Operation definition*/
+#define OP_FUNCTION_ACTIVE         0
+
+/*Driver's status*/
+#define STATUS_OP_INVALID          0
+#define STATUS_FUNCTION_INVALID    1
+
+#define STATUS_FUNCTION_ACTIVE     31
+#define STATUS_FUNCTION_INACTIVE   32
+
+#define MTKSTP_CRC_SIZE     (2)
+#define MTKSTP_HEADER_SIZE  (4)
+#define MTKSTP_SEQ_SIZE     (8)
+
+/*#define MTKSTP_WINSIZE      (4)*/
+#define MTKSTP_WINSIZE      (7)
+#define MTKSTP_TX_TIMEOUT   (180)	/*TODO: Baudrate to decide this */
+#define MTKSTP_RETRY_LIMIT  (10)
+
+#define INDEX_INC(idx)  \
+{                       \
+	idx++;              \
+	idx &= 0x7;         \
+}
+
+#define INDEX_DEC(idx)  \
+{                       \
+	idx--;              \
+	idx &= 0x7;         \
+}
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef INT32(*IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size);
+/* event/signal */
+typedef INT32(*EVENT_SET) (UINT8 function_type);
+typedef INT32(*EVENT_TX_RESUME) (UINT8 winspace);
+typedef INT32(*FUNCTION_STATUS) (UINT8 type, UINT8 op);
+typedef INT32(*WMT_NOTIFY_FUNC_T) (UINT32 action);
+typedef INT32(*BTM_NOTIFY_WMT_FUNC_T) (INT32);
+
+#if CFG_STP_CORE_CTX_SPIN_LOCK
+typedef OSAL_UNSLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK;
+#else
+typedef OSAL_SLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK;
+#endif
+
+typedef struct {
+	/* common interface */
+	IF_TX cb_if_tx;
+	/* event/signal */
+	EVENT_SET cb_event_set;
+	EVENT_TX_RESUME cb_event_tx_resume;
+	FUNCTION_STATUS cb_check_funciton_status;
+} mtkstp_callback;
+
+typedef enum {
+	MTKSTP_SYNC = 0,
+	MTKSTP_SEQ,
+	MTKSTP_ACK,
+	MTKSTP_NAK,
+	MTKSTP_TYPE,
+	MTKSTP_LENGTH,
+	MTKSTP_CHECKSUM,
+	MTKSTP_DATA,
+	MTKSTP_CRC1,
+	MTKSTP_CRC2,
+	MTKSTP_RESYNC1,
+	MTKSTP_RESYNC2,
+	MTKSTP_RESYNC3,
+	MTKSTP_RESYNC4,
+	MTKSTP_FW_MSG,
+} mtkstp_parser_state;
+
+typedef struct {
+	mtkstp_parser_state state;
+	UINT8 seq;
+	UINT8 ack;
+	UINT8 nak;
+	UINT8 type;
+	UINT16 length;
+	UINT8 checksum;
+	UINT16 crc;
+#if 1
+	UINT8 wmtsubtype;
+#endif
+} mtkstp_parser_context_struct;
+
+typedef struct {
+	UINT8 txseq;		/* last tx pkt's seq + 1 */
+	UINT8 txack;		/* last tx pkt's ack */
+	UINT8 rxack;		/* last rx pkt's ack */
+	UINT8 winspace;		/* current sliding window size */
+	UINT8 expected_rxseq;	/* last rx pkt's seq + 1 */
+	UINT8 retry_times;
+} mtkstp_sequence_context_struct;
+
+typedef struct {
+	/* MTK_WCN_MUTEX           mtx; */
+	OSAL_UNSLEEPABLE_LOCK mtx;
+	UINT8 buffer[MTKSTP_BUFFER_SIZE];
+	UINT32 read_p;
+	UINT32 write_p;
+} mtkstp_ring_buffer_struct;
+
+typedef struct {
+	UINT8 inband_rst_set;
+	UINT32 rx_counter;	/* size of current processing pkt in rx_buf[] */
+	UINT8 rx_buf[MTKSTP_BUFFER_SIZE];	/* input buffer of STP, room for current processing pkt */
+	UINT32 tx_read;		/* read ptr of tx_buf[] */
+	UINT32 tx_write;	/* write ptr of tx_buf[] */
+	UINT8 tx_buf[MTKSTP_BUFFER_SIZE];	/* output buffer of STP */
+	UINT32 tx_start_addr[MTKSTP_SEQ_SIZE];	/* ptr of each pkt in tx_buf[] */
+	UINT32 tx_length[MTKSTP_SEQ_SIZE];	/* length of each pkt in tx_buf[] */
+	mtkstp_ring_buffer_struct ring[MTKSTP_MAX_TASK_NUM];	/* ring buffers for each function driver */
+	mtkstp_parser_context_struct parser;	/* current rx pkt's content */
+	mtkstp_sequence_context_struct sequence;	/* state machine's current status */
+	/* MTK_WCN_MUTEX stp_mutex; */
+	/* OSAL_UNSLEEPABLE_LOCK stp_mutex; */
+	STP_CTX_LOCK stp_mutex;
+	/* MTK_WCN_TIMER tx_timer; // timer for tx timeout handling */
+	OSAL_TIMER tx_timer;
+
+	MTKSTP_PSM_T *psm;
+	MTKSTP_BTM_T *btm;
+	UINT8 f_enable;		/* default disabled */
+	UINT8 f_ready;		/* default non-ready */
+	UINT8 f_pending_type;
+	UINT8 f_coredump;	/*block tx flag, for now, only when f/w assert happens, we will set this bit on */
+	UINT8 en_coredump;
+	/* Flag to identify Blueztooth is Bluez/or MTK Stack */
+	MTK_WCN_BOOL f_bluez;
+	MTK_WCN_BOOL f_dbg_en;
+	MTK_WCN_BOOL f_autorst_en;
+
+	/* Flag to identify STP by SDIO or UART */
+	UINT32 f_mode;
+
+	/* Flag to indicate the last WMT CLOSE */
+	UINT32 f_wmt_last_close;
+
+	/* Flag to indicate evt err has triggered assert or not */
+	UINT32 f_evt_err_assert;
+} mtkstp_context_struct;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_init
+* DESCRIPTION
+*  init STP kernel
+* PARAMETERS
+*  cb_func      [IN] function pointers of system APIs
+* RETURNS
+*  INT32    0 = success, others = failure
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_deinit
+* DESCRIPTION
+*  deinit STP kernel
+* PARAMETERS
+*  void
+* RETURNS
+*  INT32    0 = success, others = failure
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_deinit(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_enable
+* DESCRIPTION
+*  enable/disable STP
+* PARAMETERS
+*  value        [IN]        0 = disable, others = enable
+* RETURNS
+*  INT32    0 = success, others = error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_enable(INT32 value);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_ready
+* DESCRIPTION
+*  ready/non-ready STP
+* PARAMETERS
+*  value        [IN]        0 = non-ready, others = ready
+* RETURNS
+*  INT32    0 = success, others = error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_ready(INT32 value);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_coredump_start_ctrl
+* DESCRIPTION
+*  set f/w assert flag in STP context
+* PARAMETERS
+*  value        [IN]        0=assert end, others=assert begins
+* RETURNS
+*  INT32    0=success, others=error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_coredump_start_get
+* DESCRIPTION
+*  get f/w assert flag in STP context
+* PARAMETERS
+*  VOID
+* RETURNS
+*  INT32    0= f/w assert flag is not set, others=f/w assert flag is set
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_coredump_start_get(VOID);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_send_data_raw
+* DESCRIPTION
+*  send raw data to common interface, bypass STP
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    length transmitted
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_set_sdio_mode
+* DESCRIPTION
+*  Set stp for SDIO mode
+* PARAMETERS
+*  sdio_flag  [IN]        sdio mode flag (TRUE:SDIO mode, FALSE:UART mode)
+* RETURNS
+*  void
+*****************************************************************************/
+extern void mtk_wcn_stp_set_mode(UINT32 sdio_flag);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_uart_fullset_mode
+* DESCRIPTION
+*  Is stp use UART Fullset  mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:UART Fullset, FALSE:UART Fullset
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_uart_mand_mode
+* DESCRIPTION
+*  Is stp use UART Mandatory  mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:UART Mandatory, FALSE:UART Mandatory
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void);
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_btif_fullset_mode
+* DESCRIPTION
+*  Is stp use BTIF Fullset  mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:BTIF Fullset, FALSE:BTIF Fullset
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_btif_mand_mode
+* DESCRIPTION
+*  Is stp use BTIF Mandatory  mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:BTIF Mandatory, FALSE:BTIF Mandatory
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_sdio_mode
+* DESCRIPTION
+*  Is stp use SDIO mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:SDIO mode, FALSE:UART mode
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void);
+
+/*****************************************************************************
+* FUNCTION
+*  stp_send_inband_reset
+* DESCRIPTION
+*  To sync to oringnal stp state with f/w stp
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+extern void mtk_wcn_stp_inband_reset(void);
+
+/*****************************************************************************
+* FUNCTION
+*  stp_send_inband_reset
+* DESCRIPTION
+*  To send testing command to chip
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+extern void mtk_wcn_stp_test_cmd(INT32 no);
+
+/*****************************************************************************
+* FUNCTION
+*  stp_send_inband_reset
+* DESCRIPTION
+* To control STP debugging mechanism
+* PARAMETERS
+*  func_no: function control, func_op: dumpping filer, func_param: dumpping parameter
+* RETURNS
+*  none
+*****************************************************************************/
+extern void mtk_wcn_stp_debug_ctrl(INT32 func_no, INT32 func_op, INT32 func_param);
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_flush
+* DESCRIPTION
+*  flush all stp context
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+extern void mtk_wcn_stp_flush_context(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_rx_queue
+* DESCRIPTION
+*  flush all stp rx queue
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+extern void mtk_wcn_stp_flush_rx_queue(UINT32 type);
+
+/*****************************************************************************
+* FUNCTION
+*  set stp debugging mdoe
+* DESCRIPTION
+*  set stp debugging mdoe
+* PARAMETERS
+* dbg_mode: switch to dbg mode ?
+* RETURNS
+*  void
+*****************************************************************************/
+extern void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode);
+
+/*****************************************************************************
+* FUNCTION
+*  set stp auto reset mdoe
+* DESCRIPTION
+*  set stp auto reset mdoe
+* PARAMETERS
+* auto_rst: switch to auto reset mode ?
+* RETURNS
+*  void
+*****************************************************************************/
+extern void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst);
+
+/*stp_psm support*/
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_psm_notify_stp
+* DESCRIPTION
+*  WMT notification to STP that power saving job is done or not
+* PARAMETERS
+*
+* RETURNS
+*  0: Sccuess  Negative value: Fail
+*****************************************************************************/
+extern int mtk_wcn_stp_psm_notify_stp(const UINT32 action);
+
+extern int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_psm_enabla
+* DESCRIPTION
+*  enable STP PSM
+* PARAMETERS
+*  int idle_time_to_sleep: IDLE time to sleep
+* RETURNS
+*  0: Sccuess  Negative value: Fail
+*****************************************************************************/
+extern int mtk_wcn_stp_psm_enable(int idle_time_to_sleep);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_psm_disable
+* DESCRIPTION
+*  disable STP PSM
+* PARAMETERS
+*  void
+* RETURNS
+*  0: Sccuess  Negative value: Fail
+*****************************************************************************/
+extern int mtk_wcn_stp_psm_disable(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_psm_reset
+* DESCRIPTION
+*  reset STP PSM (used on whole chip reset)
+* PARAMETERS
+*  void
+* RETURNS
+*  0: Sccuess  Negative value: Fail
+*****************************************************************************/
+extern int mtk_wcn_stp_psm_reset(void);
+extern void stp_do_tx_timeout(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_btm_get_dmp
+* DESCRIPTION
+*  get stp dump related information
+* PARAMETERS
+*  buffer: dump placement, len: dump size
+* RETURNS
+*   0: Success Negative Value: Fail
+*****************************************************************************/
+extern int mtk_wcn_stp_btm_get_dmp(char *buf, int *len);
+
+extern int mtk_wcn_stp_dbg_enable(void);
+
+extern int mtk_wcn_stp_dbg_disable(void);
+
+extern void mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type);
+
+extern int mtk_wcn_sys_if_rx(UINT8 *data, INT32 size);
+
+extern MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel);
+
+extern INT32 mtk_wcn_stp_dbg_dump_package(VOID);
+
+extern int stp_drv_init(void);
+
+extern void stp_drv_exit(void);
+
+extern INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on);
+
+extern INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on);
+
+extern INT32 mtk_wcn_stp_coredump_flag_get(VOID);
+extern INT32 mtk_wcn_stp_notify_sleep_for_thermal(void);
+
+extern INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value);
+
+/*stp btif API declared*/
+extern INT32 mtk_wcn_stp_open_btif(VOID);
+extern INT32 mtk_wcn_stp_close_btif(VOID);
+extern INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb);
+extern INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len);
+extern INT32 mtk_wcn_stp_wakeup_consys(VOID);
+extern INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag);
+extern INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode);
+extern INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag);
+extern VOID mtk_wcn_stp_ctx_save(VOID);
+extern VOID mtk_wcn_stp_ctx_restore(VOID);
+extern INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(VOID);
+extern VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value);
+extern UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(VOID);
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _STP_CORE_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h
new file mode 100644
index 0000000000000..94b3d8a597ac3
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h
@@ -0,0 +1,89 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _STP_WMT_H
+#define _STP_WMT_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum {
+	BTM_RST_OP = 0,
+	BTM_DMP_OP = 1,
+	BTM_GET_AEE_SUPPORT_FLAG = 2,
+	BTM_MAX_OP,
+} MTKSTP_BTM_WMT_OP_T;
+
+typedef enum {
+	SLEEP = 0,
+	HOST_AWAKE,
+	WAKEUP,
+	EIRQ,
+	ROLL_BACK,
+	STP_PSM_MAX_ACTION
+} MTKSTP_PSM_ACTION_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+extern MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op);
+
+extern INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action);
+extern MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _STP_WMT_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h
new file mode 100644
index 0000000000000..4c64b6b5e65bb
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h
@@ -0,0 +1,74 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_CONF_H_
+#define _WMT_CONF_H_
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define CUST_CFG_WMT "WMT_SOC.cfg"
+#define CUST_CFG_WMT_PREFIX "/lib/firmware/mediatek/"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+INT32 wmt_conf_read_file(VOID);
+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID);
+INT32 wmt_conf_set_cfg_file(const char *name);
+
+#endif /* _WMT_CONF_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h
new file mode 100644
index 0000000000000..cca52a15cc982
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h
@@ -0,0 +1,428 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_CORE_H_
+#define _WMT_CORE_H_
+
+#include "osal.h"
+#include "wmt_ctrl.h"
+#include "wmt_exp.h"
+#include "wmt_plat.h"
+/* TODO: [GeorgeKuo][FixMe] remove temporarily */
+/* for AIF state definition */
+/* #include "mtk_wcn_cmb_stub.h" */
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+#define CFG_CORE_MT6620_SUPPORT 0	/* whether MT6620 is supported or not */
+
+#define CFG_CORE_MT6628_SUPPORT 0	/* whether MT6628 is supported or not */
+
+#define CFG_CORE_SOC_SUPPORT 1
+
+/* TODO:[ChangeFeature][George] move this definition outside so that wmt_dev can remove wmt_core.h inclusion. */
+#define defaultPatchName "mt66xx_patch_hdr.bin"
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define BCNT_PATCH_BUF_HEADROOM (8)
+
+#define DWCNT_HIF_CONF    (4)
+#define DWCNT_STRAP_CONF  (4)
+#define DWCNT_RESERVED    (8)
+#define DWCNT_CTRL_DATA  (16)
+
+#if 0				/* TODO: [obsolete][GeorgeKuo]: remove ubsolete definitions */
+#define WMT_SET (1)
+#define WMT_QUERY (0)
+#define WMT_PKT_FMT_RAW (1)
+#define WMT_PKT_FMT_STP (0)
+#endif
+
+#define WMT_FUNC_CTRL_ON  (MTK_WCN_BOOL_TRUE)
+#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE)
+
+#define WMT_HDR_LEN             (4)	/* header length */
+#define WMT_STS_LEN             (1)	/* status length */
+#define WMT_FLAG_LEN            (1)
+#define WMT_HIF_UART_INFO_LEN   (4)
+#define WMT_FUNC_CTRL_PARAM_LEN (1)
+
+#define WMT_DEFAULT_BAUD_RATE   (115200)
+
+#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s}
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _ENUM_WMT_FM_T {
+	WMT_FM_INVALID = 0,
+	WMT_FM_I2C = 1,
+	WMT_FM_COMM = 2,
+	WMT_FM_MAX
+} ENUM_WMT_FM_T, *P_ENUM_WMT_FM_T;
+
+typedef enum _ENUM_WMT_HIF_T {
+	WMT_HIF_UART = 0,
+	WMT_HIF_SDIO = 1,
+	WMT_HIF_BTIF = 2,
+	WMT_HIF_MAX
+} ENUM_WMT_HIF_T, *P_ENUM_WMT_HIF_T;
+
+#if 0				/* [George] moved to wmt_exp.h for hif_sdio's use */
+typedef enum {
+	WMT_SDIO_SLOT_INVALID = 0,
+	WMT_SDIO_SLOT_SDIO1 = 1,	/* Wi-Fi dedicated SDIO1 */
+	WMT_SDIO_SLOT_SDIO2 = 2,
+	WMT_SDIO_SLOT_MAX
+} WMT_SDIO_SLOT_NUM;
+
+typedef enum {
+	WMT_SDIO_FUNC_STP = 0,
+	WMT_SDIO_FUNC_WIFI = 1,
+	WMT_SDIO_FUNC_MAX
+} WMT_SDIO_FUNC_TYPE;
+#endif
+
+typedef enum _ENUM_WMT_OPID_T {
+	WMT_OPID_HIF_CONF = 0,
+	WMT_OPID_PWR_ON = 1,
+	WMT_OPID_PWR_OFF = 2,
+	WMT_OPID_FUNC_ON = 3,
+	WMT_OPID_FUNC_OFF = 4,
+	WMT_OPID_REG_RW = 5,	/* TODO:[ChangeFeature][George] is this OP obsoleted? */
+	WMT_OPID_EXIT = 6,
+	WMT_OPID_PWR_SV = 7,
+	WMT_OPID_DSNS = 8,
+	WMT_OPID_LPBK = 9,
+	WMT_OPID_CMD_TEST = 10,
+	WMT_OPID_HW_RST = 11,
+	WMT_OPID_SW_RST = 12,
+	WMT_OPID_BAUD_RST = 13,
+	WMT_OPID_STP_RST = 14,
+	WMT_OPID_THERM_CTRL = 15,
+	WMT_OPID_EFUSE_RW = 16,
+	WMT_OPID_GPIO_CTRL = 17,
+	WMT_OPID_FW_COREDMP = 18,
+	WMT_OPID_GPIO_STATE = 19,
+	WMT_OPID_BGW_DS = 20,
+	WMT_OPID_SET_MCU_CLK = 21,
+	WMT_OPID_ADIE_LPBK_TEST = 22,
+#if CFG_WMT_LTE_COEX_HANDLING
+	WMT_OPID_IDC_MSG_HANDLING = 23,
+#endif
+#ifdef CONFIG_MTK_COMBO_ANT
+	WMT_OPID_ANT_RAM_DOWN = 24,
+	WMT_OPID_ANT_RAM_STA_GET = 25,
+#endif
+	WMT_OPID_MAX
+} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T;
+
+typedef OSAL_OP_DAT WMT_OP;
+typedef P_OSAL_OP_DAT P_WMT_OP;
+
+typedef struct _WMT_HIF_CONF {
+	UINT32 hifType;		/* HIF Type */
+	UINT32 au4HifConf[DWCNT_HIF_CONF];	/* HIF Config */
+	UINT32 au4StrapConf[DWCNT_STRAP_CONF];	/* Strap Config */
+} WMT_HIF_CONF, *P_WMT_HIF_CONF;
+
+typedef INT32(*WMT_OPID_FUNC) (P_WMT_OP);
+
+typedef struct _WMT_GEN_CONF {
+	UINT8 cfgExist;
+
+	UINT8 coex_wmt_ant_mode;
+	UINT8 coex_wmt_ext_component;
+	UINT8 coex_wmt_wifi_time_ctl;
+	UINT8 coex_wmt_ext_pta_dev_on;
+	/*mt6592 and LTE coex filter mode setting */
+	UINT8 coex_wmt_filter_mode;
+
+	UINT8 coex_bt_rssi_upper_limit;
+	UINT8 coex_bt_rssi_mid_limit;
+	UINT8 coex_bt_rssi_lower_limit;
+	UINT8 coex_bt_pwr_high;
+	UINT8 coex_bt_pwr_mid;
+	UINT8 coex_bt_pwr_low;
+
+	UINT8 coex_wifi_rssi_upper_limit;
+	UINT8 coex_wifi_rssi_mid_limit;
+	UINT8 coex_wifi_rssi_lower_limit;
+	UINT8 coex_wifi_pwr_high;
+	UINT8 coex_wifi_pwr_mid;
+	UINT8 coex_wifi_pwr_low;
+
+	UINT8 coex_ext_pta_hi_tx_tag;
+	UINT8 coex_ext_pta_hi_rx_tag;
+	UINT8 coex_ext_pta_lo_tx_tag;
+	UINT8 coex_ext_pta_lo_rx_tag;
+	UINT16 coex_ext_pta_sample_t1;
+	UINT16 coex_ext_pta_sample_t2;
+	UINT8 coex_ext_pta_wifi_bt_con_trx;
+
+	UINT32 coex_misc_ext_pta_on;
+	UINT32 coex_misc_ext_feature_set;
+	/*GPS LNA setting */
+	UINT8 wmt_gps_lna_pin;
+	UINT8 wmt_gps_lna_enable;
+	/*Power on sequence */
+	UINT8 pwr_on_rtc_slot;
+	UINT8 pwr_on_ldo_slot;
+	UINT8 pwr_on_rst_slot;
+	UINT8 pwr_on_off_slot;
+	UINT8 pwr_on_on_slot;
+	UINT8 co_clock_flag;
+
+	/* Combo chip side SDIO driving setting */
+	UINT32 sdio_driving_cfg;
+
+} WMT_GEN_CONF, *P_WMT_GEN_CONF;
+
+typedef enum _ENUM_DRV_STS_ {
+#if 0
+	DRV_STS_INVALID = 0,
+	DRV_STS_UNREG = 1,	/* Initial State */
+#endif
+	DRV_STS_POWER_OFF = 0,	/* initial state */
+	DRV_STS_POWER_ON = 1,	/* powered on, only WMT */
+	DRV_STS_FUNC_ON = 2,	/* FUNC ON */
+	DRV_STS_MAX
+} ENUM_DRV_STS, *P_ENUM_DRV_STS;
+
+typedef enum _WMT_IC_PIN_ID_ {
+	WMT_IC_PIN_AUDIO = 0,
+	WMT_IC_PIN_EEDI = 1,
+	WMT_IC_PIN_EEDO = 2,
+	WMT_IC_PIN_GSYNC = 3,
+	WMT_IC_PIN_MAX
+} WMT_IC_PIN_ID, *P_WMT_IC_PIN_ID;
+
+typedef enum _WMT_IC_PIN_STATE_ {
+	WMT_IC_PIN_EN = 0,
+	WMT_IC_PIN_DIS = 1,
+	WMT_IC_AIF_0 = 2,	/* = CMB_STUB_AIF_0, */
+	WMT_IC_AIF_1 = 3,	/* = CMB_STUB_AIF_1, */
+	WMT_IC_AIF_2 = 4,	/* = CMB_STUB_AIF_2, */
+	WMT_IC_AIF_3 = 5,	/* = CMB_STUB_AIF_3, */
+	WMT_IC_PIN_MUX = 6,
+	WMT_IC_PIN_GPIO = 7,
+	WMT_IC_PIN_GPIO_HIGH = 8,
+	WMT_IC_PIN_GPIO_LOW = 9,
+	WMT_IC_PIN_STATE_MAX
+} WMT_IC_PIN_STATE, *P_WMT_IC_PIN_STATE;
+
+typedef enum _WMT_CO_CLOCK_ {
+	WMT_CO_CLOCK_DIS = 0,
+	WMT_CO_CLOCK_EN = 1,
+	WMT_CO_CLOCK_MAX
+} WMT_CO_CLOCK, *P_WMT_CO_CLOCK;
+
+typedef INT32(*SW_INIT) (P_WMT_HIF_CONF pWmtHifConf);
+typedef INT32(*SW_DEINIT) (P_WMT_HIF_CONF pWmtHifConf);
+typedef INT32(*IC_PIN_CTRL) (WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag);
+typedef INT32(*IC_VER_CHECK) (VOID);
+typedef INT32(*CO_CLOCK_CTRL) (WMT_CO_CLOCK on);
+typedef MTK_WCN_BOOL(*IS_QUICK_SLEEP_SUPPORT) (VOID);
+typedef MTK_WCN_BOOL(*IS_AEE_DUMP_SUPPORT) (VOID);
+
+typedef struct _WMT_IC_OPS_ {
+	UINT32 icId;
+	SW_INIT sw_init;
+	SW_DEINIT sw_deinit;
+	IC_PIN_CTRL ic_pin_ctrl;
+	IC_VER_CHECK ic_ver_check;
+	CO_CLOCK_CTRL co_clock_ctrl;
+	IS_QUICK_SLEEP_SUPPORT is_quick_sleep;
+	IS_AEE_DUMP_SUPPORT is_aee_dump_support;
+} WMT_IC_OPS, *P_WMT_IC_OPS;
+
+typedef struct _WMT_CTX_ {
+	ENUM_DRV_STS eDrvStatus[WMTDRV_TYPE_MAX];	/* Controlled driver status */
+	UINT32 wmtInfoBit;	/* valid info bit */
+	WMT_HIF_CONF wmtHifConf;	/* HIF information */
+
+	/* Pointer to WMT_IC_OPS. Shall be assigned to a correct table in stp_init
+	 * if and only if getting chip id successfully. hwver and fwver are kept in
+	 * WMT-IC module only.
+	 */
+	P_WMT_IC_OPS p_ic_ops;
+} WMT_CTX, *P_WMT_CTX;
+
+/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */
+/* Using this struct relies on compiler's implementation and pack() settings */
+typedef struct _WMT_PKT_ {
+	UINT8 eType;		/* PKT_TYPE_* */
+	UINT8 eOpCode;		/* OPCODE_* */
+	UINT16 u2SduLen;	/* 2 bytes length, little endian */
+	UINT8 aucParam[32];
+} WMT_PKT, *P_WMT_PKT;
+
+/* WMT Packet Format */
+typedef enum _ENUM_PKT_TYPE {
+	PKT_TYPE_INVALID = 0,
+	PKT_TYPE_CMD = 1,
+	PKT_TYPE_EVENT = 2,
+	_PKT_TYPE_MAX
+} ENUM_PKT_TYPE, *P_ENUM_PKT_TYPE;
+
+typedef enum _ENUM_OPCODE {
+	OPCODE_INVALID = 0,
+	OPCODE_PATCH = 1,
+	OPCODE_TEST = 2,
+	OPCODE_WAKEUP = 3,
+	OPCODE_HIF = 4,
+	OPCODE_STRAP_CONF = 5,
+	OPCODE_FUNC_CTRL = 6,
+	OPCODE_RESET = 7,
+	OPCODE_INT = 8,
+	OPCODE_MAX
+} ENUM_OPCODE, *P_ENUM_OPCODE;
+
+typedef enum {
+	WMT_STP_CONF_EN = 0,
+	WMT_STP_CONF_RDY = 1,
+	WMT_STP_CONF_MODE = 2,
+	WMT_STP_CONF_MAX
+} WMT_STP_CONF_TYPE;
+
+struct init_script {
+	UINT8 *cmd;
+	UINT32 cmdSz;
+	UINT8 *evt;
+	UINT32 evtSz;
+	UINT8 *str;
+};
+
+typedef struct _WMT_PATCH {
+	UINT8 ucDateTime[16];
+	UINT8 ucPLat[4];
+	UINT16 u2HwVer;
+	UINT16 u2SwVer;
+	UINT32 u4PatchVer;
+} WMT_PATCH, *P_WMT_PATCH;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+#if CFG_CORE_MT6620_SUPPORT
+extern WMT_IC_OPS wmt_ic_ops_mt6620;
+#endif
+
+#if CFG_CORE_MT6628_SUPPORT
+extern WMT_IC_OPS wmt_ic_ops_mt6628;
+#endif
+
+#if CFG_CORE_SOC_SUPPORT
+extern WMT_IC_OPS wmt_ic_ops_soc;
+#endif
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+extern INT32 wmt_core_init(VOID);
+extern INT32 wmt_core_deinit(VOID);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_wmtd
+* DESCRIPTION
+*  deinit STP kernel
+* PARAMETERS
+*  void
+* RETURNS
+*  INT32    0 = success, others = failure
+*****************************************************************************/
+extern INT32 wmt_core_opid(P_WMT_OP pWmtOp);
+
+extern INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2);
+
+extern INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn);
+
+extern INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask);
+
+extern VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len);
+
+extern MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer);
+
+extern INT32 wmt_core_init_script(struct init_script *script, INT32 count);
+
+extern INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize);
+
+extern INT32 wmt_core_tx(const PUINT8 pData, UINT32 size, PUINT32 writtenSize, MTK_WCN_BOOL bRawFlag);
+extern MTK_WCN_BOOL wmt_core_is_quick_ps_support(void);
+
+extern MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void);
+
+#if CFG_CORE_INTERNAL_TXRX
+extern INT32 wmt_core_lpbk_do_stp_init(void);
+extern INT32 wmt_core_lpbk_do_stp_deinit(void);
+#endif
+
+extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state);
+#if CFG_WMT_LTE_COEX_HANDLING
+extern VOID wmt_core_set_flag_for_test(UINT32 enable);
+extern UINT32 wmt_core_get_flag_for_test(VOID);
+#endif
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+static _osal_inline_ MTK_WCN_BOOL wmt_core_ic_ops_check(P_WMT_IC_OPS p_ops)
+{
+	if (!p_ops)
+		return MTK_WCN_BOOL_FALSE;
+
+	if ((NULL == p_ops->sw_init)
+	    || (NULL == p_ops->sw_deinit)
+	    || (NULL == p_ops->ic_ver_check)
+	    || (NULL == p_ops->ic_pin_ctrl))
+		return MTK_WCN_BOOL_FALSE;
+	else
+		return MTK_WCN_BOOL_TRUE;
+}
+
+#endif /* _WMT_CORE_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h
new file mode 100644
index 0000000000000..0ff3d6058c394
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h
@@ -0,0 +1,120 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_CTRL_H_
+#define _WMT_CTRL_H_
+
+#include "osal.h"
+#include "wmt_stp_exp.h"
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define DWCNT_CTRL_DATA  (16)
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef struct _WMT_CTRL_DATA_ {
+	SIZE_T ctrlId;
+	SIZE_T au4CtrlData[DWCNT_CTRL_DATA];
+} WMT_CTRL_DATA, *P_WMT_CTRL_DATA;
+
+typedef enum _ENUM_WMT_CTRL_T {
+	WMT_CTRL_HW_PWR_OFF = 0,	/* whole chip power off */
+	WMT_CTRL_HW_PWR_ON = 1,	/* whole chip power on */
+	WMT_CTRL_HW_RST = 2,	/* whole chip rst */
+	WMT_CTRL_STP_CLOSE = 3,
+	WMT_CTRL_STP_OPEN = 4,
+	WMT_CTRL_STP_CONF = 5,
+	WMT_CTRL_FREE_PATCH = 6,
+	WMT_CTRL_GET_PATCH = 7,
+	WMT_CTRL_GET_PATCH_NAME = 8,
+	WMT_CTRL_HWIDVER_SET = 9,	/* TODO: rename this and add chip id information in addition to chip version */
+	WMT_CTRL_STP_RST = 10,
+	WMT_CTRL_GET_WMT_CONF = 11,
+	WMT_CTRL_TX = 12,	/* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */
+	WMT_CTRL_RX = 13,	/* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */
+	WMT_CTRL_RX_FLUSH = 14,	/* [FixMe][SeanWang]: to be removed by Sean's stp integration */
+	WMT_CTRL_GPS_SYNC_SET = 15,
+	WMT_CTRL_GPS_LNA_SET = 16,
+	WMT_CTRL_PATCH_SEARCH = 17,
+	WMT_CTRL_CRYSTAL_TRIMING_GET = 18,
+	WMT_CTRL_CRYSTAL_TRIMING_PUT = 19,
+	WMT_CTRL_HW_STATE_DUMP = 20,
+	WMT_CTRL_GET_PATCH_NUM = 21,
+	WMT_CTRL_GET_PATCH_INFO = 22,
+	WMT_CTRL_SOC_PALDO_CTRL = 23,
+	WMT_CTRL_SOC_WAKEUP_CONSYS = 24,
+	WMT_CTRL_SET_STP_DBG_INFO = 25,
+	WMT_CTRL_BGW_DESENSE_CTRL = 26,
+	WMT_CTRL_EVT_ERR_TRG_ASSERT = 27,
+#if CFG_WMT_LTE_COEX_HANDLING
+	WMT_CTRL_GET_TDM_REQ_ANTSEL = 28,
+#endif
+	WMT_CTRL_EVT_PARSER = 29,
+	WMT_CTRL_MAX
+} ENUM_WMT_CTRL_T, *P_ENUM_WMT_CTRL_T;
+
+typedef INT32(*WMT_CTRL_FUNC) (P_WMT_CTRL_DATA);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+extern INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData);
+
+extern INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WMT_CTRL_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h
new file mode 100644
index 0000000000000..d586f442e7ef0
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h
@@ -0,0 +1,140 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_FUNC_H_
+#define _WMT_FUNC_H_
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "wmt_core.h"
+#include "wmt_plat.h"
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#if 1	/* defined(CONFIG_MTK_COMBO_HCI_DRIVER) || defined(CONFIG_MTK_COMBO_BT) */
+#define CFG_FUNC_BT_SUPPORT 1
+#else
+#define CFG_FUNC_BT_SUPPORT 0
+#endif
+
+#if 1	/* defined(CONFIG_MTK_COMBO_FM) */
+#define CFG_FUNC_FM_SUPPORT 1
+#else
+#define CFG_FUNC_FM_SUPPORT 0
+#endif
+
+#if 1	/* defined(CONFIG_MTK_COMBO_GPS) */
+#define CFG_FUNC_GPS_SUPPORT 1
+#else
+#define CFG_FUNC_GPS_SUPPORT 0
+#endif
+
+#if 1	/* defined(CONFIG_MTK_COMBO_WIFI) */
+#define CFG_FUNC_WIFI_SUPPORT 1
+#else
+#define CFG_FUNC_WIFI_SUPPORT 0
+#endif
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef INT32(*SUBSYS_FUNC_ON) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+typedef INT32(*SUBSYS_FUNC_OFF) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+
+typedef struct _WMT_FUNC_OPS_ {
+	SUBSYS_FUNC_ON func_on;
+	SUBSYS_FUNC_OFF func_off;
+} WMT_FUNC_OPS, *P_WMT_FUNC_OPS;
+
+typedef struct _CMB_PIN_CTRL_REG_ {
+	UINT32 regAddr;
+	UINT32 regValue;
+	UINT32 regMask;
+
+} CMB_PIN_CTRL_REG, *P_CMB_PIN_CTRL_REG;
+
+typedef struct _CMB_PIN_CTRL_ {
+	UINT32 pinId;
+	UINT32 regNum;
+	P_CMB_PIN_CTRL_REG pFuncOnArray;
+	P_CMB_PIN_CTRL_REG pFuncOffArray;
+
+} CMB_PIN_CTRL, *P_CMB_PIN_CTRL;
+
+typedef enum _ENUM_CMP_PIN_ID_ {
+	CMB_PIN_EEDI_ID = 0,
+	CMB_PIN_EEDO_ID = 1,
+	CMB_PIN_GSYNC_ID = 2,
+} ENUM_CMP_PIN_ID, *P_ENUM_CMP_PIN_ID;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+#if CFG_FUNC_BT_SUPPORT
+extern WMT_FUNC_OPS wmt_func_bt_ops;
+#endif
+
+#if CFG_FUNC_FM_SUPPORT
+extern WMT_FUNC_OPS wmt_func_fm_ops;
+#endif
+
+#if CFG_FUNC_GPS_SUPPORT
+extern WMT_FUNC_OPS wmt_func_gps_ops;
+#endif
+
+#if CFG_FUNC_WIFI_SUPPORT
+extern WMT_FUNC_OPS wmt_func_wifi_ops;
+#endif
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WMT_FUNC_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h
new file mode 100644
index 0000000000000..901becfdb92f0
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h
@@ -0,0 +1,122 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_IC_H_
+#define _WMT_IC_H_
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "wmt_core.h"
+#include "wmt_exp.h"
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define WMT_IC_NAME_MT6620 "MT6620"
+#define WMT_IC_NAME_MT6628 "MT6628"
+#define WMT_IC_NAME_DEFAULT "SOC_CONSYS"
+
+#define WMT_IC_VER_E1 "E1"
+#define WMT_IC_VER_E2 "E2"
+#define WMT_IC_VER_E3 "E3"
+#define WMT_IC_VER_E4 "E4"
+#define WMT_IC_VER_E5 "E5"
+#define WMT_IC_VER_E6 "E6"
+
+#define WMT_IC_PATCH_DUMMY_EXT "_ex"
+#define WMT_IC_PATCH_NO_EXT ""
+#define WMT_IC_PATCH_E1_EXT "_e1"
+#define WMT_IC_PATCH_E2_EXT "_e2"
+#define WMT_IC_PATCH_E3_EXT "_e3"
+#define WMT_IC_PATCH_E4_EXT "_e4"
+#define WMT_IC_PATCH_E5_EXT "_e5"
+#define WMT_IC_PATCH_E6_EXT "_e6"
+
+#define WMT_IC_PATCH_TAIL    "_hdr.bin"
+
+#define WMT_IC_INVALID_CHIP_ID 0xFFFF
+
+#define MAJORNUM(x) (x & 0x00F0)
+#define MINORNUM(x) (x & 0x000F)
+
+/*******************************************************************************
+*                             R E G I S T E R   M A P
+********************************************************************************
+*/
+/* General definition used for ALL/UNKNOWN CHIPS */
+/* Now MT6620 uses these definitions */
+#define GEN_CONFG_BASE (0x80000000UL)
+#define GEN_HVR (GEN_CONFG_BASE + 0x0UL)	/* HW_VER */
+#define GEN_FVR (GEN_CONFG_BASE + 0x4UL)	/* FW_VER */
+#define GEN_VER_MASK (0x0000FFFFUL)	/* HW_VER and FW_VER valid bits mask */
+#define GEN_HCR (GEN_CONFG_BASE + 0x8UL)	/* HW_CODE, chip id */
+#define GEN_HCR_MASK (0x0000FFFFUL)	/* HW_CODE valid bits mask */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef struct _WMT_IC_INFO_S {
+	UINT32 u4HwVer;		/* u4HwId */
+	PUINT8 cChipName;
+	PUINT8 cChipVersion;
+	PUINT8 cPatchNameExt;
+	MTK_WCN_BOOL bPsmSupport;
+	MTK_WCN_BOOL bWorkWithoutPatch;
+	ENUM_WMTHWVER_TYPE_T eWmtHwVer;
+} WMT_IC_INFO_S, *P_WMT_IC_INFO_S;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WMT_IC_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h
new file mode 100644
index 0000000000000..b0c05cf3a2529
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h
@@ -0,0 +1,300 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_LIB_H_
+#define _WMT_LIB_H_
+
+#include "osal.h"
+#include "wmt_core.h"
+#include "wmt_exp.h"
+#include <mtk_wcn_cmb_stub.h>
+#include "stp_wmt.h"
+#include "wmt_plat.h"
+#include "wmt_idc.h"
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define WMT_OP_BUF_SIZE (16)
+
+typedef enum _ENUM_WMTRSTRET_TYPE_T {
+	WMTRSTRET_SUCCESS = 0x0,
+	WMTRSTRET_FAIL = 0x1,
+	WMTRSTRET_ONGOING = 0x2,
+	WMTRSTRET_MAX
+} ENUM_WMTRSTRET_TYPE_T, *P_ENUM_WMTRSTRET_TYPE_T;
+
+/*
+3(retry times) * 180 (STP retry time out)
++ 10 (firmware process time) +
+10 (transmit time) +
+10 (uart process -> WMT response pool) +
+230 (others)
+*/
+#define WMT_LIB_RX_TIMEOUT 20000	/*800-->cover v1.2phone BT function on time (~830ms) */
+/*
+open wifi during wifi power on procedure
+(because wlan is insert to system after mtk_hif_sdio module,
+so wifi card is not registered to hif module
+when mtk_wcn_wmt_func_on is called by wifi through rfkill)
+*/
+#define MAX_WIFI_ON_TIME 55000
+
+#define WMT_PWRON_RTY_DFT 2
+#define MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT (WMT_PWRON_RTY_DFT * WMT_LIB_RX_TIMEOUT)
+#define MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY WMT_LIB_RX_TIMEOUT	/*each WMT command */
+#define MAX_FUNC_ON_TIME \
+	(MAX_WIFI_ON_TIME + MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT + MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY * 3)
+
+#define MAX_EACH_FUNC_OFF (WMT_LIB_RX_TIMEOUT + 1000)	/*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */
+#define MAX_FUNC_OFF_TIME (MAX_EACH_FUNC_OFF * 4)
+
+#define MAX_EACH_WMT_CMD (WMT_LIB_RX_TIMEOUT + 1000)	/*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */
+
+#define MAX_GPIO_CTRL_TIME (2000)	/* [FixMe][GeorgeKuo] a temp value */
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/* AIF FLAG definition */
+/* bit(0): share pin or not */
+#define WMT_LIB_AIF_FLAG_MASK (0x1UL)
+#define WMT_LIB_AIF_FLAG_SHARE (0x1UL << 0)
+#define WMT_LIB_AIF_FLAG_SEPARATE (0x0UL << 0)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/* bit field offset definition */
+typedef enum {
+	WMT_STAT_PWR = 0,	/* is powered on */
+	WMT_STAT_STP_REG = 1,	/* is STP driver registered: */
+	WMT_STAT_STP_OPEN = 2,	/* is STP opened: default FALSE */
+	WMT_STAT_STP_EN = 3,	/* is STP enabled: default FALSE */
+	WMT_STAT_STP_RDY = 4,	/* is STP ready for client: default FALSE */
+	WMT_STAT_RX = 5,	/* is rx data available */
+	WMT_STAT_CMD = 6,	/* is cmd string to be read */
+	WMT_STAT_RST_ON = 7,
+	WMT_STAT_MAX
+} WMT_STAT;
+
+typedef enum _ENUM_WMTRSTSRC_TYPE_T {
+	WMTRSTSRC_RESET_BT = 0x0,
+	WMTRSTSRC_RESET_FM = 0x1,
+	WMTRSTSRC_RESET_GPS = 0x2,
+	WMTRSTSRC_RESET_WIFI = 0x3,
+	WMTRSTSRC_RESET_STP = 0x4,
+	WMTRSTSRC_RESET_TEST = 0x5,
+	WMTRSTSRC_RESET_MAX
+} ENUM_WMTRSTSRC_TYPE_T, *P_ENUM_WMTRSTSRC_TYPE_T;
+
+typedef struct {
+	PF_WMT_CB fDrvRst[4];
+} WMT_FDRV_CB, *P_WMT_FDRV_CB;
+
+typedef struct {
+	UINT32 dowloadSeq;
+	UINT8 addRess[4];
+	UINT8 patchName[256];
+} WMT_PATCH_INFO, *P_WMT_PATCH_INFO;
+
+/* OS independent wrapper for WMT_OP */
+typedef struct _DEV_WMT_ {
+
+	OSAL_SLEEPABLE_LOCK psm_lock;
+	OSAL_SLEEPABLE_LOCK idc_lock;
+	/* WMTd thread information */
+	/* struct task_struct *pWmtd; */
+	OSAL_THREAD thread;		/* main thread (wmtd) handle */
+	/* wait_queue_head_t rWmtdWq;   */
+	OSAL_EVENT rWmtdWq;		/*WMTd command wait queue */
+	/* ULONG state; */
+	OSAL_BIT_OP_VAR state;	/* bit field of WMT_STAT */
+
+	/* STP context information */
+	/* wait_queue_head_t rWmtRxWq; */
+	OSAL_EVENT rWmtRxWq;	/* STP Rx wait queue */
+	/* WMT_STP_FUNC rStpFunc; */
+	WMT_FDRV_CB rFdrvCb;	/* STP functions */
+
+	/* WMT Configurations */
+	WMT_HIF_CONF rWmtHifConf;
+	WMT_GEN_CONF rWmtGenConf;
+
+	/* Patch information */
+	UINT8 cPatchName[NAME_MAX + 1];
+	UINT8 cFullPatchName[NAME_MAX + 1];
+	UINT32 patchNum;
+
+	const osal_firmware *pPatch;
+
+	UINT8 cWmtcfgName[NAME_MAX + 1];
+	const osal_firmware *pWmtCfg;
+
+	const osal_firmware *pNvram;
+
+	/* Current used UART port description */
+	INT8 cUartName[NAME_MAX + 1];
+
+	OSAL_OP_Q rFreeOpQ;	/* free op queue */
+	OSAL_OP_Q rActiveOpQ;	/* active op queue */
+	OSAL_OP arQue[WMT_OP_BUF_SIZE];	/* real op instances */
+	P_OSAL_OP pCurOP;	/* current op */
+
+	/* cmd str buffer */
+	UINT8 cCmd[NAME_MAX + 1];
+	INT32 cmdResult;
+	/* struct completion cmd_comp; */
+	/* wait_queue_head_t cmd_wq; */
+	OSAL_SIGNAL cmdResp;	/* read command queues */
+	OSAL_EVENT cmdReq;
+
+	/* WMT loopback Thread Information */
+	/* WMT_CMB_VER combo_ver; */
+	/* P_WMT_CMB_CHIP_INFO_S pChipInfo; */
+	UINT32 chip_id;
+	UINT32 hw_ver;
+	UINT32 fw_ver;
+	/* TODO:  [FixMe][GeorgeKuo] remove this translated version code in the */
+	/* future. Just return the above 3 info to querist */
+	ENUM_WMTHWVER_TYPE_T eWmtHwVer;
+
+	P_WMT_PATCH_INFO pWmtPatchInfo;
+} DEV_WMT, *P_DEV_WMT;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+extern DEV_WMT gDevWmt;
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+extern INT32 wmt_lib_init(VOID);
+extern INT32 wmt_lib_deinit(VOID);
+extern INT32 wmt_lib_tx(PUINT8 data, UINT32 size, PUINT32 writtenSize);
+extern INT32 wmt_lib_tx_raw(PUINT8 data, UINT32 size, PUINT32 writtenSize);
+extern INT32 wmt_lib_rx(PUINT8 buff, UINT32 buffLen, PUINT32 readSize);
+extern VOID wmt_lib_flush_rx(VOID);
+
+#if CFG_WMT_PS_SUPPORT
+extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime);
+extern INT32 wmt_lib_ps_init(VOID);
+extern INT32 wmt_lib_ps_deinit(VOID);
+extern INT32 wmt_lib_ps_enable(VOID);
+extern INT32 wmt_lib_ps_ctrl(UINT32 state);
+
+extern INT32 wmt_lib_ps_disable(VOID);
+extern VOID wmt_lib_ps_irq_cb(VOID);
+#endif
+extern VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb);
+
+/* LXOP functions: */
+extern P_OSAL_OP wmt_lib_get_free_op(VOID);
+extern INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp);
+extern MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp);
+
+/* extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); */
+extern UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T type);
+
+extern MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID);
+extern MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID);
+extern INT32 wmt_lib_trigger_cmd_signal(INT32 result);
+extern PUINT8 wmt_lib_get_cmd(VOID);
+extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID);
+extern INT32 wmt_lib_set_patch_name(PUINT8 cPatchName);
+extern INT32 wmt_lib_set_hif(unsigned long hifconf);
+extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID);
+extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID);
+
+/* GeorgeKuo: replace set_chip_gpio() with more specific ones */
+#if 0				/* moved to wmt_exp.h */
+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share);	/* set AUDIO interface options */
+#endif
+extern INT32 wmt_lib_host_awake_get(VOID);
+extern INT32 wmt_lib_host_awake_put(VOID);
+extern UINT32 wmt_lib_dbg_level_set(UINT32 level);
+
+extern INT32 wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb);
+
+extern INT32 wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType);
+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src);
+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst);
+MTK_WCN_BOOL wmt_lib_hw_rst(VOID);
+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask);
+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask);
+
+extern INT32 DISABLE_PSM_MONITOR(void);
+extern VOID ENABLE_PSM_MONITOR(void);
+extern INT32 wmt_lib_notify_stp_sleep(void);
+extern void wmt_lib_psm_lock_release(void);
+extern INT32 wmt_lib_psm_lock_aquire(void);
+extern VOID wmt_lib_idc_lock_release(VOID);
+extern INT32 wmt_lib_idc_lock_aquire(VOID);
+extern INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value);
+
+extern VOID wmt_lib_set_patch_num(UINT32 num);
+extern VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo);
+extern INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp);
+extern P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev);
+extern PUINT8 wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, PUINT8 buff, UINT32 len);
+extern INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee);
+extern PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 len);
+extern INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl);
+extern UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en);
+extern INT8 wmt_lib_co_clock_get(VOID);
+extern UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver);
+
+#if CFG_WMT_LTE_COEX_HANDLING
+extern MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor);
+#endif
+#if CFG_WMT_PS_SUPPORT
+extern UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en);
+#endif
+#if CONSYS_ENALBE_SET_JTAG
+extern UINT32 wmt_lib_jtag_flag_set(UINT32 en);
+#endif
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WMT_LIB_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c
new file mode 100644
index 0000000000000..c826c513e2bd8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c
@@ -0,0 +1,1890 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "osal_typedef.h"
+#include "osal.h"
+#include "psm_core.h"
+#include "stp_core.h"
+#include <mtk_wcn_cmb_stub.h>
+
+INT32 gPsmDbgLevel = STP_PSM_LOG_INFO;
+MTKSTP_PSM_T stp_psm_i;
+MTKSTP_PSM_T *stp_psm = &stp_psm_i;
+
+STP_PSM_RECORD_T *g_stp_psm_dbg = NULL;
+static UINT32 g_record_num;
+
+P_STP_PSM_OPID_RECORD g_stp_psm_opid_dbg = NULL;
+static UINT32 g_opid_record_num;
+
+#define STP_PSM_LOUD_FUNC(fmt, arg...) \
+do { \
+	if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) \
+		pr_debug(PFX_PSM "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_PSM_DBG_FUNC(fmt, arg...) \
+do { \
+	if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \
+		pr_debug(PFX_PSM "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_PSM_INFO_FUNC(fmt, arg...) \
+do { \
+	if (gPsmDbgLevel >= STP_PSM_LOG_INFO) \
+		pr_debug(PFX_PSM "[I]%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_PSM_WARN_FUNC(fmt, arg...) \
+do { \
+	if (gPsmDbgLevel >= STP_PSM_LOG_WARN) \
+		pr_warn(PFX_PSM "[W]%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_PSM_ERR_FUNC(fmt, arg...) \
+do { \
+	if (gPsmDbgLevel >= STP_PSM_LOG_ERR) \
+		pr_err(PFX_PSM "[E]%s(%d):ERROR! "   fmt, __func__ , __LINE__, ##arg); \
+} while (0)
+#define STP_PSM_TRC_FUNC(f) \
+do { \
+	if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \
+		pr_debug(PFX_PSM "<%s> <%d>\n", __func__, __LINE__); \
+} while (0)
+
+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action);
+static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm);
+static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm);
+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num);
+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg);
+
+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num);
+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg);
+
+static const char *g_psm_state[STP_PSM_MAX_STATE] = {
+	"ACT",
+	"ACT_INACT",
+	"INACT",
+	"INACT_ACT"
+};
+
+static const char *g_psm_action[STP_PSM_MAX_ACTION] = {
+	"SLEEP",
+	"HOST_AWAKE",
+	"WAKEUP",
+	"EIRQ",
+	"ROLL_BACK"
+};
+
+static const char *g_psm_op_name[STP_OPID_PSM_NUM] = {
+	"STP_OPID_PSM_SLEEP",
+	"STP_OPID_PSM_WAKEUP",
+	"STP_OPID_PSM_HOST_AWAKE",
+	"STP_OPID_PSM_EXIT"
+};
+
+static int _stp_psm_release_data(MTKSTP_PSM_T *stp_psm);
+
+static inline int _stp_psm_get_state(MTKSTP_PSM_T *stp_psm);
+
+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ);
+
+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ);
+static MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID);
+
+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel)
+{
+	if (dbglevel <= 4) {
+		gPsmDbgLevel = dbglevel;
+		STP_PSM_INFO_FUNC("gPsmDbgLevel = %d\n", gPsmDbgLevel);
+		return true;
+	}
+	STP_PSM_INFO_FUNC("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel);
+
+	return false;
+}
+
+static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp)
+{
+	INT32 ret = -1;
+
+	/* if (NULL == pStpOp) */
+	/* { */
+	/* return -1; */
+	/* } */
+	ret = _stp_psm_thread_lock_aquire(stp_psm);
+	if (ret) {
+		STP_PSM_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret);
+		return ret;
+	}
+
+	switch (pStpOp->opId) {
+	case STP_OPID_PSM_EXIT:
+		/* TODO: clean all up? */
+		ret = 0;
+		break;
+
+	case STP_OPID_PSM_SLEEP:
+		if (stp_psm_check_sleep_enable(stp_psm) > 0)
+			ret = _stp_psm_notify_wmt(stp_psm, SLEEP);
+		else
+			STP_PSM_INFO_FUNC("cancel sleep request\n");
+
+		break;
+
+	case STP_OPID_PSM_WAKEUP:
+		ret = _stp_psm_notify_wmt(stp_psm, WAKEUP);
+		break;
+
+	case STP_OPID_PSM_HOST_AWAKE:
+		ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE);
+		break;
+
+	default:
+		STP_PSM_ERR_FUNC("invalid operation id (%d)\n", pStpOp->opId);
+		ret = -1;
+		break;
+	}
+	_stp_psm_thread_lock_release(stp_psm);
+	return ret;
+}
+
+static P_OSAL_OP _stp_psm_get_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ)
+{
+	P_OSAL_OP pOp;
+
+	if (!pOpQ) {
+		STP_PSM_WARN_FUNC("pOpQ == NULL\n");
+		return NULL;
+	}
+
+	osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
+	/* acquire lock success */
+	RB_GET(pOpQ, pOp);
+
+	if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) {
+		/* stp_psm->current_active_op = pOp; */
+		stp_psm->last_active_opId = pOp->op.opId;
+	}
+	osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
+
+	if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp))
+		STP_PSM_DBG_FUNC("last_active_opId(%d)\n", stp_psm->last_active_opId);
+
+	if (!pOp)
+		STP_PSM_WARN_FUNC("RB_GET fail\n");
+
+	return pOp;
+}
+
+static INT32 _stp_psm_dump_active_q(P_OSAL_OP_Q pOpQ)
+{
+	UINT32 read_idx;
+	UINT32 write_idx;
+	UINT32 opId;
+
+	if (pOpQ == &stp_psm->rActiveOpQ) {
+		read_idx = stp_psm->rActiveOpQ.read;
+		write_idx = stp_psm->rActiveOpQ.write;
+
+		STP_PSM_DBG_FUNC("Active op list:++\n");
+		while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ))) {
+			opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId;
+			if (opId < STP_OPID_PSM_NUM)
+				STP_PSM_DBG_FUNC("%s\n", g_psm_op_name[opId]);
+			else
+				STP_PSM_WARN_FUNC("Unknown OP Id\n");
+
+			++read_idx;
+		}
+		STP_PSM_DBG_FUNC("Active op list:--\n");
+	} else {
+		STP_PSM_DBG_FUNC("%s: not active queue, dont dump\n", __func__);
+	}
+
+	return 0;
+}
+
+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ)
+{
+	unsigned int opId = 0;
+	unsigned int prev_opId = 0;
+
+	/* if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op)) */
+	if ((pOpQ == &stp_psm->rActiveOpQ) && (STP_OPID_PSM_INALID != stp_psm->last_active_opId)) {
+		opId = pOp->op.opId;
+
+		if (opId == STP_OPID_PSM_SLEEP) {
+			if (RB_EMPTY(pOpQ)) {
+				/* prev_opId = stp_psm->current_active_op->op.opId; */
+				prev_opId = stp_psm->last_active_opId;
+			} else {
+				prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId;
+			}
+
+			if (prev_opId == STP_OPID_PSM_SLEEP) {
+				STP_PSM_DBG_FUNC("redundant sleep opId found\n");
+				return 1;
+			} else {
+				return 0;
+			}
+		} else {
+			if (RB_EMPTY(pOpQ)) {
+				/* prev_opId = stp_psm->current_active_op->op.opId; */
+				prev_opId = stp_psm->last_active_opId;
+			} else {
+				prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId;
+			}
+
+			if (((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_WAKEUP)) ||
+			    ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_WAKEUP)) ||
+			    ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) ||
+			    ((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_HOST_AWAKE))
+			    ) {
+				STP_PSM_DBG_FUNC("redundant opId found, opId(%d), preOpid(%d)\n", opId, prev_opId);
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+	} else {
+		return 0;
+	}
+
+}
+
+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ)
+{
+	unsigned int prev_opId = 0;
+	unsigned int prev_prev_opId = 0;
+
+	P_OSAL_OP pOp;
+	P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ;
+
+	if (pOpQ == &stp_psm->rActiveOpQ) {
+		/* sleep , wakeup | sleep, --> null | sleep (x) */
+		/* wakeup , sleep , wakeup | sleep --> wakeup | sleep (v) */
+		/* sleep , wakeup , sleep | wakeup --> sleep | wakeup (v) */
+		/* xxx, sleep | sleep --> xxx, sleep  (v) */
+		/* xxx, wakeup | wakeup --> xxx, wakeup  (v) */
+		/* xxx, awake | awake --> xxx, awake  (v) --> should never happen */
+		while (RB_COUNT(pOpQ) > 2) {
+			prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId;
+			prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId;
+
+			if ((prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_WAKEUP) ||
+			    (prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) ||
+			    (prev_opId == STP_OPID_PSM_WAKEUP && prev_prev_opId == STP_OPID_PSM_SLEEP) ||
+			    (prev_opId == STP_OPID_PSM_HOST_AWAKE && prev_prev_opId == STP_OPID_PSM_SLEEP)
+			    ) {
+				RB_GET(pOpQ, pOp);
+				RB_PUT(pFreeOpQ, pOp);
+				RB_GET(pOpQ, pOp);
+				RB_PUT(pFreeOpQ, pOp);
+			} else if (prev_opId == prev_prev_opId) {
+				RB_GET(pOpQ, pOp);
+				STP_PSM_DBG_FUNC("redundant opId(%d) found, remove it\n", pOp->op.opId);
+				RB_PUT(pFreeOpQ, pOp);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static INT32 _stp_psm_put_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp)
+{
+	INT32 ret;
+
+	/* if (!pOpQ || !pOp) */
+	/* { */
+	/* STP_PSM_WARN_FUNC("pOpQ = 0x%p, pLxOp = 0x%p\n", pOpQ, pOp); */
+	/* return 0; */
+	/* } */
+	ret = 0;
+
+	osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
+	/* acquire lock success */
+	if (pOpQ == &stp_psm->rActiveOpQ) {
+		if (!_stp_psm_is_redundant_active_op(pOp, pOpQ)) {
+			/* acquire lock success */
+			if (!RB_FULL(pOpQ)) {
+				RB_PUT(pOpQ, pOp);
+				STP_PSM_DBG_FUNC("opId(%d) enqueue\n", pOp->op.opId);
+			} else {
+				STP_PSM_INFO_FUNC("************ Active Queue Full ************\n");
+				ret = -1;
+			}
+
+			_stp_psm_clean_up_redundant_active_op(pOpQ);
+		} else {
+			/*redundant opId, mark ret as success */
+			P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ;
+
+			if (!RB_FULL(pFreeOpQ))
+				RB_PUT(pFreeOpQ, pOp);
+			else
+				osal_assert(!RB_FULL(pFreeOpQ));
+
+			ret = 0;
+		}
+	} else {
+		if (!RB_FULL(pOpQ))
+			RB_PUT(pOpQ, pOp);
+		else
+			ret = -1;
+
+	}
+
+	if (pOpQ == &stp_psm->rActiveOpQ)
+		_stp_psm_dump_active_q(&stp_psm->rActiveOpQ);
+
+
+	osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
+	STP_PSM_DBG_FUNC("stp_psm do unlock,active queue? (%s)\n", (pOpQ == &stp_psm->rActiveOpQ) ? "y" : "n");
+
+	if (ret) {
+		STP_PSM_WARN_FUNC("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n", RB_COUNT(pOpQ), RB_SIZE(pOpQ));
+		return 0;
+	} else
+		return 1;
+
+}
+
+P_OSAL_OP _stp_psm_get_free_op(MTKSTP_PSM_T *stp_psm)
+{
+	P_OSAL_OP pOp;
+
+	if (stp_psm) {
+		pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ);
+		if (pOp)
+			osal_memset(&pOp->op, 0, sizeof(pOp->op));
+
+		return pOp;
+	} else
+		return NULL;
+
+}
+
+INT32 _stp_psm_put_act_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP pOp)
+{
+	INT32 bRet = 0;		/* MTK_WCN_BOOL_FALSE; */
+	INT32 bCleanup = 0;	/* MTK_WCN_BOOL_FALSE; */
+	INT32 wait_ret = -1;
+	P_OSAL_SIGNAL pSignal = NULL;
+
+	do {
+		if (!stp_psm || !pOp) {
+			STP_PSM_ERR_FUNC("stp_psm = %p, pOp = %p\n", stp_psm, pOp);
+			break;
+		}
+
+		pSignal = &pOp->signal;
+
+		if (pSignal->timeoutValue) {
+			pOp->result = -9;
+			osal_signal_init(&pOp->signal);
+		}
+
+		/* put to active Q */
+		bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp);
+
+		if (0 == bRet) {
+			STP_PSM_WARN_FUNC("+++++++++++ Put op Active queue Fail\n");
+			bCleanup = 1;	/* MTK_WCN_BOOL_TRUE; */
+			break;
+		}
+		_stp_psm_opid_dbg_dmp_in(g_stp_psm_opid_dbg, pOp->op.opId, __LINE__);
+
+		/* wake up wmtd */
+		osal_trigger_event(&stp_psm->STPd_event);
+
+		if (pSignal->timeoutValue == 0) {
+			bRet = 1;	/* MTK_WCN_BOOL_TRUE; */
+			/* clean it in wmtd */
+			break;
+		}
+
+		/* wait result, clean it here */
+		bCleanup = 1;	/* MTK_WCN_BOOL_TRUE; */
+
+		/* check result */
+		wait_ret = osal_wait_for_signal_timeout(&pOp->signal);
+		STP_PSM_DBG_FUNC("wait completion:%d\n", wait_ret);
+		if (!wait_ret) {
+			STP_PSM_ERR_FUNC("wait completion timeout\n");
+			/* TODO: how to handle it? retry? */
+		} else {
+			if (pOp->result)
+				STP_PSM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result);
+			/* op completes, check result */
+			bRet = (pOp->result) ? 0 : 1;
+		}
+	} while (0);
+
+	if (bCleanup) {
+		/* put Op back to freeQ */
+		bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp);
+		if (bRet == 0)
+			STP_PSM_WARN_FUNC("+++++++++++ Put op active free fail, maybe disable/enable psm\n");
+	}
+
+	return bRet;
+}
+
+static INT32 _stp_psm_wait_for_msg(void *pvData)
+{
+	MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData;
+
+	STP_PSM_DBG_FUNC("%s: stp_psm->rActiveOpQ = %d\n", __func__, RB_COUNT(&stp_psm->rActiveOpQ));
+
+	return (!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd);
+}
+
+static INT32 _stp_psm_proc(void *pvData)
+{
+	MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData;
+	P_OSAL_OP pOp;
+	UINT32 id;
+	INT32 result;
+
+	if (!stp_psm) {
+		STP_PSM_WARN_FUNC("!stp_psm\n");
+		return -1;
+	}
+/* STP_PSM_INFO_FUNC("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d]\n", */
+/* stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio); */
+
+	for (;;) {
+
+		pOp = NULL;
+
+		osal_wait_for_event(&stp_psm->STPd_event, _stp_psm_wait_for_msg, (void *)stp_psm);
+
+		/* we set reset flag when calling stp_reset after cleanup all op. */
+		if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) {
+			osal_clear_bit(STP_PSM_RESET_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+		}
+		if (osal_thread_should_stop(&stp_psm->PSMd)) {
+			STP_PSM_INFO_FUNC("should stop now...\n");
+			/* TODO: clean up active opQ */
+			break;
+		}
+
+		/* get Op from activeQ */
+		pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ);
+		if (!pOp) {
+			STP_PSM_WARN_FUNC("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n");
+			continue;
+		}
+
+		id = osal_op_get_id(pOp);
+
+		if (id >= STP_OPID_PSM_NUM) {
+			STP_PSM_WARN_FUNC("abnormal opid id: 0x%x\n", id);
+			result = -1;
+			goto handler_done;
+		}
+
+		result = _stp_psm_handler(stp_psm, &pOp->op);
+
+handler_done:
+
+		if (result) {
+			STP_PSM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id,
+					  (id >= 4) ? ("???") : (g_psm_op_name[id]), result);
+		}
+
+		if (osal_op_is_wait_for_signal(pOp))
+			osal_op_raise_signal(pOp, result);
+		else {
+			/* put Op back to freeQ */
+			if (_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0)
+				STP_PSM_WARN_FUNC("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n");
+		}
+
+		if (STP_OPID_PSM_EXIT == id)
+			break;
+	}
+	STP_PSM_INFO_FUNC("exits\n");
+
+	return 0;
+};
+
+static inline INT32 _stp_psm_get_time(void)
+{
+	if (gPsmDbgLevel >= STP_PSM_LOG_LOUD)
+		osal_printtimeofday("<psm time>>>>");
+
+	return 0;
+}
+
+static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm)
+{
+
+	if (stp_psm == NULL)
+		return STP_PSM_OPERATION_FAIL;
+
+	if (stp_psm->work_state < STP_PSM_MAX_STATE)
+		return stp_psm->work_state;
+	STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state);
+
+			return STP_PSM_OPERATION_FAIL;
+}
+
+static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_STATE_T state)
+{
+	if (stp_psm == NULL)
+		return STP_PSM_OPERATION_FAIL;
+
+	if (stp_psm->work_state < STP_PSM_MAX_STATE) {
+		_stp_psm_get_time();
+		/* STP_PSM_INFO_FUNC("work_state = %s --> %s\n",
+		*	g_psm_state[stp_psm->work_state], g_psm_state[state]);
+		*/
+
+		stp_psm->work_state = state;
+		if (stp_psm->work_state != ACT) {
+			/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */
+			osal_set_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */
+		}
+	} else
+		STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state);
+
+
+	return STP_PSM_OPERATION_SUCCESS;
+}
+
+static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm)
+{
+
+	if (!stp_psm)
+		return STP_PSM_OPERATION_FAIL;
+
+	if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) {
+		STP_PSM_DBG_FUNC("STP-PSM DISABLE, DONT restart monitor!\n\r");
+		return STP_PSM_OPERATION_SUCCESS;
+	}
+
+	STP_PSM_LOUD_FUNC("start monitor\n");
+	osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep);
+
+	return STP_PSM_OPERATION_SUCCESS;
+}
+
+static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm)
+{
+
+	if (!stp_psm)
+		return STP_PSM_OPERATION_FAIL;
+
+	STP_PSM_DBG_FUNC("stop monitor\n");
+	osal_timer_stop_sync(&stp_psm->psm_timer);
+
+	return STP_PSM_OPERATION_SUCCESS;
+}
+
+INT32 _stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type)
+{
+	INT32 available_space = 0;
+	INT32 needed_space = 0;
+	UINT8 delimiter[] = { 0xbb, 0xbb };
+
+	if (!stp_psm)
+		return STP_PSM_OPERATION_FAIL;
+
+	osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global);
+
+	available_space = STP_PSM_FIFO_SIZE - osal_fifo_len(&stp_psm->hold_fifo);
+	needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2;
+
+	/* STP_PSM_INFO_FUNC("*******FIFO Available(%d), Need(%d)\n", available_space, needed_space); */
+
+	if (available_space < needed_space) {
+		STP_PSM_ERR_FUNC("FIFO Available!! Reset FIFO\n");
+		osal_fifo_reset(&stp_psm->hold_fifo);
+	}
+	/* type */
+	osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8));
+	/* length */
+	osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32));
+	/* buffer */
+	osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) buffer, len);
+	/* delimiter */
+	osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) delimiter, 2);
+
+	osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global);
+
+	return len;
+
+}
+
+INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm)
+{
+	return osal_fifo_len(&stp_psm->hold_fifo);
+}
+
+INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm)
+{
+
+	INT32 i = 20;		/*Max buffered packet number */
+	INT32 ret = 0;
+	UINT8 type = 0;
+	UINT32 len = 0;
+	UINT8 delimiter[2];
+
+	/* STP_PSM_ERR_FUNC("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo)); */
+	while (osal_fifo_len(&stp_psm->hold_fifo) && i > 0) {
+		/* acquire spinlock */
+		osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global);
+
+		ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8));
+		ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32));
+
+		if (len > STP_PSM_PACKET_SIZE_MAX) {
+			STP_PSM_ERR_FUNC("***psm packet's length too Long!****\n");
+			STP_PSM_INFO_FUNC("***reset psm's fifo***\n");
+		} else {
+			osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE);
+			ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) stp_psm->out_buf, len);
+		}
+
+		ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) delimiter, 2);
+
+		if (delimiter[0] == 0xbb && delimiter[1] == 0xbb) {
+			/* osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32); */
+			stp_send_data_no_ps(stp_psm->out_buf, len, type);
+		} else {
+			STP_PSM_ERR_FUNC("***psm packet fifo parsing fail****\n");
+			STP_PSM_INFO_FUNC("***reset psm's fifo***\n");
+
+			osal_fifo_reset(&stp_psm->hold_fifo);
+		}
+		i--;
+		osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global);
+	}
+	return STP_PSM_OPERATION_SUCCESS;
+}
+
+static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm)
+{
+
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_psm == NULL)
+		return STP_PSM_OPERATION_FAIL;
+
+	pOp = _stp_psm_get_free_op(stp_psm);
+	if (!pOp) {
+		STP_PSM_WARN_FUNC("get_free_lxop fail\n");
+		return -1;	/* break; */
+	}
+
+	pOp->op.opId = STP_OPID_PSM_HOST_AWAKE;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_psm_put_act_op(stp_psm, pOp);
+
+	STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+
+	retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0;
+
+	return retval;
+}
+
+static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm)
+{
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_psm == NULL)
+		return STP_PSM_OPERATION_FAIL;
+
+	pOp = _stp_psm_get_free_op(stp_psm);
+	if (!pOp) {
+		STP_PSM_WARN_FUNC("get_free_lxop fail\n");
+		return -1;	/* break; */
+	}
+
+	pOp->op.opId = STP_OPID_PSM_WAKEUP;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_psm_put_act_op(stp_psm, pOp);
+	if (0 == bRet) {
+		STP_PSM_WARN_FUNC("OPID(%d) type(%zd) bRet(%s)\n\n",
+				  pOp->op.opId, pOp->op.au4OpData[0], "fail");
+	}
+	retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS);
+
+	return retval;
+}
+
+static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm)
+{
+	P_OSAL_OP pOp;
+	INT32 bRet;
+	INT32 retval;
+
+	if (stp_psm == NULL)
+		return STP_PSM_OPERATION_FAIL;
+
+	if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag))
+		return 0;
+#if PSM_USE_COUNT_PACKAGE
+	if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag))
+		return 0;
+#endif
+	if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag))
+		return 0;
+
+	pOp = _stp_psm_get_free_op(stp_psm);
+	if (!pOp) {
+		STP_PSM_WARN_FUNC("get_free_lxop fail\n");
+		return -1;	/* break; */
+	}
+
+	pOp->op.opId = STP_OPID_PSM_SLEEP;
+	pOp->signal.timeoutValue = 0;
+	bRet = _stp_psm_put_act_op(stp_psm, pOp);
+
+	STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet);
+
+	retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 1;
+
+	return retval;
+}
+
+/*internal function*/
+
+static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm)
+{
+	INT32 i = 0;
+	P_OSAL_OP_Q pOpQ;
+	P_OSAL_OP pOp;
+
+	STP_PSM_DBG_FUNC("PSM MODE RESET=============================>\n\r");
+
+	STP_PSM_DBG_FUNC("_stp_psm_reset\n");
+	STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
+	osal_wake_unlock(&stp_psm->wake_lock);
+	STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
+
+	/* --> disable psm <--// */
+	stp_psm->flag.data = 0;
+	osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag);
+	_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+	_stp_psm_stop_monitor(stp_psm);
+
+	/* --> prepare the op list <--// */
+	osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
+	RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE);
+	RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE);
+
+	/* stp_psm->current_active_op = NULL; */
+	stp_psm->last_active_opId = STP_OPID_PSM_INALID;
+
+	pOpQ = &stp_psm->rFreeOpQ;
+	for (i = 0; i < STP_OP_BUF_SIZE; i++) {
+		if (!RB_FULL(pOpQ)) {
+			pOp = &stp_psm->arQue[i];
+			RB_PUT(pOpQ, pOp);
+		}
+	}
+	osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
+
+	/* --> clean up interal data structure<--// */
+	_stp_psm_set_state(stp_psm, ACT);
+
+	osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global);
+	osal_fifo_reset(&stp_psm->hold_fifo);
+	osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global);
+
+	/* --> stop psm thread wait <--// */
+	osal_set_bit(STP_PSM_RESET_EN, &stp_psm->flag);
+	_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+	osal_trigger_event(&stp_psm->wait_wmt_q);
+
+	STP_PSM_DBG_FUNC("PSM MODE RESET<============================\n\r");
+
+	return STP_PSM_OPERATION_SUCCESS;
+}
+
+static INT32 _stp_psm_wait_wmt_event(void *pvData)
+{
+	MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData;
+
+	STP_PSM_DBG_FUNC("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data);
+
+	return (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) ||
+		(osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) ||
+		(osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) ||
+		(osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag));
+}
+
+static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm)
+{
+
+	INT32 retval = 0;
+
+	if (stp_psm == NULL)
+		return STP_PSM_OPERATION_FAIL;
+
+	osal_wait_for_event_timeout(&stp_psm->wait_wmt_q, _stp_psm_wait_wmt_event, (void *)stp_psm);
+
+	if (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) {
+		osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag);
+		_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */
+		/* STP send data here: STP enqueue data to psm buffer. */
+		_stp_psm_release_data(stp_psm);
+		/* STP send data here: STP enqueue data to psm buffer. We release packet by the next one. */
+		osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag);
+		_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+		/* STP send data here: STP sends data directly without PSM. */
+		_stp_psm_set_state(stp_psm, ACT);
+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */
+
+		if (stp_psm_is_quick_ps_support())
+			stp_psm_notify_wmt_sleep(stp_psm);
+		else
+			_stp_psm_start_monitor(stp_psm);
+	} else if (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) {
+		osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag);
+		_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+		_stp_psm_set_state(stp_psm, INACT);
+
+		STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle++\n");
+		mt_combo_plt_enter_deep_idle(COMBO_IF_BTIF);
+		STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle--\n");
+
+		STP_PSM_DBG_FUNC("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
+		osal_wake_unlock(&stp_psm->wake_lock);
+		STP_PSM_DBG_FUNC("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
+	} else if (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) {
+		osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag);
+		_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+		if (_stp_psm_get_state(stp_psm) == ACT_INACT) {
+			/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */
+			_stp_psm_release_data(stp_psm);
+			osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			_stp_psm_set_state(stp_psm, ACT);
+			/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */
+		} else if (_stp_psm_get_state(stp_psm) == INACT_ACT) {
+			_stp_psm_set_state(stp_psm, INACT);
+			STP_PSM_INFO_FUNC("[WARNING]PSM state rollback due too wakeup fail\n");
+		}
+	} else if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) {
+		osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag);
+		_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+	} else {
+		STP_PSM_ERR_FUNC("flag = %ld<== Abnormal flag be set!!\n\r", stp_psm->flag.data);
+		STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+		wcn_psm_flag_trigger_collect_ftrace();	/* trigger collect SYS_FTRACE */
+		_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+	}
+	retval = STP_PSM_OPERATION_SUCCESS;
+
+	return retval;
+}
+
+static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action)
+{
+
+	INT32 retval = 0;
+
+	if (action == EIRQ) {
+		STP_PSM_DBG_FUNC("Call _stp_psm_notify_wmt_host_awake_wq\n\r");
+
+		_stp_psm_notify_wmt_host_awake_wq(stp_psm);
+
+		return STP_PSM_OPERATION_FAIL;
+	}
+
+	if ((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0)) {
+		STP_PSM_DBG_FUNC("state = %s, action=%s\n\r", g_psm_state[_stp_psm_get_state(stp_psm)],
+				 g_psm_action[action]);
+	}
+	/* If STP trigger WAKEUP and SLEEP, to do the job below */
+	switch (_stp_psm_get_state(stp_psm)) {
+		/* stp trigger */
+	case ACT_INACT:
+
+		if (action == SLEEP) {
+			STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, ready to INACT\n\r", g_psm_action[action]);
+			osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			osal_set_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			/* wake_up(&stp_psm->wait_wmt_q); */
+			osal_trigger_event(&stp_psm->wait_wmt_q);
+		} else if (action == ROLL_BACK) {
+			STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, back to ACT\n\r", g_psm_action[action]);
+			/* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */
+			osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			/* wake_up(&stp_psm->wait_wmt_q); */
+			osal_trigger_event(&stp_psm->wait_wmt_q);
+		} else {
+			if (action < STP_PSM_MAX_ACTION) {
+				STP_PSM_ERR_FUNC("Action = %s, ACT_INACT state, the case should not happens\n\r",
+						 g_psm_action[action]);
+				STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+			} else {
+				STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
+			}
+			_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+			retval = STP_PSM_OPERATION_FAIL;
+		}
+		break;
+		/* stp trigger */
+
+	case INACT_ACT:
+
+		if (action == WAKEUP) {
+			STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]);
+			osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			/* wake_up(&stp_psm->wait_wmt_q); */
+			osal_trigger_event(&stp_psm->wait_wmt_q);
+		} else if (action == HOST_AWAKE) {
+			STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]);
+			osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			/* wake_up(&stp_psm->wait_wmt_q); */
+			osal_trigger_event(&stp_psm->wait_wmt_q);
+		} else if (action == ROLL_BACK) {
+			STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, back to INACT\n\r", g_psm_action[action]);
+			osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag);
+			_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			/* wake_up(&stp_psm->wait_wmt_q); */
+			osal_trigger_event(&stp_psm->wait_wmt_q);
+		} else {
+			if (action < STP_PSM_MAX_ACTION) {
+				STP_PSM_ERR_FUNC("Action = %s, INACT_ACT state, the case should not happens\n\r",
+						 g_psm_action[action]);
+				STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+			} else {
+				STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
+			}
+			_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+			retval = STP_PSM_OPERATION_FAIL;
+		}
+		break;
+
+	case INACT:
+
+		if (action < STP_PSM_MAX_ACTION) {
+			STP_PSM_ERR_FUNC("Action = %s, INACT state, the case should not happens\n\r",
+					 g_psm_action[action]);
+			STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+		} else {
+			STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
+		}
+		_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+		retval = -1;
+
+		break;
+
+	case ACT:
+
+		if (action < STP_PSM_MAX_ACTION) {
+			STP_PSM_ERR_FUNC("Action = %s, ACT state, the case should not happens\n\r",
+					 g_psm_action[action]);
+			STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+		} else {
+			STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
+		}
+		_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+		retval = STP_PSM_OPERATION_FAIL;
+
+		break;
+
+	default:
+
+		/*invalid */
+		if (action < STP_PSM_MAX_ACTION) {
+			STP_PSM_ERR_FUNC("Action = %s, Invalid state, the case should not happens\n\r",
+					 g_psm_action[action]);
+			STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+		} else {
+			STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
+		}
+		_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+		retval = STP_PSM_OPERATION_FAIL;
+
+		break;
+	}
+
+	return retval;
+
+}
+
+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action)
+{
+	INT32 ret = 0;
+
+	if (stp_psm == NULL)
+		return STP_PSM_OPERATION_FAIL;
+
+	switch (_stp_psm_get_state(stp_psm)) {
+	case ACT:
+
+		if (action == SLEEP) {
+			if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) {
+				STP_PSM_ERR_FUNC("psm monitor disabled, can't do sleep op\n");
+				return STP_PSM_OPERATION_FAIL;
+			}
+
+			_stp_psm_set_state(stp_psm, ACT_INACT);
+
+			_stp_psm_release_data(stp_psm);
+
+			if (stp_psm->wmt_notify) {
+				stp_psm->wmt_notify(SLEEP);
+				_stp_psm_wait_wmt_event_wq(stp_psm);
+			} else {
+				STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n");
+				ret = STP_PSM_OPERATION_FAIL;
+			}
+		} else if (action == WAKEUP || action == HOST_AWAKE) {
+			STP_PSM_INFO_FUNC("In ACT state, dont do WAKEUP/HOST_AWAKE again\n");
+			_stp_psm_release_data(stp_psm);
+		} else {
+			STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n");
+			STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+			_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+			ret = STP_PSM_OPERATION_FAIL;
+
+		}
+
+		break;
+
+	case INACT:
+
+		if (action == WAKEUP) {
+			_stp_psm_set_state(stp_psm, INACT_ACT);
+
+			if (stp_psm->wmt_notify) {
+				STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
+				osal_wake_lock(&stp_psm->wake_lock);
+				STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock));
+
+				STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n");
+				mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF);
+				STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n");
+
+				stp_psm->wmt_notify(WAKEUP);
+				_stp_psm_wait_wmt_event_wq(stp_psm);
+			} else {
+				STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n");
+				ret = STP_PSM_OPERATION_FAIL;
+			}
+		} else if (action == HOST_AWAKE) {
+			_stp_psm_set_state(stp_psm, INACT_ACT);
+
+			if (stp_psm->wmt_notify) {
+				STP_PSM_DBG_FUNC("host awake +wake_lock(%d)\n",
+						 osal_wake_lock_count(&stp_psm->wake_lock));
+				osal_wake_lock(&stp_psm->wake_lock);
+				STP_PSM_DBG_FUNC("host awake +wake_lock(%d)#\n",
+						 osal_wake_lock_count(&stp_psm->wake_lock));
+
+				STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n");
+				mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF);
+				STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n");
+
+				stp_psm->wmt_notify(HOST_AWAKE);
+				_stp_psm_wait_wmt_event_wq(stp_psm);
+			} else {
+				STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n");
+				ret = STP_PSM_OPERATION_FAIL;
+			}
+		} else if (action == SLEEP) {
+			STP_PSM_INFO_FUNC("In INACT state, dont do SLEEP again\n");
+		} else {
+			STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n");
+			STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+			_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+			ret = STP_PSM_OPERATION_FAIL;
+		}
+
+		break;
+
+	default:
+
+		/*invalid */
+		STP_PSM_ERR_FUNC("invalid state, the case should not happen\n");
+		STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data);
+		_stp_psm_dbg_out_printk(g_stp_psm_dbg);
+		ret = STP_PSM_OPERATION_FAIL;
+
+		break;
+	}
+	return ret;
+}
+
+static inline void _stp_psm_stp_is_idle(/*unsigned long data*/struct timer_list *t)
+{
+	//MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) data;
+	MTKSTP_PSM_T *stp_psm = from_timer(stp_psm,t,psm_timer.timer);
+
+	osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag);
+	_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+	osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag);
+	_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+	if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) {
+		STP_PSM_DBG_FUNC("STP-PSM DISABLE!\n");
+		return;
+	}
+
+	if (1 == _stp_psm_notify_wmt_sleep_wq(stp_psm))
+		STP_PSM_INFO_FUNC("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep);
+}
+
+static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm)
+{
+	if (!stp_psm)
+		return STP_PSM_OPERATION_FAIL;
+
+	STP_PSM_INFO_FUNC("init monitor\n");
+
+	stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle;
+	stp_psm->psm_timer.timeroutHandlerData = (unsigned long)stp_psm;
+	osal_timer_create(&stp_psm->psm_timer);
+
+	return STP_PSM_OPERATION_SUCCESS;
+}
+
+static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm)
+{
+
+	if (!stp_psm)
+		return STP_PSM_OPERATION_FAIL;
+
+	STP_PSM_INFO_FUNC("deinit monitor\n");
+
+	osal_timer_stop_sync(&stp_psm->psm_timer);
+
+	return 0;
+}
+
+static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm)
+{
+	INT32 iRet = -1;
+
+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */
+
+	if (osal_test_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag))
+		iRet = 1;
+	else
+		iRet = 0;
+
+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */
+	return iRet;
+}
+
+static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm)
+{
+	if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag))
+		return 1;
+	else
+		return 0;
+}
+
+static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state)
+{
+
+#define POLL_WAIT 20		/* 200 */
+#define POLL_WAIT_TIME 2000
+
+	INT32 i = 0;
+	INT32 limit = POLL_WAIT_TIME / POLL_WAIT;
+
+	while (_stp_psm_get_state(stp_psm) != state && i < limit) {
+		osal_sleep_ms(POLL_WAIT);
+		i++;
+		STP_PSM_INFO_FUNC("STP is waiting state for %s, i=%d, state = %d\n", g_psm_state[state], i,
+				  _stp_psm_get_state(stp_psm));
+	}
+
+	if (i == limit) {
+		STP_PSM_WARN_FUNC("-Wait for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT);
+		_stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg);
+		return STP_PSM_OPERATION_FAIL;
+	}
+	STP_PSM_DBG_FUNC("+Total waits for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT);
+	/* _stp_psm_dbg_out_printk(g_stp_psm_opid_dbg); */
+	return STP_PSM_OPERATION_SUCCESS;
+}
+
+static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm)
+{
+
+	INT32 ret = 0;
+	INT32 retry = 10;
+	P_OSAL_OP_Q pOpQ;
+	P_OSAL_OP pOp;
+
+	STP_PSM_LOUD_FUNC("*** Do Force Wakeup!***\n\r");
+
+	/* <1>If timer is active, we will stop it. */
+	_stp_psm_stop_monitor(stp_psm);
+
+	osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
+
+	pOpQ = &stp_psm->rFreeOpQ;
+
+	while (!RB_EMPTY(&stp_psm->rActiveOpQ)) {
+		RB_GET(&stp_psm->rActiveOpQ, pOp);
+		if (NULL != pOp && !RB_FULL(pOpQ)) {
+			STP_PSM_DBG_FUNC("opid = %d\n", pOp->op.opId);
+			RB_PUT(pOpQ, pOp);
+		} else {
+			STP_PSM_ERR_FUNC("clear up active queue fail, freeQ full\n");
+		}
+	}
+	osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
+	/* <5>We issue wakeup request into op queue. and wait for active. */
+	do {
+		ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm);
+
+		if (ret == STP_PSM_OPERATION_SUCCESS) {
+			ret = _stp_psm_do_wait(stp_psm, ACT);
+
+			/* STP_PSM_INFO_FUNC("<< wait ret = %d, num of activeQ = %d\n",
+			*	ret,  RB_COUNT(&stp_psm->rActiveOpQ));
+			*/
+			if (ret == STP_PSM_OPERATION_SUCCESS)
+				break;
+		} else
+			STP_PSM_ERR_FUNC("_stp_psm_notify_wmt_wakeup_wq fail!!\n");
+
+		/* STP_PSM_INFO_FUNC("retry = %d\n", retry); */
+		retry--;
+
+		if (retry == 0)
+			break;
+	} while (1);
+
+	if (retry == 0)
+		return STP_PSM_OPERATION_FAIL;
+	else
+		return STP_PSM_OPERATION_SUCCESS;
+}
+
+static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm)
+{
+	INT32 ret = STP_PSM_OPERATION_FAIL;
+
+	STP_PSM_DBG_FUNC("PSM Disable start\n\r");
+
+	osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag);
+	_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+	ret = _stp_psm_do_wakeup(stp_psm);
+	if (ret == STP_PSM_OPERATION_SUCCESS)
+		STP_PSM_DBG_FUNC("PSM Disable Success\n");
+	else
+		STP_PSM_ERR_FUNC("***PSM Disable Fail***\n");
+
+	return ret;
+}
+
+static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep)
+{
+	INT32 ret = STP_PSM_OPERATION_FAIL;
+
+	STP_PSM_LOUD_FUNC("PSM Enable start\n\r");
+
+	osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag);
+	_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+
+	ret = _stp_psm_do_wakeup(stp_psm);
+	if (ret == STP_PSM_OPERATION_SUCCESS) {
+		osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag);
+		_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+		stp_psm->idle_time_to_sleep = idle_time_to_sleep;
+
+		if (osal_wake_lock_count(&stp_psm->wake_lock) == 0) {
+			STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
+			osal_wake_lock(&stp_psm->wake_lock);
+			STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock));
+		}
+
+		_stp_psm_start_monitor(stp_psm);
+
+		STP_PSM_DBG_FUNC("PSM Enable succeed\n\r");
+	} else
+		STP_PSM_ERR_FUNC("***PSM Enable Fail***\n");
+
+	return ret;
+}
+
+INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm)
+{
+	return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock);
+}
+
+INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm)
+{
+	osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock);
+	return 0;
+}
+
+MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID)
+{
+	if (stp_psm->is_wmt_quick_ps_support)
+		return (*(stp_psm->is_wmt_quick_ps_support)) ();
+
+	STP_PSM_DBG_FUNC("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r");
+	return MTK_WCN_BOOL_FALSE;
+}
+
+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID)
+{
+	return _stp_psm_is_quick_ps_support();
+}
+
+#if PSM_USE_COUNT_PACKAGE
+int stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, int dir)
+{
+
+	/* easy the variable maintain beween stp tx, rx thread. */
+	/* so we create variable for tx, rx respectively. */
+
+	static int tx_cnt;
+	static int rx_cnt;
+	static int is_tx_first = 1;
+	static int is_rx_first = 1;
+	static unsigned long tx_end_time;
+	static unsigned long rx_end_time;
+
+	/*  */
+	/* BT A2DP                  TX CNT = 220, RX CNT = 843 */
+	/* BT FTP Transferring  TX CNT = 574, RX CNT = 2233 (1228~1588) */
+	/* BT FTP Receiving      TX CNT = 204, RX CNT = 3301 (2072~2515) */
+	/* BT OPP  Tx               TX_CNT= 330, RX CNT = 1300~1800 */
+	/* BT OPP  Rx               TX_CNT= (109~157), RX CNT = 1681~2436 */
+	if (dir == 0) {		/* tx */
+
+		tx_cnt++;
+
+		if (((long)jiffies - (long)tx_end_time >= 0) || (is_tx_first)) {
+			tx_end_time = jiffies + (3 * HZ);
+			STP_PSM_INFO_FUNC("tx cnt = %d in the previous 3 sec\n", tx_cnt);
+			/* if(tx_cnt > 400)//for high traffic , not to do sleep. */
+			if (tx_cnt > 300) {
+				osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag);
+				_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+				stp_psm_start_monitor(stp_psm);
+			} else {
+				osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag);
+				_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			}
+			tx_cnt = 0;
+			if (is_tx_first)
+				is_tx_first = 0;
+		}
+	} else {
+		rx_cnt++;
+
+		if (((long)jiffies - (long)rx_end_time >= 0) || (is_rx_first)) {
+			rx_end_time = jiffies + (3 * HZ);
+			STP_PSM_INFO_FUNC("rx cnt = %d in the previous 3 sec\n", rx_cnt);
+
+			/* if(rx_cnt > 2000)//for high traffic , not to do sleep. */
+			if (rx_cnt > 1200) {	/* for high traffic , not to do sleep. */
+				osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag);
+				_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+				stp_psm_start_monitor(stp_psm);
+			} else {
+				osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag);
+				_stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__);
+			}
+			rx_cnt = 0;
+			if (is_rx_first)
+				is_rx_first = 0;
+		}
+	}
+
+	return 0;
+}
+
+#else
+static struct timeval tv_now, tv_end;
+static INT32 sample_start;
+static INT32 tx_sum_len;
+static INT32 rx_sum_len;
+
+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length)
+{
+	if (sample_start) {
+		if (dir)
+			rx_sum_len += length;
+		else
+			tx_sum_len += length;
+
+		do_gettimeofday(&tv_now);
+		/* STP_PSM_INFO_FUNC("tv_now:%d.%d tv_end:%d.%d\n",
+		*	tv_now.tv_sec,tv_now.tv_usec,tv_end.tv_sec,tv_end.tv_usec);
+		*/
+		if (((tv_now.tv_sec == tv_end.tv_sec) && (tv_now.tv_usec > tv_end.tv_usec)) ||
+		    (tv_now.tv_sec > tv_end.tv_sec)) {
+			STP_PSM_INFO_FUNC("STP speed rx:%d tx:%d\n", rx_sum_len, tx_sum_len);
+			if ((rx_sum_len + tx_sum_len) > RTX_SPEED_THRESHOLD) {
+				/* STP_PSM_INFO_FUNC("High speed,Disable monitor\n"); */
+				osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag);
+				stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP_1000;
+				stp_psm_start_monitor(stp_psm);
+			} else {
+				/* STP_PSM_INFO_FUNC("Low speed,Enable monitor\n"); */
+				stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP;
+				osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag);
+			}
+			sample_start = 0;
+			rx_sum_len = 0;
+			tx_sum_len = 0;
+		}
+	} else {
+		sample_start = 1;
+		do_gettimeofday(&tv_now);
+		tv_end = tv_now;
+		tv_end.tv_sec += SAMPLE_DURATION;
+	}
+
+	return 0;
+}
+#endif
+
+/*external function for WMT module to do sleep/wakeup*/
+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state)
+{
+	return _stp_psm_set_state(stp_psm, state);
+}
+
+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_thread_lock_aquire(stp_psm);
+}
+
+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_thread_lock_release(stp_psm);
+}
+
+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_do_wakeup(stp_psm);
+}
+
+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action)
+{
+
+	return _stp_psm_notify_stp(stp_psm, action);
+}
+
+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_notify_wmt_wakeup_wq(stp_psm);
+}
+
+int stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm)
+{
+
+	return _stp_psm_notify_wmt_sleep_wq(stp_psm);
+}
+
+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_start_monitor(stp_psm);
+}
+
+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_is_to_block_traffic(stp_psm);
+}
+
+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_is_disable(stp_psm);
+}
+
+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_has_pending_data(stp_psm);
+}
+
+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_release_data(stp_psm);
+}
+
+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type)
+{
+	return _stp_psm_hold_data(stp_psm, buffer, len, type);
+}
+
+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_disable(stp_psm);
+}
+
+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep)
+{
+	return _stp_psm_enable(stp_psm, idle_time_to_sleep);
+}
+
+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm)
+{
+	stp_psm_set_sleep_enable(stp_psm);
+
+	return _stp_psm_reset(stp_psm);
+}
+
+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm)
+{
+	return _stp_psm_notify_wmt_sleep_wq(stp_psm);
+}
+
+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm)
+{
+	INT32 ret = 0;
+
+	if (stp_psm) {
+		stp_psm->sleep_en = 1;
+		STP_PSM_DBG_FUNC("\n");
+		ret = 0;
+	} else {
+		STP_PSM_INFO_FUNC("Null pointer\n");
+		ret = -1;
+	}
+
+	return ret;
+}
+
+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm)
+{
+	INT32 ret = 0;
+
+	if (stp_psm) {
+		stp_psm->sleep_en = 0;
+		STP_PSM_DBG_FUNC("\n");
+		ret = 0;
+	} else {
+		STP_PSM_INFO_FUNC("Null pointer\n");
+		ret = -1;
+	}
+
+	return ret;
+}
+
+/* stp_psm_check_sleep_enable  - to check if sleep cmd is enabled or not
+ * @ stp_psm - pointer of psm
+ *
+ * return 1 if sleep is enabled; else return 0 if disabled; else error code
+ */
+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm)
+{
+	INT32 ret = 0;
+
+	if (stp_psm) {
+		ret = stp_psm->sleep_en;
+		STP_PSM_DBG_FUNC("%s\n", ret ? "enabled" : "disabled");
+	} else {
+		STP_PSM_INFO_FUNC("Null pointer\n");
+		ret = -1;
+	}
+
+	return ret;
+}
+
+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num)
+{
+	INT32 index = 0;
+	struct timeval now;
+
+	if (stp_psm_dbg) {
+		osal_lock_unsleepable_lock(&stp_psm_dbg->lock);
+		do_gettimeofday(&now);
+		index = stp_psm_dbg->in - 1;
+		index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE;
+		STP_PSM_DBG_FUNC("index(%d)\n", index);
+		stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag = stp_psm_dbg->queue[index].cur_flag;
+		stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag = flag;
+		stp_psm_dbg->queue[stp_psm_dbg->in].line_num = line_num;
+		stp_psm_dbg->queue[stp_psm_dbg->in].package_no = g_record_num++;
+		stp_psm_dbg->queue[stp_psm_dbg->in].sec = now.tv_sec;
+		stp_psm_dbg->queue[stp_psm_dbg->in].usec = now.tv_usec;
+		stp_psm_dbg->size++;
+		STP_PSM_DBG_FUNC("pre_Flag = %d, cur_flag = %d\n", stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag,
+				 stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag);
+		stp_psm_dbg->size = (stp_psm_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : stp_psm_dbg->size;
+		stp_psm_dbg->in = (stp_psm_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (stp_psm_dbg->in + 1);
+		STP_PSM_DBG_FUNC("record size = %d, in = %d num = %d\n", stp_psm_dbg->size, stp_psm_dbg->in, line_num);
+
+		osal_unlock_unsleepable_lock(&stp_psm_dbg->lock);
+	}
+	return 0;
+}
+
+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg)
+{
+
+	UINT32 dumpSize = 0;
+	UINT32 inIndex = 0;
+	UINT32 outIndex = 0;
+
+	if (!stp_psm_dbg) {
+		STP_PSM_ERR_FUNC("NULL g_stp_psm_dbg reference\n");
+		return -1;
+	}
+	osal_lock_unsleepable_lock(&stp_psm_dbg->lock);
+
+	inIndex = stp_psm_dbg->in;
+	dumpSize = stp_psm_dbg->size;
+	if (STP_PSM_DBG_SIZE == dumpSize)
+		outIndex = inIndex;
+	else
+		outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE;
+
+	STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex);
+	while (dumpSize > 0) {
+
+		pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d)\n",
+		       stp_psm_dbg->queue[outIndex].sec,
+		       stp_psm_dbg->queue[outIndex].usec,
+		       stp_psm_dbg->queue[outIndex].package_no,
+		       stp_psm_dbg->queue[outIndex].prev_flag,
+		       stp_psm_dbg->queue[outIndex].cur_flag, stp_psm_dbg->queue[outIndex].line_num);
+
+		outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1);
+		dumpSize--;
+
+	}
+
+	osal_unlock_unsleepable_lock(&stp_psm_dbg->lock);
+
+	return 0;
+}
+
+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num)
+{
+	INT32 index = 0;
+	struct timeval now;
+
+	if (p_opid_dbg) {
+		osal_lock_unsleepable_lock(&p_opid_dbg->lock);
+		do_gettimeofday(&now);
+		index = p_opid_dbg->in - 1;
+		index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE;
+		STP_PSM_DBG_FUNC("index(%d)\n", index);
+		p_opid_dbg->queue[p_opid_dbg->in].prev_flag = p_opid_dbg->queue[index].cur_flag;
+		p_opid_dbg->queue[p_opid_dbg->in].cur_flag = opid;
+		p_opid_dbg->queue[p_opid_dbg->in].line_num = line_num;
+		p_opid_dbg->queue[p_opid_dbg->in].package_no = g_opid_record_num++;
+		p_opid_dbg->queue[p_opid_dbg->in].sec = now.tv_sec;
+		p_opid_dbg->queue[p_opid_dbg->in].usec = now.tv_usec;
+		p_opid_dbg->queue[p_opid_dbg->in].pid = current->pid;
+		p_opid_dbg->size++;
+		STP_PSM_DBG_FUNC("pre_opid = %d, cur_opid = %d\n", p_opid_dbg->queue[p_opid_dbg->in].prev_flag,
+				 p_opid_dbg->queue[p_opid_dbg->in].cur_flag);
+		p_opid_dbg->size = (p_opid_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : p_opid_dbg->size;
+		p_opid_dbg->in = (p_opid_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (p_opid_dbg->in + 1);
+		STP_PSM_DBG_FUNC("opid record size = %d, in = %d num = %d\n", p_opid_dbg->size, p_opid_dbg->in,
+				 line_num);
+
+		osal_unlock_unsleepable_lock(&p_opid_dbg->lock);
+	}
+	return 0;
+
+}
+
+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg)
+{
+	UINT32 dumpSize = 0;
+	UINT32 inIndex = 0;
+	UINT32 outIndex = 0;
+
+	if (!p_opid_dbg) {
+		STP_PSM_ERR_FUNC("NULL p_opid_dbg reference\n");
+		return -1;
+	}
+	osal_lock_unsleepable_lock(&p_opid_dbg->lock);
+
+	inIndex = p_opid_dbg->in;
+	dumpSize = p_opid_dbg->size;
+	if (STP_PSM_DBG_SIZE == dumpSize)
+		outIndex = inIndex;
+	else
+		outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE;
+
+	STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex);
+	while (dumpSize > 0) {
+
+		pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d) pid(%d)\n",
+		       p_opid_dbg->queue[outIndex].sec,
+		       p_opid_dbg->queue[outIndex].usec,
+		       p_opid_dbg->queue[outIndex].package_no,
+		       p_opid_dbg->queue[outIndex].prev_flag,
+		       p_opid_dbg->queue[outIndex].cur_flag,
+		       p_opid_dbg->queue[outIndex].line_num, p_opid_dbg->queue[outIndex].pid);
+
+		outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1);
+		dumpSize--;
+
+	}
+
+	osal_unlock_unsleepable_lock(&p_opid_dbg->lock);
+
+	return 0;
+
+}
+
+MTKSTP_PSM_T *stp_psm_init(void)
+{
+	INT32 err = 0;
+	INT32 i = 0;
+	INT32 ret = -1;
+
+	STP_PSM_INFO_FUNC("psm init\n");
+
+	stp_psm->work_state = ACT;
+	stp_psm->wmt_notify = wmt_lib_ps_stp_cb;
+	stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support;
+	stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP;
+	stp_psm->flag.data = 0;
+	stp_psm->stp_tx_cb = NULL;
+	stp_psm_set_sleep_enable(stp_psm);
+
+	ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE);
+	if (ret < 0) {
+		STP_PSM_ERR_FUNC("FIFO INIT FAILS\n");
+		goto ERR_EXIT4;
+	}
+
+	osal_fifo_reset(&stp_psm->hold_fifo);
+	osal_sleepable_lock_init(&stp_psm->hold_fifo_spinlock_global);
+	osal_unsleepable_lock_init(&stp_psm->wq_spinlock);
+	osal_sleepable_lock_init(&stp_psm->stp_psm_lock);
+
+/* osal_unsleepable_lock_init(&stp_psm->flagSpinlock); */
+
+	osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6);
+	osal_wake_lock_init(&stp_psm->wake_lock);
+
+	osal_event_init(&stp_psm->STPd_event);
+	RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE);
+	RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE);
+	/* Put all to free Q */
+	for (i = 0; i < STP_OP_BUF_SIZE; i++) {
+		osal_signal_init(&(stp_psm->arQue[i].signal));
+		_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i]));
+	}
+	/* stp_psm->current_active_op = NULL; */
+	stp_psm->last_active_opId = STP_OPID_PSM_INALID;
+	/*Generate BTM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake */
+	stp_psm->PSMd.pThreadData = (VOID *) stp_psm;
+	stp_psm->PSMd.pThreadFunc = (VOID *) _stp_psm_proc;
+	osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME));
+
+	ret = osal_thread_create(&stp_psm->PSMd);
+	if (ret < 0) {
+		STP_PSM_ERR_FUNC("osal_thread_create fail...\n");
+		goto ERR_EXIT5;
+	}
+	/* init_waitqueue_head(&stp_psm->wait_wmt_q); */
+	stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT;
+	osal_event_init(&stp_psm->wait_wmt_q);
+
+	err = _stp_psm_init_monitor(stp_psm);
+	if (err) {
+		STP_PSM_ERR_FUNC("__stp_psm_init ERROR\n");
+		goto ERR_EXIT6;
+	}
+	/* Start STPd thread */
+	ret = osal_thread_run(&stp_psm->PSMd);
+	if (ret < 0) {
+		STP_PSM_ERR_FUNC("osal_thread_run FAILS\n");
+		goto ERR_EXIT6;
+	}
+	/* psm disable in default */
+	_stp_psm_disable(stp_psm);
+
+	g_stp_psm_dbg = (STP_PSM_RECORD_T *) osal_malloc(osal_sizeof(STP_PSM_RECORD_T));
+	if (!g_stp_psm_dbg) {
+		STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n");
+		return NULL;
+	}
+	osal_memset(g_stp_psm_dbg, 0, osal_sizeof(STP_PSM_RECORD_T));
+	osal_unsleepable_lock_init(&g_stp_psm_dbg->lock);
+
+	g_stp_psm_opid_dbg = (STP_PSM_OPID_RECORD *) osal_malloc(osal_sizeof(STP_PSM_OPID_RECORD));
+	if (!g_stp_psm_opid_dbg) {
+		STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n");
+		return NULL;
+	}
+	osal_memset(g_stp_psm_opid_dbg, 0, osal_sizeof(STP_PSM_OPID_RECORD));
+	osal_unsleepable_lock_init(&g_stp_psm_opid_dbg->lock);
+
+	return stp_psm;
+
+ERR_EXIT6:
+
+	ret = osal_thread_destroy(&stp_psm->PSMd);
+	if (ret < 0) {
+		STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n");
+		goto ERR_EXIT5;
+	}
+ERR_EXIT5:
+	osal_fifo_deinit(&stp_psm->hold_fifo);
+ERR_EXIT4:
+
+	return NULL;
+}
+
+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm)
+{
+	INT32 ret = -1;
+
+	STP_PSM_INFO_FUNC("psm deinit\n");
+
+	if (g_stp_psm_dbg) {
+		osal_unsleepable_lock_deinit(&g_stp_psm_dbg->lock);
+		osal_free(g_stp_psm_dbg);
+		g_stp_psm_dbg = NULL;
+	}
+
+	if (!stp_psm)
+		return STP_PSM_OPERATION_FAIL;
+
+	ret = osal_thread_destroy(&stp_psm->PSMd);
+	if (ret < 0)
+		STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n");
+
+	ret = _stp_psm_deinit_monitor(stp_psm);
+	if (ret < 0)
+		STP_PSM_ERR_FUNC("_stp_psm_deinit_monitor ERROR\n");
+
+	osal_wake_lock_deinit(&stp_psm->wake_lock);
+	osal_fifo_deinit(&stp_psm->hold_fifo);
+	osal_sleepable_lock_deinit(&stp_psm->hold_fifo_spinlock_global);
+	osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock);
+	osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock);
+/* osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock); */
+
+	return STP_PSM_OPERATION_SUCCESS;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c
new file mode 100644
index 0000000000000..a3c24ca144411
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c
@@ -0,0 +1,3358 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "osal_typedef.h"
+#include "stp_core.h"
+#include "psm_core.h"
+#include "btm_core.h"
+#include "stp_dbg.h"
+#include "stp_btif.h"
+
+#define PFX                         "[STP] "
+#define STP_LOG_DBG                  4
+#define STP_LOG_PKHEAD               3
+#define STP_LOG_INFO                 2
+#define STP_LOG_WARN                 1
+#define STP_LOG_ERR                  0
+
+#define STP_DEL_SIZE   2	/* STP delimiter length */
+
+UINT32 gStpDbgLvl = STP_LOG_INFO;
+unsigned int g_coredump_mode = 0;
+#define REMOVE_USELESS_LOG 1
+
+#define STP_POLL_CPUPCR_NUM 16
+#define STP_POLL_CPUPCR_DELAY 10
+#define STP_RETRY_OPTIMIZE 0
+
+/* global variables */
+static const UINT8 stp_delimiter[STP_DEL_SIZE] = { 0x55, 0x55 };
+
+static INT32 fgEnableNak;	/* 0=enable NAK; 1=disable NAK */
+static INT32 fgEnableDelimiter;	/* 0=disable Delimiter; 1=enable Delimiter */
+#if STP_RETRY_OPTIMIZE
+static UINT32 g_retry_times;
+#endif
+/* common interface */
+static IF_TX sys_if_tx;
+/* event/signal */
+static EVENT_SET sys_event_set;
+static EVENT_TX_RESUME sys_event_tx_resume;
+static FUNCTION_STATUS sys_check_function_status;
+/* kernel lib */
+/* int                g_block_tx = 0; */
+static mtkstp_context_struct stp_core_ctx = { 0 };
+
+#define STP_PSM_CORE(x)           ((x).psm)
+#define STP_SET_PSM_CORE(x, v)     ((x).psm = (v))
+
+#define STP_BTM_CORE(x)           ((x).btm)
+#define STP_SET_BTM_CORE(x, v)     ((x).btm = (v))
+
+#define STP_IS_ENABLE(x)          ((x).f_enable != 0)
+#define STP_NOT_ENABLE(x)         ((x).f_enable == 0)
+#define STP_SET_ENABLE(x, v)       ((x).f_enable = (v))
+
+#define STP_IS_READY(x)           ((x).f_ready != 0)
+#define STP_NOT_READY(x)          ((x).f_ready == 0)
+#define STP_SET_READY(x, v)        ((x).f_ready = (v))
+
+#define STP_PENDING_TYPE(x)       ((x).f_pending_type)
+#define STP_SET_PENDING_TYPE(x, v) ((x).f_pending_type = (v))
+
+#define STP_BLUE_ANGEL        (0)
+#define STP_BLUE_Z            (1)
+#define STP_BT_STK(x)         ((x).f_bluez)
+#define STP_BT_STK_IS_BLUEZ(x) ((x).f_bluez == (STP_BLUE_Z))
+#define STP_SET_BT_STK(x, v) ((x).f_bluez = (v))
+
+#define STP_IS_ENABLE_DBG(x)         ((x).f_dbg_en != 0)
+#define STP_NOT_ENABLE_DBG(x)        ((x).f_dbg_en == 0)
+#define STP_SET_ENABLE_DBG(x, v)      ((x).f_dbg_en = (v))
+
+#define STP_IS_ENABLE_RST(x)         ((x).f_autorst_en != 0)
+#define STP_NOT_ENABLE_RST(x)        ((x).f_autorst_en == 0)
+#define STP_SET_ENABLE_RST(x, v)        ((x).f_autorst_en = (v))
+
+#define STP_SUPPORT_PROTOCOL(x)      ((x).f_mode)
+#define STP_SET_SUPPORT_PROTOCOL(x, v)  ((x).f_mode = (v))
+
+#define STP_FW_COREDUMP_FLAG(x)  ((x).f_coredump)
+#define STP_SET_FW_COREDUMP_FLAG(x, v)  ((x).f_coredump = (v))
+#define STP_ENABLE_FW_COREDUMP(x, v)  ((x).en_coredump = (v))
+#define STP_ENABLE_FW_COREDUMP_FLAG(x)  ((x).en_coredump)
+
+#define STP_WMT_LAST_CLOSE(x)       ((x).f_wmt_last_close)
+#define STP_SET_WMT_LAST_CLOSE(x, v) ((x).f_wmt_last_close = (v))
+
+#define STP_EVT_ERR_ASSERT(x)		((x).f_evt_err_assert)
+#define STP_SET_EVT_ERR_ASSERT(x, v)	((x).f_evt_err_assert = (v))
+
+/*[PatchNeed]Need to calculate the timeout value*/
+static UINT32 mtkstp_tx_timeout = MTKSTP_TX_TIMEOUT;
+static mtkstp_parser_state prev_state = -1;
+
+#define CONFIG_DEBUG_STP_TRAFFIC_SUPPORT
+#ifdef CONFIG_DEBUG_STP_TRAFFIC_SUPPORT
+static MTKSTP_DBG_T *g_mtkstp_dbg;
+#endif
+static VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len);
+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc);
+static VOID stp_update_tx_queue(UINT32 txseq);
+static VOID stp_rest_ctx_state(VOID);
+static VOID stp_change_rx_state(mtkstp_parser_state next);
+static void stp_tx_timeout_handler(/*unsigned long data*/ struct timer_list *t);
+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len);
+static VOID stp_dump_tx_queue(UINT32 txseq);
+static INT32 stp_is_apply_powersaving(VOID);
+/*static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type);*/
+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length);
+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length);
+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type);
+static VOID stp_send_tx_queue(UINT32 txseq);
+static VOID stp_send_ack(UINT8 txAck, UINT8 nak);
+static INT32 stp_process_rxack(VOID);
+static VOID stp_process_packet(VOID);
+
+/*private functions*/
+
+static INT32 stp_ctx_lock_init(mtkstp_context_struct *pctx)
+{
+#if CFG_STP_CORE_CTX_SPIN_LOCK
+	return osal_unsleepable_lock_init(&((pctx)->stp_mutex));
+#else
+	osal_sleepable_lock_init(&((pctx)->stp_mutex));
+	return 0;
+#endif
+}
+
+static INT32 stp_ctx_lock_deinit(mtkstp_context_struct *pctx)
+{
+#if CFG_STP_CORE_CTX_SPIN_LOCK
+	return osal_unsleepable_lock_deinit(&((pctx)->stp_mutex));
+#else
+	return osal_sleepable_lock_deinit(&((pctx)->stp_mutex));
+#endif
+}
+
+static INT32 stp_ctx_lock(mtkstp_context_struct *pctx)
+{
+#if CFG_STP_CORE_CTX_SPIN_LOCK
+	return osal_lock_unsleepable_lock(&((pctx)->stp_mutex));
+#else
+	return osal_lock_sleepable_lock(&((pctx)->stp_mutex));
+#endif
+}
+
+static INT32 stp_ctx_unlock(mtkstp_context_struct *pctx)
+{
+#if CFG_STP_CORE_CTX_SPIN_LOCK
+	return osal_unlock_unsleepable_lock(&((pctx)->stp_mutex));
+#else
+	return osal_unlock_sleepable_lock(&((pctx)->stp_mutex));
+#endif
+}
+
+MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel)
+{
+	if (dbglevel <= 4) {
+		gStpDbgLvl = dbglevel;
+		STP_INFO_FUNC("gStpDbgLvl = %d\n", gStpDbgLvl);
+		return MTK_WCN_BOOL_TRUE;
+	}
+	STP_INFO_FUNC("invalid stp debug level. gStpDbgLvl = %d\n", gStpDbgLvl);
+
+	return MTK_WCN_BOOL_FALSE;
+}
+
+#if !(REMOVE_USELESS_LOG)
+static UINT8 *stp_type_to_dbg_string(UINT32 type)
+{
+	UINT8 *type_name = NULL;
+
+	if (type == BT_TASK_INDX)
+		type_name = "< BT>";
+	else if (type == GPS_TASK_INDX)
+		type_name = "<GPS>";
+	else if (type == WMT_TASK_INDX)
+		type_name = "<WMT>";
+	else if (type == FM_TASK_INDX)
+		type_name = "< FM>";
+	else if (type == ANT_TASK_INDX)
+		type_name = "<ANT>";
+
+	return type_name;
+}
+#endif
+#if 0
+/*****************************************************************************
+* FUNCTION
+*  crc16
+* DESCRIPTION
+*  Compute the CRC-16 for the data buffer
+* PARAMETERS
+*  crc         [IN]        previous CRC value
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  the updated CRC value
+*****************************************************************************/
+static UINT16 crc16(const UINT8 *buffer, const UINT32 length)
+{
+	UINT32 crc, i;
+
+	/* FIXME: Add STP checksum feature */
+	crc = 0;
+	for (i = 0; i < length; i++, buffer++)
+		crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff];
+
+	return crc;
+}
+
+#endif
+
+VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len)
+{
+
+#ifndef CONFIG_LOG_STP_INTERNAL
+	return;
+#endif
+
+	if (STP_IS_ENABLE_DBG(stp_core_ctx)) {
+		stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_PKT, type,	/* type */
+				txAck,	/* ack */
+				seq,	/* seq */
+				crc,	/* crc */
+				dir,	/* dir */
+				len,	/* len */
+				pBuf);	/* body */
+	} else {
+		STP_DBG_FUNC("stp_dbg not enabled");
+	}
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_check_crc
+* DESCRIPTION
+*  check the check sum of packet payload
+* PARAMETERS
+*  pdata       [IN]        the data want to check
+*  length      [IN]        the length of pdata
+*  crc         [IN]        the crc of pdata
+* RETURNS
+*  KAL_TRUE        crc is ok
+*  KAL_FALSE       crc is wrong
+*****************************************************************************/
+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc)
+{
+    /*----------------------------------------------------------------*/
+	/* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+	UINT16 checksum;
+
+    /*----------------------------------------------------------------*/
+	/* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+	/* FIXME: Add STP feature: check or skip crc */
+
+	checksum = osal_crc16(buffer, length);
+	if (checksum == crc)
+		return MTK_WCN_BOOL_TRUE;
+
+	STP_ERR_FUNC("CRC fail, length = %d, rx = %x, calc = %x \r\n", length, crc, checksum);
+	return MTK_WCN_BOOL_FALSE;
+
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_update_tx_queue
+* DESCRIPTION
+*  update packet's ACK field
+* PARAMETERS
+*  txseq       [IN]        index of the tx packet which we want to update
+* RETURNS
+*  void
+*****************************************************************************/
+static void stp_update_tx_queue(UINT32 txseq)
+{
+	INT32 tx_read, i;
+	UINT8 checksum = 0;
+
+	tx_read = stp_core_ctx.tx_start_addr[txseq];
+	stp_core_ctx.tx_buf[tx_read] &= 0xf8;
+	stp_core_ctx.tx_buf[tx_read] |= stp_core_ctx.sequence.txack;
+
+	for (i = 0; i < 3; i++) {
+		checksum += stp_core_ctx.tx_buf[tx_read];
+		tx_read++;
+		if (tx_read >= MTKSTP_BUFFER_SIZE)
+			tx_read -= MTKSTP_BUFFER_SIZE;
+
+	}
+
+	stp_core_ctx.tx_buf[tx_read] = checksum;
+
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_rest_ctx_state
+* DESCRIPTION
+*  Reset stp context state variables only. Mutex and timer resources are not touched.
+*
+* PARAMETERS
+*  void
+* RETURNS
+*  void
+*****************************************************************************/
+static VOID stp_rest_ctx_state(VOID)
+{
+	INT32 i;
+
+	/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_lock(&stp_core_ctx);
+	stp_core_ctx.rx_counter = 0;
+
+	/*reset rx buffer pointer */
+	for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) {
+		stp_core_ctx.ring[i].read_p = 0;
+		stp_core_ctx.ring[i].write_p = 0;
+	}
+
+	/*reset tx buffer pointer */
+	stp_core_ctx.tx_write = 0;
+	stp_core_ctx.tx_read = 0;
+
+	/*reset STP protocol context */
+	stp_core_ctx.parser.state = MTKSTP_SYNC;
+	stp_core_ctx.sequence.txseq = 0;
+	stp_core_ctx.sequence.txack = 7;
+	stp_core_ctx.sequence.rxack = 7;
+	stp_core_ctx.sequence.winspace = MTKSTP_WINSIZE;
+	stp_core_ctx.sequence.expected_rxseq = 0;
+	stp_core_ctx.sequence.retry_times = 0;
+	stp_core_ctx.inband_rst_set = 0;
+
+	/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_unlock(&stp_core_ctx);
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_change_rx_state
+* DESCRIPTION
+*  change the rx fsm of STP to "next"
+* PARAMETERS
+*  next     [IN] the next state of rx fsm
+* RETURNS
+*  void
+*****************************************************************************/
+static VOID stp_change_rx_state(mtkstp_parser_state next)
+{
+	prev_state = stp_core_ctx.parser.state;
+	stp_core_ctx.parser.state = next;
+
+}
+
+/* static void stp_tx_timeout_handler(void){ */
+static void stp_tx_timeout_handler(/*unsigned long data*/struct timer_list *t)
+{
+	STP_WARN_FUNC("call retry btm retry wq ...\n");
+	/*shorten the softirq lattency */
+	stp_btm_notify_stp_retry_wq(STP_BTM_CORE(stp_core_ctx));
+	STP_WARN_FUNC("call retry btm retry wq ...#\n");
+}
+
+VOID stp_do_tx_timeout(VOID)
+{
+	UINT32 seq;
+	UINT32 ret;
+	INT32 iRet;
+	ENUM_STP_FW_ISSUE_TYPE issue_type;
+	UINT8 resync[4];
+
+	STP_WARN_FUNC("==============================================================================\n");
+
+	/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_lock(&stp_core_ctx);
+
+#if STP_RETRY_OPTIMIZE
+	if ((g_retry_times != 0) && (stp_core_ctx.sequence.retry_times == 0)) {
+		STP_INFO_FUNC("STP TX timeout has been recoveryed by resend,record_retry_time(%d)\n", g_retry_times);
+		g_retry_times = 0;
+		stp_ctx_unlock(&stp_core_ctx);
+		return;
+	}
+#endif
+	if (stp_core_ctx.sequence.retry_times > (MTKSTP_RETRY_LIMIT)) {
+		STP_INFO_FUNC("STP retry times(%d) have reached retry limit,stop it\n",
+			      stp_core_ctx.sequence.retry_times);
+		stp_ctx_unlock(&stp_core_ctx);
+		return;
+	}
+#if STP_RETRY_OPTIMIZE
+	else
+		STP_DBG_FUNC("current TX timeout package has not received ACK yet,retry_times(%d)\n",
+		g_retry_times);
+#endif
+	/*polling cpupcr when no ack occurs at first retry */
+	stp_notify_btm_poll_cpupcr(STP_BTM_CORE(stp_core_ctx), STP_POLL_CPUPCR_NUM, STP_POLL_CPUPCR_DELAY);
+
+	seq = stp_core_ctx.sequence.rxack;
+	INDEX_INC(seq);
+
+	if (seq != stp_core_ctx.sequence.txseq) {
+		osal_memset(&resync[0], 127, 4);
+		(*sys_if_tx) (&resync[0], 4, &ret);
+		if (ret != 4) {
+			STP_ERR_FUNC("mtkstp_tx_timeout_handler: send resync fail\n");
+			osal_assert(0);
+		}
+
+		do {
+			STP_WARN_FUNC("[stp.ctx]*rxack (=last rx ack) = %d\n\r", stp_core_ctx.sequence.rxack);
+			STP_WARN_FUNC("[stp.ctx]txack (=last rx seq)= %d\n\r", stp_core_ctx.sequence.txack);
+			STP_WARN_FUNC("[stp.ctx]*txseq (=next tx seq)= %d\n\r", stp_core_ctx.sequence.txseq);
+			STP_WARN_FUNC("Resend STP packet from %d -> %d\n\r", seq,
+				      (stp_core_ctx.sequence.txseq <= 0) ? (7) : (stp_core_ctx.sequence.txseq - 1));
+			stp_dump_tx_queue(seq);
+
+			stp_send_tx_queue(seq);
+			INDEX_INC(seq);
+		} while (seq != stp_core_ctx.sequence.txseq);
+
+	}
+
+	osal_timer_stop(&stp_core_ctx.tx_timer);
+	osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout);
+
+	if (stp_core_ctx.sequence.winspace == MTKSTP_WINSIZE) {
+		osal_timer_stop(&stp_core_ctx.tx_timer);
+		STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n");
+	} else {
+		stp_core_ctx.sequence.retry_times++;
+		STP_ERR_FUNC("mtkstp_tx_timeout_handler, retry = %d\n", stp_core_ctx.sequence.retry_times);
+#if STP_RETRY_OPTIMIZE
+		g_retry_times = stp_core_ctx.sequence.retry_times;
+#endif
+		/*If retry too much, try to recover STP by return back to initializatin state */
+		/*And not to retry again */
+		if (stp_core_ctx.sequence.retry_times > MTKSTP_RETRY_LIMIT) {
+#if STP_RETRY_OPTIMIZE
+			g_retry_times = 0;
+#endif
+			osal_timer_stop(&stp_core_ctx.tx_timer);
+			stp_ctx_unlock(&stp_core_ctx);
+
+			STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n");
+
+			STP_ERR_FUNC("TX retry limit = %d\n", MTKSTP_RETRY_LIMIT);
+			osal_assert(0);
+			mtk_wcn_stp_dbg_dump_package();
+
+			/*Whole Chip Reset Procedure Invoke */
+			/*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */
+
+			if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) {
+				stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+				mtk_wcn_stp_set_wmt_evt_err_trg_assert(1);
+				stp_dbg_set_host_assert_info(4, 36, 1);
+				STP_INFO_FUNC("**STP NoAck trigger firmware assert**\n");
+				iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx));
+
+				if (iRet) {
+					STP_ERR_FUNC("host tigger fw assert fail(%d), do noack handle flow\n", iRet);
+					mtk_wcn_stp_set_wmt_evt_err_trg_assert(0);
+					issue_type = STP_FW_NOACK_ISSUE;
+					iRet = stp_dbg_set_fw_info("STP NoAck", osal_strlen("STP NoAck"), issue_type);
+
+					osal_dbg_assert_aee("[SOC_CONNSYS]NoAck",
+						"**[WCN_ISSUE_INFO]STP Tx Timeout**\n F/W has NO any RESPONSE. Please check F/W status first\n");
+					if (STP_IS_ENABLE_RST(stp_core_ctx)) {
+						STP_SET_READY(stp_core_ctx, 0);
+						stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx));
+					} else {
+						STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n");
+					}
+				}
+			} else {
+				STP_INFO_FUNC("do trigger assert & chip reset in wmt\n");
+			}
+			return;
+		}
+	}
+
+	/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_unlock(&stp_core_ctx);
+	STP_WARN_FUNC("==============================================================================#\n");
+}
+
+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len)
+{
+	osal_buffer_dump(buf, title, len, 32);
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  stp_tx_timeout_handler
+ * DESCRIPTION
+ *  tx timeout handler, send resync & retransmitt
+ * PARAMETERS
+ *  void
+ * RETURNS
+ *  void
+ *****************************************************************************/
+static VOID stp_dump_tx_queue(UINT32 txseq)
+{
+	INT32 tx_read, tx_length, last_len;
+
+	tx_read = stp_core_ctx.tx_start_addr[txseq];
+	tx_length = stp_core_ctx.tx_length[txseq];
+
+	STP_ERR_FUNC("tx_seq=%d ..", txseq);
+
+	if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) {
+		stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q", (tx_length >= 8) ? (8) : (tx_length));
+	} else {
+		last_len = MTKSTP_BUFFER_SIZE - tx_read;
+		stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q_0", (last_len >= 8) ? (8) : (last_len));
+		stp_dump_data(&stp_core_ctx.tx_buf[0], "tx_q_0",
+			      ((tx_length - last_len) ? (8) : (tx_length - last_len)));
+	}
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_is_apply_powersaving
+* DESCRIPTION
+*  Check if STP support power saving mode.
+* PARAMETERS
+*
+* RETURNS
+*  True: support power saving False: not support power saving
+*****************************************************************************/
+static INT32 stp_is_apply_powersaving(VOID)
+{
+
+	if (STP_IS_READY(stp_core_ctx) && !stp_psm_is_disable(STP_PSM_CORE(stp_core_ctx))) {
+		/* osal_dbg_print("apply power saving\n"); */
+		return MTK_WCN_BOOL_TRUE;
+	}
+	if (mtk_wcn_stp_is_sdio_mode())
+		return MTK_WCN_BOOL_FALSE;
+
+	STP_DBG_FUNC("not apply power saving\n");
+	return MTK_WCN_BOOL_FALSE;
+}
+#if 0
+/*****************************************************************************
+* FUNCTION
+*  stp_is_privileges_cmd
+* DESCRIPTION
+*  Check if the data is privilege command
+* PARAMETERS
+*
+* RETURNS
+*  True/False
+*****************************************************************************/
+static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type)
+{
+	typedef struct privileges_cmd {
+		UINT32 length;
+		UINT8 type;
+		UINT8 buf[7];	/* MAX length of target command is only 5 currently */
+	} p_cmd_t;
+
+	p_cmd_t p_cmd_table[] = {
+		{0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x01} },	/* sleep command */
+		{0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x02} },	/* host_awake command */
+	};
+
+	UINT32 i;
+	UINT32 size = sizeof(p_cmd_table) / sizeof(p_cmd_table[0]);
+
+	for (i = 0; i < size; i++) {
+		if (type != p_cmd_table[i].type)
+			continue;
+
+		if (length != p_cmd_table[i].length)
+			continue;
+
+		if (osal_memcmp(p_cmd_table[i].buf, buffer, length))
+			continue;
+
+		/* matched entry is found */
+		STP_DBG_FUNC("It's p_cmd_t\n");
+		return MTK_WCN_BOOL_TRUE;
+	}
+
+	return MTK_WCN_BOOL_FALSE;
+}
+#endif
+/*****************************************************************************
+* FUNCTION
+*  tx_queue_room_available
+* DESCRIPTION
+*  check room if available,
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  void
+*****************************************************************************/
+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length)
+{
+	UINT32 roomLeft;
+
+	/*
+	   Get available space of TX Queue
+	 */
+	if (stp_core_ctx.tx_read <= stp_core_ctx.tx_write)
+		roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write + stp_core_ctx.tx_read - 1;
+	else
+		roomLeft = stp_core_ctx.tx_read - stp_core_ctx.tx_write - 1;
+
+	if (roomLeft < length) {
+		STP_ERR_FUNC("%s: tx queue room shortage\n", __func__);
+		return MTK_WCN_BOOL_FALSE;
+	} else
+		return MTK_WCN_BOOL_TRUE;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_add_to_tx_queue
+* DESCRIPTION
+*  put data to tx queue
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  void
+*****************************************************************************/
+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length)
+{
+	UINT32 last_len;
+
+	/* Get available space of TX Queue */
+	if (length + stp_core_ctx.tx_write < MTKSTP_BUFFER_SIZE) {
+		osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, length);
+		stp_core_ctx.tx_write += length;
+	} else {
+		last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write;
+		osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, last_len);
+		osal_memcpy(stp_core_ctx.tx_buf, buffer + last_len, length - last_len);
+
+		stp_core_ctx.tx_write = length - last_len;
+	}
+
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_add_to_rx_queue
+* DESCRIPTION
+*  put data to corresponding task's rx queue and notify corresponding task
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        corresponding task index
+* RETURNS
+*  INT32    0=success, others=error
+*****************************************************************************/
+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type)
+{
+	UINT32 roomLeft, last_len;
+
+	osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+
+	if (stp_core_ctx.ring[type].read_p <= stp_core_ctx.ring[type].write_p)
+		roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p + stp_core_ctx.ring[type].read_p - 1;
+	else
+		roomLeft = stp_core_ctx.ring[type].read_p - stp_core_ctx.ring[type].write_p - 1;
+
+	if (roomLeft < length) {
+		osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+		STP_ERR_FUNC("Queue is full !!!, type = %d\n", type);
+		osal_assert(0);
+		return -1;
+	}
+
+	if (length + stp_core_ctx.ring[type].write_p < MTKSTP_BUFFER_SIZE) {
+		osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, length);
+		stp_core_ctx.ring[type].write_p += length;
+	} else {
+		last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p;
+		osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, last_len);
+		osal_memcpy(stp_core_ctx.ring[type].buffer, buffer + last_len, length - last_len);
+		stp_core_ctx.ring[type].write_p = length - last_len;
+	}
+
+	osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_send_tx_queue
+* DESCRIPTION
+*  send data in tx buffer to common interface
+* PARAMETERS
+*  txseq       [IN]        sequence number of outgoing packet in tx buffer
+* RETURNS
+*  void
+*****************************************************************************/
+static VOID stp_send_tx_queue(UINT32 txseq)
+{
+	UINT32 ret;
+	INT32 tx_read, tx_length, last_len;
+
+	tx_read = stp_core_ctx.tx_start_addr[txseq];
+	tx_length = stp_core_ctx.tx_length[txseq];
+
+	stp_update_tx_queue(txseq);
+
+	if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) {
+
+		(*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], tx_length, &ret);
+
+		if (ret != tx_length) {
+			STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length, ret);
+			osal_assert(0);
+		}
+	} else {
+		last_len = MTKSTP_BUFFER_SIZE - tx_read;
+		(*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], last_len, &ret);
+
+		if (ret != last_len) {
+			STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", last_len, ret);
+			osal_assert(0);
+		}
+
+		(*sys_if_tx) (&stp_core_ctx.tx_buf[0], tx_length - last_len, &ret);
+
+		if (ret != tx_length - last_len) {
+			STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length - last_len, ret);
+			osal_assert(0);
+		}
+	}
+
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_send_ack
+* DESCRIPTION
+*  send ack packet to the peer
+* PARAMETERS
+*  txAck    [IN] Ack number
+*  nak      [IN] 0 = ack; !0 = NAK
+* RETURNS
+*  void
+*****************************************************************************/
+static VOID stp_send_ack(UINT8 txAck, UINT8 nak)
+{
+	UINT8 mtkstp_header[MTKSTP_HEADER_SIZE];
+	UINT32 ret;
+	INT32 iStatus;
+
+	mtkstp_header[0] = 0x80 + (0 << 3) + txAck;	/* stp_core_ctx.sequence.txack; */
+
+	if (fgEnableNak == 0)
+		mtkstp_header[1] = 0x00;	/* disable NAK */
+	else
+		mtkstp_header[1] = ((nak == 0) ? 0x00 : 0x80);
+
+	mtkstp_header[2] = 0;
+	mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff;
+
+	stp_dbg_pkt_log(STP_TASK_INDX, txAck, 0, 0, PKT_DIR_TX, NULL, 0);
+
+	if (fgEnableDelimiter == 1) {
+		iStatus = (*sys_if_tx) ((PUINT8) &stp_delimiter[0], STP_DEL_SIZE, &ret);
+		STP_DUMP_PACKET_HEAD((PUINT8) &stp_delimiter[0], "tx del", STP_DEL_SIZE);
+		if (ret != STP_DEL_SIZE) {
+			STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", STP_DEL_SIZE, ret, iStatus);
+			osal_assert(0);
+		}
+	}
+
+	iStatus = (*sys_if_tx) (&mtkstp_header[0], MTKSTP_HEADER_SIZE, &ret);
+
+	if (ret != MTKSTP_HEADER_SIZE) {
+		STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", MTKSTP_HEADER_SIZE, ret, iStatus);
+		osal_assert(0);
+	}
+
+}
+
+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type)
+{
+	UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2];
+	UINT8 *p_tx_buf = NULL;
+	UINT16 crc;
+	INT32 ret = 0;
+
+	/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_lock(&stp_core_ctx);
+
+	/*Only WMT can set raw data */
+	if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) {
+		/* no op */
+		/* NULL; */
+	} else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) {
+		/* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */
+		/* NULL; */
+	}
+	/* STP over SDIO */
+	else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) {
+		osal_printtimeofday("[ STP][SDIO][ B][W]");
+
+		mtkstp_header[0] = 0x80;
+		mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f);
+		mtkstp_header[2] = (length) & 0xff;
+		mtkstp_header[3] = 0x00;
+
+		p_tx_buf = &stp_core_ctx.tx_buf[0];
+		osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE);
+		p_tx_buf += MTKSTP_HEADER_SIZE;
+
+		osal_memcpy(p_tx_buf, buffer, length);
+		p_tx_buf += length;
+
+		temp[0] = 0x00;
+		temp[1] = 0x00;
+		osal_memcpy(p_tx_buf, temp, 2);
+		stp_dbg_pkt_log(type,
+				stp_core_ctx.sequence.txack,
+				stp_core_ctx.sequence.txseq, 0, PKT_DIR_TX, buffer, length);
+		(*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret);
+		if ((MTKSTP_HEADER_SIZE + length + 2) != ret) {
+			STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret);
+			osal_assert(0);
+			ret = 0;
+		} else {
+			ret = (INT32) length;
+		}
+
+		osal_printtimeofday("[ STP][SDIO][ E][W]");
+	}
+	/* STP over BTIF OR UART */
+	else if ((mtk_wcn_stp_is_btif_fullset_mode()) && STP_IS_ENABLE(stp_core_ctx)) {
+
+		if ((stp_core_ctx.sequence.winspace > 0) &&
+		    (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) {
+			mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack;
+			mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8);
+			mtkstp_header[2] = length & 0xff;
+			mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff;
+
+			stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write;
+			stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2;
+
+			if (fgEnableDelimiter == 1) {
+				stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE;
+				stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE);
+			}
+
+			stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE);
+
+			/*Make Payload */
+			stp_add_to_tx_queue(buffer, length);
+
+			/*Make CRC */
+			crc = osal_crc16(buffer, length);
+			temp[0] = crc & 0xff;
+			temp[1] = (crc & 0xff00) >> 8;
+			stp_add_to_tx_queue(temp, 2);
+
+			stp_dbg_pkt_log(type,
+					stp_core_ctx.sequence.txack,
+					stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length);
+
+			/*Kick to UART */
+			stp_send_tx_queue(stp_core_ctx.sequence.txseq);
+			INDEX_INC(stp_core_ctx.sequence.txseq);
+			stp_core_ctx.sequence.winspace--;
+
+			/*Setup the Retry Timer */
+			osal_timer_stop(&stp_core_ctx.tx_timer);
+			if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE)
+				osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout);
+			else
+				STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n");
+
+			ret = (INT32) length;
+		} else {
+			/* No winspace to send. Let caller retry */
+			STP_ERR_FUNC("%s: There is no winspace/txqueue to send !!!\n", __func__);
+			ret = 0;
+		}
+	}
+
+	stp_ctx_unlock(&stp_core_ctx);
+	/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+
+	return ret;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_process_rxack
+* DESCRIPTION
+*  process ack packet
+* PARAMETERS
+*  void
+* RETURNS
+*  INT32    0=success, others=error
+*****************************************************************************/
+static INT32 stp_process_rxack(VOID)
+{
+	INT32 j, k;
+	UINT8 rxack;
+	INT32 fgResult = (-1);
+
+	if (stp_core_ctx.sequence.rxack != stp_core_ctx.parser.ack) {
+		j = k = 0;
+		rxack = stp_core_ctx.sequence.rxack;
+		INDEX_INC(rxack);
+		while (rxack != stp_core_ctx.sequence.txseq) {
+			j++;
+			if (rxack == stp_core_ctx.parser.ack) {
+				k = 1;
+				break;
+			}
+			INDEX_INC(rxack);
+		}
+		if (k == 1) {
+			stp_core_ctx.sequence.rxack = stp_core_ctx.parser.ack;
+			stp_core_ctx.tx_read = stp_core_ctx.tx_start_addr[rxack] + stp_core_ctx.tx_length[rxack];
+			if (stp_core_ctx.tx_read >= MTKSTP_BUFFER_SIZE)
+				stp_core_ctx.tx_read -= MTKSTP_BUFFER_SIZE;
+
+			stp_core_ctx.sequence.winspace += j;
+			stp_core_ctx.sequence.retry_times = 0;
+
+			osal_timer_stop(&stp_core_ctx.tx_timer);
+			if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE)
+				osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout);
+
+			fgResult = 0;
+		}
+	}
+
+	return fgResult;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_process_packet
+* DESCRIPTION
+*  process STP packet
+* PARAMETERS
+*  void
+* RETURNS
+*  void
+*****************************************************************************/
+static VOID stp_process_packet(VOID)
+{
+	INT32 fgTriggerResume = (-1);
+	UINT8 txAck = 0;
+	static INT32 fgRxOk;
+	MTK_WCN_BOOL b;
+	MTK_WCN_BOOL is_function_active = 0;
+	static INT32 stp_process_packet_fail_count;
+	INT32 iRet = -1;
+
+	stp_dbg_pkt_log(stp_core_ctx.parser.type,
+			stp_core_ctx.parser.ack,
+			stp_core_ctx.parser.seq,
+			stp_core_ctx.parser.crc, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.parser.length);
+	/*Optimization */
+	/*If bluez, direct send packet to hci_core not through RX buffer! */
+	if ((stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) &&
+	    (stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) {
+		/*Indicate packet to hci_stp */
+		STP_DBG_FUNC("Send Packet to BT_SUBFUCTION, len = %d\n", stp_core_ctx.rx_counter);
+
+		b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter);
+		if (b)
+			STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n");
+
+		/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+		stp_ctx_lock(&stp_core_ctx);
+		/*Process rx ack */
+		fgTriggerResume = stp_process_rxack();
+		stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq;
+		INDEX_INC(stp_core_ctx.sequence.expected_rxseq);
+		txAck = stp_core_ctx.sequence.txack;
+
+		/*Send ack back */
+		stp_send_ack(txAck, 0);
+
+		/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+		stp_ctx_unlock(&stp_core_ctx);
+		fgRxOk = 0;
+	}
+	/* sequence matches expected, enqueue packet */
+	else if (stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) {
+		is_function_active =
+		    ((*sys_check_function_status) (stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) ==
+		     STATUS_FUNCTION_ACTIVE);
+		/*If type is valid and function works, then try to enqueue */
+		if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && (is_function_active == MTK_WCN_BOOL_TRUE)) {
+			if (stp_core_ctx.parser.type == BT_TASK_INDX) {
+				static const UINT8 rst_buf[7] = { 0x04, 0x0e, 0x04, 0x01, 0x3, 0xc, 0x00 };
+
+				if (!osal_strncmp(stp_core_ctx.rx_buf, rst_buf, 7))
+					osal_printtimeofday("############ BT Rest end <--");
+			}
+
+			stp_ctx_lock(&stp_core_ctx);
+
+			fgTriggerResume = stp_process_rxack();
+			stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq;
+			INDEX_INC(stp_core_ctx.sequence.expected_rxseq);
+
+			/*Send tx ack */
+			txAck = stp_core_ctx.sequence.txack;
+			stp_send_ack(txAck, 0);
+
+			stp_ctx_unlock(&stp_core_ctx);
+#if CFG_WMT_LTE_COEX_HANDLING
+			if ((stp_core_ctx.parser.type == WMT_TASK_INDX) &&
+			    (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) {
+				fgRxOk =
+				    stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, COEX_TASK_INDX);
+			} else {
+				fgRxOk =
+				    stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter,
+							stp_core_ctx.parser.type);
+			}
+#else
+			if ((stp_core_ctx.parser.type == WMT_TASK_INDX) &&
+			    (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) {
+				STP_WARN_FUNC("BT/WIFI & LTE coex in non-LTE projects,drop it...\n");
+			} else {
+				fgRxOk =
+				    stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter,
+							stp_core_ctx.parser.type);
+			}
+#endif
+		} else {
+			if (is_function_active == MTK_WCN_BOOL_FALSE) {
+				STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n",
+					     stp_core_ctx.parser.type);
+				fgRxOk = 0;	/*drop packet */
+			} else {
+				STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n",
+					     stp_core_ctx.parser.type);
+				fgRxOk = 0;	/*drop packet */
+			}
+			stp_ctx_lock(&stp_core_ctx);
+
+			fgTriggerResume = stp_process_rxack();
+			stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq;
+			INDEX_INC(stp_core_ctx.sequence.expected_rxseq);
+
+			/*Send tx ack */
+			txAck = stp_core_ctx.sequence.txack;
+			stp_send_ack(txAck, 0);
+
+			stp_ctx_unlock(&stp_core_ctx);
+		}
+
+		/* enqueue successfully */
+		if (fgRxOk == 0) {
+			stp_process_packet_fail_count = 0;
+			/*notify corresponding subfunction of incoming data */
+#if CFG_WMT_LTE_COEX_HANDLING
+			if ((stp_core_ctx.parser.type == WMT_TASK_INDX) &&
+			    (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) {
+#if 1
+				STP_DBG_FUNC
+				    ("WMT/LTE package:[0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x]\n",
+				     stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], stp_core_ctx.rx_buf[2],
+				     stp_core_ctx.rx_buf[3], stp_core_ctx.rx_buf[4], stp_core_ctx.rx_buf[5],
+				     stp_core_ctx.rx_buf[6], stp_core_ctx.rx_buf[7]);
+#endif
+				stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx));
+			} else {
+				(*sys_event_set) (stp_core_ctx.parser.type);
+			}
+#else
+			if ((stp_core_ctx.parser.type == WMT_TASK_INDX) &&
+			    (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) {
+				STP_WARN_FUNC("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n");
+			} else {
+				(*sys_event_set) (stp_core_ctx.parser.type);
+			}
+#endif
+		} else {
+			stp_process_packet_fail_count++;
+			/*Queue is full */
+			if (stp_core_ctx.parser.type == GPS_TASK_INDX) {
+				/*Clear Rx Queue if GPS */
+				mtk_wcn_stp_flush_rx_queue(GPS_TASK_INDX);
+			} else {
+				/*notify corresponding subfunction of incoming data */
+				(*sys_event_set) (stp_core_ctx.parser.type);
+			}
+			/*enqueue fail, don't send ack and wait for peer retry */
+			STP_ERR_FUNC("Enqueue to Rx queue fail, maybe function %d queue is full\n",
+				     stp_core_ctx.parser.type);
+		}
+	}
+	/*sequence not match && previous packet enqueue successfully, send the previous ACK */
+	else if (fgRxOk == 0) {
+		STP_ERR_FUNC("mtkstp_process_packet: expected_rxseq = %d, parser.seq = %d\n",
+			     stp_core_ctx.sequence.expected_rxseq, stp_core_ctx.parser.seq);
+		stp_process_packet_fail_count++;
+
+		stp_ctx_lock(&stp_core_ctx);
+		/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+		txAck = stp_core_ctx.sequence.txack;
+		stp_send_ack(txAck, 1);
+		stp_ctx_unlock(&stp_core_ctx);
+		/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+		STP_ERR_FUNC
+		    ("sequence not match && previous packet enqueue successfully, send the previous ACK (ack no =%d)\n",
+		     txAck);
+	}
+	/*sequence not match && previous packet enqueue failed, do nothing, make the other side timeout */
+	else {
+		stp_process_packet_fail_count++;
+		STP_ERR_FUNC
+		    ("sequence not match && previous packet enqueue failed, do nothing, make the other side timeout\n");
+	}
+
+	if (fgTriggerResume == 0) {
+		/*[PatchNeed]Just Notificaiton, not blocking call */
+		/* notify adaptation layer for possible tx resume mechanism */
+		(*sys_event_tx_resume) (stp_core_ctx.sequence.winspace);
+	}
+
+	if (stp_process_packet_fail_count > MTKSTP_RETRY_LIMIT) {
+		stp_process_packet_fail_count = 0;
+		STP_ERR_FUNC("The process packet fail count > 10 lastly\n\r, whole chip reset\n\r");
+		mtk_wcn_stp_dbg_dump_package();
+		/*Whole Chip Reset Procedure Invoke */
+		/*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */
+		if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) {
+			stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+			mtk_wcn_stp_set_wmt_evt_err_trg_assert(1);
+			stp_dbg_set_host_assert_info(4, 37, 1);
+			STP_INFO_FUNC("**Ack Miss trigger firmware assert**\n");
+			iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx));
+			if (iRet) {
+				mtk_wcn_stp_set_wmt_evt_err_trg_assert(0);
+				/* (*sys_dbg_assert_aee)("[MT662x]Ack Miss", "**STP Ack Miss**\n Ack Miss.\n"); */
+				osal_dbg_assert_aee("[SOC_CONSYS]Ack Miss",
+						    "**[WCN_ISSUE_INFO]STP Ack Miss**\n Ack Miss.\n");
+
+				if (STP_IS_ENABLE_RST(stp_core_ctx)) {
+					STP_SET_READY(stp_core_ctx, 0);
+					stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx));
+				} else {
+					STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n");
+				}
+			}
+		}
+	}
+
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_init
+* DESCRIPTION
+*  init STP kernel
+* PARAMETERS
+*  cb_func      [IN] function pointers of system APIs
+* RETURNS
+*  INT32    0 = success, others = failure
+*****************************************************************************/
+INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func)
+{
+	INT32 ret = 0;
+	INT32 i = 0;
+
+	/* Function pointer to point to the currently used transmission interface
+	 */
+	sys_if_tx = cb_func->cb_if_tx;
+
+	/* Used to inform the function driver has received the corresponding type of information */
+	sys_event_set = cb_func->cb_event_set;
+
+	/*  Used to inform the function driver can continue to send information and
+	   STP has resources to deal with
+	 */
+	sys_event_tx_resume = cb_func->cb_event_tx_resume;
+
+	/*  STP driver determines whether the function is enable. If not enable and
+	   STP has received the kind of information, and STP have the right to put it away.
+	 */
+	sys_check_function_status = cb_func->cb_check_funciton_status;
+
+	/* osal_unsleepable_lock_init(&stp_core_ctx.stp_mutex); */
+	stp_ctx_lock_init(&stp_core_ctx);
+	/*  Setup timer to be used to check if f/w receive the data in the specific time
+	   interval after being sent
+	 */
+	for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++)
+		osal_unsleepable_lock_init(&stp_core_ctx.ring[i].mtx);
+
+	stp_core_ctx.tx_timer.timeoutHandler = stp_tx_timeout_handler;
+	stp_core_ctx.tx_timer.timeroutHandlerData = 0;
+	osal_timer_create(&stp_core_ctx.tx_timer);
+
+	STP_SET_BT_STK(stp_core_ctx, 0);
+	STP_SET_ENABLE(stp_core_ctx, 0);
+	STP_SET_ENABLE_DBG(stp_core_ctx, 0);
+	STP_SET_ENABLE_RST(stp_core_ctx, 0);
+	STP_SET_PENDING_TYPE(stp_core_ctx, 0);
+	STP_SET_READY(stp_core_ctx, 0);
+	STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, 0);
+	STP_SET_PSM_CORE(stp_core_ctx, stp_psm_init());
+	STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, 0);
+	STP_ENABLE_FW_COREDUMP(stp_core_ctx, 0);
+	STP_SET_WMT_LAST_CLOSE(stp_core_ctx, 0);
+	STP_SET_EVT_ERR_ASSERT(stp_core_ctx, 0);
+
+	if (!STP_PSM_CORE(stp_core_ctx)) {
+		ret = (-3);
+		goto ERROR;
+	}
+
+	STP_SET_BTM_CORE(stp_core_ctx, stp_btm_init());
+	if (!STP_BTM_CORE(stp_core_ctx)) {
+		STP_ERR_FUNC("STP_BTM_CORE(stp_core_ctx) initialization fail!\n");
+		ret = (-3);
+		goto ERROR;
+	}
+
+	if (STP_BTM_CORE(stp_core_ctx) != NULL)
+		g_mtkstp_dbg = stp_dbg_init(STP_BTM_CORE(stp_core_ctx));
+	else
+		g_mtkstp_dbg = stp_dbg_init(NULL);
+
+	if (!g_mtkstp_dbg) {
+		STP_ERR_FUNC("g_mtkstp_dbg initialization fail!\n");
+		ret = (-3);
+		goto ERROR;
+	}
+	STP_SET_ENABLE_RST(stp_core_ctx, 1);
+#ifdef CONFIG_LOG_STP_INTERNAL
+	mtk_wcn_stp_dbg_enable();
+#else
+	mtk_wcn_stp_dbg_enable();
+#endif
+	goto RETURN;
+
+ERROR:
+	stp_psm_deinit(STP_PSM_CORE(stp_core_ctx));
+
+RETURN:
+	return ret;
+
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_deinit
+* DESCRIPTION
+*  deinit STP kernel
+* PARAMETERS
+*  void
+* RETURNS
+*  INT32    0 = success, others = failure
+*****************************************************************************/
+INT32 mtk_wcn_stp_deinit(void)
+{
+	UINT32 i = 0;
+
+	sys_if_tx = NULL;
+	sys_event_set = NULL;
+	sys_event_tx_resume = NULL;
+	sys_check_function_status = NULL;
+
+	stp_dbg_deinit(g_mtkstp_dbg);
+	stp_btm_deinit(STP_BTM_CORE(stp_core_ctx));
+	stp_psm_deinit(STP_PSM_CORE(stp_core_ctx));
+
+	for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++)
+		osal_unsleepable_lock_deinit(&stp_core_ctx.ring[i].mtx);
+
+	stp_ctx_lock_deinit(&stp_core_ctx);
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_btm_get_dmp
+* DESCRIPTION
+*  get stp dump related information
+* PARAMETERS
+*  buffer: dump placement, len: dump size
+* RETURNS
+*   0: Success Negative Value: Fail
+*****************************************************************************/
+
+int mtk_wcn_stp_btm_get_dmp(char *buf, int *len)
+{
+	return stp_dbg_dmp_out(g_mtkstp_dbg, buf, len);
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_psm_notify_stp
+* DESCRIPTION
+*  WMT notification to STP that power saving job is done or not
+* PARAMETERS
+*
+* RETURNS
+*  0: Sccuess  Negative value: Fail
+*****************************************************************************/
+int mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action)
+{
+	return stp_psm_notify_stp(STP_PSM_CORE(stp_core_ctx), action);
+}
+
+int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state)
+{
+	return stp_psm_set_state(STP_PSM_CORE(stp_core_ctx), state);
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_psm_enable
+* DESCRIPTION
+*  enable STP sleep/wakeup support
+* PARAMETERS
+*  void
+* RETURNS
+*  0: Sccuess  Negative value: Fail
+*****************************************************************************/
+INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep)
+{
+#if 0
+	if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) {
+		if (mtk_wcn_stp_is_ready())
+			return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep);
+		STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n");
+		return -1;
+	}
+	if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) {
+		return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep);
+	} else if (mtk_wcn_stp_is_sdio_mode()) {
+		stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep);
+		STP_DBG_FUNC("PSM is not support under SDIO mode\n");
+		return 0;
+	}
+	STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n");
+	return -1;
+
+#else
+	if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) {
+		return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep);
+	} else if (mtk_wcn_stp_is_sdio_mode()) {
+		stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep);
+		STP_DBG_FUNC("PSM is not support under SDIO mode\n");
+		return 0;
+	}
+	STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n");
+	return -1;
+#endif
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_psm_disable
+* DESCRIPTION
+*  disable STP sleep/wakeup support
+* PARAMETERS
+*  void
+* RETURNS
+*  0: Sccuess  Negative value: Fail
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_psm_disable(VOID)
+{
+#if 0
+	if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) {
+		if (mtk_wcn_stp_is_ready())
+			return stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+		STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n");
+		return -1;
+	}
+	if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) {
+		return stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+	} else if (mtk_wcn_stp_is_sdio_mode()) {
+		stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+		return 0;
+	}
+	STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n");
+	return -1;
+
+#else
+	if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) {
+		return stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+	} else if (mtk_wcn_stp_is_sdio_mode()) {
+		stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+		return 0;
+	}
+	STP_DBG_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n");
+	return 0;
+
+#endif
+}
+
+extern INT32 mtk_wcn_stp_psm_reset(VOID)
+{
+	return stp_psm_reset(STP_PSM_CORE(stp_core_ctx));
+}
+
+extern INT32 mtk_wcn_stp_dbg_disable(VOID)
+{
+	if (STP_IS_ENABLE_DBG(stp_core_ctx)) {
+		STP_DBG_FUNC("STP dbg mode is turned off\n");
+		STP_SET_ENABLE_DBG(stp_core_ctx, 0);
+		stp_dbg_disable(g_mtkstp_dbg);
+	} else {
+		STP_WARN_FUNC("STP dbg mode has been turned off\n");
+	}
+
+	return 0;
+}
+
+extern INT32 mtk_wcn_stp_dbg_enable(VOID)
+{
+	if (STP_NOT_ENABLE_DBG(stp_core_ctx)) {
+		STP_DBG_FUNC("STP dbg mode is turned on\n");
+		STP_SET_ENABLE_DBG(stp_core_ctx, 1);
+		stp_dbg_enable(g_mtkstp_dbg);
+	} else {
+		STP_WARN_FUNC("STP dbg mode has been turned on\n");
+	}
+
+	return 0;
+}
+
+INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on)
+{
+	stp_dbg_log_ctrl(on);
+	return 0;
+}
+
+INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on)
+{
+	STP_ENABLE_FW_COREDUMP(stp_core_ctx, on);
+	STP_INFO_FUNC("coredump function mode: %d.\n", on);
+	g_coredump_mode = on;
+	return 0;
+}
+
+INT32 mtk_wcn_stp_coredump_flag_get(VOID)
+{
+	return STP_ENABLE_FW_COREDUMP_FLAG(stp_core_ctx);
+}
+
+static INT32 stp_parser_data_in_mand_mode(UINT32 length, UINT8 *p_data)
+{
+	UINT8 padding_len = 0;
+	INT32 remain_length;	/* GeorgeKuo: sync from MAUI, change to unsigned */
+	MTK_WCN_BOOL is_function_active = 0;
+	INT32 i = length;
+
+	while (i > 0) {
+		switch (stp_core_ctx.parser.state) {
+		case MTKSTP_SYNC:	/* b'10 */
+			/* if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) */
+			/* if(*p_data == 0x80) */
+			if ((*p_data & 0x80) == 0x80) {
+				/* STP_DBG_FUNC("[STP] STP Packet Start =========>\n"); */
+				if (*p_data != 0x80)
+					STP_WARN_FUNC("SDIO not 0x80!!(0x%x)\n", *p_data);
+
+				if (i >= 4) {
+#if !(REMOVE_USELESS_LOG)
+					/*print header, when get the full STP header */
+					UINT32 type = (*(p_data + 1) & 0x70) >> 4;
+					UINT8 *type_name = "<UNKNOWN>";
+
+					type_name = stp_type_to_dbg_string(type);
+					STP_DBG_FUNC(
+						"STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n",
+						*p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3),
+						type_name, ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2),
+						(*p_data & 0x38) >> 3, *p_data & 0x07);
+#endif
+				} else {
+						STP_WARN_FUNC("STP Rx: discard due to i < 4 (%d)\n", i);
+				}
+
+				/* STP_DBG_FUNC("[STP] sync->nak\n"); */
+				stp_change_rx_state(MTKSTP_NAK);
+				stp_core_ctx.rx_counter++;
+			} else {
+				STP_WARN_FUNC("sync to sync!!(0x%x)\n", *p_data);
+				stp_change_rx_state(MTKSTP_SYNC);
+			}
+			break;
+
+		case MTKSTP_NAK:
+			/* STP_DBG_FUNC("[STP] nak->length\n"); */
+			stp_change_rx_state(MTKSTP_LENGTH);
+			stp_core_ctx.parser.type = (*p_data & 0x70) >> 4;
+			if (stp_core_ctx.parser.type <= MTKSTP_MAX_TASK_NUM) {
+				stp_core_ctx.parser.length = (*p_data & 0x0f) << 8;
+				stp_core_ctx.rx_counter++;
+			} else {
+				STP_WARN_FUNC("nak to sync\n");
+				stp_change_rx_state(MTKSTP_SYNC);
+			}
+			break;
+
+		case MTKSTP_LENGTH:
+			/* STP_DBG_FUNC("[STP] length -> checksum\n"); */
+			stp_change_rx_state(MTKSTP_CHECKSUM);
+			stp_core_ctx.parser.length += *p_data;
+
+			/*Valid length checking */
+			if (stp_core_ctx.parser.length < 2000) {
+				stp_core_ctx.rx_counter++;
+			} else {
+				STP_WARN_FUNC("The length of STP packet is not valid !!! length = %d\n",
+					stp_core_ctx.parser.length);
+				stp_change_rx_state(MTKSTP_SYNC);
+				stp_core_ctx.rx_counter = 0;
+					/* return -1; */
+			}
+
+			break;
+
+		case MTKSTP_CHECKSUM:
+
+			if ((stp_core_ctx.parser.type == STP_TASK_INDX) ||
+				   (stp_core_ctx.parser.type == INFO_TASK_INDX)) {
+				stp_change_rx_state(MTKSTP_FW_MSG);
+				stp_core_ctx.rx_counter = 0;
+				i -= 1;
+				if (i != 0)
+					p_data += 1;
+
+				continue;
+			}
+
+			if (stp_core_ctx.parser.length == 0) {
+				STP_WARN_FUNC("checksum to sync\n");
+				stp_change_rx_state(MTKSTP_SYNC);
+				stp_core_ctx.rx_counter = 0;
+			} else {
+				/* STP_DBG_FUNC("[STP] checksum->data\n"); */
+				stp_change_rx_state(MTKSTP_DATA);
+				stp_core_ctx.rx_counter = 0;
+			}
+			break;
+
+		case MTKSTP_DATA:
+
+			/* block copy instead of byte copy */
+			if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) {
+				STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n",
+						stp_core_ctx.parser.length, stp_core_ctx.rx_counter);
+				osal_assert(0);
+			}
+			remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter;
+			if (i >= remain_length) {
+				/*boundary checking */
+				if (stp_core_ctx.rx_counter + remain_length >= MTKSTP_BUFFER_SIZE) {
+					STP_ERR_FUNC("Abnormal!! Memory operation over boundary!!\n");
+					stp_change_rx_state(MTKSTP_SYNC);
+					stp_core_ctx.rx_counter = 0;
+					return -1;
+				}
+
+				osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data,
+							remain_length);
+				i -= remain_length;
+				p_data += remain_length;
+				stp_core_ctx.rx_counter = stp_core_ctx.parser.length;
+				stp_core_ctx.parser.state = MTKSTP_CRC1;
+				continue;
+
+			} else {	/* only copy by data length */
+
+				/*fixed klocwork insight issue */
+				/*boundary checking */
+				if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) {
+					STP_ERR_FUNC("Abnormal!! Memory operation over boundary 2!!\n");
+					stp_core_ctx.rx_counter = 0;
+					return -1;
+				}
+
+				osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i);
+				stp_core_ctx.rx_counter += i;	/* all remain buffer are data */
+				i = 0;
+				p_data += i;
+				continue;
+			}
+			break;
+
+		case MTKSTP_CRC1:
+			stp_change_rx_state(MTKSTP_CRC2);
+			break;
+
+		case MTKSTP_CRC2:
+#if 1
+			if (stp_core_ctx.parser.type == WMT_TASK_INDX) {
+				stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1];
+				STP_DBG_FUNC("wmt sub type (0x%x)\n", stp_core_ctx.parser.wmtsubtype);
+			}
+#endif
+			/*SDIO mode do it. */
+			if (mtk_wcn_stp_is_sdio_mode()) {
+				/*STP packet 4-bytes alignment */
+				/*Discard padding bytes , otherwise make parser state machine disorder */
+				if (i <= 4) {
+					/*STP_DBG_FUNC("STP last block padding %d bytes\n", i-1); */
+					p_data += (i - 1);
+					i -= (i - 1);
+				} else {
+					padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03;
+					p_data += padding_len;
+					i -= padding_len;
+					/*STP_DBG_FUNC("STP Agg padding %d bytes\n", padding_len); */
+				}
+			}
+			stp_dbg_pkt_log(stp_core_ctx.parser.type,
+					0, 0, 0, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.rx_counter);
+			if ((stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) {
+				int b;
+
+				/*Indicate packet to hci_stp */
+				if (gStpDbgLvl >= STP_LOG_DBG) {
+					stp_dump_data(stp_core_ctx.rx_buf, "indicate_to_bt_core",
+								stp_core_ctx.rx_counter);
+				}
+
+				b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter);
+				if (b)
+					STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n");
+
+			} else {
+
+				is_function_active = (
+					(*sys_check_function_status)(stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE)
+					     == STATUS_FUNCTION_ACTIVE);
+
+				/*check type and function if active? */
+				if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM)
+						&& (is_function_active == MTK_WCN_BOOL_TRUE)) {
+#if CFG_WMT_LTE_COEX_HANDLING
+					if ((stp_core_ctx.parser.type == WMT_TASK_INDX)
+							&& stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) {
+						STP_INFO_FUNC("wmt/lte coex package!\n");
+						stp_add_to_rx_queue(stp_core_ctx.rx_buf,
+									stp_core_ctx.rx_counter, COEX_TASK_INDX);
+						stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx));
+					} else {
+						stp_add_to_rx_queue(stp_core_ctx.rx_buf,
+									stp_core_ctx.rx_counter,
+									stp_core_ctx.parser.type);
+
+						/*notify corresponding subfunction of incoming data */
+						(*sys_event_set) (stp_core_ctx.parser.type);
+					}
+#else
+					if ((stp_core_ctx.parser.type == WMT_TASK_INDX)
+							&& stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) {
+						STP_WARN_FUNC
+							("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n");
+					} else {
+						stp_add_to_rx_queue(stp_core_ctx.rx_buf,
+											stp_core_ctx.rx_counter,
+											stp_core_ctx.parser.type);
+
+						/*notify corresponding subfunction of incoming data */
+						(*sys_event_set) (stp_core_ctx.parser.type);
+					}
+#endif
+				} else {
+					if (is_function_active == MTK_WCN_BOOL_FALSE) {
+						STP_ERR_FUNC
+							("function type = %d is inactive, so no en-queue to rx\n",
+							stp_core_ctx.parser.type);
+					} else {
+						STP_ERR_FUNC
+							("mtkstp_process_packet: type = %x, the type is invalid\n",
+							stp_core_ctx.parser.type);
+					}
+				}
+			}
+
+			/* STP_DBG_FUNC("[STP] crc2->sync\n"); */
+			/* STP_DBG_FUNC("[STP] STP Packet End <=========\n"); */
+			stp_core_ctx.rx_counter = 0;
+			stp_change_rx_state(MTKSTP_SYNC);
+
+			break;
+
+		case MTKSTP_FW_MSG:
+
+			/*f/w assert and exception information */
+			if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) {
+				STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n",
+					     stp_core_ctx.parser.length, stp_core_ctx.rx_counter);
+			}
+
+			remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter;
+
+			if (i >= remain_length) {
+				osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data,
+					    remain_length);
+				i -= remain_length;
+				p_data += remain_length;
+				stp_core_ctx.rx_counter = stp_core_ctx.parser.length;
+				*(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0';
+				/*Trace32 Dump */
+				if (stp_core_ctx.parser.type == STP_TASK_INDX) {
+					/* g_block_tx = 1; */
+					mtk_wcn_stp_coredump_start_ctrl(1);
+					pr_debug("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter,
+					       stp_core_ctx.parser.type, stp_core_ctx.rx_buf);
+					/*use paged dump or full dump */
+					stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm);
+#if 0
+					stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_DMP /*STP_DBG_FW_ASSERT */ , 5,
+							0, 0, 0, 0,
+							(stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf);
+#endif
+				}
+
+				/*discard CRC */
+				/* we will discard antoher CRC on the outer switch procedure. */
+				if (i >= 1) {
+					STP_INFO_FUNC("crc discard.. i = %d\n", i);
+					i -= 1;
+					if (i > 0)
+						p_data += 1;
+
+				}
+
+				/*STP packet 4-bytes alignment */
+				/*Discard padding bytes , otherwise make parser state machine disorder */
+				if (i <= 4) {
+					STP_INFO_FUNC
+					    ("\n[STP]FW_EVENT========= block padding %d bytes =========\n",
+					     i - 1);
+					p_data += (i - 1);
+					i -= (i - 1);
+				} else {
+					padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03;
+					p_data += padding_len;
+					i -= padding_len;
+					STP_INFO_FUNC
+					    ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n",
+					     padding_len);
+				}
+				stp_change_rx_state(MTKSTP_SYNC);
+
+			} else {	/* only copy by data length */
+
+				STP_ERR_FUNC("raw data doesn't contain full stp packet!!\n");
+			}
+			break;
+		default:
+			break;
+		}
+		p_data++;
+		i--;
+	}
+
+	return 0;
+}
+
+static INT32 stp_parser_data_in_full_mode(UINT32 length, UINT8 *p_data)
+{
+	INT32 remain_length;	/* GeorgeKuo: sync from MAUI, change to unsigned */
+	INT32 i = length;
+
+	while (i > 0) {
+		switch (stp_core_ctx.parser.state) {
+
+		case MTKSTP_RESYNC1:	/* RESYNC must be 4 _continuous_ 0x7f */
+			if (*p_data == 0x7f)
+				stp_change_rx_state(MTKSTP_RESYNC2);
+			else
+				stp_change_rx_state(MTKSTP_RESYNC1);
+			break;
+		case MTKSTP_RESYNC2:
+			if (*p_data == 0x7f)
+				stp_change_rx_state(MTKSTP_RESYNC3);
+			else
+				stp_change_rx_state(MTKSTP_RESYNC1);
+			break;
+		case MTKSTP_RESYNC3:
+			if (*p_data == 0x7f)
+				stp_change_rx_state(MTKSTP_RESYNC4);
+			else
+				stp_change_rx_state(MTKSTP_RESYNC1);
+			break;
+		case MTKSTP_RESYNC4:
+			if (*p_data == 0x7f)
+				stp_change_rx_state(MTKSTP_SYNC);
+			else
+				stp_change_rx_state(MTKSTP_RESYNC1);
+			break;
+		case MTKSTP_SYNC:	/* b'10 */
+			STP_DUMP_PACKET_HEAD(p_data, "rx (uart):", length > 4 ? 4 : length);
+			if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) {
+				stp_change_rx_state(MTKSTP_NAK);
+				stp_core_ctx.parser.seq = (*p_data & 0x38) >> 3;
+				stp_core_ctx.parser.ack = *p_data & 0x07;
+				stp_core_ctx.rx_buf[0] = *p_data;
+				/* Geoge FIXME: WHY comment the following line? */
+				/* stp_core_ctx.rx_counter++; */
+
+				if (i >= 4 && gStpDbgLvl >= STP_LOG_DBG) {
+					/*print header, when get the full STP header */
+#if !(REMOVE_USELESS_LOG)
+					int type = (*(p_data + 1) & 0x70) >> 4;
+					char *type_name = "<UNKNOWN>";
+
+					type_name = stp_type_to_dbg_string(type);
+
+					STP_DBG_FUNC
+					    ("STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n",
+					     *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), type_name,
+					     ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2),
+					     (*p_data & 0x38) >> 3, *p_data & 0x07);
+#endif
+				} else {
+					STP_DBG_FUNC("STP Rx: discard due to i < 4\n");
+				}
+			} else if ((*p_data == 0x7f) && (prev_state == MTKSTP_RESYNC4)) {
+				/* if this 0x7f is continuous to resync pattern */
+				/* skip this continuous 0x7f, remain current & prev state */
+				osal_assert(0);
+				STP_ERR_FUNC("MTKSTP_SYNC: continuous resync pattern, buff = %x\n", *p_data);
+			} else if (*p_data == 0x7f) {	/* a start of 0x7f, maybe this is resync pattern */
+				stp_change_rx_state(MTKSTP_RESYNC2);
+				osal_assert(0);
+				STP_ERR_FUNC("MTKSTP_SYNC: go to MTKSTP_RESYNC2, buff = %x\n", *p_data);
+			} else if (*p_data == 0x55) {	/* STP delimiter */
+				/* do nothing for delimiter */
+			} else {	/* unexpected, go to resync1 */
+				osal_assert(0);
+				STP_ERR_FUNC("MTKSTP_SYNC: unexpected data, buff = %x\n", *p_data);
+			}
+			break;
+
+		case MTKSTP_NAK:
+			/* (*sys_dbg_print)("MTKSTP_NAK : mtk_wcn_stp_parser_data, buff = %x", *p_data); */
+			if (fgEnableNak == 0)
+				stp_core_ctx.parser.nak = 0;	/* disable NAK */
+			else
+				stp_core_ctx.parser.nak = (*p_data & 0x80) >> 7;
+
+			stp_core_ctx.parser.type = (*p_data & 0x70) >> 4;
+			stp_core_ctx.parser.length = (*p_data & 0x0f) << 8;
+			stp_core_ctx.rx_buf[1] = *p_data;
+			/* Geoge FIXME: WHY comment the following line? */
+			/*stp_core_ctx.rx_counter++; */
+			if (stp_core_ctx.parser.nak)
+				STP_ERR_FUNC("MTKSTP_NAK TRUE: mtk_wcn_stp_parser_data, buff = %x\n", *p_data);
+
+			if (stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM)
+				stp_change_rx_state(MTKSTP_LENGTH);
+			else
+				stp_change_rx_state(MTKSTP_SYNC);
+			break;
+
+		case MTKSTP_LENGTH:
+			/* (*sys_dbg_print)("MTKSTP_LENGTH : mtk_wcn_stp_parser_data, buff = %x", *p_data); */
+			stp_change_rx_state(MTKSTP_CHECKSUM);
+			stp_core_ctx.parser.length += *p_data;
+
+			/*Valid length checking */
+			if (stp_core_ctx.parser.length > 2048) {
+				STP_ERR_FUNC("The length of STP packet is not valid !!! length = %d\n",
+					     stp_core_ctx.parser.length);
+				stp_change_rx_state(MTKSTP_RESYNC1);
+				stp_core_ctx.rx_counter = 0;
+				STP_TRACE_FUNC("--\n");
+				return -1;
+			}
+
+			stp_core_ctx.rx_buf[2] = *p_data;
+			/* Geoge FIXME: WHY comment the following line? */
+			/*stp_core_ctx.rx_counter++; */
+			break;
+
+		case MTKSTP_CHECKSUM:
+			/* (*sys_dbg_print)("MTKSTP_CHECKSUM : mtk_wcn_stp_parser_data, buff = %x", *p_data); */
+			if ((stp_core_ctx.parser.type == STP_TASK_INDX) ||
+			    (stp_core_ctx.parser.type == INFO_TASK_INDX)) {
+				stp_change_rx_state(MTKSTP_FW_MSG);
+				stp_core_ctx.rx_counter = 0;
+				i -= 1;
+				if (i != 0)
+					p_data += 1;
+
+				continue;
+			}
+
+			if (((stp_core_ctx.rx_buf[0] +
+			      stp_core_ctx.rx_buf[1] + stp_core_ctx.rx_buf[2]) & 0xff) == *p_data) {
+				/* header only packet */
+				if (stp_core_ctx.parser.length == 0) {
+					INT32 fgTriggerResume = (-1);
+
+					/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+					stp_ctx_lock(&stp_core_ctx);
+					if (stp_core_ctx.inband_rst_set == 0) {
+						stp_dbg_pkt_log(STP_TASK_INDX,
+								stp_core_ctx.parser.ack,
+								stp_core_ctx.parser.seq,
+								5,	/* STP type id */
+								PKT_DIR_RX,
+								NULL,
+								0);
+						fgTriggerResume = stp_process_rxack();
+					} else {
+						STP_WARN_FUNC
+						    ("Now it's inband reset process and drop ACK packet.\n");
+					}
+
+					if (fgTriggerResume == 0) {
+						/* notify adaptation layer for
+						* possible tx resume mechanism
+						*/
+						(*sys_event_tx_resume) (stp_core_ctx.sequence.winspace);
+					}
+					stp_ctx_unlock(&stp_core_ctx);
+					/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+					stp_change_rx_state(MTKSTP_SYNC);
+					stp_core_ctx.rx_counter = 0;
+				} else {
+					stp_change_rx_state(MTKSTP_DATA);
+					stp_core_ctx.rx_counter = 0;
+				}
+			} else {
+				STP_ERR_FUNC("The checksum of header is error !!! %02x %02x %02x %02x\n",
+					     stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1],
+					     stp_core_ctx.rx_buf[2], *p_data);
+				/* George FIXME: error handling mechanism shall be refined */
+				stp_change_rx_state(MTKSTP_RESYNC1);
+				stp_core_ctx.rx_counter = 0;
+
+				/* since checksum error is usually related to interface
+				 * buffer overflow, so we just let timeout mechanism to
+				 * handle such error.
+				 */
+				STP_TRACE_FUNC("--\n");
+				/* return and purge COMM port */
+				return -1;
+				/*stp_send_ack(1); NAK mechanism is removed */
+			}
+			break;
+
+		case MTKSTP_DATA:
+#if 0
+			if (stp_core_ctx.rx_counter < stp_core_ctx.parser.length) {
+				stp_core_ctx.rx_buf[stp_core_ctx.rx_counter] = *p_data;
+				stp_core_ctx.rx_counter++;
+			}
+			if (stp_core_ctx.rx_counter == stp_core_ctx.parser.length)
+				stp_change_rx_state(MTKSTP_CRC1);
+#else
+			/* block copy instead of byte copy */
+			if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) {
+				STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n",
+					     stp_core_ctx.parser.length, stp_core_ctx.rx_counter);
+				osal_assert(0);
+			}
+			remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter;
+			if (i >= remain_length) {
+				osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data,
+					    remain_length);
+
+				i -= remain_length;
+				p_data += remain_length;
+				stp_core_ctx.rx_counter = stp_core_ctx.parser.length;
+				stp_core_ctx.parser.state = MTKSTP_CRC1;
+				continue;
+			} else {	/* only copy by data length */
+
+				/*fixed klocwork insight issue */
+				if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) {
+					STP_ERR_FUNC
+					    ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n");
+					stp_change_rx_state(MTKSTP_RESYNC1);
+					stp_core_ctx.rx_counter = 0;
+					STP_TRACE_FUNC("--\n");
+					return -1;
+				}
+
+				osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i);
+				stp_core_ctx.rx_counter += i;	/* all remain buffer are data */
+				i = 0;
+				p_data += i;
+				continue;
+			}
+#endif
+			break;
+
+		case MTKSTP_CRC1:
+			stp_change_rx_state(MTKSTP_CRC2);
+			stp_core_ctx.parser.crc = *p_data;
+			break;
+		case MTKSTP_CRC2:
+			stp_change_rx_state(MTKSTP_SYNC);
+			stp_core_ctx.parser.crc += (*p_data) << 8;
+#if 1
+			if (stp_core_ctx.parser.type == WMT_TASK_INDX) {
+				stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1];
+				STP_DBG_FUNC("wmt sub type is (0x%x)\n", stp_core_ctx.parser.wmtsubtype);
+			}
+#endif
+			if (stp_check_crc(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, stp_core_ctx.parser.crc)
+			    == MTK_WCN_BOOL_TRUE) {
+				if (stp_core_ctx.inband_rst_set == 0)
+					stp_process_packet();
+				else
+					STP_WARN_FUNC("Now it's inband reset process and drop packet.\n");
+			} else {
+				STP_ERR_FUNC("The CRC of packet is error !!!\n");
+				/* George FIXME: error handling mechanism shall be refined */
+				stp_change_rx_state(MTKSTP_RESYNC1);
+				stp_core_ctx.rx_counter = 0;
+
+				/* since checksum error is usually related to interface
+				 * buffer overflow, so we just let timeout mechanism to
+				 * handle such error.
+				 */
+				STP_TRACE_FUNC("--\n");
+				/* return and purge COMM port */
+				return -1;
+				/*stp_send_ack(1); NAK mechanism is removed */
+			}
+			break;
+
+		case MTKSTP_FW_MSG:
+#if CFG_WMT_DUMP_INT_STATUS
+			if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status())
+				wmt_plat_BGF_irq_dump_status();
+#endif
+			if (STP_IS_READY(stp_core_ctx))
+				mtk_wcn_stp_dbg_dump_package();
+
+			STP_SET_READY(stp_core_ctx, 0);
+			/*stp inband reset */
+			if (stp_core_ctx.parser.type == STP_TASK_INDX &&
+			    stp_core_ctx.parser.seq == 0 &&
+			    stp_core_ctx.parser.ack == 0 &&
+			    stp_core_ctx.parser.length == 0 && stp_core_ctx.inband_rst_set == 1) {
+				STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r");
+				stp_rest_ctx_state();
+				stp_change_rx_state(MTKSTP_RESYNC1);
+				stp_core_ctx.inband_rst_set = 0;
+				/* STP_INFO_FUNC("Restart STP Timer\n\r"); */
+				/* (*sys_timer_start)(stp_core_ctx.tx_timer,
+				*		mtkstp_tx_timeout,
+				*		(MTK_WCN_TIMER_CB)stp_tx_timeout_handler,
+				*		NULL);
+				*/
+				STP_TRACE_FUNC("--\n");
+				return 0;
+			}
+
+			/*f/w assert and exception information */
+			if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) {
+				STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n",
+					     stp_core_ctx.parser.length, stp_core_ctx.rx_counter);
+				osal_assert(0);
+			}
+
+			remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter;
+			if (i >= remain_length) {
+				osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data,
+					    remain_length);
+				i -= remain_length;
+				p_data += remain_length;
+				stp_core_ctx.rx_counter = stp_core_ctx.parser.length;
+				stp_change_rx_state(MTKSTP_SYNC);
+				*(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0';
+				/* STP_ERR_FUNC("%s [%d]\n", stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); */
+#if 0
+				if ((stp_core_ctx.rx_counter == 1) && (stp_core_ctx.rx_buf[0] == 0xFF)) {
+					/* For MT6620, enable/disable coredump function is controlled by
+					* firmware for the moment, we need to set coredump enable flag
+					* to be 1 after see firmware send a pariticallar character(0xff)
+					* before any coredump packet is sent
+					*/
+					mtk_wcn_stp_coredump_flag_ctrl(1);
+				}
+#endif
+				/*Trace32 Dump */
+				if (STP_IS_ENABLE_DBG(stp_core_ctx) &&
+					(stp_core_ctx.parser.type == STP_TASK_INDX)) {
+					if (0 != stp_core_ctx.rx_counter) {
+						STP_SET_READY(stp_core_ctx, 0);
+						mtk_wcn_stp_ctx_save();
+						STP_INFO_FUNC("++ start to read paged dump and paged trace ++\n");
+						stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm);
+						stp_btm_notify_wmt_trace_wq(stp_core_ctx.btm);
+						STP_INFO_FUNC("++ start to read paged dump and paged trace --\n");
+
+					}
+					STP_INFO_FUNC("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter,
+					       stp_core_ctx.parser.type, stp_core_ctx.rx_buf);
+				}
+
+				/*Runtime FW Log */
+				else if (STP_IS_ENABLE_DBG(stp_core_ctx)
+					 && (stp_core_ctx.parser.type == INFO_TASK_INDX)) {
+					stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0,
+							(stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf);
+					mtk_wcn_stp_dbg_dump_package();
+				}
+				/*Normal mode: whole chip reset */
+				else {
+					/*Aee Kernel Warning Message Shown First */
+					/* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */
+					mtk_wcn_stp_coredump_start_ctrl(0);
+					mtk_wcn_stp_dbg_dump_package();
+
+					osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf);
+					/*Whole Chip Reset Procedure Invoke */
+					if (STP_IS_ENABLE_RST(stp_core_ctx)) {
+						STP_SET_READY(stp_core_ctx, 0);
+						stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx));
+					} else {
+						STP_INFO_FUNC
+						    ("No to launch whole chip reset! for debugging purpose\n");
+					}
+				}
+				/*discard CRC */
+				if (i >= 2) {
+					STP_DBG_FUNC("crc discard.. i = %d\n", i);
+					i -= 2;
+					if (i > 0)
+						p_data += 2;
+				}
+				continue;
+			} else {	/* only copy by data length */
+
+				/*fixed klocwork insight issue */
+				if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) {
+					STP_ERR_FUNC
+					    ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n");
+					stp_change_rx_state(MTKSTP_RESYNC1);
+					stp_core_ctx.rx_counter = 0;
+					return -1;
+				}
+				osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i);
+				stp_core_ctx.rx_counter += i;	/* all remain buffer are data */
+				i = 0;
+				p_data += i;
+				continue;
+			}
+
+			break;
+		default:
+			break;
+		}
+		p_data++;
+		i--;
+	}
+
+	return 0;
+}
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_parser_data
+* DESCRIPTION
+*  push data to serial transport protocol parser engine
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  int            0 = success; -1 = crc/checksum error
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+int _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length)
+#else
+int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length)
+#endif
+{
+    /*----------------------------------------------------------------*/
+	/* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+	INT32 i;
+	UINT8 *p_data;
+	INT32 ret = 0;
+#ifdef DEBUG_DUMP_PACKET_HEAD
+	static UINT32 counter;
+
+	STP_TRACE_FUNC("++, rx (cnt=%d,len=%d)\n", ++counter, length);
+#endif
+
+#if 0
+#ifdef CONFIG_POWER_SAVING_SUPPORT
+	if (stp_is_apply_powersaving()) {
+		/* If now chip is awake, to restart monitor! */
+		if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) {
+			STP_DBG_FUNC("To restart moinotr when rx\n\r");
+			stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx));
+		}
+	}
+#endif
+#endif
+
+    /*----------------------------------------------------------------*/
+	/* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+	/* George FIXME: WHY or HOW can we reduct the locked region? */
+	/*flags = (*sys_mutex_lock)(stp_core_ctx.stp_mutex); */
+	i = length;
+	p_data = (UINT8 *) buffer;
+
+/* stp_dump_data(buffer, "rx queue", length); */
+
+	/*STP is not enabled and only WMT can use Raw data path */
+	if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == STP_PENDING_TYPE(stp_core_ctx)) {
+		/* route to task who send command */
+		stp_add_to_rx_queue(buffer, length, STP_PENDING_TYPE(stp_core_ctx));
+
+		/* mike: notify corresponding subfunction of incoming data */
+		(*sys_event_set) (STP_PENDING_TYPE(stp_core_ctx));
+	}
+	/* STP over SDIO */
+	else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) {
+#if !(REMOVE_USELESS_LOG)
+		if (gStpDbgLvl >= STP_LOG_DBG)
+			stp_dump_data(buffer, "sdio parser_in", length);
+#endif
+		/* STP_DBG_FUNC("sdio stp parser data length = %d\n", length); */
+		ret = stp_parser_data_in_mand_mode(i, p_data);
+	}
+	/* STP over UART */
+	else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx))
+		ret = stp_parser_data_in_full_mode(i, p_data);
+
+	/* George FIXME: WHY or HOW can we reduct the locked region? */
+	/*(*sys_mutex_unlock)(stp_core_ctx.stp_mutex, flags); */
+	STP_TRACE_FUNC("--\n");
+	return ret;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_parser_data);
+#endif
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_enable
+* DESCRIPTION
+*  enable/disable STP
+* PARAMETERS
+*  value        [IN]        0=disable, others=enable
+* RETURNS
+*  INT32    0=success, others=error
+*****************************************************************************/
+INT32 mtk_wcn_stp_enable(INT32 value)
+{
+	STP_DBG_FUNC("%s: set the current enable = (%d)\n", __func__, value);
+
+	stp_rest_ctx_state();
+	STP_SET_ENABLE(stp_core_ctx, value);
+	if (!value) {
+		mtk_wcn_stp_psm_reset();
+	} else {
+/* g_block_tx = 0; */
+		mtk_wcn_stp_coredump_start_ctrl(0);
+	}
+	return 0;
+}
+
+INT32 mtk_wcn_stp_dbg_dump_package(VOID)
+{
+	if (STP_NOT_ENABLE(stp_core_ctx)) {
+		STP_INFO_FUNC("STP dbg mode is off\n");
+
+	} else {
+		STP_INFO_FUNC("STP dbg mode is on\n");
+		/* if (0 == g_block_tx) */
+		if (0 == mtk_wcn_stp_coredump_start_get()) {
+			mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG);
+			mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG);
+			stp_dbg_dmp_printk(g_mtkstp_dbg);
+		} else {
+			STP_INFO_FUNC("assert start flag is set, disable packet dump function\n");
+		}
+	}
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_ready
+* DESCRIPTION
+*  ready/un-ready STP
+* PARAMETERS
+*  value        [IN]        0=un-ready, others=ready
+* RETURNS
+*  INT32    0=success, others=error
+*****************************************************************************/
+INT32 mtk_wcn_stp_ready(INT32 value)
+{
+	STP_DBG_FUNC("set ready (%d)\n", value);
+
+	STP_SET_READY(stp_core_ctx, value);
+	/*if whole chip reset, reset the debuggine mode */
+#ifndef CONFIG_LOG_STP_INTERNAL
+	/* mtk_wcn_stp_dbg_disable(); */
+#endif
+
+	if (stp_is_apply_powersaving()) {
+		STP_INFO_FUNC("Restart the stp-psm monitor !!\n");
+		stp_psm_disable(STP_PSM_CORE(stp_core_ctx));
+	}
+
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_coredump_start_ctrl
+* DESCRIPTION
+*  set f/w assert flag in STP context
+* PARAMETERS
+*  value        [IN]        0=assert end, others=assert begins
+* RETURNS
+*  INT32    0=success, others=error
+*****************************************************************************/
+INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value)
+{
+	STP_DBG_FUNC("set f/w assert (%d)\n", value);
+
+	STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, value);
+
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_coredump_start_get
+* DESCRIPTION
+*  get f/w assert flag in STP context
+* PARAMETERS
+*  VOID
+* RETURNS
+*  INT32    0= f/w assert flag is not set, others=f/w assert flag is set
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_coredump_start_get(VOID)
+#else
+INT32 mtk_wcn_stp_coredump_start_get(VOID)
+#endif
+{
+	return STP_FW_COREDUMP_FLAG(stp_core_ctx);
+}
+
+/* mtk_wcn_stp_set_wmt_last_close -- set the state of link(UART or SDIO)
+ * @ value - 1, link already be closed; 0, link is open
+ *
+ * Return 0 if success; else error code
+ */
+INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value)
+{
+	STP_INFO_FUNC("set wmt_last_close flag (%d)\n", value);
+
+	STP_SET_WMT_LAST_CLOSE(stp_core_ctx, value);
+
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_send_data
+* DESCRIPTION
+*  subfunction send data through STP
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    > 0: length transmitted; = 0: error
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type)
+#else
+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type)
+#endif
+{
+	UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2];
+	UINT8 *p_tx_buf = NULL;
+	UINT16 crc;
+	INT32 ret = 0;
+	MTK_WCN_BOOL is_quick_enable = MTK_WCN_BOOL_TRUE;
+
+	/* osal_buffer_dump(buffer,"tx", length, 32); */
+
+	if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) {
+		STP_ERR_FUNC("WMT lats close,should not have tx request!\n");
+		return length;
+	}
+	/* if(g_block_tx) */
+	if (0 != mtk_wcn_stp_coredump_start_get()) {
+		STP_ERR_FUNC("STP fw coredump start flag set...\n");
+		return length;
+	}
+#ifdef CONFIG_POWER_SAVING_SUPPORT
+	is_quick_enable = stp_psm_is_quick_ps_support();
+	STP_DBG_FUNC("is quick sleep enable:%s\n", is_quick_enable ? "yes" : "no");
+	if (MTK_WCN_BOOL_TRUE == is_quick_enable) {
+		if (type != WMT_TASK_INDX) {
+#if PSM_USE_COUNT_PACKAGE
+			stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0);
+#else
+			stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0, length);
+#endif
+		}
+		/* if(stp_is_apply_powersaving()) */
+		{
+			if (type == WMT_TASK_INDX)
+				goto DONT_MONITOR;
+		/*-----------------------------STP_PSM_Lock----------------------------------------*/
+			ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx));
+			if (ret) {
+				STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret);
+				return ret;
+			}
+
+			if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) {
+				if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) {
+					STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n");
+					stp_psm_release_data(STP_PSM_CORE(stp_core_ctx));
+				}
+			} else {
+				ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type);
+				stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx));
+				/*-----------------------------STP_PSM_UnLock----------------------------------------*/
+				stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx));
+				return ret;
+			}
+		}
+	} else {
+		/* if(stp_is_apply_powersaving()) */
+		{
+		 if (type == WMT_TASK_INDX)
+				goto DONT_MONITOR;
+			/* If now chip is awake, to restart monitor! */
+			/* STP_INFO_FUNC("check if block traffic !!\n"); */
+		/*-----------------------------STP_PSM_Lock----------------------------------------*/
+			ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx));
+			if (ret) {
+				STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret);
+				return ret;
+			}
+
+			if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) {
+				/* STP_INFO_FUNC("not to block !!\n"); */
+				if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) {
+					STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n");
+					stp_psm_release_data(STP_PSM_CORE(stp_core_ctx));
+				}
+				stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx));
+			} else {
+				/* STP_INFO_FUNC("to block !!\n"); */
+
+				/* STP_INFO_FUNC("*****hold data in psm queue data length = %d\n",
+				* length);
+				*/
+				/* stp_dump_data(buffer, "Hold in psm queue", length); */
+				/* hold datas */
+				ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type);
+				/* wmt notification */
+				STP_INFO_FUNC("#####Type = %d, to inform WMT to wakeup chip, ret = %d:0x%2x,0x%2x\n",
+					      type, ret, *buffer, *(buffer + 1));
+				stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx));
+				/* STP_INFO_FUNC("*********Type = %d, to inform WMT to wakeup chip>end\n", type); */
+		    /*-----------------------------STP_PSM_UnLock----------------------------------------*/
+				stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx));
+				return ret;
+			}
+		}
+	}
+DONT_MONITOR:
+#endif
+	if (type == BT_TASK_INDX) {
+		static const UINT8 rst_buf[4] = { 0x01, 0x03, 0x0c, 0x00 };
+
+		if (!osal_strncmp(buffer, rst_buf, 4))
+			osal_printtimeofday("############ BT Rest start -->");
+	}
+	/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_lock(&stp_core_ctx);
+	/*Only WMT can set raw data */
+	if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) {
+		/* no-op */
+		/* NULL; */
+	} else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) {
+		/* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */
+		/* NULL; */
+	}
+	/* STP over SDIO */
+	else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) {
+
+		/* osal_printtimeofday("[ STP][SDIO][ B][W]"); */
+
+		mtkstp_header[0] = 0x80;
+		mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f);
+		mtkstp_header[2] = (length) & 0xff;
+		mtkstp_header[3] = 0x00;
+
+		/* HEADER */
+		p_tx_buf = &stp_core_ctx.tx_buf[0];
+		osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE);
+		p_tx_buf += MTKSTP_HEADER_SIZE;
+
+		/* PAYLOAD */
+		osal_memcpy(p_tx_buf, buffer, length);
+		p_tx_buf += length;
+
+		/* CRC */
+		temp[0] = 0x00;
+		temp[1] = 0x00;
+		osal_memcpy(p_tx_buf, temp, 2);
+		stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length);
+		(*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret);
+
+		if ((MTKSTP_HEADER_SIZE + length + 2) != ret) {
+			STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret);
+			osal_assert(0);
+			ret = 0;
+		} else {
+			ret = (INT32) length;
+		}
+
+		/* osal_printtimeofday("[ STP][SDIO][ E][W]"); */
+	}
+	/* STP over UART */
+	else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) {
+
+		/* osal_printtimeofday("[ STP][UART][ B][W]"); */
+		/* STP_INFO_FUNC("Write byte %d\n", length); */
+
+		if ((stp_core_ctx.sequence.winspace > 0) &&
+		    (stp_core_ctx.inband_rst_set == 0) &&
+		    (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) {
+			/*Make Header */
+			/* (*sys_dbg_print)("mtk_wcn_stp_send_data 1, txseq = %d, winspace = %d",
+			* stp_core_ctx.sequence.txseq, stp_core_ctx.sequence.winspace);
+			*/
+			mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack;
+			mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8);
+			mtkstp_header[2] = length & 0xff;
+			mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff;
+			stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write;
+			stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2;
+			if (fgEnableDelimiter == 1) {
+				stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE;
+				stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE);
+			}
+			stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE);
+
+			/*Make Payload */
+			stp_add_to_tx_queue(buffer, length);
+
+			/*Make CRC */
+			crc = osal_crc16(buffer, length);
+			temp[0] = crc & 0xff;
+			temp[1] = (crc & 0xff00) >> 8;
+			stp_add_to_tx_queue(temp, 2);
+			stp_dbg_pkt_log(type,
+					stp_core_ctx.sequence.txack,
+					stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length);
+
+			/*Kick to UART */
+			stp_send_tx_queue(stp_core_ctx.sequence.txseq);
+
+			INDEX_INC(stp_core_ctx.sequence.txseq);
+			stp_core_ctx.sequence.winspace--;
+
+			/*Setup the Retry Timer */
+			osal_timer_stop(&stp_core_ctx.tx_timer);
+			if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE)
+				osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout);
+			else
+				STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n");
+
+			ret = (INT32) length;
+		} else {
+			/*
+			   No winspace to send. Let caller retry
+			 */
+			if (stp_core_ctx.inband_rst_set == 1)
+				STP_WARN_FUNC("Now it's inband reset process and drop sent packet.\n");
+			else
+				STP_ERR_FUNC("There is no winspace/txqueue to send !!!\n");
+
+			ret = 0;
+		}
+
+		/* osal_printtimeofday("[ STP][UART][ E][W]"); */
+	}
+	/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_unlock(&stp_core_ctx);
+
+#ifdef CONFIG_POWER_SAVING_SUPPORT
+
+	if (MTK_WCN_BOOL_TRUE == is_quick_enable) {
+		if (type != WMT_TASK_INDX) {
+			stp_psm_notify_wmt_sleep(STP_PSM_CORE(stp_core_ctx));
+			/*-----------------------STP_PSM_UnLock-------------------------*/
+			stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx));
+		}
+	} else {
+		/* if(stp_is_apply_powersaving()) */
+		/* { */
+		if (type != WMT_TASK_INDX) {
+
+			/*--------------------STP_PSM_UnLock--------------------------*/
+			stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx));
+		}
+		/* } */
+	}
+#endif
+
+	return ret;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_send_data);
+#endif
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_send_data_raw
+* DESCRIPTION
+*  send raw data to common interface, bypass STP
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    >= 0: length transmitted; < 0: error
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type)
+#else
+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type)
+#endif
+{
+	UINT32 written = 0;
+	INT32 ret = 0;
+
+	if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) {
+		STP_ERR_FUNC("WMT lats close,should not have tx request!");
+		return length;
+	}
+
+	STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d, data = %x %x %x %x %x %x ", type, buffer[0], buffer[1],
+		     buffer[2], buffer[3], buffer[4], buffer[5]);
+	STP_SET_PENDING_TYPE(stp_core_ctx, type);	/* remember tx type, forward following rx to this type */
+
+	/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_lock(&stp_core_ctx);
+	stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, 1);
+	(*sys_if_tx) (&buffer[0], length, &written);
+	/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_unlock(&stp_core_ctx);
+
+	if (written == 0)
+		stp_dump_data(&buffer[0], "tx raw failed:", length);
+
+	if (written == length)
+		ret = (INT32) written;
+	else
+		ret = (-1);
+
+	return ret;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw);
+#endif
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_receive_data
+* DESCRIPTION
+*  receive data from serial protocol engine
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    >= 0: size of data received; < 0: error
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type)
+#else
+INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type)
+#endif
+{
+	/* GeorgeKuo modify: reduce "if" branch */
+	UINT16 copyLen = 0;
+	UINT16 tailLen = 0;
+
+	osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+
+	while (stp_core_ctx.ring[type].read_p != stp_core_ctx.ring[type].write_p) {
+		/* GeorgeKuo modify: reduce if branch */
+		if (stp_core_ctx.ring[type].write_p > stp_core_ctx.ring[type].read_p) {
+			copyLen = stp_core_ctx.ring[type].write_p - stp_core_ctx.ring[type].read_p;
+			if (copyLen > length)
+				copyLen = length;
+
+			osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, copyLen);
+			stp_core_ctx.ring[type].read_p += copyLen;
+		} else {
+			tailLen = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].read_p;
+			if (tailLen > length) {	/* exclude equal case to skip wrap check */
+				copyLen = length;
+				osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p,
+					    copyLen);
+				stp_core_ctx.ring[type].read_p += copyLen;
+			} else {
+				/* part 1: copy tailLen */
+				osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p,
+					    tailLen);
+
+				buffer += tailLen;	/* update buffer offset */
+
+				/* part 2: check if head length is enough */
+				copyLen = length - tailLen;
+				copyLen =
+				    (stp_core_ctx.ring[type].write_p <
+				     copyLen) ? stp_core_ctx.ring[type].write_p : copyLen;
+
+				if (copyLen)
+					osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + 0, copyLen);
+
+				/* Update read_p final position */
+				stp_core_ctx.ring[type].read_p = copyLen;
+
+				/* update return length: head + tail */
+				copyLen += tailLen;
+			}
+		}
+		break;
+	}
+
+	osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+
+	if ((MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) && (type != WMT_TASK_INDX)) {
+#if PSM_USE_COUNT_PACKAGE
+		stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1);
+#else
+		stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1, copyLen);
+#endif
+	}
+
+	return copyLen;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_receive_data);
+#endif
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_rxqueue_empty
+* DESCRIPTION
+*  Is certain rx queue empty?
+* PARAMETERS
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    0: queue is NOT empyt; !0: queue is empty
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_is_rxqueue_empty(UINT8 type)
+#else
+INT32 mtk_wcn_stp_is_rxqueue_empty(UINT8 type)
+#endif
+{
+	INT32 ret;
+
+	osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+
+	if (stp_core_ctx.ring[type].read_p == stp_core_ctx.ring[type].write_p)
+		ret = 1;	/* queue is empty */
+	else
+		ret = 0;	/* queue is not empty */
+
+	osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+
+	return ret;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty);
+#endif
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_set_sdio_mode
+* DESCRIPTION
+*  Set stp for SDIO mode
+* PARAMETERS
+*  sdio_flag  [IN]        sdio mode flag (TRUE:SDIO mode, FALSE:UART mode)
+* RETURNS
+*  void
+*****************************************************************************/
+
+void mtk_wcn_stp_set_mode(UINT32 mode)
+{
+	STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, mode);
+
+	STP_DBG_FUNC("STP_SUPPORT_PROTOCOL = %08x\n", STP_SUPPORT_PROTOCOL(stp_core_ctx));
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_uart_fullset_mode
+* DESCRIPTION
+*  Is stp use UART fullset mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:Uart Fullset mode, FALSE:Not UART Fullset mode
+*****************************************************************************/
+MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void)
+{
+	/*
+	   bit 0: uart fullset   mode
+	   bit 1: uart mandatory mode
+	   bit 2: sdio mode
+	 */
+	if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_FULL_MODE)
+		return MTK_WCN_BOOL_TRUE;
+	else
+		return MTK_WCN_BOOL_FALSE;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_uart_mand_mode
+* DESCRIPTION
+*  Is stp use UART mandatory mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:Uart Mandatory mode, FALSE:Not UART Mandotary mode
+*****************************************************************************/
+MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void)
+{
+	/*
+	   bit 0: uart fullset   mode
+	   bit 1: uart mandatory mode
+	   bit 2: sdio mode
+	 */
+	if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_MAND_MODE)
+		return MTK_WCN_BOOL_TRUE;
+	else
+		return MTK_WCN_BOOL_FALSE;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_btif_fullset_mode
+* DESCRIPTION
+*  Is stp use BTIF fullset mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:BTIF Fullset mode, FALSE:Not BTIF Fullset mode
+*****************************************************************************/
+MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void)
+{
+
+	if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_FULL_MODE)
+		return MTK_WCN_BOOL_TRUE;
+	else
+		return MTK_WCN_BOOL_FALSE;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_btif_mand_mode
+* DESCRIPTION
+*  Is stp use BTIF mandatory mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:BTIF Mandatory mode, FALSE:Not BTIF Mandotary mode
+*****************************************************************************/
+
+MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void)
+{
+
+	if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_MAND_MODE)
+		return MTK_WCN_BOOL_TRUE;
+	else
+		return MTK_WCN_BOOL_FALSE;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_sdio_mode
+* DESCRIPTION
+*  Is stp use SDIO mode?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:SDIO mode, FALSE:UART mode
+*****************************************************************************/
+MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void)
+{
+	/*
+	   bit 0: uart fullset   mode
+	   bit 1: uart mandatory mode
+	   bit 2: sdio mode
+	 */
+	if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_SDIO_MODE)
+		return MTK_WCN_BOOL_TRUE;
+	else
+		return MTK_WCN_BOOL_FALSE;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  stp_send_inband_reset
+* DESCRIPTION
+*  To sync to oringnal stp state with f/w stp
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+void mtk_wcn_stp_inband_reset(void)
+{
+	UINT8 inband_reset_packet[64];
+	UINT32 txseq = 0;
+	UINT32 txack = 0;
+	UINT32 crc = 0;
+	UINT32 ret = 0;
+	UINT32 reset_payload_len = 0;
+
+	/*512 bytes */
+	UINT8 reset_payload[] = {
+		0xc0, 0x01, 0xc0, 0xde, 0x3e, 0xd1, 0xa7, 0xef
+	};
+
+	/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+	stp_ctx_lock(&stp_core_ctx);
+
+	 /*RESYNC*/ inband_reset_packet[0] = 0x7f;
+	inband_reset_packet[1] = 0x7f;
+	inband_reset_packet[2] = 0x7f;
+	inband_reset_packet[3] = 0x7f;
+	inband_reset_packet[4] = 0x7f;
+	inband_reset_packet[5] = 0x7f;
+	inband_reset_packet[6] = 0x7f;
+	inband_reset_packet[7] = 0x7f;
+
+	/*header */
+	reset_payload_len = sizeof(reset_payload) / sizeof(reset_payload[0]);
+	inband_reset_packet[8] = 0x80 + (txseq << 3) + txack;
+	inband_reset_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8);
+	inband_reset_packet[10] = reset_payload_len & 0xff;
+	inband_reset_packet[11] = (inband_reset_packet[8] + inband_reset_packet[9] + inband_reset_packet[10]) & 0xff;
+
+	/*payload */
+	osal_memcpy(&inband_reset_packet[12], reset_payload, reset_payload_len);
+
+	/*crc */
+	crc = osal_crc16(&reset_payload[0], reset_payload_len);
+	inband_reset_packet[12 + reset_payload_len] = crc & 0xff;
+	inband_reset_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8;
+
+	(*sys_if_tx) (&inband_reset_packet[0], 14 + reset_payload_len, &ret);
+
+	if (ret != (14 + reset_payload_len))
+		STP_ERR_FUNC("Inband sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ret);
+
+	stp_core_ctx.inband_rst_set = 1;
+	stp_ctx_unlock(&stp_core_ctx);
+	/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+}
+
+void mtk_wcn_stp_debug_ctrl(INT32 op, INT32 filter, INT32 filter_param)
+{
+	/*nothing at now*/
+}
+
+void mtk_wcn_stp_test_cmd(INT32 cmd_no)
+{
+	UINT8 test_packet[64];
+	UINT32 txseq = 0;
+	UINT32 txack = 0;
+	UINT32 crc = 0;
+	UINT32 ret = 0;
+	UINT32 reset_payload_len = 0;
+
+	UINT8 test_payload[] = {
+		0xAA, 0xAA, 0xC0, 0xDE, 0x3E, 0xD1, 0xA7, 0xEF
+	};
+/*  */
+/* select your test command by cmd_no */
+/*  */
+	if (cmd_no == 0) {
+		/* to test new command to chip */
+		/* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+		stp_ctx_lock(&stp_core_ctx);
+
+		 /*RESYNC*/ test_packet[0] = 0x7f;
+		test_packet[1] = 0x7f;
+		test_packet[2] = 0x7f;
+		test_packet[3] = 0x7f;
+		test_packet[4] = 0x7f;
+		test_packet[5] = 0x7f;
+		test_packet[6] = 0x7f;
+		test_packet[7] = 0x7f;
+
+		/*header */
+		reset_payload_len = sizeof(test_payload) / sizeof(test_payload[0]);
+		test_packet[8] = 0x80 + (txseq << 3) + txack;
+		test_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8);
+		test_packet[10] = reset_payload_len & 0xff;
+		test_packet[11] = (test_packet[8] + test_packet[9] + test_packet[10]) & 0xff;
+
+		/*payload */
+		osal_memcpy(&test_packet[12], test_payload, reset_payload_len);
+
+		/*crc */
+		crc = osal_crc16(&test_payload[0], reset_payload_len);
+		test_packet[12 + reset_payload_len] = crc & 0xff;
+		test_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8;
+
+		(*sys_if_tx) (&test_packet[0], 14 + reset_payload_len, &ret);
+		if (ret != (14 + reset_payload_len)) {
+			STP_ERR_FUNC("stp test sending error, sending %d , but ret = %d\n", 10 + reset_payload_len,
+				     ret);
+		}
+		/* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */
+		stp_ctx_unlock(&stp_core_ctx);
+	}
+
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_flush_context
+* DESCRIPTION
+*  Flush STP Context
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+void mtk_wcn_stp_flush_context(void)
+{
+	stp_rest_ctx_state();
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_flush_rx_queue
+* DESCRIPTION
+*  Flush STP Rx Queue
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+
+void mtk_wcn_stp_flush_rx_queue(UINT32 type)
+{
+	osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+	if (type < MTKSTP_MAX_TASK_NUM) {
+		stp_core_ctx.ring[type].read_p = 0;
+		stp_core_ctx.ring[type].write_p = 0;
+	}
+	osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx);
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_enable
+* DESCRIPTION
+*  STP is ready?
+* PARAMETERS
+*  none.
+* RETURNS
+*  none
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void)
+#else
+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void)
+#endif
+{
+	return STP_IS_READY(stp_core_ctx);
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_is_ready);
+#endif
+/*****************************************************************************
+* FUNCTION
+*  set_bluetooth_rx_interface
+* DESCRIPTION
+*  Set bluetooth rx interface
+* PARAMETERS
+*  rx interface type
+* RETURNS
+*  void
+*****************************************************************************/
+#if STP_EXP_HID_API_EXPORT
+void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag)
+#else
+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag)
+#endif
+{
+	/* g_mtkstp_bluez_flag = bluez_flag; */
+	STP_SET_BT_STK(stp_core_ctx, bluez_flag);
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez);
+#endif
+/*****************************************************************************
+* FUNCTION
+*  set stp debugging mdoe
+* DESCRIPTION
+*  set stp debugging mdoe
+* PARAMETERS
+* dbg_mode: switch to dbg mode ?
+* RETURNS
+*  void
+*****************************************************************************/
+void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode)
+{
+	STP_SET_ENABLE_DBG(stp_core_ctx, dbg_mode);
+}
+
+/*****************************************************************************
+* FUNCTION
+*  set stp auto reset mdoe
+* DESCRIPTION
+*  set stp auto reset mdoe
+* PARAMETERS
+* auto_rst: switch to auto reset mode ?
+* RETURNS
+*  void
+*****************************************************************************/
+void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst)
+{
+	STP_SET_ENABLE_RST(stp_core_ctx, auto_rst);
+}
+
+INT32 mtk_wcn_stp_notify_sleep_for_thermal(void)
+{
+	return stp_psm_sleep_for_thermal(STP_PSM_CORE(stp_core_ctx));
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_open_btif
+* DESCRIPTION
+*  init btif hw & sw by owner stp
+* PARAMETERS
+* VOID
+* RETURNS
+*  INT32 0-success,other fail.
+*****************************************************************************/
+INT32 mtk_wcn_stp_open_btif(VOID)
+{
+	return mtk_wcn_consys_stp_btif_open();
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_open_close
+* DESCRIPTION
+*  close btif hw & sw by owner stp
+* PARAMETERS
+* VOID
+* RETURNS
+*  INT32 0-success,other fail.
+*****************************************************************************/
+INT32 mtk_wcn_stp_close_btif(VOID)
+{
+	return mtk_wcn_consys_stp_btif_close();
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_rx_cb_register
+* DESCRIPTION
+*  register stp rx cb to btif
+* PARAMETERS
+* MTK_WCN_BTIF_RX_CB stp rx handle function
+* RETURNS
+*  INT32 0-success,other fail.
+*****************************************************************************/
+INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb)
+{
+	return mtk_wcn_consys_stp_btif_rx_cb_register(rx_cb);
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_tx
+* DESCRIPTION
+*  send stp package by btif
+* PARAMETERS
+* pBuf:package buffer pointer,len:package length
+* written_len:package written length
+* RETURNS
+*  INT32 package length-success,other fail.
+*****************************************************************************/
+INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len)
+{
+	INT32 iRet = -1;
+
+	iRet = mtk_wcn_consys_stp_btif_tx(pBuf, len, written_len);
+	return iRet;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_wakeup_consys
+* DESCRIPTION
+*  STP wakeup consys by btif
+* PARAMETERS
+* VOID
+* RETURNS
+*  INT32 0-success,other fail.
+*****************************************************************************/
+INT32 mtk_wcn_stp_wakeup_consys(VOID)
+{
+	/*log wakeup int for debug */
+	stp_dbg_pkt_log(7, 0, 0, 0, PKT_DIR_TX, NULL, 0);
+	return mtk_wcn_consys_stp_btif_wakeup();
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_dpidle_ctrl
+* DESCRIPTION
+*  decide AP enter or exit deep idle
+* PARAMETERS
+* en_flag:1,enter,0,exit
+* RETURNS
+*  always 0
+*****************************************************************************/
+INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag)
+{
+	mtk_wcn_consys_stp_btif_dpidle_ctrl(en_flag);
+
+	return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_lpbk_ctrl
+* DESCRIPTION
+*  enable stp internal lpbk test or not
+* PARAMETERS
+* mode:1,enable,0,disabel
+* RETURNS
+*  INT32 0-success,other fail.
+*****************************************************************************/
+INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode)
+{
+	return mtk_wcn_consys_stp_btif_lpbk_ctrl(mode);
+}
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_logger_ctrl
+* DESCRIPTION
+*  dump btif buffer or register status when No ACK or assert occurs
+* PARAMETERS
+* flag:see enum value in ENUM_BTIF_DBG_ID
+* RETURNS
+*  INT32 0-success,other fail.
+*****************************************************************************/
+INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag)
+{
+	return mtk_wcn_consys_stp_btif_logger_ctrl(flag);
+}
+
+VOID mtk_wcn_stp_ctx_save(void)
+{
+	STP_INFO_FUNC("start ++\n");
+	mtk_wcn_stp_coredump_start_ctrl(1);
+	stp_psm_set_sleep_disable(stp_core_ctx.psm);
+	STP_INFO_FUNC("exit --\n");
+}
+
+VOID mtk_wcn_stp_ctx_restore(void)
+{
+	STP_INFO_FUNC("start ++\n");
+	stp_psm_set_sleep_enable(stp_core_ctx.psm);
+	stp_btm_reset_btm_wq(STP_BTM_CORE(stp_core_ctx));
+
+	if (STP_IS_ENABLE_RST(stp_core_ctx))
+		stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx));
+	else
+		STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n");
+#if STP_RETRY_OPTIMIZE
+	g_retry_times = 0;
+#endif
+	STP_INFO_FUNC("exit --\n");
+}
+
+INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(void)
+{
+	INT32 ret = -1;
+
+	if (mtk_wcn_stp_coredump_start_get() != 0) {
+		STP_INFO_FUNC("firmware assert has been triggered\n");
+		return 0;
+	}
+
+	ret = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx));
+	if (ret) {
+		STP_ERR_FUNC("evt err trigger assert fail,do chip reset to recovery\n");
+
+		mtk_wcn_stp_set_wmt_evt_err_trg_assert(0);
+		if (STP_IS_ENABLE_RST(stp_core_ctx))
+			stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx));
+		else
+			STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n");
+	}
+
+	return ret;
+}
+
+VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value)
+{
+	STP_INFO_FUNC("set evt err tigger assert flag to %d\n", value);
+	STP_SET_EVT_ERR_ASSERT(stp_core_ctx, value);
+}
+
+UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(void)
+{
+	return STP_EVT_ERR_ASSERT(stp_core_ctx);
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c
new file mode 100644
index 0000000000000..3009bd26df41a
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c
@@ -0,0 +1,529 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-CONF]"
+
+#include "osal_typedef.h"
+/* #include "osal.h" */
+#include "wmt_lib.h"
+#include "wmt_dev.h"
+#include "wmt_conf.h"
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+struct parse_data {
+	PINT8 name;
+	INT32 (*parser)(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 value);
+	PINT8 (*writer)(P_DEV_WMT pWmtDev, const struct parse_data *data);
+	/*PINT8 param1, *param2, *param3; */
+	/* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */
+	PINT8 param1;
+	PINT8 param2;
+	PINT8 param3;
+};
+
+/*******************************************************************************
+*                        P U B L I C   D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+*                       P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+*******************************************************************************
+*/
+static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos);
+
+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data);
+
+static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos);
+
+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data);
+
+static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos);
+
+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data);
+
+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal);
+
+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size);
+
+#define OFFSET(v) ((void *) &((P_DEV_WMT) 0)->v)
+
+#define CHAR(f) \
+{ \
+	#f, \
+	wmt_conf_parse_char, \
+	wmt_conf_write_char, \
+	OFFSET(rWmtGenConf.f), \
+	NULL, \
+	NULL \
+}
+/* #define CHAR(f) _CHAR(f), NULL, NULL} */
+
+#define SHORT(f) \
+{ \
+	#f, \
+	wmt_conf_parse_short, \
+	wmt_conf_write_short, \
+	OFFSET(rWmtGenConf.f), \
+	NULL, \
+	NULL \
+}
+/* #define SHORT(f) _SHORT(f), NULL, NULL */
+
+#define INT(f) \
+{ \
+	#f, \
+	wmt_conf_parse_int, \
+	wmt_conf_write_int, \
+	OFFSET(rWmtGenConf.f), \
+	NULL, \
+	NULL \
+}
+/* #define INT(f) _INT(f), NULL, NULL */
+
+/*******************************************************************************
+*                          F U N C T I O N S
+********************************************************************************
+*/
+
+static const struct parse_data wmtcfg_fields[] = {
+	CHAR(coex_wmt_ant_mode),
+	CHAR(coex_wmt_ext_component),
+	CHAR(coex_wmt_wifi_time_ctl),
+	CHAR(coex_wmt_ext_pta_dev_on),
+	CHAR(coex_wmt_filter_mode),
+
+	CHAR(coex_bt_rssi_upper_limit),
+	CHAR(coex_bt_rssi_mid_limit),
+	CHAR(coex_bt_rssi_lower_limit),
+	CHAR(coex_bt_pwr_high),
+	CHAR(coex_bt_pwr_mid),
+	CHAR(coex_bt_pwr_low),
+
+	CHAR(coex_wifi_rssi_upper_limit),
+	CHAR(coex_wifi_rssi_mid_limit),
+	CHAR(coex_wifi_rssi_lower_limit),
+	CHAR(coex_wifi_pwr_high),
+	CHAR(coex_wifi_pwr_mid),
+	CHAR(coex_wifi_pwr_low),
+
+	CHAR(coex_ext_pta_hi_tx_tag),
+	CHAR(coex_ext_pta_hi_rx_tag),
+	CHAR(coex_ext_pta_lo_tx_tag),
+	CHAR(coex_ext_pta_lo_rx_tag),
+	SHORT(coex_ext_pta_sample_t1),
+	SHORT(coex_ext_pta_sample_t2),
+	CHAR(coex_ext_pta_wifi_bt_con_trx),
+
+	INT(coex_misc_ext_pta_on),
+	INT(coex_misc_ext_feature_set),
+
+	CHAR(wmt_gps_lna_pin),
+	CHAR(wmt_gps_lna_enable),
+
+	CHAR(pwr_on_rtc_slot),
+	CHAR(pwr_on_ldo_slot),
+	CHAR(pwr_on_rst_slot),
+	CHAR(pwr_on_off_slot),
+	CHAR(pwr_on_on_slot),
+	CHAR(co_clock_flag),
+
+	INT(sdio_driving_cfg),
+
+};
+
+#define NUM_WMTCFG_FIELDS (osal_sizeof(wmtcfg_fields) / osal_sizeof(wmtcfg_fields[0]))
+
+static int wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos)
+{
+	PINT8 dst;
+	long res;
+	int ret;
+
+	dst = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1);
+
+	if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
+		ret = osal_strtol(pos + 2, 16, &res);
+		if (ret)
+			WMT_ERR_FUNC("fail(%d)\n", ret);
+		*dst = res;
+		WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst);
+	} else {
+		ret = osal_strtol(pos, 10, &res);
+		if (ret)
+			WMT_ERR_FUNC("fail(%d)\n", ret);
+		*dst = res;
+		WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst);
+	}
+	return 0;
+}
+
+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data)
+{
+	PINT8 src;
+	INT32 res;
+	PINT8 value;
+
+	src = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1);
+
+	value = osal_malloc(20);
+	if (value == NULL)
+		return NULL;
+	res = osal_snprintf(value, 20, "0x%x", *src);
+	if (res < 0 || res >= 20) {
+		osal_free(value);
+		return NULL;
+	}
+	value[20 - 1] = '\0';
+	return value;
+}
+
+static int wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos)
+{
+	PUINT16 dst;
+	long res;
+	int ret;
+
+	dst = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1);
+
+	/* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */
+
+	if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
+		ret = osal_strtol(pos + 2, 16, &res);
+		if (ret)
+			WMT_ERR_FUNC("fail(%d)\n", ret);
+		*dst = res;
+		WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst);
+	} else {
+		ret = osal_strtol(pos, 10, &res);
+		if (ret)
+			WMT_ERR_FUNC("fail(%d)\n", ret);
+		*dst = res;
+		WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst);
+	}
+
+	return 0;
+}
+
+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data)
+{
+	PINT16 src;
+	INT32 res;
+	PINT8 value;
+
+	/* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */
+	src = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1);
+
+	value = osal_malloc(20);
+	if (value == NULL)
+		return NULL;
+	res = osal_snprintf(value, 20, "0x%x", *src);
+	if (res < 0 || res >= 20) {
+		osal_free(value);
+		return NULL;
+	}
+	value[20 - 1] = '\0';
+	return value;
+}
+
+static int wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos)
+{
+	PUINT32 dst;
+	long res;
+	int ret;
+
+	dst = (PINT32) (((PUINT8) pWmtDev) + (long)data->param1);
+
+	/* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */
+
+	if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
+		ret = osal_strtol(pos + 2, 16, &res);
+		if (ret)
+			WMT_ERR_FUNC("fail(%d)\n", ret);
+		*dst = res;
+		WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst);
+	} else {
+		ret = osal_strtol(pos, 10, &res);
+		if (ret)
+			WMT_ERR_FUNC("fail(%d)\n", ret);
+		*dst = res;
+		WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst);
+	}
+
+	return 0;
+}
+
+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data)
+{
+	PINT32 src;
+	INT32 res;
+	PINT8 value;
+
+	src = (PUINT32) (((PUINT8) pWmtDev) + (long)data->param1);
+
+	value = osal_malloc(20);
+	if (value == NULL)
+		return NULL;
+	res = osal_snprintf(value, 20, "0x%x", *src);
+	if (res < 0 || res >= 20) {
+		osal_free(value);
+		return NULL;
+	}
+	value[20 - 1] = '\0';
+	return value;
+}
+
+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal)
+{
+	int i = 0;
+	int ret = 0;
+
+	/* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */
+
+	for (i = 0; i < NUM_WMTCFG_FIELDS; i++) {
+		const struct parse_data *field = &wmtcfg_fields[i];
+
+		if (osal_strcmp(pKey, field->name) != 0)
+			continue;
+		if (field->parser(pWmtDev, field, pVal)) {
+			WMT_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal);
+			ret = -1;
+		}
+		break;
+	}
+	if (i == NUM_WMTCFG_FIELDS) {
+		WMT_ERR_FUNC("unknown field '%s'.\n", pKey);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size)
+{
+	PINT8 pch;
+	PINT8 pBuf;
+	PINT8 pLine;
+	PINT8 pKey;
+	PINT8 pVal;
+	PINT8 pPos;
+	INT32 ret = 0;
+	INT32 i = 0;
+	PINT8 pa = NULL;
+
+	pBuf = osal_malloc(size);
+	if (!pBuf)
+		return -1;
+
+	osal_memcpy(pBuf, pInBuf, size);
+	pBuf[size] = '\0';
+
+	pch = pBuf;
+	/* pch is to be updated by strsep(). Keep pBuf unchanged!! */
+
+#if 0
+	{
+		PINT8 buf_ptr = pBuf;
+		INT32 k = 0;
+
+		WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size);
+		for (k = 0; k < size; k++) {
+			/* if(k%16 == 0)  WMT_INFO_FUNC("\n"); */
+			WMT_INFO_FUNC("%c", buf_ptr[k]);
+		}
+		WMT_INFO_FUNC("--end\n");
+	}
+#endif
+
+	while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) {
+		/* pch is updated to the end of pLine by strsep() and updated to '\0' */
+		/*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */
+		/* parse each line */
+
+		/* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */
+
+		if (!*pLine)
+			continue;
+
+		pVal = osal_strchr(pLine, '=');
+		if (!pVal) {
+			WMT_WARN_FUNC("mal-format cfg string(%s)\n", pLine);
+			continue;
+		}
+
+		/* |<-pLine->|'='<-pVal->|'\n' ('\0')|  */
+		*pVal = '\0';	/* replace '=' with '\0' to get key */
+		/* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')|  */
+		pKey = pLine;
+
+		if ((pVal - pBuf) < size)
+			pVal++;
+
+		/*key handling */
+		pPos = pKey;
+		/*skip space characeter */
+		while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) {
+			if ((pPos - pBuf) >= size)
+				break;
+			pPos++;
+		}
+		/*key head */
+		pKey = pPos;
+		while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) {
+			if ((pPos - pBuf) >= size)
+				break;
+			pPos++;
+		}
+		/*key tail */
+		(*pPos) = '\0';
+
+		/*value handling */
+		pPos = pVal;
+		/*skip space characeter */
+		while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) {
+			if ((pPos - pBuf) >= size)
+				break;
+			pPos++;
+		}
+		/*value head */
+		pVal = pPos;
+		while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) {
+			if ((pPos - pBuf) >= size)
+				break;
+			pPos++;
+		}
+		/*value tail */
+		(*pPos) = '\0';
+
+		/* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */
+		ret = wmt_conf_parse_pair(pWmtDev, pKey, pVal);
+		WMT_DBG_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret);
+		if (ret)
+			WMT_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret);
+	}
+
+	for (i = 0; i < NUM_WMTCFG_FIELDS; i++) {
+		const struct parse_data *field = &wmtcfg_fields[i];
+
+		pa = field->writer(pWmtDev, field);
+		if (pa) {
+			WMT_DBG_FUNC("#%d(%s)=>%s\n", i, field->name, pa);
+			osal_free(pa);
+		} else {
+			WMT_ERR_FUNC("failed to parse '%s'.\n", field->name);
+		}
+	}
+	osal_free(pBuf);
+	return 0;
+}
+
+INT32 wmt_conf_set_cfg_file(const char *name)
+{
+	if (NULL == name) {
+		WMT_ERR_FUNC("name is NULL\n");
+		return -1;
+	}
+	if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) {
+		WMT_ERR_FUNC("name is too long, length=%d, expect to < %d\n", osal_strlen(name),
+			     osal_sizeof(gDevWmt.cWmtcfgName));
+		return -2;
+	}
+	osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName));
+	osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name);
+	WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0]));
+
+	return 0;
+}
+
+INT32 wmt_conf_read_file(VOID)
+{
+	INT32 ret = -1;
+
+	osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf));
+	osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg));
+
+#if 1
+	osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName));
+
+	osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_PREFIX, osal_sizeof(CUST_CFG_WMT_PREFIX));
+	osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT, osal_sizeof(CUST_CFG_WMT));
+#endif
+
+	if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) {
+		WMT_ERR_FUNC("empty Wmtcfg name\n");
+		osal_assert(0);
+		return ret;
+	}
+	WMT_DBG_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0]));
+	if (0 == wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg, 0)) {
+		/*get full name patch success */
+		WMT_DBG_FUNC("get full file name(%s) buf(0x%p) size(%d)\n",
+			      &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size);
+
+		if (0 == wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size)) {
+			/*config file exists */
+			gDevWmt.rWmtGenConf.cfgExist = 1;
+
+			WMT_DBG_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf);
+			ret = 0;
+		} else {
+			WMT_ERR_FUNC("wmt conf parsing fail\n");
+			osal_assert(0);
+			ret = -1;
+		}
+		wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg);
+/*
+	if (gDevWmt.pWmtCfg)
+	{
+	    if (gDevWmt.pWmtCfg->data)
+	    {
+		osal_free(gDevWmt.pWmtCfg->data);
+	    }
+	    osal_free(gDevWmt.pWmtCfg);
+	    gDevWmt.pWmtCfg = 0;
+	}
+*/
+		return ret;
+	}
+	WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0]));
+	osal_assert(0);
+
+	gDevWmt.rWmtGenConf.cfgExist = 0;
+	return ret;
+}
+
+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID)
+{
+	if (0 == gDevWmt.rWmtGenConf.cfgExist)
+		return NULL;
+
+	return &gDevWmt.rWmtGenConf;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c
new file mode 100644
index 0000000000000..cca6729d53a07
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c
@@ -0,0 +1,2521 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-CORE]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+
+#include "wmt_lib.h"
+#include "wmt_core.h"
+#include "wmt_ctrl.h"
+#include "wmt_ic.h"
+#include "wmt_conf.h"
+
+#include "wmt_func.h"
+#include "stp_core.h"
+#include "psm_core.h"
+
+
+P_WMT_FUNC_OPS gpWmtFuncOps[4] = {
+#if CFG_FUNC_BT_SUPPORT
+	[0] = &wmt_func_bt_ops,
+#else
+	[0] = NULL,
+#endif
+
+#if CFG_FUNC_FM_SUPPORT
+	[1] = &wmt_func_fm_ops,
+#else
+	[1] = NULL,
+#endif
+
+#if CFG_FUNC_GPS_SUPPORT
+	[2] = &wmt_func_gps_ops,
+#else
+	[2] = NULL,
+#endif
+
+#if CFG_FUNC_WIFI_SUPPORT
+	[3] = &wmt_func_wifi_ops,
+#else
+	[3] = NULL,
+#endif
+
+};
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/* TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting?
+*move to wmt_ic_6620 temporarily.
+*/
+/* BT Port 2 Feature. */
+/* #define CFG_WMT_BT_PORT2 (1) */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+static WMT_CTX gMtkWmtCtx;
+static UINT8 gLpbkBuf[1024+5] = { 0 };
+#ifdef CONFIG_MTK_COMBO_ANT
+static UINT8 gAntBuf[1024] = { 0 };
+#define CFG_CHECK_WMT_RESULT (1)
+#endif
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp);
+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp);
+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp);
+static INT32 opfunc_func_on(P_WMT_OP pWmtOp);
+static INT32 opfunc_func_off(P_WMT_OP pWmtOp);
+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp);
+static INT32 opfunc_exit(P_WMT_OP pWmtOp);
+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp);
+static INT32 opfunc_dsns(P_WMT_OP pWmtOp);
+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp);
+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp);
+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp);
+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp);
+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp);
+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp);
+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp);
+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp);
+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp);
+static INT32 opfunc_pin_state(P_WMT_OP pWmtOp);
+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp);
+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp);
+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp);
+#if CFG_WMT_LTE_COEX_HANDLING
+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp);
+#endif
+#ifdef CONFIG_MTK_COMBO_ANT
+static INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp);
+static INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp);
+#endif
+static VOID wmt_core_dump_func_state(PINT8 pSource);
+static INT32 wmt_core_stp_init(VOID);
+static INT32 wmt_core_stp_deinit(VOID);
+static INT32 wmt_core_hw_check(VOID);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+static const UINT8 WMT_SLEEP_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x01 };
+static const UINT8 WMT_SLEEP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 };
+
+static const UINT8 WMT_HOST_AWAKE_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x02 };
+static const UINT8 WMT_HOST_AWAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 };
+
+static const UINT8 WMT_WAKEUP_CMD[] = { 0xFF };
+static const UINT8 WMT_WAKEUP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 };
+
+static UINT8 WMT_THERM_CMD[] = { 0x01, 0x11, 0x01, 0x00,
+	0x00			/*thermal sensor operation */
+};
+static UINT8 WMT_THERM_CTRL_EVT[] = { 0x02, 0x11, 0x01, 0x00, 0x00 };
+static UINT8 WMT_THERM_READ_EVT[] = { 0x02, 0x11, 0x02, 0x00, 0x00, 0x00 };
+
+static UINT8 WMT_EFUSE_CMD[] = { 0x01, 0x0D, 0x08, 0x00,
+	0x01,			/*[4]operation, 0:init, 1:write 2:read */
+	0x01,			/*[5]Number of register setting */
+	0xAA, 0xAA,		/*[6-7]Address */
+	0xBB, 0xBB, 0xBB, 0xBB	/*[8-11] Value */
+};
+
+static UINT8 WMT_EFUSE_EVT[] = { 0x02, 0x0D, 0x08, 0x00,
+	0xAA,			/*[4]operation, 0:init, 1:write 2:read */
+	0xBB,			/*[5]Number of register setting */
+	0xCC, 0xCC,		/*[6-7]Address */
+	0xDD, 0xDD, 0xDD, 0xDD	/*[8-11] Value */
+};
+
+static UINT8 WMT_DSNS_CMD[] = { 0x01, 0x0E, 0x02, 0x00, 0x01,
+	0x00			/*desnse type */
+};
+static UINT8 WMT_DSNS_EVT[] = { 0x02, 0x0E, 0x01, 0x00, 0x00 };
+
+/* TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT */
+static UINT8 WMT_SET_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00	/*length */
+	    , 0x00		/*op: w(1) & r(2) */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*res */
+	    , 0x01		/*1 register */
+	    , 0x00, 0x00, 0x00, 0x00	/* addr */
+	    , 0x00, 0x00, 0x00, 0x00	/* value */
+	    , 0xFF, 0xFF, 0xFF, 0xFF	/*mask */
+};
+
+static UINT8 WMT_SET_REG_WR_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 register */
+	    /* , 0x00, 0x00, 0x00, 0x00  */		/* addr */
+	    /* , 0x00, 0x00, 0x00, 0x00  */		/* value */
+};
+
+static UINT8 WMT_SET_REG_RD_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 register */
+	    , 0x00, 0x00, 0x00, 0x00	/* addr */
+	    , 0x00, 0x00, 0x00, 0x00	/* value */
+};
+
+#ifdef CONFIG_MTK_COMBO_ANT
+static UINT8 WMT_ANT_RAM_STA_GET_CMD[] = { 0x01, 0x06, 0x02, 0x00, 0x05, 0x02
+};
+
+static UINT8 WMT_ANT_RAM_STA_GET_EVT[] = { 0x02, 0x06, 0x03, 0x00	/*length */
+	    , 0x05, 0x02, 0x00	/*S: result */
+};
+
+static UINT8 WMT_ANT_RAM_DWN_CMD[] = { 0x01, 0x15, 0x00, 0x00, 0x01
+};
+
+static UINT8 WMT_ANT_RAM_DWN_EVT[] = { 0x02, 0x15, 0x01, 0x00	/*length */
+	, 0x00
+};
+#endif
+
+/* GeorgeKuo: Use designated initializers described in
+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html
+ */
+
+static const WMT_OPID_FUNC wmt_core_opfunc[] = {
+	[WMT_OPID_HIF_CONF] = opfunc_hif_conf,
+	[WMT_OPID_PWR_ON] = opfunc_pwr_on,
+	[WMT_OPID_PWR_OFF] = opfunc_pwr_off,
+	[WMT_OPID_FUNC_ON] = opfunc_func_on,
+	[WMT_OPID_FUNC_OFF] = opfunc_func_off,
+	[WMT_OPID_REG_RW] = opfunc_reg_rw,	/* TODO:[ChangeFeature][George] is this OP obsoleted? */
+	[WMT_OPID_EXIT] = opfunc_exit,
+	[WMT_OPID_PWR_SV] = opfunc_pwr_sv,
+	[WMT_OPID_DSNS] = opfunc_dsns,
+	[WMT_OPID_LPBK] = opfunc_lpbk,
+	[WMT_OPID_CMD_TEST] = opfunc_cmd_test,
+	[WMT_OPID_HW_RST] = opfunc_hw_rst,
+	[WMT_OPID_SW_RST] = opfunc_sw_rst,
+	[WMT_OPID_STP_RST] = opfunc_stp_rst,
+	[WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl,
+	[WMT_OPID_EFUSE_RW] = opfunc_efuse_rw,
+	[WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl,
+	[WMT_OPID_GPIO_STATE] = opfunc_pin_state,
+	[WMT_OPID_BGW_DS] = opfunc_bgw_ds,
+	[WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk,
+	[WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test,
+#if CFG_WMT_LTE_COEX_HANDLING
+	[WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling,
+#endif
+#ifdef CONFIG_MTK_COMBO_ANT
+	[WMT_OPID_ANT_RAM_DOWN] = opfunc_ant_ram_down,
+	[WMT_OPID_ANT_RAM_STA_GET] = opfunc_ant_ram_stat_get,
+#endif
+};
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+INT32 wmt_core_init(VOID)
+{
+	INT32 i = 0;
+
+	osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx));
+	/* gMtkWmtCtx.p_ops is cleared to NULL */
+
+	/* default FUNC_OFF state */
+	for (i = 0; i < WMTDRV_TYPE_MAX; ++i) {
+		/* WinMo is default to DRV_STS_UNREG; */
+		gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF;
+	}
+
+	return 0;
+}
+
+INT32 wmt_core_deinit(VOID)
+{
+	/* return to init state */
+	osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx));
+	/* gMtkWmtCtx.p_ops is cleared to NULL */
+	return 0;
+}
+
+/* TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not...... */
+/* parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer. */
+INT32 wmt_core_tx(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag)
+{
+	INT32 iRet;
+#if 0				/* Test using direct function call instead of wmt_ctrl() interface */
+	WMT_CTRL_DATA ctrlData;
+
+	ctrlData.ctrlId = WMT_CTRL_TX;
+	ctrlData.au4CtrlData[0] = (UINT32) pData;
+	ctrlData.au4CtrlData[1] = size;
+	ctrlData.au4CtrlData[2] = (UINT32) writtenSize;
+	ctrlData.au4CtrlData[3] = bRawFlag;
+
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		/* ERROR */
+		WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_TX, iRet:%d\n", iRet);
+		/* (*sys_dbg_assert)(0, __FILE__, __LINE__); */
+		osal_assert(0);
+	}
+#endif
+	iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag);
+	if (0 == *writtenSize) {
+		INT32 retry_times = 0;
+		INT32 max_retry_times = 3;
+		INT32 retry_delay_ms = 360;
+
+		WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n",
+			      *writtenSize);
+		while ((0 == *writtenSize) && (retry_times < max_retry_times)) {
+			WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms);
+			osal_sleep_ms(retry_delay_ms);
+
+			iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag);
+			retry_times++;
+		}
+	}
+	return iRet;
+}
+
+INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize)
+{
+	INT32 iRet;
+	WMT_CTRL_DATA ctrlData;
+
+	ctrlData.ctrlId = WMT_CTRL_RX;
+	ctrlData.au4CtrlData[0] = (SIZE_T) pBuf;
+	ctrlData.au4CtrlData[1] = bufLen;
+	ctrlData.au4CtrlData[2] = (SIZE_T) readSize;
+
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		/* ERROR */
+		WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet);
+		mtk_wcn_stp_dbg_dump_package();
+		osal_assert(0);
+	}
+	return iRet;
+}
+
+INT32 wmt_core_rx_flush(UINT32 type)
+{
+	INT32 iRet;
+	WMT_CTRL_DATA ctrlData;
+
+	ctrlData.ctrlId = WMT_CTRL_RX_FLUSH;
+	ctrlData.au4CtrlData[0] = (UINT32) type;
+
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		/* ERROR */
+		WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet);
+		osal_assert(0);
+	}
+	return iRet;
+}
+
+INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn)
+{
+	INT32 iRet = 0;
+	UINT32 u4WmtCmdPduLen;
+	UINT32 u4WmtEventPduLen;
+	UINT32 u4ReadSize;
+	UINT32 u4WrittenSize;
+	WMT_PKT rWmtPktCmd;
+	WMT_PKT rWmtPktEvent;
+	MTK_WCN_BOOL fgFail;
+
+	/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */
+	/* Using this struct relies on compiler's implementation and pack() settings */
+	osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd));
+	osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent));
+
+	rWmtPktCmd.eType = (UINT8) PKT_TYPE_CMD;
+	rWmtPktCmd.eOpCode = (UINT8) OPCODE_FUNC_CTRL;
+
+	/* Flag field: driver type */
+	rWmtPktCmd.aucParam[0] = (UINT8) type;
+	/* Parameter field: ON/OFF */
+	rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0;
+	rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN;	/* (2) */
+
+	/* WMT Header + WMT SDU */
+	u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen;	/* (6) */
+	u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN;	/* (5) */
+
+	do {
+		fgFail = MTK_WCN_BOOL_TRUE;
+/* iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize); */
+		iRet = wmt_core_tx((PUINT8) &rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, MTK_WCN_BOOL_FALSE);
+		if (iRet) {
+			WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed\n");
+			break;
+		}
+
+		iRet = wmt_core_rx((PUINT8) &rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize);
+		if (iRet) {
+			WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_rx failed\n");
+			break;
+		}
+
+		/* Error Checking */
+		if (PKT_TYPE_EVENT != rWmtPktEvent.eType) {
+			WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n",
+				     rWmtPktEvent.eType);
+			break;
+		}
+
+		if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) {
+			WMT_ERR_FUNC
+			    ("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n",
+			     rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode);
+			break;
+		}
+
+		if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) {
+			WMT_ERR_FUNC
+			    ("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n",
+			     u4WmtEventPduLen, rWmtPktEvent.u2SduLen);
+			break;
+		}
+		/* Status field of event check */
+		if (0 != rWmtPktEvent.aucParam[0]) {
+			WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", rWmtPktEvent.aucParam[0]);
+			break;
+		}
+
+		fgFail = MTK_WCN_BOOL_FALSE;
+	} while (0);
+
+	if (MTK_WCN_BOOL_FALSE == fgFail) {
+		/* WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n"); */
+		return 0;
+	}
+	WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]);
+	return -3;
+}
+
+INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp)
+{
+	UINT32 opId;
+	INT32 ret;
+
+	opId = pWmtOp->opId;
+
+	if (wmt_core_opfunc[opId]) {
+		ret = (*(wmt_core_opfunc[opId])) (pWmtOp);	/*wmtCoreOpidHandlerPack[].opHandler */
+		return ret;
+	}
+	WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId);
+	return -2;
+
+}
+
+INT32 wmt_core_opid(P_WMT_OP pWmtOp)
+{
+
+	/*sanity check */
+	if (NULL == pWmtOp) {
+		WMT_ERR_FUNC("null pWmtOP\n");
+		/*print some message with error info */
+		return -1;
+	}
+
+	if (WMT_OPID_MAX <= pWmtOp->opId) {
+		WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId);
+		return -2;
+	}
+	/* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */
+	return wmt_core_opid_handler(pWmtOp);
+}
+
+INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2)
+{
+	INT32 iRet = -1;
+	WMT_CTRL_DATA ctrlData;
+	SIZE_T val1 = (pPa1) ? *pPa1 : 0;
+	SIZE_T val2 = (pPa2) ? *pPa2 : 0;
+
+	ctrlData.ctrlId = (SIZE_T) ctrId;
+	ctrlData.au4CtrlData[0] = val1;
+	ctrlData.au4CtrlData[1] = val2;
+
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		/* ERROR */
+		WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%d), value(%d) iRet:(%d)\n", ctrId, val1,
+			     val2, iRet);
+		osal_assert(0);
+	} else {
+		if (pPa1)
+			*pPa1 = ctrlData.au4CtrlData[0];
+		if (pPa2)
+			*pPa2 = ctrlData.au4CtrlData[1];
+	}
+	return iRet;
+}
+
+VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len)
+{
+	PUINT8 ptr = pData;
+	INT32 k = 0;
+
+	WMT_INFO_FUNC("%s len=%d\n", pTitle, len);
+	for (k = 0; k < len; k++) {
+		if (k % 16 == 0)
+			WMT_INFO_FUNC("\n");
+		WMT_INFO_FUNC("0x%02x ", *ptr);
+		ptr++;
+	}
+	WMT_INFO_FUNC("--end\n");
+}
+
+/*!
+ * \brief An WMT-CORE function to support read, write, and read after write to
+ * an internal register.
+ *
+ * Detailed description.
+ *
+ * \param isWrite 1 for write, 0 for read
+ * \param offset of register to be written or read
+ * \param pVal a pointer to the 32-bit value to be writtern or read
+ * \param mask a 32-bit mask to be applied for the read or write operation
+ *
+ * \retval 0 operation success
+ * \retval -1 invalid parameters
+ * \retval -2 tx cmd fail
+ * \retval -3 rx event fail
+ * \retval -4 read check error
+ */
+INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask)
+{
+	INT32 iRet;
+	UINT32 u4Res;
+	UINT32 evtLen;
+	UINT8 evtBuf[16] = { 0 };
+
+	WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2;	/* w:1, r:2 */
+	osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4);	/* offset */
+	osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4);	/* [2] is var addr */
+	osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4);	/* mask */
+
+	/* send command */
+	iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
+	if ((iRet) || (u4Res != sizeof(WMT_SET_REG_CMD))) {
+		WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %d)\n", iRet, u4Res, sizeof(WMT_SET_REG_CMD));
+		return -2;
+	}
+
+	/* receive event */
+	evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT);
+	iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
+	if ((iRet) || (u4Res != evtLen)) {
+		WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen);
+		return -3;
+	}
+
+	if (!isWrite) {
+		UINT32 rxEvtAddr;
+		UINT32 txCmdAddr;
+
+		osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4);
+		osal_memcpy(&rxEvtAddr, &evtBuf[8], 4);
+
+		/* check read result */
+		if (txCmdAddr != rxEvtAddr) {
+			WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, txCmdAddr);
+			return -4;
+		}
+		WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr);
+
+		osal_memcpy(pVal, &evtBuf[12], 4);
+	}
+
+	/* no error here just return 0 */
+	return 0;
+}
+
+INT32 wmt_core_init_script(struct init_script *script, INT32 count)
+{
+	UINT8 evtBuf[256];
+	UINT32 u4Res;
+	INT32 i = 0;
+	INT32 iRet;
+
+	for (i = 0; i < count; i++) {
+		WMT_DBG_FUNC("WMT-CORE: init_script operation %s start\n", script[i].str);
+		/* CMD */
+		/* iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res); */
+		iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != script[i].cmdSz)) {
+			WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", script[i].str, iRet, u4Res,
+				     script[i].cmdSz);
+			break;
+		}
+		/* EVENT BUF */
+		osal_memset(evtBuf, 0, sizeof(evtBuf));
+		iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res);
+		if (iRet || (u4Res != script[i].evtSz)) {
+			WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", script[i].str, iRet,
+				     u4Res, script[i].evtSz);
+			mtk_wcn_stp_dbg_dump_package();
+			break;
+		}
+		/* RESULT */
+		if (0x14 != evtBuf[1]) {	/* workaround RF calibration data EVT,do not care this EVT */
+			if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) {
+				WMT_ERR_FUNC("WMT-CORE:compare %s result error\n", script[i].str);
+				WMT_ERR_FUNC
+				    ("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+				     u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], script[i].evtSz,
+				     script[i].evt[0], script[i].evt[1], script[i].evt[2], script[i].evt[3],
+				     script[i].evt[4]);
+				mtk_wcn_stp_dbg_dump_package();
+				break;
+			}
+		}
+		WMT_DBG_FUNC("init_script operation %s ok\n", script[i].str);
+	}
+
+	return (i == count) ? 0 : -1;
+}
+
+static INT32 wmt_core_stp_init(VOID)
+{
+	INT32 iRet = -1;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+	UINT8 co_clock_type;
+	P_WMT_CTX pctx = &gMtkWmtCtx;
+	P_WMT_GEN_CONF pWmtGenConf = NULL;
+
+	wmt_conf_read_file();
+	pWmtGenConf = wmt_conf_get_cfg();
+	if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) {
+		WMT_ERR_FUNC("WMT-CORE: no hif info!\n");
+		osal_assert(0);
+		return -1;
+	}
+	/* 4 <1> open stp */
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: wmt open stp\n");
+		return -2;
+	}
+	/* 4 <1.5> disable and un-ready stp */
+	ctrlPa1 = WMT_STP_CONF_EN;
+	ctrlPa2 = 0;
+	iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+	ctrlPa1 = WMT_STP_CONF_RDY;
+	ctrlPa2 = 0;
+	iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+
+	/* 4 <2> set mode and enable */
+	if (WMT_HIF_BTIF == pctx->wmtHifConf.hifType) {
+		ctrlPa1 = WMT_STP_CONF_MODE;
+		ctrlPa2 = MTKSTP_BTIF_MAND_MODE;
+		iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+	}
+
+	ctrlPa1 = WMT_STP_CONF_EN;
+	ctrlPa2 = 1;
+	iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet);
+		return -3;
+	}
+	/* TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips??? */
+
+	iRet = wmt_core_hw_check();
+	if (iRet) {
+		WMT_ERR_FUNC("hw_check fail:%d\n", iRet);
+		return -4;
+	}
+	/* mtkWmtCtx.p_ic_ops is identified and checked ok */
+	if ((NULL != pctx->p_ic_ops->co_clock_ctrl) && (pWmtGenConf != NULL)) {
+		co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f);
+		(*(pctx->p_ic_ops->co_clock_ctrl)) (co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN);
+	} else {
+		WMT_WARN_FUNC("pctx->p_ic_ops->co_clock_ctrl(0x%x), pWmtGenConf(0x%x)\n", pctx->p_ic_ops->co_clock_ctrl,
+			      pWmtGenConf);
+	}
+	osal_assert(NULL != pctx->p_ic_ops->sw_init);
+	if (NULL != pctx->p_ic_ops->sw_init) {
+		iRet = (*(pctx->p_ic_ops->sw_init)) (&pctx->wmtHifConf);
+	} else {
+		WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n");
+		return -5;
+	}
+	if (iRet) {
+		WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet);
+		return -6;
+	}
+	/* 4 <10> set stp ready */
+	ctrlPa1 = WMT_STP_CONF_RDY;
+	ctrlPa2 = 1;
+	iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+
+	return iRet;
+}
+
+static INT32 wmt_core_stp_deinit(VOID)
+{
+	INT32 iRet;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+
+	WMT_DBG_FUNC(" start\n");
+
+	if (NULL == gMtkWmtCtx.p_ic_ops) {
+		WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n");
+		goto deinit_ic_ops_done;
+	}
+	if (NULL != gMtkWmtCtx.p_ic_ops->sw_deinit) {
+		iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit)) (&gMtkWmtCtx.wmtHifConf);
+		/* unbind WMT-IC */
+		gMtkWmtCtx.p_ic_ops = NULL;
+	} else {
+		WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n");
+	}
+
+deinit_ic_ops_done:
+
+	/* 4 <1> un-ready, disable, and close stp. */
+	ctrlPa1 = WMT_STP_CONF_RDY;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+	ctrlPa1 = WMT_STP_CONF_EN;
+	ctrlPa2 = 0;
+	iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2);
+
+	if (iRet)
+		WMT_WARN_FUNC("end with fail:%d\n", iRet);
+
+	return iRet;
+}
+
+static VOID wmt_core_dump_func_state(PINT8 pSource)
+{
+	WMT_WARN_FUNC("[%s]status(b:%d f:%d g:%d w:%d lpbk:%d coredump:%d wmt:%d stp:%d)\n",
+		      (pSource == NULL ? (PINT8) "CORE" : pSource),
+		      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT],
+		      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM],
+		      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS],
+		      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI],
+		      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK],
+		      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP],
+		      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP]
+	    );
+	return;
+
+}
+
+MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer)
+{
+	if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) {
+		/*major no. does not match */
+		WMT_ERR_FUNC("WMT-CORE: chip version(0x%d) does not match patch version(0x%d)\n", u4HwVer, u4PatchVer);
+		return MTK_WCN_BOOL_FALSE;
+	}
+	return MTK_WCN_BOOL_TRUE;
+}
+
+static INT32 wmt_core_hw_check(VOID)
+{
+	UINT32 chipid;
+	P_WMT_IC_OPS p_ops;
+	INT32 iret;
+
+	/* 1. get chip id */
+	chipid = 0;
+	WMT_LOUD_FUNC("before read hwcode (chip id)\n");
+	iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK);	/* read 0x80000008 */
+	if (iret) {
+		WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret);
+		return -2;
+	}
+	WMT_DBG_FUNC("get hwcode (chip id) (0x%x)\n", chipid);
+
+	/* TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id */
+	switch (chipid) {
+#if CFG_CORE_MT6620_SUPPORT
+	case 0x6620:
+		p_ops = &wmt_ic_ops_mt6620;
+		break;
+#endif
+#if CFG_CORE_MT6628_SUPPORT
+	case 0x6628:
+		p_ops = &wmt_ic_ops_mt6628;
+		break;
+#endif
+#if CFG_CORE_SOC_SUPPORT
+	case 0x6572:
+	case 0x6582:
+	case 0x6592:
+	case 0x8127:
+	case 0x6571:
+	case 0x6752:
+	case 0x0279:
+	case 0x0326:
+	case 0x0321:
+	case 0x0335:
+	case 0x0337:
+	case 0x8163:
+	case 0x6580:
+		p_ops = &wmt_ic_ops_soc;
+		break;
+#endif
+	default:
+		p_ops = (P_WMT_IC_OPS) NULL;
+#if CFG_CORE_SOC_SUPPORT
+		if (0x7f90 == chipid - 0x600) {
+			p_ops = &wmt_ic_ops_soc;
+			chipid -= 0xf6d;
+		}
+#endif
+		break;
+	}
+
+	if (NULL == p_ops) {
+		WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid);
+		return -3;
+	} else if (MTK_WCN_BOOL_FALSE == wmt_core_ic_ops_check(p_ops)) {
+		WMT_ERR_FUNC
+		    ("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n",
+		     chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check);
+		return -4;
+	}
+	WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n",
+		     chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check);
+
+	wmt_ic_ops_soc.icId = chipid;
+	WMT_DBG_FUNC("wmt_ic_ops_soc.icId(0x%x)\n", wmt_ic_ops_soc.icId);
+	iret = p_ops->ic_ver_check();
+	if (iret) {
+		WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret);
+		return -5;
+	}
+
+	WMT_DBG_FUNC("chip id(0x%x) ver_check ok\n", chipid);
+	gMtkWmtCtx.p_ic_ops = p_ops;
+	return 0;
+}
+
+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp)
+{
+	if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) {
+		WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n");
+		return -1;
+	}
+
+	if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) {
+		WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. overwrite! old (%d), new(%d))\n",
+			     gMtkWmtCtx.wmtHifConf.hifType, pWmtOp->au4OpData[0]);
+	} else {
+		gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT;
+		WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n");
+	}
+
+	osal_memcpy(&gMtkWmtCtx.wmtHifConf, &pWmtOp->au4OpData[0], osal_sizeof(gMtkWmtCtx.wmtHifConf));
+	return 0;
+
+}
+
+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+	INT32 retry = WMT_PWRON_RTY_DFT;
+
+	if (DRV_STS_POWER_OFF != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n",
+			     gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]);
+		osal_assert(0);
+		return -1;
+	}
+	/* TODO: [FixMe][GeorgeKuo]: clarify the following is reqiured or not! */
+	if (pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)
+		opfunc_hif_conf(pWmtOp);
+
+pwr_on_rty:
+	/* power on control */
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet);
+		if (0 == retry--) {
+			WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry);
+			goto pwr_on_rty;
+		}
+		return -1;
+	}
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
+
+	/* init stp */
+	iRet = wmt_core_stp_init();
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet);
+		osal_assert(0);
+
+		/* deinit stp */
+		iRet = wmt_core_stp_deinit();
+		iRet = opfunc_pwr_off(pWmtOp);
+		if (iRet)
+			WMT_ERR_FUNC("WMT-CORE: opfunc_pwr_off fail during pwr_on retry\n");
+
+		if (0 < retry--) {
+			WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry);
+			goto pwr_on_rty;
+		}
+		iRet = -2;
+		return iRet;
+	}
+
+	WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n");
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON;
+
+	/* What to do when state is changed from POWER_OFF to POWER_ON?
+	 * 1. STP driver does s/w reset
+	 * 2. UART does 0xFF wake up
+	 * 3. SDIO does re-init command(changed to trigger by host)
+	 */
+	return iRet;
+
+}
+
+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+
+	if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n",
+			      gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]);
+		osal_assert(0);
+		return -1;
+	}
+	if (MTK_WCN_BOOL_FALSE == g_pwr_off_flag) {
+		WMT_WARN_FUNC("CONNSYS power off be disabled, maybe need trigger core dump!\n");
+		osal_assert(0);
+		return -2;
+	}
+
+	/* wmt and stp are initialized successfully */
+	if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		iRet = wmt_core_stp_deinit();
+		if (iRet) {
+			WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet);
+			/*should let run to power down chip */
+		}
+	}
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
+
+	/* power off control */
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2);
+	if (iRet)
+		WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet);
+	WMT_WARN_FUNC("HW_PWR_OFF ok\n");
+
+	/*anyway, set to POWER_OFF state */
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF;
+	return iRet;
+
+}
+
+static INT32 opfunc_func_on(P_WMT_OP pWmtOp)
+{
+	INT32 iRet = -1;
+	INT32 iPwrOffRet = -1;
+	UINT32 drvType;
+
+	drvType = pWmtOp->au4OpData[0];
+
+	/* Check abnormal type */
+	if (WMTDRV_TYPE_COREDUMP < drvType) {
+		WMT_ERR_FUNC("abnormal Fun(%d)\n", drvType);
+		osal_assert(0);
+		return -1;
+	}
+
+	/* Check abnormal state */
+	if ((DRV_STS_POWER_OFF > gMtkWmtCtx.eDrvStatus[drvType])
+	    || (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType])) {
+		WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n", drvType, gMtkWmtCtx.eDrvStatus[drvType]);
+		osal_assert(0);
+		return -2;
+	}
+
+	/* check if func already on */
+	if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[drvType]) {
+		WMT_WARN_FUNC("func(%d) already on\n", drvType);
+		return 0;
+	}
+	/*enable power off flag, if flag=0, power off connsys will not be executed */
+	mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE);
+	/* check if chip power on is needed */
+	if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		iRet = opfunc_pwr_on(pWmtOp);
+
+		if (iRet) {
+			WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet);
+			osal_assert(0);
+
+			/* check all sub-func and do power off */
+			return -3;
+		}
+	}
+
+	if (WMTDRV_TYPE_WMT > drvType) {
+		if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_on) {
+			iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg());
+			if (0 != iRet)
+				gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
+			else
+				gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON;
+		} else {
+			WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType);
+			iRet = -5;
+		}
+	} else {
+		if (WMTDRV_TYPE_LPBK == drvType)
+			gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON;
+		else if (WMTDRV_TYPE_COREDUMP == drvType)
+			gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON;
+		iRet = 0;
+	}
+
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet);
+		osal_assert(0);
+		/* FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary? */
+		/* check all sub-func and do power off */
+		if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) &&
+		    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) &&
+		    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) &&
+		    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) &&
+		    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) &&
+		    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) {
+			WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType);
+			mtk_wcn_wmt_system_state_reset();
+
+			iPwrOffRet = opfunc_pwr_off(pWmtOp);
+			if (iPwrOffRet) {
+				WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iPwrOffRet,
+					     drvType);
+				osal_assert(0);
+			}
+		}
+		return iRet;
+	}
+
+	wmt_core_dump_func_state("AF FUNC ON");
+
+	return 0;
+}
+
+static INT32 opfunc_func_off(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet = -1;
+	UINT32 drvType;
+
+	drvType = pWmtOp->au4OpData[0];
+	/* Check abnormal type */
+	if (WMTDRV_TYPE_COREDUMP < drvType) {
+		WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off\n", drvType);
+		osal_assert(0);
+		return -1;
+	}
+
+	/* Check abnormal state */
+	if (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) {
+		WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off\n",
+			     drvType, gMtkWmtCtx.eDrvStatus[drvType]);
+		osal_assert(0);
+		return -2;
+	}
+
+	if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[drvType]) {
+		WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n",
+			      drvType, gMtkWmtCtx.eDrvStatus[drvType]);
+		/* needs to check 4 subsystem's state? */
+		return 0;
+	} else if (WMTDRV_TYPE_WMT > drvType) {
+		if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_off) {
+			iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg());
+		} else {
+			WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType);
+			iRet = -3;
+		}
+	} else {
+		if (WMTDRV_TYPE_LPBK == drvType)
+			gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
+		else if (WMTDRV_TYPE_COREDUMP == drvType)
+			gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
+		iRet = 0;
+	}
+
+	/* shall we put device state to POWER_OFF state when fail? */
+	gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
+
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet);
+		osal_assert(0);
+		/* no matter subsystem function control fail or not,
+		*chip should be powered off when no subsystem is active
+		*/
+		/* return iRet; */
+	}
+
+	/* check all sub-func and do power off */
+	if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) &&
+	    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) &&
+	    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) &&
+	    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) &&
+	    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) &&
+	    (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) {
+		WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType);
+
+		iRet = opfunc_pwr_off(pWmtOp);
+		if (iRet) {
+			WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iRet, drvType);
+			osal_assert(0);
+		}
+	}
+
+	wmt_core_dump_func_state("AF FUNC OFF");
+	return iRet;
+}
+
+/* TODO:[ChangeFeature][George] is this OP obsoleted? */
+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp)
+{
+	INT32 iret;
+
+	if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		WMT_ERR_FUNC("reg_rw when WMT is powered off\n");
+		return -1;
+	}
+	iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0],
+				   pWmtOp->au4OpData[1], (PUINT32) pWmtOp->au4OpData[2], pWmtOp->au4OpData[3]);
+
+	return iret;
+}
+
+static INT32 opfunc_exit(P_WMT_OP pWmtOp)
+{
+	/* TODO: [FixMe][George] is ok to leave this function empty??? */
+	WMT_WARN_FUNC("EMPTY FUNCTION\n");
+	return 0;
+}
+
+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp)
+{
+	INT32 ret = -1;
+	UINT32 u4_result = 0;
+	UINT32 evt_len;
+	UINT8 evt_buf[16] = { 0 };
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+
+	typedef INT32(*STP_PSM_CB) (INT32);
+	STP_PSM_CB psm_cb = NULL;
+
+	if (SLEEP == pWmtOp->au4OpData[0]) {
+		WMT_DBG_FUNC("**** Send sleep command\n");
+		/* mtk_wcn_stp_set_psm_state(ACT_INACT); */
+		/* (*kal_stp_flush_rx)(WMT_TASK_INDX); */
+		ret = wmt_core_tx((PUINT8) &WMT_SLEEP_CMD[0], sizeof(WMT_SLEEP_CMD), &u4_result, 0);
+		if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) {
+			WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result,
+				     sizeof(WMT_SLEEP_CMD));
+			goto pwr_sv_done;
+		}
+
+		evt_len = sizeof(WMT_SLEEP_EVT);
+		ret = wmt_core_rx(evt_buf, evt_len, &u4_result);
+		if (ret || (u4_result != evt_len)) {
+			unsigned long type = WMTDRV_TYPE_WMT;
+			unsigned long reason = 33;
+			unsigned long ctrlpa = 1;
+
+			wmt_core_rx_flush(WMT_TASK_INDX);
+			WMT_ERR_FUNC("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len);
+			mtk_wcn_stp_dbg_dump_package();
+			ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0);
+			if (!ret) {	/* parser ok */
+				reason = 38;	/* host schedule issue reason code */
+				WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n");
+			}
+			wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason);
+			goto pwr_sv_done;
+		}
+
+		if (osal_memcmp(evt_buf, WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0) {
+			WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n");
+			wmt_core_rx_flush(WMT_TASK_INDX);
+			WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
+				u4_result,
+				evt_buf[0],
+				evt_buf[1],
+				evt_buf[2],
+				evt_buf[3],
+				evt_buf[4],
+				evt_buf[5]);
+			WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
+				sizeof(WMT_SLEEP_EVT),
+				WMT_SLEEP_EVT[0],
+				WMT_SLEEP_EVT[1],
+				WMT_SLEEP_EVT[2],
+			    WMT_SLEEP_EVT[3],
+			    WMT_SLEEP_EVT[4],
+			    WMT_SLEEP_EVT[5]);
+			mtk_wcn_stp_dbg_dump_package();
+			goto pwr_sv_done;
+		} else {
+			WMT_DBG_FUNC("Send sleep command OK!\n");
+		}
+	} else if (pWmtOp->au4OpData[0] == WAKEUP) {
+		WMT_DBG_FUNC("wakeup connsys by btif");
+
+		ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS, &ctrlPa1, &ctrlPa2);
+		if (ret) {
+			WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)", ret);
+			goto pwr_sv_done;
+		}
+#if 0
+		WMT_DBG_FUNC("**** Send wakeup command\n");
+		ret = wmt_core_tx(WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1);
+
+		if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD))) {
+			wmt_core_rx_flush(WMT_TASK_INDX);
+			WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result,
+				     sizeof(WMT_WAKEUP_CMD));
+			goto pwr_sv_done;
+		}
+#endif
+		evt_len = sizeof(WMT_WAKEUP_EVT);
+		ret = wmt_core_rx(evt_buf, evt_len, &u4_result);
+		if (ret || (u4_result != evt_len)) {
+			unsigned long type = WMTDRV_TYPE_WMT;
+			unsigned long reason = 34;
+			unsigned long ctrlpa = 2;
+
+			WMT_ERR_FUNC("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len);
+			mtk_wcn_stp_dbg_dump_package();
+			ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0);
+			if (!ret) {	/* parser ok */
+				reason = 39;	/* host schedule issue reason code */
+				WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n");
+			}
+			wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason);
+			goto pwr_sv_done;
+		}
+
+		if (osal_memcmp(evt_buf, WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0) {
+			WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n");
+			wmt_core_rx_flush(WMT_TASK_INDX);
+			WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
+				u4_result,
+				evt_buf[0],
+				evt_buf[1],
+				evt_buf[2],
+				evt_buf[3],
+				evt_buf[4],
+				evt_buf[5]);
+			WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
+				sizeof(WMT_WAKEUP_EVT),
+				WMT_WAKEUP_EVT[0],
+				WMT_WAKEUP_EVT[1],
+				WMT_WAKEUP_EVT[2],
+			    WMT_WAKEUP_EVT[3],
+			    WMT_WAKEUP_EVT[4],
+			    WMT_WAKEUP_EVT[5]);
+			mtk_wcn_stp_dbg_dump_package();
+			goto pwr_sv_done;
+		} else {
+			WMT_DBG_FUNC("Send wakeup command OK!\n");
+		}
+	} else if (pWmtOp->au4OpData[0] == HOST_AWAKE) {
+
+		WMT_DBG_FUNC("**** Send host awake command\n");
+
+		psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1];
+		/* (*kal_stp_flush_rx)(WMT_TASK_INDX); */
+		ret = wmt_core_tx((PUINT8) WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), &u4_result, 0);
+		if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD))) {
+			WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result,
+				     sizeof(WMT_HOST_AWAKE_CMD));
+			goto pwr_sv_done;
+		}
+
+		evt_len = sizeof(WMT_HOST_AWAKE_EVT);
+		ret = wmt_core_rx(evt_buf, evt_len, &u4_result);
+		if (ret || (u4_result != evt_len)) {
+			unsigned long type = WMTDRV_TYPE_WMT;
+			unsigned long reason = 35;
+			unsigned long ctrlpa = 3;
+
+			wmt_core_rx_flush(WMT_TASK_INDX);
+			WMT_ERR_FUNC("wmt_core: read HOST_AWAKE_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len);
+			mtk_wcn_stp_dbg_dump_package();
+			ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0);
+			if (!ret) {	/* parser ok */
+				reason = 40;	/* host schedule issue reason code */
+				WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n");
+			}
+			wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason);
+			goto pwr_sv_done;
+		}
+
+		if (osal_memcmp(evt_buf, WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0) {
+			WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n");
+			wmt_core_rx_flush(WMT_TASK_INDX);
+			WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
+				u4_result,
+				evt_buf[0],
+				evt_buf[1],
+				evt_buf[2],
+				evt_buf[3],
+				evt_buf[4],
+				evt_buf[5]);
+			WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
+				sizeof(WMT_HOST_AWAKE_EVT),
+				WMT_HOST_AWAKE_EVT[0],
+				WMT_HOST_AWAKE_EVT[1],
+				WMT_HOST_AWAKE_EVT[2],
+			    WMT_HOST_AWAKE_EVT[3],
+			    WMT_HOST_AWAKE_EVT[4],
+			    WMT_HOST_AWAKE_EVT[5]);
+			mtk_wcn_stp_dbg_dump_package();
+			/* goto pwr_sv_done; */
+		} else {
+			WMT_DBG_FUNC("Send host awake command OK!\n");
+		}
+	}
+pwr_sv_done:
+
+	if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) {
+		psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1];
+		WMT_DBG_FUNC("Do STP-CB! %d %p / %p\n", pWmtOp->au4OpData[0], (PVOID) pWmtOp->au4OpData[1],
+			     (PVOID) psm_cb);
+		if (NULL != psm_cb) {
+			psm_cb(pWmtOp->au4OpData[0]);
+		} else {
+			WMT_ERR_FUNC("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n",
+				     psm_cb);
+		}
+	}
+
+	return ret;
+}
+
+static INT32 opfunc_dsns(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet = -1;
+	UINT32 u4Res;
+	UINT32 evtLen;
+	UINT8 evtBuf[16] = { 0 };
+
+	WMT_DSNS_CMD[4] = (UINT8) pWmtOp->au4OpData[0];
+	WMT_DSNS_CMD[5] = (UINT8) pWmtOp->au4OpData[1];
+
+	/* send command */
+	/* iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res); */
+	iRet = wmt_core_tx((PUINT8) WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) {
+		WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res,
+			     osal_sizeof(WMT_DSNS_CMD));
+		return iRet;
+	}
+
+	evtLen = osal_sizeof(WMT_DSNS_EVT);
+
+	iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
+	if (iRet || (u4Res != evtLen)) {
+		WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen);
+		mtk_wcn_stp_dbg_dump_package();
+		return iRet;
+	}
+
+	if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) {
+		WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n");
+		WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+			     u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4],
+			     osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2],
+			     WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]);
+	} else {
+		WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n");
+	}
+
+	return iRet;
+}
+
+#if CFG_CORE_INTERNAL_TXRX
+INT32 wmt_core_lpbk_do_stp_init(void)
+{
+	INT32 iRet = 0;
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: wmt open stp\n");
+		return -1;
+	}
+
+	ctrlPa1 = WMT_STP_CONF_MODE;
+	ctrlPa2 = MTKSTP_BTIF_MAND_MODE;
+	iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+
+	ctrlPa1 = WMT_STP_CONF_EN;
+	ctrlPa2 = 1;
+	iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet);
+		return -2;
+	}
+}
+
+INT32 wmt_core_lpbk_do_stp_deinit(void)
+{
+	INT32 iRet = 0;
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-CORE: wmt open stp\n");
+		return -1;
+	}
+
+	return 0;
+}
+#endif
+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet;
+	UINT32 u4WrittenSize = 0;
+	UINT32 u4ReadSize = 0;
+	UINT32 buf_length = 0;
+	UINT32 *pbuffer = NULL;
+	UINT16 len_in_cmd;
+
+	/* UINT32 offset; */
+	UINT8 WMT_TEST_LPBK_CMD[] = { 0x1, 0x2, 0x0, 0x0, 0x7 };
+	UINT8 WMT_TEST_LPBK_EVT[] = { 0x2, 0x2, 0x0, 0x0, 0x0 };
+
+	/* UINT8 lpbk_buf[1024 + 5] = {0}; */
+	MTK_WCN_BOOL fgFail;
+
+	buf_length = pWmtOp->au4OpData[0];	/* packet length */
+	pbuffer = (VOID *) pWmtOp->au4OpData[1];	/* packet buffer pointer */
+	WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk\n");
+
+#if 0
+	osal_memcpy(&WMT_TEST_LPBK_EVT[0], &WMT_TEST_LPBK_CMD[0], osal_sizeof(WMT_TEST_LPBK_CMD));
+#endif
+#if !CFG_CORE_INTERNAL_TXRX
+	/*check if WMTDRV_TYPE_LPBK function is already on */
+	if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]
+	    || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) {
+		WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n");
+		osal_assert(0);
+		return -2;
+	}
+#endif
+	/*package loopback for STP */
+
+	/* init buffer */
+	osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf));
+
+	len_in_cmd = buf_length + 1;	/* add flag field */
+
+	osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2);
+	osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2);
+
+	/* wmt cmd */
+	osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD));
+	osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length);
+
+	do {
+		fgFail = MTK_WCN_BOOL_TRUE;
+		/*send packet through STP */
+
+		/* iRet = (*kal_stp_tx)(
+		*(PUINT8)gLpbkBuf,
+		*osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length,
+		*&u4WrittenSize);
+		*/
+		iRet = wmt_core_tx((PUINT8) gLpbkBuf,
+				(osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length),
+				&u4WrittenSize,
+				MTK_WCN_BOOL_FALSE);
+		if (iRet) {
+			WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed\n");
+			break;
+		}
+		WMT_INFO_FUNC("opfunc_lpbk wmt_core_tx OK\n");
+
+		/*receive firmware response from STP */
+		iRet = wmt_core_rx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), &u4ReadSize);
+		if (iRet) {
+			WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed\n");
+			break;
+		}
+		WMT_INFO_FUNC("opfunc_lpbk wmt_core_rx  OK\n");
+		/*check if loopback response ok or not */
+		if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) {
+			WMT_ERR_FUNC("lpbk event read size wrong(%d, %d)\n", u4ReadSize,
+				     (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length));
+			break;
+		}
+		WMT_INFO_FUNC("lpbk event read size right(%d, %d)\n", u4ReadSize,
+			      (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length));
+
+		if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) {
+			WMT_ERR_FUNC("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x]\n",
+				     (INT32) u4ReadSize, gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], gLpbkBuf[4]
+			    );
+			break;
+		}
+		pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT);
+		osal_memcpy((VOID *) pWmtOp->au4OpData[1], gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length);
+		fgFail = MTK_WCN_BOOL_FALSE;
+	} while (0);
+	/*return result */
+	/* WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d\n", fgFail); */
+	return fgFail;
+
+}
+
+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet = 0;
+	UINT32 cmdNo = 0;
+	UINT32 cmdNoPa = 0;
+
+	UINT8 tstCmd[64];
+	UINT8 tstEvt[64];
+	UINT8 tstEvtTmp[64];
+	UINT32 u4Res;
+	SIZE_T tstCmdSz = 0;
+	SIZE_T tstEvtSz = 0;
+
+	UINT8 *pRes = NULL;
+	UINT32 resBufRoom = 0;
+	/*test command list */
+	/*1 */
+	UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 };
+	UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 };
+	UINT8 WMT_NOACK_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0A };
+	UINT8 WMT_NOACK_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 };
+	UINT8 WMT_WARNRST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0B };
+	UINT8 WMT_WARNRST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 };
+	UINT8 WMT_FWLOGTST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0C };
+	UINT8 WMT_FWLOGTST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 };
+
+	UINT8 WMT_EXCEPTION_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x09 };
+	UINT8 WMT_EXCEPTION_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 };
+	/*2 */
+	UINT8 WMT_COEXDBG_CMD[] = { 0x01, 0x10, 0x02, 0x00,
+		0x08,
+		0xAA		/*Debugging Parameter */
+	};
+	UINT8 WMT_COEXDBG_1_EVT[] = { 0x02, 0x10, 0x05, 0x00,
+		0x00,
+		0xAA, 0xAA, 0xAA, 0xAA	/*event content */
+	};
+	UINT8 WMT_COEXDBG_2_EVT[] = { 0x02, 0x10, 0x07, 0x00,
+		0x00,
+		0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB	/*event content */
+	};
+	UINT8 WMT_COEXDBG_3_EVT[] = { 0x02, 0x10, 0x0B, 0x00,
+		0x00,
+		0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB	/*event content */
+	};
+	/*test command list -end */
+
+	cmdNo = pWmtOp->au4OpData[0];
+
+	WMT_INFO_FUNC("Send Test command %d!\n", cmdNo);
+	if (cmdNo == 0) {
+		/*dead command */
+		WMT_INFO_FUNC("Send Assert command !\n");
+		tstCmdSz = osal_sizeof(WMT_ASSERT_CMD);
+		tstEvtSz = osal_sizeof(WMT_ASSERT_EVT);
+		osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz);
+		osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz);
+	} else if (cmdNo == 1) {
+		/*dead command */
+		WMT_INFO_FUNC("Send Exception command !\n");
+		tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD);
+		tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT);
+		osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz);
+		osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz);
+	} else if (cmdNo == 2) {
+		cmdNoPa = pWmtOp->au4OpData[1];
+		pRes = (PUINT8) pWmtOp->au4OpData[2];
+		resBufRoom = pWmtOp->au4OpData[3];
+		if (cmdNoPa <= 0xf) {
+			WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa);
+			tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD);
+			osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz);
+			if (tstCmdSz > 5)
+				tstCmd[5] = cmdNoPa;
+
+			/*setup the expected event length */
+			if (cmdNoPa <= 0x4) {
+				tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT);
+				osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz);
+			} else if (cmdNoPa == 0x5) {
+				tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT);
+				osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz);
+			} else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) {
+				tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT);
+				osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz);
+			} else {
+
+			}
+		} else {
+			WMT_ERR_FUNC("cmdNoPa is wrong\n");
+			return iRet;
+		}
+	} else if (cmdNo == 3) {
+		/*dead command */
+		WMT_INFO_FUNC("Send No Ack command !\n");
+		tstCmdSz = osal_sizeof(WMT_NOACK_CMD);
+		tstEvtSz = osal_sizeof(WMT_NOACK_EVT);
+		osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz);
+		osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz);
+	} else if (cmdNo == 4) {
+		/*dead command */
+		WMT_INFO_FUNC("Send Warm reset command !\n");
+		tstCmdSz = osal_sizeof(WMT_WARNRST_CMD);
+		tstEvtSz = osal_sizeof(WMT_WARNRST_EVT);
+		osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz);
+		osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz);
+	} else if (cmdNo == 5) {
+		/*dead command */
+		WMT_INFO_FUNC("Send f/w log test command !\n");
+		tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD);
+		tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT);
+		osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz);
+		osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz);
+	}
+
+	else {
+		/*Placed youer test WMT command here, easiler to integrate and test with F/W side */
+	}
+
+	/* send command */
+	/* iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res); */
+	iRet = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != tstCmdSz)) {
+		WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, tstCmdSz);
+		return -1;
+	}
+
+	if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) {
+		WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n");
+		return 0;
+	}
+
+	iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res);
+
+	/*Event Post Handling */
+	if (cmdNo == 2) {
+		WMT_INFO_FUNC("#=========================================================#\n");
+		WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa);
+		if (tstEvtSz > 5) {
+			wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5);
+		} else {
+			/* error log */
+			WMT_ERR_FUNC("error coex debugging event\n");
+		}
+		/*put response to buffer for shell to read */
+		if (pRes != NULL && resBufRoom > 0) {
+			pWmtOp->au4OpData[3] = resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5;
+			osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]);
+		} else
+			pWmtOp->au4OpData[3] = 0;
+		WMT_INFO_FUNC("#=========================================================#\n");
+	}
+
+	return iRet;
+
+}
+
+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet = -1;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+
+	wmt_core_dump_func_state("BE HW RST");
+    /*-->Reset WMT  data structure*/
+	/* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]   = DRV_STS_POWER_OFF; */
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF;
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF;
+	/* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; */
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] = DRV_STS_POWER_OFF;
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF;
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF;
+	/*enable power off flag, if flag=0, power off connsys will not be executed */
+	mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE);
+	/* if wmt is poweroff, we need poweron chip first */
+	/* Zhiguo : this action also needed in BTIF interface to avoid KE */
+#if 1
+	if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n");
+		/* power on control */
+		ctrlPa1 = 0;
+		ctrlPa2 = 0;
+		iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2);
+		if (iRet) {
+			WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet);
+			return -1;
+		}
+		gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
+	}
+#endif
+	if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON) {
+
+		ctrlPa1 = BT_PALDO;
+		ctrlPa2 = PALDO_OFF;
+		iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+		if (iRet)
+			WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2);
+
+		gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF;
+	}
+
+	if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) {
+
+		if (NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI] && NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off) {
+			iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg());
+			if (iRet) {
+				WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet);
+
+				/* check all sub-func and do power off */
+			} else {
+				WMT_INFO_FUNC("wmt core: turn off  WIFI func ok!!\n");
+			}
+		}
+		gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF;
+	}
+#if 0
+	/*<4>Power off Combo chip */
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2);
+	if (iRet)
+		WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet);
+	WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet);
+#endif
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF;
+
+    /*-->PesetCombo chip*/
+	iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2);
+	if (iRet)
+		WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet);
+	WMT_WARN_FUNC("WMT-CORE: -->[HW RST] ok\n");
+
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
+
+	/* 4  close stp */
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		if (iRet == -2) {
+			WMT_INFO_FUNC("WMT-CORE:stp should have be closed\n");
+			return 0;
+		}
+		WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n");
+		return -1;
+	}
+
+	wmt_core_dump_func_state("AF HW RST");
+	return iRet;
+
+}
+
+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp)
+{
+	INT32 iRet = 0;
+
+	iRet = wmt_core_stp_init();
+	if (!iRet)
+		gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON;
+	return iRet;
+}
+
+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp)
+{
+
+	return 0;
+}
+
+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet = -1;
+	UINT32 u4Res;
+	UINT32 evtLen;
+	UINT8 evtBuf[16] = { 0 };
+
+	WMT_THERM_CMD[4] = pWmtOp->au4OpData[0];	/*CMD type, refer to ENUM_WMTTHERM_TYPE_T */
+
+	/* send command */
+	/* iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res); */
+	iRet = wmt_core_tx((PUINT8) WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) {
+		WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res,
+			     osal_sizeof(WMT_THERM_CMD));
+		return iRet;
+	}
+
+	evtLen = 16;
+
+	iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
+	if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT)))) {
+		WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d, %d)\n", iRet, u4Res,
+			     evtLen);
+		mtk_wcn_stp_dbg_dump_package();
+		return iRet;
+	}
+	if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT)) {
+		if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) {
+			WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n");
+			WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+				     u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4],
+				     osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], WMT_THERM_CTRL_EVT[1],
+				     WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], WMT_THERM_CTRL_EVT[4]);
+			pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE;	/*will return to function driver */
+			mtk_wcn_stp_dbg_dump_package();
+		} else {
+			WMT_DBG_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n");
+			pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE;	/*will return to function driver */
+		}
+	} else {
+		/*no need to judge the real thermal value */
+		if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != 0) {
+			WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n");
+			WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X]\n",
+				     u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5],
+				     osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], WMT_THERM_READ_EVT[1],
+				     WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]);
+			pWmtOp->au4OpData[1] = 0xFF;	/*will return to function driver */
+			mtk_wcn_stp_dbg_dump_package();
+		} else {
+			WMT_DBG_FUNC("Send WMT_THERM_READ_CMD command OK!\n");
+			pWmtOp->au4OpData[1] = evtBuf[5];	/*will return to function driver */
+		}
+	}
+
+	return iRet;
+
+}
+
+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp)
+{
+
+	INT32 iRet = -1;
+	UINT32 u4Res;
+	UINT32 evtLen;
+	UINT8 evtBuf[16] = { 0 };
+
+	if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n");
+		return -1;
+	}
+
+	WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2;	/* w:2, r:1 */
+	osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8) &pWmtOp->au4OpData[1], 2);	/* address */
+	osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32) pWmtOp->au4OpData[2], 4);	/* value */
+
+	wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD));
+
+	/* send command */
+	/* iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res); */
+	iRet = wmt_core_tx((PUINT8) WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) {
+		WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res,
+			     osal_sizeof(WMT_EFUSE_CMD));
+		return iRet;
+	}
+
+	evtLen = (pWmtOp->au4OpData[0]) ? osal_sizeof(WMT_EFUSE_EVT) : osal_sizeof(WMT_EFUSE_EVT);
+
+	iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
+	if (iRet || (u4Res != evtLen))
+		WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen);
+	wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf));
+
+	return iRet;
+
+}
+
+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp)
+{
+	INT32 iRet = -1;
+	WMT_IC_PIN_ID id;
+	WMT_IC_PIN_STATE stat;
+	UINT32 flag;
+
+	if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
+		WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n");
+		return -1;
+	}
+
+	if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) {
+		WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n");
+		return -1;
+	}
+
+	id = pWmtOp->au4OpData[0];
+	stat = pWmtOp->au4OpData[1];
+	flag = pWmtOp->au4OpData[2];
+
+	WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id, stat, flag);
+
+	iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl)) (id, stat, flag);
+
+	return iRet;
+}
+
+MTK_WCN_BOOL wmt_core_is_quick_ps_support(void)
+{
+	P_WMT_CTX pctx = &gMtkWmtCtx;
+
+	if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_quick_sleep))
+		return (*(pctx->p_ic_ops->is_quick_sleep)) ();
+
+	return MTK_WCN_BOOL_FALSE;
+}
+
+MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void)
+{
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	P_WMT_CTX pctx = &gMtkWmtCtx;
+
+	if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_aee_dump_support))
+		bRet = (*(pctx->p_ic_ops->is_aee_dump_support)) ();
+	else
+		bRet = MTK_WCN_BOOL_FALSE;
+
+	return bRet;
+}
+
+INT32 opfunc_pin_state(P_WMT_OP pWmtOp)
+{
+
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+	UINT32 iRet = 0;
+
+	iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2);
+	return iRet;
+}
+
+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp)
+{
+	INT32 iRet = -1;
+	UINT32 u4WrittenSize = 0;
+	UINT32 u4ReadSize = 0;
+	UINT32 buf_len = 0;
+	UINT8 *buffer = NULL;
+	UINT8 evt_buffer[8] = { 0 };
+	MTK_WCN_BOOL fgFail;
+
+	UINT8 WMT_BGW_DESENSE_CMD[] = {
+		0x01, 0x0e, 0x0f, 0x00,
+		0x02, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00
+	};
+	UINT8 WMT_BGW_DESENSE_EVT[] = { 0x02, 0x0e, 0x01, 0x00, 0x00 };
+
+	buf_len = pWmtOp->au4OpData[0];
+	buffer = (PUINT8) pWmtOp->au4OpData[1];
+
+	osal_memcpy(&WMT_BGW_DESENSE_CMD[5], buffer, buf_len);
+
+	do {
+		fgFail = MTK_WCN_BOOL_TRUE;
+
+		iRet =
+		    wmt_core_tx(&WMT_BGW_DESENSE_CMD[0], osal_sizeof(WMT_BGW_DESENSE_CMD), &u4WrittenSize,
+				MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))) {
+			WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize);
+			break;
+		}
+
+		iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_BGW_DESENSE_EVT), &u4ReadSize);
+		if (iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))) {
+			WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize);
+			break;
+		}
+
+		if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) {
+			WMT_ERR_FUNC
+			    ("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
+			     evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4]);
+			break;
+		}
+
+		fgFail = MTK_WCN_BOOL_FALSE;
+
+	} while (0);
+
+	return fgFail;
+}
+
+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp)
+{
+	UINT32 kind = 0;
+	INT32 iRet = -1;
+	UINT32 u4WrittenSize = 0;
+	UINT32 u4ReadSize = 0;
+	UINT8 evt_buffer[12] = { 0 };
+	MTK_WCN_BOOL fgFail;
+	PUINT8 set_mcu_clk_str[] = {
+		"Enable MCU PLL",
+		"SET MCU CLK to 26M",
+		"SET MCU CLK to 37M",
+		"SET MCU CLK to 64M",
+		"SET MCU CLK to 69M",
+		"SET MCU CLK to 104M",
+		"SET MCU CLK to 118.857M",
+		"SET MCU CLK to 138.67M",
+		"Disable MCU PLL"
+	};
+	UINT8 WMT_SET_MCU_CLK_CMD[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0xff, 0xff, 0xff, 0xff
+	};
+	UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+
+	UINT8 WMT_EN_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00 };	/* enable pll clk */
+	UINT8 WMT_26_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x00, 0x4d, 0x84, 0x00 };	/* set 26M */
+	UINT8 WMT_37_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1e, 0x4d, 0x84, 0x00 };	/* set 37.8M */
+	UINT8 WMT_64_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1d, 0x4d, 0x84, 0x00 };	/* set 64M */
+	UINT8 WMT_69_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1c, 0x4d, 0x84, 0x00 };	/* set 69M */
+	UINT8 WMT_104_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5b, 0x4d, 0x84, 0x00 };	/* set 104M */
+	UINT8 WMT_108_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5a, 0x4d, 0x84, 0x00 };	/* set 118.857M */
+	UINT8 WMT_138_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x59, 0x4d, 0x84, 0x00 };	/* set 138.67M */
+	UINT8 WMT_DIS_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 };	/* disable pll clk */
+
+	kind = pWmtOp->au4OpData[0];
+	WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]);
+
+	switch (kind) {
+	case 0:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_EN_MCU_CLK_CMD[0], osal_sizeof(WMT_EN_MCU_CLK_CMD));
+		break;
+	case 1:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_26_MCU_CLK_CMD[0], osal_sizeof(WMT_26_MCU_CLK_CMD));
+		break;
+	case 2:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_37_MCU_CLK_CMD[0], osal_sizeof(WMT_37_MCU_CLK_CMD));
+		break;
+	case 3:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_64_MCU_CLK_CMD[0], osal_sizeof(WMT_64_MCU_CLK_CMD));
+		break;
+	case 4:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_69_MCU_CLK_CMD[0], osal_sizeof(WMT_69_MCU_CLK_CMD));
+		break;
+	case 5:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_104_MCU_CLK_CMD[0], osal_sizeof(WMT_104_MCU_CLK_CMD));
+		break;
+	case 6:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_108_MCU_CLK_CMD[0], osal_sizeof(WMT_108_MCU_CLK_CMD));
+		break;
+	case 7:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_138_MCU_CLK_CMD[0], osal_sizeof(WMT_138_MCU_CLK_CMD));
+		break;
+	case 8:
+		osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_DIS_MCU_CLK_CMD[0], osal_sizeof(WMT_DIS_MCU_CLK_CMD));
+		break;
+	default:
+		WMT_ERR_FUNC("unknown kind\n");
+		break;
+	}
+
+	do {
+		fgFail = MTK_WCN_BOOL_TRUE;
+
+		iRet =
+		    wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize,
+				MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) {
+			WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize);
+			break;
+		}
+
+		iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize);
+		if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) {
+			WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize);
+			break;
+		}
+
+		if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) {
+			WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
+				     evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4],
+				     evt_buffer[5], evt_buffer[6], evt_buffer[7]);
+			break;
+		}
+
+		fgFail = MTK_WCN_BOOL_FALSE;
+
+	} while (0);
+
+	if (MTK_WCN_BOOL_FALSE == fgFail)
+		WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]);
+
+	WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]);
+
+	return fgFail;
+}
+
+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp)
+{
+	UINT8 *buffer = NULL;
+	MTK_WCN_BOOL fgFail;
+	UINT32 u4Res;
+	UINT32 aDieChipid = 0;
+	UINT8 soc_adie_chipid_cmd[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 };
+	UINT8 soc_adie_chipid_evt[] = { 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	UINT8 evtbuf[20];
+	INT32 iRet = -1;
+
+	buffer = (PUINT8) pWmtOp->au4OpData[1];
+
+	do {
+		fgFail = MTK_WCN_BOOL_TRUE;
+
+		/* read A die chipid by wmt cmd */
+		iRet =
+		    wmt_core_tx((PUINT8) &soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res,
+				MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) {
+			WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res);
+			break;
+		}
+		osal_memset(evtbuf, 0, osal_sizeof(evtbuf));
+		iRet = wmt_core_rx(evtbuf, osal_sizeof(soc_adie_chipid_evt), &u4Res);
+		if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) {
+			WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res);
+			break;
+		}
+		osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2);
+		osal_memcpy(buffer, &evtbuf[u4Res - 2], 2);
+		pWmtOp->au4OpData[0] = 2;
+		WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid);
+
+		fgFail = MTK_WCN_BOOL_FALSE;
+
+	} while (0);
+
+	return fgFail;
+}
+
+#if CFG_WMT_LTE_COEX_HANDLING
+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp)
+{
+	MTK_WCN_BOOL fgFail;
+	UINT32 u4Res;
+	UINT8 host_lte_btwf_coex_cmd[] = { 0x01, 0x10, 0x00, 0x00, 0x00 };
+	UINT8 host_lte_btwf_coex_evt[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+	UINT8 *pTxBuf = NULL;
+	UINT8 evtbuf[8] = { 0 };
+	INT32 iRet = -1;
+	UINT16 msg_len = 0;
+	UINT32 total_len = 0;
+	UINT32 index = 0;
+	UINT8 *msg_local_buffer = NULL;
+
+	msg_local_buffer = kmalloc(1300, GFP_KERNEL);
+	if (!msg_local_buffer) {
+			WMT_ERR_FUNC("msg_local_buffer kmalloc memory fail\n");
+			return 0;
+	}
+
+	pTxBuf = (UINT8 *) pWmtOp->au4OpData[0];
+	if (NULL == pTxBuf) {
+		WMT_ERR_FUNC("idc msg buffer is NULL\n");
+		return -1;
+	}
+	iRet = wmt_lib_idc_lock_aquire();
+	if (iRet) {
+		WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", iRet);
+		return iRet;
+	}
+	osal_memcpy(&msg_len, &pTxBuf[0], osal_sizeof(msg_len));
+	if (msg_len > 1200) {
+		wmt_lib_idc_lock_release();
+		WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len);
+		return -2;
+	}
+	msg_len += 1;	/*flag byte */
+
+	osal_memcpy(&host_lte_btwf_coex_cmd[2], &msg_len, 2);
+	host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff);
+	osal_memcpy(&msg_local_buffer[0], &host_lte_btwf_coex_cmd[0], osal_sizeof(host_lte_btwf_coex_cmd));
+	osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)],
+		&pTxBuf[osal_sizeof(msg_len)], msg_len - 1);
+
+	wmt_lib_idc_lock_release();
+	total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1;
+
+	WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n", msg_len - 1,
+		     total_len);
+	WMT_DBG_FUNC("wmt_core:idc msg payload:\n");
+
+	for (index = 0; index < total_len; index++)
+		WMT_DBG_FUNC("0x%02x ", msg_local_buffer[index]);
+
+
+	do {
+		fgFail = MTK_WCN_BOOL_TRUE;
+
+		/* read A die chipid by wmt cmd */
+		iRet = wmt_core_tx((PUINT8) &msg_local_buffer[0], total_len, &u4Res, MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != total_len)) {
+			WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", iRet, u4Res);
+			break;
+		}
+		osal_memset(evtbuf, 0, osal_sizeof(evtbuf));
+		iRet = wmt_core_rx(evtbuf, osal_sizeof(host_lte_btwf_coex_evt), &u4Res);
+		if (iRet || (u4Res != osal_sizeof(host_lte_btwf_coex_evt))) {
+			WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d),size(%d)\n", iRet, u4Res);
+			break;
+		}
+
+		fgFail = MTK_WCN_BOOL_FALSE;
+
+	} while (0);
+	kfree(msg_local_buffer);
+	return fgFail;
+}
+#endif
+
+VOID wmt_core_set_coredump_state(ENUM_DRV_STS state)
+{
+	WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n", state);
+	gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state;
+}
+#ifdef CONFIG_MTK_COMBO_ANT
+INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp)
+{
+	INT32 iRet = 0;
+	size_t ctrlPa1 = pWmtOp->au4OpData[0];
+	UINT32 ctrlPa2 = pWmtOp->au4OpData[1];
+	PUINT8 pbuf = (PUINT8) ctrlPa1;
+	UINT32 fragSeq = 0;
+	UINT16 fragSize = 0;
+	UINT16 wmtCmdLen;
+	UINT16 wmtPktLen;
+	UINT32 u4Res = 0;
+	UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_DWN_EVT)];
+#if 1
+	UINT32 ctrlPa3 = pWmtOp->au4OpData[2];
+
+	do {
+		fragSize = ctrlPa2;
+		fragSeq = ctrlPa3;
+		gAntBuf[5] = fragSeq;
+
+
+		wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_DWN_CMD) + 1;
+
+		/*WMT command length cal */
+		wmtCmdLen = wmtPktLen - 4;
+#if 0
+		WMT_ANT_RAM_DWN_CMD[2] = wmtCmdLen & 0xFF;
+		WMT_ANT_RAM_DWN_CMD[3] = (wmtCmdLen & 0xFF00) >> 16;
+#else
+		osal_memcpy(&WMT_ANT_RAM_DWN_CMD[2], &wmtCmdLen, 2);
+#endif
+
+
+
+		WMT_ANT_RAM_DWN_CMD[4] = 1;	/*RAM CODE download */
+
+		osal_memcpy(gAntBuf, WMT_ANT_RAM_DWN_CMD, sizeof(WMT_ANT_RAM_DWN_CMD));
+
+		/*copy ram code content to global buffer */
+		osal_memcpy(&gAntBuf[osal_sizeof(WMT_ANT_RAM_DWN_CMD) + 1], pbuf, fragSize);
+
+		iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != wmtPktLen)) {
+			WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq,
+				     wmtPktLen, u4Res, iRet);
+			iRet = -4;
+			break;
+		}
+		WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n",
+			     fragSeq, wmtPktLen, u4Res);
+
+		osal_memset(antEvtBuf, 0, sizeof(antEvtBuf));
+
+		WMT_ANT_RAM_DWN_EVT[4] = 0;	/*download result; 0 */
+
+		iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_DWN_EVT), &u4Res);
+		if (iRet || (u4Res != sizeof(WMT_ANT_RAM_DWN_EVT))) {
+			WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) fail(%d)\n",
+				     sizeof(WMT_ANT_RAM_DWN_EVT), u4Res, iRet);
+			iRet = -5;
+			break;
+		}
+#if CFG_CHECK_WMT_RESULT
+		if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_DWN_EVT, sizeof(WMT_ANT_RAM_DWN_EVT)) != 0) {
+			WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_DWN_EVT result error\n");
+			WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n",
+					u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3],
+					antEvtBuf[4], sizeof(WMT_ANT_RAM_DWN_EVT), WMT_ANT_RAM_DWN_EVT[0],
+					WMT_ANT_RAM_DWN_EVT[1], WMT_ANT_RAM_DWN_EVT[2], WMT_ANT_RAM_DWN_EVT[3],
+					WMT_ANT_RAM_DWN_EVT[4]);
+			iRet = -6;
+			break;
+		}
+#endif
+		WMT_DBG_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) ok\n",
+			     sizeof(WMT_ANT_RAM_DWN_EVT), u4Res);
+
+	} while (0);
+#else
+	UINT32 patchSize = ctrlPa2;
+	UINT32 patchSizePerFrag = 1000;
+	UINT32 offset;
+	UINT32 fragNum = 0;
+	/*cal patch fragNum */
+	fragNum = (patchSize + patchSizePerFrag - 1) / patchSizePerFrag;
+	if (2 >= fragNum) {
+		WMT_WARN_FUNC("ANT ramcode size(%d) too short\n", patchSize);
+		return -1;
+	}
+
+	while (fragSeq < fragNum) {
+		/*update fragNum */
+		fragSeq++;
+
+		if (1 == fragSeq) {
+			fragSize = patchSizePerFrag;
+			/*first package */
+			gAntBuf[5] = 1;	/*RAM CODE start */
+		} else if (fragNum == fragSeq) {
+			/*last package */
+			fragSize = patchSizePerFrag;
+			gAntBuf[5] = 3;	/*RAM CODE end */
+		} else {
+			/*middle package */
+			fragSize = patchSize - ((fragNum - 1) * patchSizePerFrag);
+			gAntBuf[5] = 2;	/*RAM CODE confinue */
+		}
+		wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_OP_CMD) + 1;
+
+		/*WMT command length cal */
+		wmtCmdLen = wmtPktLen - 4;
+
+		WMT_ANT_RAM_OP_CMD[2] = wmtCmdLen & 0xFF;
+		WMT_ANT_RAM_OP_CMD[3] = (wmtCmdLen & 0xFF00) >> 16;
+
+		WMT_ANT_RAM_OP_CMD[4] = 1;	/*RAM CODE download */
+
+		osal_memcpy(gAntBuf, WMT_ANT_RAM_OP_CMD, sizeof(WMT_ANT_RAM_OP_CMD));
+
+		/*copy ram code content to global buffer */
+		osal_memcpy(&gAntBuf[6], pbuf, fragSize);
+
+		/*update offset */
+		offset += fragSize;
+		pbuf += offset;
+
+		iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != wmtPktLen)) {
+			WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq,
+				     wmtPktLen, u4Res, iRet);
+			iRet = -4;
+			break;
+		}
+		WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n",
+			     fragSeq, wmtPktLen, u4Res);
+
+		osal_memset(antEvtBuf, 0, sizeof(antEvtBuf));
+
+		WMT_SET_RAM_OP_EVT[4] = 0;	/*download result; 0 */
+
+		iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_SET_RAM_OP_EVT), &u4Res);
+		if (iRet || (u4Res != sizeof(WMT_SET_RAM_OP_EVT))) {
+			WMT_ERR_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) fail(%d)\n",
+				     sizeof(WMT_SET_RAM_OP_EVT), u4Res, iRet);
+			iRet = -5;
+			break;
+		}
+#if CFG_CHECK_WMT_RESULT
+		if (osal_memcmp(antEvtBuf, WMT_SET_RAM_OP_EVT, sizeof(WMT_SET_RAM_OP_EVT)) != 0) {
+			WMT_ERR_FUNC("wmt_core: compare WMT_SET_RAM_OP_EVT result error\n");
+			WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+			     u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3],
+			     antEvtBuf[4], sizeof(WMT_SET_RAM_OP_EVT), WMT_SET_RAM_OP_EVT[0],
+			     WMT_SET_RAM_OP_EVT[1], WMT_SET_RAM_OP_EVT[2], WMT_SET_RAM_OP_EVT[3],
+			     WMT_SET_RAM_OP_EVT[4]);
+			iRet = -6;
+			break;
+		}
+#endif
+		WMT_DBG_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) ok\n",
+			     sizeof(WMT_SET_RAM_OP_EVT), u4Res);
+
+
+	}
+	if (fragSeq != fragNum)
+		iRet = -7;
+#endif
+	return iRet;
+}
+
+
+INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp)
+{
+	INT32 iRet = 0;
+	UINT32 u4Res = 0;
+	UINT32 wmtPktLen = osal_sizeof(WMT_ANT_RAM_STA_GET_CMD);
+	UINT32 u4AntRamStatus = 0;
+	UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_STA_GET_EVT)];
+
+
+	iRet = wmt_core_tx(WMT_ANT_RAM_STA_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != wmtPktLen)) {
+		WMT_ERR_FUNC
+		    ("wmt_core: write wmt and ramcode status query command failed, (%d, %d), iRet(%d)\n",
+		     wmtPktLen, u4Res, iRet);
+		iRet = -4;
+		return iRet;
+	}
+
+
+	iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_STA_GET_EVT), &u4Res);
+	if (iRet || (u4Res != sizeof(WMT_ANT_RAM_STA_GET_EVT))) {
+		WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_STA_GET_EVT length(%zu, %d) fail(%d)\n",
+			     sizeof(WMT_ANT_RAM_STA_GET_EVT), u4Res, iRet);
+		iRet = -5;
+		return iRet;
+	}
+#if CFG_CHECK_WMT_RESULT
+	if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_STA_GET_EVT, sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1) !=
+	    0) {
+		WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_STA_GET_EVT result error\n");
+		WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n",
+				u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], antEvtBuf[4],
+				sizeof(WMT_ANT_RAM_STA_GET_EVT), WMT_ANT_RAM_STA_GET_EVT[0],
+				WMT_ANT_RAM_STA_GET_EVT[1], WMT_ANT_RAM_STA_GET_EVT[2],
+				WMT_ANT_RAM_STA_GET_EVT[3], WMT_ANT_RAM_STA_GET_EVT[4]);
+		iRet = -6;
+		return iRet;
+	}
+#endif
+	if (0 == iRet) {
+		u4AntRamStatus = antEvtBuf[sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1];
+		pWmtOp->au4OpData[2] = u4AntRamStatus;
+		WMT_INFO_FUNC("ANT ram code %s\n",
+			      1 == u4AntRamStatus ? "exist already" : "not exist");
+	}
+	return iRet;
+}
+#endif
+
+#if CFG_WMT_LTE_COEX_HANDLING
+/*TEST CODE*/
+static UINT32 g_open_wmt_lte_flag;
+VOID wmt_core_set_flag_for_test(UINT32 enable)
+{
+	WMT_INFO_FUNC("%s wmt_lte_flag\n", enable ? "enable" : "disable");
+	g_open_wmt_lte_flag = enable;
+}
+
+UINT32 wmt_core_get_flag_for_test(VOID)
+{
+	return g_open_wmt_lte_flag;
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c
new file mode 100644
index 0000000000000..fa603c208e59b
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c
@@ -0,0 +1,1019 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-CTRL]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+#include "osal.h"
+
+#include "wmt_ctrl.h"
+#include "wmt_core.h"
+#include "wmt_ic.h"
+#include "wmt_lib.h"
+#include "wmt_dev.h"
+#include "wmt_plat.h"
+#include "stp_core.h"
+#include "stp_dbg.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/* moved to wmt_ctrl.h */
+/*static INT32  wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/
+
+static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value);
+
+static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA);
+#if 0
+static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA);
+#endif
+static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData);
+static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData);
+static INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData);
+static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA);
+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData);
+#if CFG_WMT_LTE_COEX_HANDLING
+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA);
+#endif
+
+static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA);
+
+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData);
+
+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData);
+
+static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData);
+
+/* TODO: [FixMe][GeorgeKuo]: remove unused function */
+/*static INT32  wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/* GeorgeKuo: Use designated initializers described in
+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html
+ */
+static const WMT_CTRL_FUNC wmt_ctrl_func[] = {
+	[WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off,
+	[WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on,
+	[WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst,
+	[WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close,
+	[WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open,
+	[WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf,
+	[WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch,
+	[WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch,
+	[WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name,
+	[WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set,
+	[WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst,
+	[WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf,
+	[WMT_CTRL_TX] = wmt_ctrl_tx,
+	[WMT_CTRL_RX] = wmt_ctrl_rx,
+	[WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush,
+	[WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set,
+	[WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set,
+	[WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search,
+	[WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get,
+	[WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put,
+	[WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show,
+	[WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num,
+	[WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info,
+	[WMT_CTRL_SOC_PALDO_CTRL] = wmt_ctrl_soc_paldo_ctrl,
+	[WMT_CTRL_SOC_WAKEUP_CONSYS] = wmt_ctrl_soc_wakeup_consys,
+	[WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info,
+	[WMT_CTRL_BGW_DESENSE_CTRL] = wmt_ctrl_bgw_desense_ctrl,
+	[WMT_CTRL_EVT_ERR_TRG_ASSERT] = wmt_ctrl_evt_err_trg_assert,
+#if CFG_WMT_LTE_COEX_HANDLING
+	[WMT_CTRL_GET_TDM_REQ_ANTSEL] = wmt_ctrl_get_tdm_req_antsel,
+#endif
+	[WMT_CTRL_EVT_PARSER] = wmt_ctrl_evt_parser,
+	[WMT_CTRL_MAX] = wmt_ctrl_others,
+};
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	UINT32 ctrlId;
+
+	if (NULL == pWmtCtrlData) {
+		osal_assert(0);
+		return -1;
+	}
+
+	ctrlId = pWmtCtrlData->ctrlId;
+	/*1sanity check, including wmtCtrlId */
+	if ((NULL == pWmtCtrlData)
+	    || (WMT_CTRL_MAX <= ctrlId))
+		/* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */
+	{
+		osal_assert(NULL != pWmtCtrlData);
+		osal_assert(WMT_CTRL_MAX > ctrlId);
+		/* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */
+		return -2;
+	}
+	/* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */
+	if (wmt_ctrl_func[ctrlId]) {
+		/*call servicd handling API */
+		return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData);	/* serviceHandlerPack[ctrlId].serviceHandler */
+	}
+	osal_assert(NULL != wmt_ctrl_func[ctrlId]);
+	return -3;
+
+}
+
+INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */)
+{
+	UINT8 *pData = (PUINT8) pWmtCtrlData->au4CtrlData[0];
+	UINT32 size = pWmtCtrlData->au4CtrlData[1];
+	PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2];
+	MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3];
+
+	return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag);
+}
+
+INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	INT32 readLen;
+	long waitRet = -1;
+	PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0];
+	UINT32 buffLen = pWmtCtrlData->au4CtrlData[1];
+	PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2];
+
+	if (readSize)
+		*readSize = 0;
+
+	/* sanity check */
+	if (!buffLen) {
+		WMT_WARN_FUNC("buffLen = 0\n");
+		osal_assert(buffLen);
+		return 0;
+	}
+#if 0
+	if (!pDev) {
+		WMT_WARN_FUNC("gpDevWmt = NULL\n");
+		osal_assert(pDev);
+		return -1;
+	}
+#endif
+
+	if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) {
+		WMT_WARN_FUNC("state(0x%lx)\n", pDev->state);
+		osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state));
+		return -2;
+	}
+
+	/* sanity ok, proceeding rx operation */
+	/* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */
+	readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX);
+
+	while (readLen == 0) {	/* got nothing, wait for STP's signal */
+		WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n");
+		/* iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state)); */
+		/* waitRet = wait_event_interruptible_timeout(
+		* pDev->rWmtRxWq,
+		* osal_test_bit(WMT_STAT_RX, &pdev->state),
+		* msecs_to_jiffies(WMT_LIB_RX_TIMEOUT));
+		*/
+		pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT;
+		/* waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX); */
+		waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq);
+
+		WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n");
+
+		if (0 == waitRet) {
+			WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d)\n",
+				     jiffies, pDev->rWmtRxWq.timeoutValue);
+			return -1;
+		} else if (waitRet < 0) {
+			WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet);
+			return waitRet;
+		}
+		WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet);
+		/* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */
+		readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX);
+
+		if (0 == readLen)
+			WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet);
+
+	}
+
+	if (readSize)
+		*readSize = readLen;
+
+	return 0;
+
+}
+
+INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	INT32 iRet;
+
+	if (NULL != writtenSize)
+		*writtenSize = 0;
+
+	/* sanity check */
+	if (0 == size) {
+		WMT_WARN_FUNC("size to tx is 0\n");
+		osal_assert(size);
+		return -1;
+	}
+
+	/* if STP is not enabled yet, can't use this function. Use tx_raw instead */
+	if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) || !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) {
+		WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state);
+		osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state));
+		osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state));
+		return -2;
+	}
+
+	/* sanity ok, proceeding tx operation */
+	/*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */
+	mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX);
+	if (bRawFlag)
+		iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX);
+	else
+		iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX);
+
+	if (iRet != size) {
+		WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet);
+		osal_assert(iRet == size);
+	}
+
+	if (writtenSize)
+		*writtenSize = iRet;
+
+	return 0;
+
+}
+
+INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	UINT32 type = pWmtCtrlData->au4CtrlData[0];
+
+	WMT_INFO_FUNC("flush rx %d queue\n", type);
+	mtk_wcn_stp_flush_rx_queue(type);
+
+	return 0;
+}
+
+INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iret;
+
+/*psm should be disabled before wmt_ic_deinit*/
+	P_DEV_WMT pDev = &gDevWmt;
+
+	if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) {
+		WMT_DBG_FUNC("on->off\n");
+		iret = wmt_plat_pwr_ctrl(FUNC_OFF);
+	} else {
+		WMT_WARN_FUNC("already off\n");
+		iret = 0;
+	}
+
+	return iret;
+}
+
+INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iret;
+	/*psm should be enabled right after wmt_ic_init */
+	P_DEV_WMT pDev = &gDevWmt;
+	if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) {
+		WMT_WARN_FUNC("already on\n");
+		iret = 0;
+	} else {
+		WMT_DBG_FUNC("off->on\n");
+		iret = wmt_plat_pwr_ctrl(FUNC_ON);
+	}
+
+	return iret;
+}
+
+INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const UINT8 *pCmdStr)
+{
+	INT32 waitRet = -1;
+	P_OSAL_SIGNAL pCmdSignal;
+	P_OSAL_EVENT pCmdReq;
+
+	if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) {
+		WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd);
+		return -1;
+	}
+
+	/* indicate baud rate change to user space app */
+#if 0
+	INIT_COMPLETION(pWmtDev->cmd_comp);
+	pWmtDev->cmd_result = -1;
+	strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX);
+	pWmtDev->cCmd[NAME_MAX] = '\0';
+	wake_up_interruptible(&pWmtDev->cmd_wq);
+#endif
+
+	pCmdSignal = &pWmtDev->cmdResp;
+	osal_signal_init(pCmdSignal);
+	pCmdSignal->timeoutValue = 2000;
+	osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX);
+	pWmtDev->cCmd[NAME_MAX] = '\0';
+
+	pCmdReq = &pWmtDev->cmdReq;
+
+	osal_trigger_event(&pWmtDev->cmdReq);
+	WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr);
+
+/* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */
+	waitRet = osal_wait_for_signal_timeout(pCmdSignal);
+	WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet);
+	if (0 == waitRet) {
+		WMT_ERR_FUNC("wait signal timeout\n");
+		return -2;
+	}
+
+	WMT_DBG_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult);
+
+	return pWmtDev->cmdResult;
+}
+
+INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	wmt_plat_pwr_ctrl(FUNC_RST);
+	return 0;
+}
+
+INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	wmt_plat_pwr_ctrl(FUNC_STAT);
+	return 0;
+}
+
+INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	INT32 iRet = 0;
+	/* un-register to STP-core for rx */
+	iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL);	/* mtk_wcn_stp_register_event_cb */
+	if (iRet) {
+		WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet);
+		return -1;
+	}
+
+	/*un-register rxcb to btif */
+	iRet = mtk_wcn_stp_rxcb_register(NULL);
+	if (iRet) {
+		WMT_WARN_FUNC("mtk_wcn_stp_rxcb_unregister fail(%d)\n", iRet);
+		return -2;
+	}
+
+	iRet = mtk_wcn_stp_close_btif();
+	if (iRet) {
+		WMT_WARN_FUNC("mtk_wcn_stp_close_btif fail(%d)\n", iRet);
+		return -3;
+	}
+	osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state);
+
+	return 0;
+}
+
+INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	INT32 iRet;
+
+	iRet = mtk_wcn_stp_open_btif();
+	if (iRet) {
+		WMT_WARN_FUNC("mtk_wcn_stp_open_btif fail(%d)\n", iRet);
+		return -1;
+	}
+
+	/*register stp rx call back to btif */
+	iRet = mtk_wcn_stp_rxcb_register((MTK_WCN_BTIF_RX_CB) mtk_wcn_stp_parser_data);
+	if (iRet) {
+		WMT_WARN_FUNC("mtk_wcn_stp_rxcb_register fail(%d)\n", iRet);
+		return -2;
+	}
+	/* register to STP-core for rx */
+	iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb);
+	if (iRet) {
+		WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet);
+		return -3;
+	}
+
+	osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state);
+
+#if 0
+	iRet = mtk_wcn_stp_lpbk_ctrl(1);
+#endif
+
+	return 0;
+}
+
+INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	INT32 iRet;
+	UINT8 cmdStr[NAME_MAX + 1] = { 0 };
+
+	osal_snprintf(cmdStr, NAME_MAX, "srh_patch");
+	iRet = wmt_ctrl_ul_cmd(pDev, cmdStr);
+	if (iRet) {
+		WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet);
+		return -1;
+	}
+	return 0;
+}
+
+INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+
+	pWmtCtrlData->au4CtrlData[0] = pDev->patchNum;
+	return 0;
+}
+
+INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	UINT32 downLoadSeq = 0;
+	P_WMT_PATCH_INFO pPatchinfo = NULL;
+	PUINT8 pNbuf = NULL;
+	PUINT8 pAbuf = NULL;
+
+	downLoadSeq = pWmtCtrlData->au4CtrlData[0];
+	WMT_DBG_FUNC("download seq is %d\n", downLoadSeq);
+
+	pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1;
+	pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1];
+	pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2];
+	if (pPatchinfo) {
+		osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName));
+		osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess));
+		WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1], pAbuf[2], pAbuf[3]);
+	} else {
+		WMT_ERR_FUNC("NULL patchinfo pointer\n");
+	}
+
+	return 0;
+}
+
+INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = 0;
+	ENUM_PALDO_TYPE ept = pWmtCtrlData->au4CtrlData[0];
+	ENUM_PALDO_OP epo = pWmtCtrlData->au4CtrlData[1];
+
+	WMT_DBG_FUNC("ept(%d),epo(%d)\n", ept, epo);
+	iRet = wmt_plat_soc_paldo_ctrl(ept, epo);
+	if (iRet) {
+		if (PMIC_CHIPID_PALDO == ept) {
+			/* special handling for PMIC CHIPID */
+			pWmtCtrlData->au4CtrlData[2] = iRet;
+		} else {
+			/* for other PA handling */
+			WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet);
+		}
+	}
+
+	return iRet;
+}
+
+INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = 0;
+
+	iRet = mtk_wcn_stp_wakeup_consys();
+	if (iRet)
+		WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet);
+
+	return iRet;
+}
+
+INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value)
+{
+	INT32 iRet = -1;
+
+	switch (type) {
+	case WMT_STP_CONF_EN:
+		iRet = mtk_wcn_stp_enable(value);
+		break;
+
+	case WMT_STP_CONF_RDY:
+		iRet = mtk_wcn_stp_ready(value);
+		break;
+
+	case WMT_STP_CONF_MODE:
+		mtk_wcn_stp_set_mode(value);
+		iRet = 0;
+		break;
+
+	default:
+		WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value);
+		break;
+	}
+	return iRet;
+}
+
+INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = -1;
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	UINT32 type;
+	UINT32 value;
+
+	if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) {
+		WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n");
+		return -1;
+	}
+
+	type = pWmtCtrlData->au4CtrlData[0];
+	value = pWmtCtrlData->au4CtrlData[1];
+	iRet = wmt_ctrl_stp_conf_ex(type, value);
+
+	if (!iRet) {
+		if (WMT_STP_CONF_EN == type) {
+			if (value) {
+				osal_set_bit(WMT_STAT_STP_EN, &pDev->state);
+				WMT_DBG_FUNC("enable STP\n");
+			} else {
+				osal_clear_bit(WMT_STAT_STP_EN, &pDev->state);
+				WMT_DBG_FUNC("disable STP\n");
+			}
+		}
+	}
+
+	return iRet;
+}
+
+INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0];
+
+	WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch);
+	if (NULL != gDevWmt.pPatch)
+		wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch));
+
+	WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch);
+	if (patchSeq == gDevWmt.patchNum) {
+		WMT_DBG_FUNC("the %d patch has been download\n", patchSeq);
+		wmt_dev_patch_info_free();
+	}
+	return 0;
+}
+
+INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0];
+
+	osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName));
+	return 0;
+}
+
+INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch);
+	if (NULL != gDevWmt.pNvram)
+		wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram));
+
+	WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(0x%08x)\n", gDevWmt.pNvram);
+	return 0;
+}
+
+INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = 0x0;
+	PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0];
+	PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1];
+	PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2];
+
+	osal_firmware *pNvram = NULL;
+
+	if ((NULL == pFileName) || (NULL == pSize)) {
+		WMT_ERR_FUNC("parameter error, pFileName(0x%08x), pSize(0x%08x)\n", pFileName, pSize);
+		iRet = -1;
+		return iRet;
+	}
+	if (0 == wmt_dev_patch_get(pFileName, &pNvram, 0)) {
+		*ppBuf = (PUINT8) (pNvram)->data;
+		*pSize = (pNvram)->size;
+		gDevWmt.pNvram = pNvram;
+		return 0;
+	}
+	return -1;
+
+}
+
+INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	UINT8 *pFullPatchName = NULL;
+	UINT8 *pDefPatchName = NULL;
+	PUINT8 *ppBuf = (PUINT8 *) pWmtCtrlData->au4CtrlData[2];
+	PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3];
+
+	osal_firmware *pPatch = NULL;
+
+	pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1];
+	WMT_DBG_FUNC("BF get patch, pPatch(0x%08x)\n", pPatch);
+	if ((NULL != pFullPatchName)
+	    && (0 == wmt_dev_patch_get(pFullPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) {
+		/*get full name patch success */
+		WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%d)\n",
+			     pFullPatchName, (pPatch)->data, (pPatch)->size);
+		WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch);
+		*ppBuf = (PUINT8) (pPatch)->data;
+		*pSize = (pPatch)->size;
+		gDevWmt.pPatch = pPatch;
+		return 0;
+	}
+
+	pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0];
+	if ((NULL != pDefPatchName)
+	    && (0 == wmt_dev_patch_get(pDefPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) {
+		WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%d)\n",
+			     pDefPatchName, (pPatch)->data, (pPatch)->size);
+		WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch);
+		/*get full name patch success */
+		*ppBuf = (PUINT8) (pPatch)->data;
+		*pSize = (pPatch)->size;
+		gDevWmt.pPatch = pPatch;
+		return 0;
+	}
+	return -1;
+
+}
+
+/*do not need contol uart because B/G/F send/receive data by BTIF*/
+#if 0
+INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = -1;
+	char cmdStr[NAME_MAX + 1] = { 0 };
+	UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0];
+	UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1];
+
+	WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl);
+
+	if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) {
+		osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl);
+		iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr);
+		if (iRet) {
+			WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) fail(%d)\n",
+				      u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet);
+		} else {
+			WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n", u4Baudrate, u4FlowCtrl);
+		}
+	} else {
+		WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n");
+	}
+	return iRet;
+}
+#endif
+/*do not need control SDIO because wifi send/receive data by sdio*/
+#if 0
+INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = 0;
+	UINT32 statBit = WMT_STAT_SDIO1_ON;
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+
+	WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0];
+	ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1];
+
+	if ((WMT_SDIO_SLOT_INVALID == sdioSlotNum)
+	    || (WMT_SDIO_SLOT_MAX <= sdioSlotNum)) {
+		WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum);
+		return -1;
+	}
+
+	WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState);
+
+	if (WMT_SDIO_SLOT_SDIO2 == sdioSlotNum)
+		statBit = WMT_STAT_SDIO2_ON;
+
+	if (funcState) {
+		if (osal_test_and_set_bit(statBit, &pDev->state)) {
+			WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum);
+			/* still return 0 */
+			iRet = 0;
+		} else {
+			iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON);
+		}
+	} else {
+		if (osal_test_and_clear_bit(statBit, &pDev->state)) {
+			iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF);
+		} else {
+			WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum);
+			/* still return 0 */
+			iRet = 0;
+		}
+	}
+
+	return iRet;
+}
+
+INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = -1;
+	UINT32 statBit = WMT_STAT_SDIO_WIFI_ON;
+	INT32 retry = 10;
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+	WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0];
+	UINT32 u4On = pWmtCtrlData->au4CtrlData[1];
+
+	if (WMT_SDIO_FUNC_MAX <= sdioFuncType) {
+		WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType);
+		return -1;
+	}
+
+	if (WMT_SDIO_FUNC_STP == sdioFuncType)
+		statBit = WMT_STAT_SDIO_STP_ON;
+
+	if (u4On) {
+		if (osal_test_bit(statBit, &pDev->state)) {
+			WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType);
+			iRet = 0;
+		} else {
+			while (retry-- > 0 && iRet != 0) {
+				if (iRet) {
+					/* sleep 150ms before sdio slot ON ready */
+					osal_sleep_ms(150);
+				}
+				iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE);
+				if (HIF_SDIO_ERR_NOT_PROBED == iRet) {
+					/* not probed case, retry */
+					continue;
+				} else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet) {
+					/* For WiFi, client not reg yet, no need to retry,
+					*WiFi function can work any time when wlan.ko
+					*is insert into system
+					*/
+					iRet = 0;
+				} else {
+					/* other fail cases, stop */
+					break;
+				}
+			}
+			if (!retry || iRet) {
+				WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n",
+					     sdioFuncType, iRet, retry);
+			} else {
+				osal_set_bit(statBit, &pDev->state);
+			}
+		}
+	} else {
+		if (osal_test_bit(statBit, &pDev->state)) {
+			iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE);
+			if (iRet)
+				WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", sdioFuncType, iRet);
+			/*any way, set to OFF state */
+			osal_clear_bit(statBit, &pDev->state);
+		} else {
+			WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType);
+			iRet = 0;
+		}
+	}
+
+	return iRet;
+}
+#endif
+
+
+INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+
+	/* input sanity check is done in wmt_ctrl() */
+	pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16;
+	pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF;
+	pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF;
+
+	/* TODO: [FixMe][GeorgeKuo] remove translated ENUM_WMTHWVER_TYPE_T in the future!!! */
+	/* Only use hw_ver read from hw. */
+	pDev->eWmtHwVer = (ENUM_WMTHWVER_TYPE_T) (pWmtCtrlData->au4CtrlData[1] & 0xFFFF0000) >> 16;
+
+	return 0;
+}
+
+INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	UINT8 *pRomVer = NULL;
+	P_WMT_PATCH pPatch = NULL;
+	UINT32 chipID = 0;
+
+	chipID = pWmtCtrlData->au4CtrlData[0];
+	pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]);
+	pPatch = (P_WMT_PATCH) (pWmtCtrlData->au4CtrlData[2]);
+	if (!pRomVer) {
+		WMT_ERR_FUNC("pRomVer null pointer\n");
+		return -1;
+	}
+	if (!pPatch) {
+		WMT_ERR_FUNC("pPatch null pointer\n");
+		return -2;
+	}
+	WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer, pPatch->ucDateTime,
+		     pPatch->ucPLat);
+	return stp_dbg_set_version_info(chipID, pRomVer, &(pPatch->ucDateTime[0]), &(pPatch->ucPLat[0]));
+}
+
+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	UINT32 cmd = pWmtCtrlData->au4CtrlData[0];
+
+	WMT_INFO_FUNC("wmt-ctrl:send native cmd(%d)\n", cmd);
+	wmt_dev_send_cmd_to_daemon(cmd);
+
+	return 0;
+}
+
+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 iRet = -1;
+
+	ENUM_WMTDRV_TYPE_T drv_type;
+	UINT32 reason = 0;
+
+	drv_type = pWmtCtrlData->au4CtrlData[0];
+	reason = pWmtCtrlData->au4CtrlData[1];
+	WMT_WARN_FUNC("wmt-ctrl:drv_type(%d),reason(%d)\n", drv_type, reason);
+
+	if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) {
+		mtk_wcn_stp_set_wmt_evt_err_trg_assert(1);
+		wmt_lib_set_host_assert_info(drv_type, reason, 1);
+
+		iRet = mtk_wcn_stp_wmt_evt_err_trg_assert();
+		if (iRet)
+			mtk_wcn_stp_set_wmt_evt_err_trg_assert(0);
+	} else {
+		/* maybe assert triggered by stp noack*/
+		WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n");
+	}
+	return 0;
+}
+
+#if CFG_WMT_LTE_COEX_HANDLING
+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 antsel_index = wmt_plat_get_tdm_antsel_index();
+
+	if (0 <= antsel_index)
+		pWmtCtrlData->au4CtrlData[0] = antsel_index;
+	else
+		pWmtCtrlData->au4CtrlData[0] = 0xff;
+
+	WMT_INFO_FUNC("get tdm req antsel index is %d\n", antsel_index);
+
+	return 0;
+}
+#endif
+
+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	INT32 ret = -1;
+	UINT32 evt_idx = (UINT32) pWmtCtrlData->au4CtrlData[0];
+	UINT8 *p_buf = NULL;
+
+	static UINT8 sleep_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 };
+	static UINT8 wakeup_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 };
+	static UINT8 hostawake_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 };
+	static UINT8 *evt_array[] = { sleep_evt, wakeup_evt, hostawake_evt };
+
+	p_buf = evt_array[evt_idx - 1];
+
+	WMT_INFO_FUNC("evt index:%d,p_buf:%p\n", evt_idx, p_buf);
+
+	ret = mtk_wcn_consys_stp_btif_parser_wmt_evt(p_buf, 6);
+	if (ret == 1) {
+		WMT_INFO_FUNC("parser wmt evt from BTIF buf is OK\n");
+		return 0;
+	}
+	WMT_ERR_FUNC("parser wmt evt from BTIF buf fail(%d)\n", ret);
+	return -1;
+}
+
+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData)
+{
+	INT32 iret;
+
+	WMT_INFO_FUNC("ctrl GPS_SYNC(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX);
+	iret = wmt_plat_gpio_ctrl(PIN_GPS_SYNC, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX);
+
+	if (iret) {
+		WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n",
+			      (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX, iret);
+	}
+
+	return 0;
+}
+
+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData)
+{
+	INT32 iret;
+
+	WMT_INFO_FUNC("ctrl GPS_LNA(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H);
+	iret = wmt_plat_gpio_ctrl(PIN_GPS_LNA, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H);
+
+	if (iret) {
+		WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n",
+			      (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret);
+	}
+
+	return 0;
+}
+
+INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	return 0;
+}
+
+INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	P_DEV_WMT pDev = &gDevWmt;	/* single instance */
+
+	pWmtCtrlData->au4CtrlData[0] = (SIZE_T) &pDev->rWmtGenConf;
+
+	return 0;
+}
+
+INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData)
+{
+	WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId);
+	return -1;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c
new file mode 100644
index 0000000000000..d42d572c92922
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c
@@ -0,0 +1,713 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-FUNC]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+
+#include "wmt_func.h"
+#include "wmt_lib.h"
+#include "wmt_core.h"
+#include "wmt_exp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+#if CFG_FUNC_BT_SUPPORT
+
+static INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+static INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+
+WMT_FUNC_OPS wmt_func_bt_ops = {
+	/* BT subsystem function on/off */
+	.func_on = wmt_func_bt_on,
+	.func_off = wmt_func_bt_off
+};
+#endif
+
+#if CFG_FUNC_FM_SUPPORT
+
+static INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+static INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+
+WMT_FUNC_OPS wmt_func_fm_ops = {
+	/* FM subsystem function on/off */
+	.func_on = wmt_func_fm_on,
+	.func_off = wmt_func_fm_off
+};
+#endif
+
+#if CFG_FUNC_GPS_SUPPORT
+
+static INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+static INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+
+WMT_FUNC_OPS wmt_func_gps_ops = {
+	/* GPS subsystem function on/off */
+	.func_on = wmt_func_gps_on,
+	.func_off = wmt_func_gps_off
+};
+
+#endif
+
+#if CFG_FUNC_WIFI_SUPPORT
+static INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+static INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf);
+
+WMT_FUNC_OPS wmt_func_wifi_ops = {
+	/* Wi-Fi subsystem function on/off */
+	.func_on = wmt_func_wifi_on,
+	.func_off = wmt_func_wifi_off
+};
+#endif
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if CFG_FUNC_GPS_SUPPORT
+CMB_PIN_CTRL_REG eediPinOhRegs[] = {
+	{
+	 /* pull down ctrl register */
+	 .regAddr = 0x80050020,
+	 .regValue = ~(0x1 << 5),
+	 .regMask = 0x00000020,
+	 },
+	{
+	 /* pull up ctrl register */
+	 .regAddr = 0x80050000,
+	 .regValue = 0x1 << 5,
+	 .regMask = 0x00000020,
+	 },
+	{
+	 /* iomode ctrl register */
+	 .regAddr = 0x80050110,
+	 .regValue = 0x1 << 0,
+	 .regMask = 0x00000007,
+	 },
+	{
+	 /* output high/low ctrl register */
+	 .regAddr = 0x80050040,
+	 .regValue = 0x1 << 5,
+	 .regMask = 0x00000020,
+	 }
+
+};
+
+CMB_PIN_CTRL_REG eediPinOlRegs[] = {
+	{
+	 .regAddr = 0x80050020,
+	 .regValue = 0x1 << 5,
+	 .regMask = 0x00000020UL,
+	 },
+	{
+	 .regAddr = 0x80050000,
+	 .regValue = ~(0x1 << 5),
+	 .regMask = 0x00000020,
+	 },
+	{
+	 .regAddr = 0x80050110,
+	 .regValue = 0x1 << 0,
+	 .regMask = 0x00000007,
+	 },
+	{
+	 .regAddr = 0x80050040,
+	 .regValue = ~(0x1 << 5),
+	 .regMask = 0x00000020,
+	 }
+};
+
+CMB_PIN_CTRL_REG eedoPinOhRegs[] = {
+	{
+	 .regAddr = 0x80050020,
+	 .regValue = ~(0x1 << 7),
+	 .regMask = 0x00000080UL,
+	 },
+	{
+	 .regAddr = 0x80050000,
+	 .regValue = 0x1 << 7,
+	 .regMask = 0x00000080UL,
+	 },
+	{
+	 .regAddr = 0x80050110,
+	 .regValue = 0x1 << 12,
+	 .regMask = 0x00007000UL,
+	 },
+	{
+	 .regAddr = 0x80050040,
+	 .regValue = 0x1 << 7,
+	 .regMask = 0x00000080,
+	 }
+};
+
+CMB_PIN_CTRL_REG eedoPinOlRegs[] = {
+	{
+	 .regAddr = 0x80050020,
+	 .regValue = 0x1 << 7,
+	 .regMask = 0x00000080,
+	 },
+	{
+	 .regAddr = 0x80050000,
+	 .regValue = ~(0x1 << 7),
+	 .regMask = 0x00000080,
+	 },
+	{
+	 .regAddr = 0x80050110,
+	 .regValue = 0x1 << 12,
+	 .regMask = 0x00007000,
+	 },
+	{
+	 .regAddr = 0x80050040,
+	 .regValue = ~(0x1 << 7),
+	 .regMask = 0x00000080,
+	 }
+
+};
+
+CMB_PIN_CTRL_REG gsyncPinOnRegs[] = {
+	{
+	 .regAddr = 0x80050110,
+	 .regValue = 0x3 << 20,
+	 .regMask = 0x7 << 20,
+	 }
+
+};
+
+CMB_PIN_CTRL_REG gsyncPinOffRegs[] = {
+	{
+	 .regAddr = 0x80050110,
+	 .regValue = 0x0 << 20,
+	 .regMask = 0x7 << 20,
+	 }
+};
+
+/* templete usage for GPIO control */
+CMB_PIN_CTRL gCmbPinCtrl[3] = {
+	{
+	 .pinId = CMB_PIN_EEDI_ID,
+	 .regNum = 4,
+	 .pFuncOnArray = eediPinOhRegs,
+	 .pFuncOffArray = eediPinOlRegs,
+	 },
+	{
+	 .pinId = CMB_PIN_EEDO_ID,
+	 .regNum = 4,
+	 .pFuncOnArray = eedoPinOhRegs,
+	 .pFuncOffArray = eedoPinOlRegs,
+	 },
+	{
+	 .pinId = CMB_PIN_GSYNC_ID,
+	 .regNum = 1,
+	 .pFuncOnArray = gsyncPinOnRegs,
+	 .pFuncOffArray = gsyncPinOffRegs,
+	 }
+};
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#if CFG_FUNC_BT_SUPPORT
+
+INT32 _osal_inline_ wmt_func_bt_ctrl(ENUM_FUNC_STATE funcState)
+{
+	/*only need to send turn BT subsystem wmt command */
+	return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE);
+}
+
+INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	/* return wmt_func_bt_ctrl(FUNC_ON); */
+	INT32 iRet = -1;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+
+	ctrlPa1 = BT_PALDO;
+	ctrlPa2 = PALDO_ON;
+	iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2);
+		return -1;
+	}
+	iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE);
+	if (iRet) {
+		WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_on) failed(%d)\n", iRet);
+		ctrlPa1 = BT_PALDO;
+		ctrlPa2 = PALDO_OFF;
+		wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+
+		/*do coredump when bt on fail */
+		wmt_core_set_coredump_state(DRV_STS_FUNC_ON);
+		ctrlPa1 = WMTDRV_TYPE_BT;
+		ctrlPa2 = 32;
+		wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2);
+		return -2;
+	}
+	osal_set_bit(WMT_BT_ON, &gBtWifiGpsState);
+	if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) {
+		/* send msg to GPS native for sending de-sense CMD */
+		ctrlPa1 = 1;
+		ctrlPa2 = 0;
+		wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2);
+	}
+		return 0;
+}
+
+INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	/* return wmt_func_bt_ctrl(FUNC_OFF); */
+	INT32 iRet1 = -1;
+	INT32 iRet2 = -1;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+
+	iRet1 = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE);
+	if (iRet1)
+		WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_off) failed(%d)\n", iRet1);
+
+	ctrlPa1 = BT_PALDO;
+	ctrlPa2 = PALDO_OFF;
+	iRet2 = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+	if (iRet2)
+		WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl(bt_off) failed(%d)\n", iRet2);
+
+	if (iRet1 + iRet2) {
+		/*do coredump when bt off fail */
+		wmt_core_set_coredump_state(DRV_STS_FUNC_ON);
+		ctrlPa1 = WMTDRV_TYPE_BT;
+		ctrlPa2 = 32;
+		wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2);
+		return -1;
+	}
+
+	osal_clear_bit(WMT_BT_ON, &gBtWifiGpsState);
+	if ((!osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) {
+		/* send msg to GPS native for stopping send de-sense CMD */
+		ctrlPa1 = 0;
+		ctrlPa2 = 0;
+		wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2);
+	}
+	return 0;
+}
+
+#endif
+
+#if CFG_FUNC_GPS_SUPPORT
+
+INT32 _osal_inline_ wmt_func_gps_ctrl(ENUM_FUNC_STATE funcState)
+{
+	/*send turn GPS subsystem wmt command */
+	return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_GPS, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE);
+}
+
+INT32 wmt_func_gps_pre_ctrl(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf, ENUM_FUNC_STATE funcStatus)
+{
+	UINT32 i = 0;
+	INT32 iRet = 0;
+	UINT32 regAddr = 0;
+	UINT32 regValue = 0;
+	UINT32 regMask = 0;
+	UINT32 regNum = 0;
+	P_CMB_PIN_CTRL_REG pReg;
+	P_CMB_PIN_CTRL pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID];
+	WMT_CTRL_DATA ctrlData;
+	WMT_IC_PIN_ID wmtIcPinId = WMT_IC_PIN_MAX;
+	/* sanity check */
+	if (FUNC_ON != funcStatus && FUNC_OFF != funcStatus) {
+		WMT_ERR_FUNC("invalid funcStatus(%d)\n", funcStatus);
+		return -1;
+	}
+	/* turn on GPS sync function on both side */
+	ctrlData.ctrlId = WMT_CTRL_GPS_SYNC_SET;
+	ctrlData.au4CtrlData[0] = (FUNC_ON == funcStatus) ? 1 : 0;
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		/*we suppose this would never print */
+		WMT_ERR_FUNC("ctrl GPS_SYNC_SET(%d) fail, ret(%d)\n", funcStatus, iRet);
+		/* TODO:[FixMe][George] error handling? */
+		return -2;
+	}
+	WMT_INFO_FUNC("ctrl GPS_SYNC_SET(%d) ok\n", funcStatus);
+
+
+	if ((NULL == pOps->ic_pin_ctrl) ||
+		(0 > pOps->ic_pin_ctrl(
+				WMT_IC_PIN_GSYNC,
+				FUNC_ON == funcStatus ? WMT_IC_PIN_MUX : WMT_IC_PIN_GPIO,
+				1))) {	/*WMT_IC_PIN_GSYNC */
+		pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID];
+		regNum = pCmbPinCtrl->regNum;
+		for (i = 0; i < regNum; i++) {
+			if (FUNC_ON == funcStatus)
+				pReg = &pCmbPinCtrl->pFuncOnArray[i];
+			else
+				pReg = &pCmbPinCtrl->pFuncOffArray[i];
+
+			regAddr = pReg->regAddr;
+			regValue = pReg->regValue;
+			regMask = pReg->regMask;
+
+			iRet = wmt_core_reg_rw_raw(1, regAddr, &regValue, regMask);
+			if (iRet) {
+				WMT_ERR_FUNC("set reg for GPS_SYNC function fail(%d)\n", iRet);
+				/* TODO:[FixMe][Chaozhong] error handling? */
+				return -2;
+			}
+
+		}
+	} else {
+		WMT_INFO_FUNC("set reg for GPS_SYNC function okay by chip ic_pin_ctrl\n");
+	}
+	WMT_INFO_FUNC("ctrl combo chip gps sync function succeed\n");
+	/* turn on GPS lna ctrl function */
+	if (NULL != pConf) {
+		if (0 == pConf->wmt_gps_lna_enable) {
+
+			WMT_INFO_FUNC("host pin used for gps lna\n");
+			/* host LNA ctrl pin needed */
+			ctrlData.ctrlId = WMT_CTRL_GPS_LNA_SET;
+			ctrlData.au4CtrlData[0] = FUNC_ON == funcStatus ? 1 : 0;
+			iRet = wmt_ctrl(&ctrlData);
+			if (iRet) {
+				/*we suppose this would never print */
+				WMT_ERR_FUNC("ctrl host GPS_LNA output high fail, ret(%d)\n", iRet);
+				/* TODO:[FixMe][Chaozhong] error handling? */
+				return -3;
+			}
+			WMT_INFO_FUNC("ctrl host gps lna function succeed\n");
+		} else {
+			WMT_INFO_FUNC("combo chip pin(%s) used for gps lna\n",
+				      0 == pConf->wmt_gps_lna_pin ? "EEDI" : "EEDO");
+			wmtIcPinId = 0 == pConf->wmt_gps_lna_pin ? WMT_IC_PIN_EEDI : WMT_IC_PIN_EEDO;
+			if ((NULL == pOps->ic_pin_ctrl) ||
+				(0 > pOps->ic_pin_ctrl(
+					wmtIcPinId,
+					FUNC_ON == funcStatus ? WMT_IC_PIN_GPIO_HIGH : WMT_IC_PIN_GPIO_LOW,
+					1))) {	/*WMT_IC_PIN_GSYNC */
+				if (0 == pConf->wmt_gps_lna_pin) {
+					/* EEDI needed */
+					pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDI_ID];
+				} else if (1 == pConf->wmt_gps_lna_pin) {
+					/* EEDO needed */
+					pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDO_ID];
+				}
+				regNum = pCmbPinCtrl->regNum;
+				for (i = 0; i < regNum; i++) {
+					if (FUNC_ON == funcStatus)
+						pReg = &pCmbPinCtrl->pFuncOnArray[i];
+					else
+						pReg = &pCmbPinCtrl->pFuncOffArray[i];
+					regAddr = pReg->regAddr;
+					regValue = pReg->regValue;
+					regMask = pReg->regMask;
+
+					iRet = wmt_core_reg_rw_raw(1, regAddr, &regValue, regMask);
+					if (iRet) {
+						WMT_ERR_FUNC("set reg for GPS_LNA function fail(%d)\n", iRet);
+						/* TODO:[FixMe][Chaozhong] error handling? */
+						return -3;
+					}
+				}
+				WMT_INFO_FUNC("ctrl combo chip gps lna succeed\n");
+			} else {
+				WMT_INFO_FUNC("set reg for GPS_LNA function okay by chip ic_pin_ctrl\n");
+			}
+		}
+	}
+	return 0;
+
+}
+
+INT32 wmt_func_gps_pre_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_ON);
+}
+
+INT32 wmt_func_gps_pre_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+
+	return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_OFF);
+}
+
+INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	INT32 iRet = 0;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+	UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f);
+
+	if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) {	/* use SOC external LNA */
+		if (!osal_test_bit(WMT_FM_ON, &gGpsFmState)) {
+			ctrlPa1 = GPS_PALDO;
+			ctrlPa2 = PALDO_ON;
+			wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+		} else {
+			WMT_INFO_FUNC("LDO VCN28 has been turn on by FM\n");
+		}
+	}
+
+	iRet = wmt_func_gps_pre_on(pOps, pConf);
+	if (0 == iRet) {
+		iRet = wmt_func_gps_ctrl(FUNC_ON);
+		if (!iRet) {
+			osal_set_bit(WMT_GPS_ON, &gBtWifiGpsState);
+			if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState))
+			    || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) {
+				/* send msg to GPS native for sending de-sense CMD */
+				ctrlPa1 = 1;
+				ctrlPa2 = 0;
+				wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2);
+			}
+
+			if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable))	/* use SOC external LNA */
+				osal_set_bit(WMT_GPS_ON, &gGpsFmState);
+		}
+	}
+	return iRet;
+}
+
+INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	INT32 iRet = 0;
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+	UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f);
+
+	iRet = wmt_func_gps_pre_off(pOps, pConf);
+	if (0 == iRet) {
+		iRet = wmt_func_gps_ctrl(FUNC_OFF);
+		if (!iRet) {
+			osal_clear_bit(WMT_GPS_ON, &gBtWifiGpsState);
+			if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState))
+			    || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) {
+				/* send msg to GPS native for stop sending de-sense CMD */
+				ctrlPa1 = 0;
+				ctrlPa2 = 0;
+				wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2);
+			}
+		}
+	}
+
+	if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) {	/* use SOC external LNA */
+		if (osal_test_bit(WMT_FM_ON, &gGpsFmState))
+			WMT_INFO_FUNC("FM is still on, do not turn off LDO VCN28\n");
+		else {
+			ctrlPa1 = GPS_PALDO;
+			ctrlPa2 = PALDO_OFF;
+			wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+		}
+
+		osal_clear_bit(WMT_GPS_ON, &gGpsFmState);
+	}
+
+	return iRet;
+
+}
+#endif
+
+#if CFG_FUNC_FM_SUPPORT
+
+INT32 _osal_inline_ wmt_func_fm_ctrl(ENUM_FUNC_STATE funcState)
+{
+	/*only need to send turn FM subsystem wmt command */
+	return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE);
+}
+
+INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	/* return wmt_func_fm_ctrl(FUNC_ON); */
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+	INT32 iRet = -1;
+	UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f);
+
+	if (co_clock_type) {
+		if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState)) {
+			ctrlPa1 = FM_PALDO;
+			ctrlPa2 = PALDO_ON;
+			wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+		} else {
+			WMT_INFO_FUNC("LDO VCN28 has been turn on by GPS\n");
+		}
+	}
+
+	iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE);
+	if (!iRet) {
+		if (co_clock_type)
+			osal_set_bit(WMT_FM_ON, &gGpsFmState);
+	}
+
+	return iRet;
+}
+
+INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	/* return wmt_func_fm_ctrl(FUNC_OFF); */
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+	INT32 iRet = -1;
+	UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f);
+
+	iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE);
+
+	if (co_clock_type) {
+		if (osal_test_bit(WMT_GPS_ON, &gGpsFmState)) {
+			WMT_INFO_FUNC("GPS is still on, do not turn off LDO VCN28\n");
+		} else {
+			ctrlPa1 = FM_PALDO;
+			ctrlPa2 = PALDO_OFF;
+			wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+		}
+
+		osal_clear_bit(WMT_FM_ON, &gGpsFmState);
+	}
+
+	return iRet;
+}
+
+#endif
+
+#if CFG_FUNC_WIFI_SUPPORT
+
+/*in soc, wmt turn on wifi directly, no not need operate SDIO*/
+#if 0
+INT32 wmt_func_wifi_ctrl(ENUM_FUNC_STATE funcState)
+{
+	INT32 iRet = 0;
+	unsigned long ctrlPa1 = WMT_SDIO_FUNC_WIFI;
+	unsigned long ctrlPa2 = (FUNC_ON == funcState) ? 1 : 0;	/* turn on Wi-Fi driver */
+
+	iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2);
+	if (iRet) {
+		WMT_ERR_FUNC("WMT-FUNC: turn on WIFI function fail (%d)", iRet);
+		return -1;
+	}
+	return 0;
+}
+#endif
+
+INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	int iRet = 0;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+
+	if (NULL != mtk_wcn_wlan_probe) {
+
+		WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan probe\n");
+		iRet = (*mtk_wcn_wlan_probe) ();
+		if (iRet) {
+			WMT_ERR_FUNC("WMT-FUNC: wmt call wlan probe fail(%d)\n", iRet);
+			iRet = -1;
+		} else {
+			WMT_WARN_FUNC("WMT-FUNC: wmt call wlan probe ok\n");
+		}
+	} else {
+		WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_probe\n");
+		gWifiProbed = 1;
+		iRet = -2;
+	}
+
+	if (!iRet) {
+		osal_set_bit(WMT_WIFI_ON, &gBtWifiGpsState);
+		if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) {
+			/* send msg to GPS native for sending de-sense CMD */
+			ctrlPa1 = 1;
+			ctrlPa2 = 0;
+			wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2);
+		}
+	}
+	return iRet;
+#if 0
+	return wmt_func_wifi_ctrl(FUNC_ON);
+#endif
+}
+
+INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf)
+{
+	int iRet = 0;
+
+	unsigned long ctrlPa1 = 0;
+	unsigned long ctrlPa2 = 0;
+
+	if (NULL != mtk_wcn_wlan_remove) {
+
+		WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan remove\n");
+		iRet = (*mtk_wcn_wlan_remove) ();
+		if (iRet) {
+			WMT_ERR_FUNC("WMT-FUNC: wmt call wlan remove fail(%d)\n", iRet);
+			iRet = -1;
+		} else {
+			WMT_WARN_FUNC("WMT-FUNC: wmt call wlan remove ok\n");
+		}
+	} else {
+		WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_remove\n");
+		iRet = -2;
+	}
+
+	if (!iRet) {
+		osal_clear_bit(WMT_WIFI_ON, &gBtWifiGpsState);
+		if ((!osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) {
+			/* send msg to GPS native for stopping send de-sense CMD */
+			ctrlPa1 = 0;
+			ctrlPa2 = 0;
+			wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2);
+		}
+	}
+	return iRet;
+#if 0
+	return wmt_func_wifi_ctrl(FUNC_OFF);
+#endif
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c
new file mode 100644
index 0000000000000..c07052bce8e6d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c
@@ -0,0 +1,2452 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-IC]"
+#define CFG_IC_SOC 1
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+#include "wmt_ic.h"
+#include "wmt_core.h"
+#include "wmt_lib.h"
+#include "stp_core.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define DEFAULT_PATCH_FRAG_SIZE (1000)
+#define WMT_PATCH_FRAG_1ST (0x1)
+#define WMT_PATCH_FRAG_MID (0x2)
+#define WMT_PATCH_FRAG_LAST (0x3)
+
+#define CFG_CHECK_WMT_RESULT (1)
+/* BT Port 2 Feature. this command does not need
+ *  after coex command is downconfirmed by LC,
+ */
+#define CFG_WMT_BT_PORT2 (0)
+
+#define CFG_SET_OPT_REG (0)
+#define CFG_WMT_I2S_DBGUART_SUPPORT (0)
+#define CFG_SET_OPT_REG_SWLA (0)
+#define CFG_SET_OPT_REG_MCUCLK (0)
+#define CFG_SET_OPT_REG_MCUIRQ (0)
+
+#define CFG_SUBSYS_COEX_NEED 0
+
+#define CFG_WMT_COREDUMP_ENABLE 0
+
+#define CFG_WMT_MULTI_PATCH (1)
+
+#define CFG_WMT_CRYSTAL_TIMING_SET (0)
+
+#define CFG_WMT_SDIO_DRIVING_SET (0)
+
+#define CFG_WMT_UART_HIF_USE (0)
+
+#define CFG_WMT_WIFI_5G_SUPPORT (1)
+
+#define CFG_WMT_PATCH_DL_OPTM (1)
+#if CFG_WMT_LTE_COEX_HANDLING
+#define CFG_WMT_FILTER_MODE_SETTING (1)
+#else
+#define CFG_WMT_FILTER_MODE_SETTING (0)
+#endif
+#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT (0)
+
+#define CFG_WMT_POWER_ON_DLM  (1)
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+static UINT8 gFullPatchName[NAME_MAX + 1];
+static const WMT_IC_INFO_S *gp_soc_info;
+static WMT_PATCH gp_soc_patch_info;
+static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS;
+#if 0
+static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 };
+static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 };
+
+static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 };
+static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 };
+#endif
+
+#if CFG_WMT_UART_HIF_USE
+static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 };
+static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 };
+static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB };
+static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB };
+static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 };
+static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF };
+static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 };
+#endif
+static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 };
+static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 };
+static UINT8 WMT_QUERY_STP_EVT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 };
+static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 };
+static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 };
+static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 };
+static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 };
+
+#if CFG_WMT_BT_PORT2
+static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 };
+static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+#endif
+
+/*soc patial patch address cmd & evt need firmware owner provide*/
+#if CFG_WMT_MULTI_PATCH
+static UINT8 WMT_PATCH_ADDRESS_CMD[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x3c, 0x02, 0x09, 0x02,
+		0x00, 0x00, 0x00, 0x00,
+		0xff, 0xff, 0xff, 0xff
+};
+static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+
+static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0xc4, 0x04, 0x09, 0x02,
+		0x00, 0x3f, 0x00, 0x01,
+		0xff, 0xff, 0xff, 0xff
+};
+static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+#endif
+
+/*coex cmd/evt++*/
+static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 };
+static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+
+#if CFG_SUBSYS_COEX_NEED
+static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B,
+	0x00, 0x02,
+	0x00, 0x00, 0x00, 0x00,
+	0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA
+};
+static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+
+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C,
+	0x00, 0x03,
+	0x00, 0x00, 0x00, 0x00, 0x00,
+	0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA
+};
+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+
+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A,
+	0x00, 0x04,
+	0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE
+};
+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+
+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09,
+	0x00, 0x05,
+	0xAA, 0xAA, 0xAA, 0xAA,
+	0xBB, 0xBB, 0xBB, 0xBB
+};
+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+#endif
+
+/*coex cmd/evt--*/
+static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 };
+static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 };
+static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 };
+static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 };
+
+#if 0
+static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 };
+static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 };
+#endif
+
+#if 0
+/* to enable dump feature */
+static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 };
+static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 };
+
+/* to get system stack dump when f/w assert */
+static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 };
+
+/* to get task and system stack dump when f/w assert */
+static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 };
+
+/* to get bt related memory dump when f/w assert */
+static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A };
+static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 };
+#endif
+/* to get full dump when f/w assert */
+static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 };
+
+static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 };
+static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 };
+
+static UINT8 WMT_CORE_START_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x1, 0x00, 0x01 };
+static UINT8 WMT_CORE_START_RF_CALIBRATION_EVT[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x01 };
+
+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT)
+static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+	    , 0x78, 0x00, 0x05, 0x80	/*addr:0x80050078 */
+	    , 0x00, 0x00, 0x11, 0x01	/*value:0x11010000 */
+	    , 0x00, 0x00, 0x77, 0x07	/*mask:0x07770000 */
+};
+
+static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+};
+
+static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+	    , 0x74, 0x00, 0x05, 0x80	/*addr:0x80050074 */
+	    , 0x44, 0x44, 0x00, 0x00	/*value:0x11010000 */
+	    , 0x77, 0x77, 0x00, 0x00	/*mask:0x07770000 */
+};
+
+static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+};
+
+static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+	    , 0xA0, 0x00, 0x05, 0x80	/*addr:0x80050074 */
+	    , 0x04, 0x00, 0x00, 0x00	/*value:0x11010000 */
+	    , 0x04, 0x00, 0x00, 0x00	/*mask:0x07770000 */
+};
+
+static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+};
+#endif
+
+#if !(CFG_IC_SOC)		/* For MT6628 no need to set ALLEINT registers, done in f/w */
+/* enable all interrupt */
+static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+	    , 0x00, 0x03, 0x05, 0x80	/*addr:0x80050300 */
+	    , 0x00, 0xC4, 0x00, 0x00	/*value:0x0000C400 */
+	    , 0x00, 0xC4, 0x00, 0x00	/*mask:0x0000C400 */
+};
+
+static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+};
+
+#endif
+
+#if CFG_SET_OPT_REG_SWLA	/* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25)  */
+static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x02		/*2 registers */
+	    , 0x10, 0x01, 0x05, 0x80	/*addr:0x80050110 */
+	    , 0x10, 0x10, 0x01, 0x00	/*value:0x00011010 */
+	    , 0xF0, 0xF0, 0x0F, 0x00	/*mask:0x000FF0F0 */
+	    , 0x40, 0x01, 0x05, 0x80	/*addr:0x80050140 */
+	    , 0x00, 0x10, 0x01, 0x00	/*value:0x00011000 */
+	    , 0x00, 0xF0, 0x0F, 0x00	/*mask:0x000FF000 */
+};
+
+static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x02		/*2 registers */
+};
+#endif
+
+#if CFG_SET_OPT_REG_MCUCLK	/* enable mcu clk: antsel_4, eedi */
+static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/* type: reg */
+	    , 0x00		/* rev */
+	    , 0x04		/* 4 registers */
+	    , 0x00, 0x04, 0x00, 0x80	/* addr:0x8000 0400 */
+	    , 0x00, 0x14, 0x00, 0x00	/* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */
+	    , 0xFF, 0xFF, 0x00, 0x00	/* mask:0x0000 FFFF */
+	    , 0x80, 0x01, 0x05, 0x80	/* addr:0x8005 0180 */
+	    , 0x12, 0x13, 0x00, 0x00	/* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */
+	    , 0xFF, 0xFF, 0x00, 0x00	/* mask:0x0000 FFFF */
+	    , 0x00, 0x01, 0x05, 0x80	/* addr:0x8005 0100 */
+	    , 0x00, 0x00, 0x02, 0x00	/* value:0x0002 0000 */
+	    , 0x00, 0x00, 0x0F, 0x00	/* mask:0x000F 0000 */
+	    , 0x10, 0x01, 0x05, 0x80	/* addr:0x8005 0110 */
+	    , 0x02, 0x00, 0x00, 0x00	/* value:0x0000 0002 */
+	    , 0x0F, 0x00, 0x00, 0x00	/* mask:0x0000 000F */
+};
+
+static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/* S: 0 */
+	    , 0x00		/* type: reg */
+	    , 0x00		/* rev */
+	    , 0x04		/* 4 registers */
+};
+#endif
+
+#if CFG_WMT_I2S_DBGUART_SUPPORT	/* register write for debug uart */
+static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x02		/*2 registers */
+	    , 0x30, 0x01, 0x05, 0x80	/*addr:0x80050130 */
+	    , 0x00, 0x00, 0x00, 0x00	/*value:0x00000000 */
+	    , 0xF0, 0x0F, 0x00, 0x00	/*mask:0x00000FF0 */
+	    , 0x40, 0x01, 0x05, 0x80	/*addr:0x80050140 */
+	    , 0x00, 0x01, 0x00, 0x00	/*value:0x00000100 */
+	    , 0x00, 0x01, 0x00, 0x00	/*mask:0x00000100 */
+};
+
+static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x02		/*2 registers */
+};
+#endif
+
+#if CFG_SET_OPT_REG_MCUIRQ	/* enable mcu irq: antsel_4, wlan_act */
+#if 1				/* Ray */
+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/* type: reg */
+	    , 0x00		/* rev */
+	    , 0x04		/* 4 registers */
+	    , 0x00, 0x04, 0x00, 0x80	/* addr:0x8000_0400 */
+	    , 0x03, 0x14, 0x00, 0x00	/* value:0x0000_1403 check confg debug flag 3 low word */
+	    , 0xFF, 0xFF, 0x00, 0x00	/* mask:0x0000_FFFF */
+	    /* cirq_int_n */
+	    , 0x10, 0x01, 0x05, 0x80	/* addr:0x8005_0110 */
+	    , 0x02, 0x00, 0x00, 0x00	/* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */
+	    , 0x07, 0x00, 0x00, 0x00	/* mask:0x0000_0007 */
+	    , 0x00, 0x01, 0x05, 0x80	/* addr:0x8005_0100 */
+	    , 0x00, 0x00, 0x02, 0x00	/* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */
+	    , 0x00, 0x00, 0x07, 0x00	/* mask:0x0007_0000 */
+	    /* 1.    ARM irq_b, monitor flag 0 */
+	    , 0x80, 0x01, 0x05, 0x80	/* addr:0x8005_0180 */
+	    , 0x1F, 0x1E, 0x00, 0x00	/* value:0x0000_1E1F check mcusys debug flag */
+	    , 0x7F, 0x7F, 0x00, 0x00	/* mask:0x0000_7F7F */
+};
+
+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/* S: 0 */
+	    , 0x00		/* type: reg */
+	    , 0x00		/* rev */
+	    , 0x04		/* 5 registers */
+};
+#elif 0				/* KC */
+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/* type: reg */
+	    , 0x00		/* rev */
+	    , 0x05		/* 5 registers */
+	    , 0x00, 0x04, 0x00, 0x80	/* addr:0x8000_0400 */
+	    , 0x00, 0x02, 0x00, 0x00	/* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */
+	    , 0x00, 0xFF, 0x00, 0x00	/* mask:0x0000_FF00 */
+	    /* 1.    ARM irq_b, monitor flag 0 */
+	    , 0x80, 0x01, 0x05, 0x80	/* addr:0x8005_0180 */
+	    , 0x18, 0x00, 0x00, 0x00	/* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */
+	    , 0x7F, 0x00, 0x00, 0x00	/* mask:0x0000_007F */
+	    , 0x00, 0x01, 0x05, 0x80	/* addr:0x8005_0100 */
+	    , 0x00, 0x00, 0x02, 0x00	/* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */
+	    , 0x00, 0x00, 0x07, 0x00	/* mask:0x0007_0000 */
+	    /* 2.    irq_bus[5] bt_timcon_irq_b monitor flag 15 */
+	    , 0xB0, 0x01, 0x05, 0x80	/* addr:0x8005_01B0 */
+	    , 0x00, 0x00, 0x00, 0x16	/* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */
+	    , 0x00, 0x00, 0x00, 0x7F	/* mask:0x7F00_0000 */
+	    , 0x30, 0x01, 0x05, 0x80	/* addr:0x8005_0130 */
+	    , 0x00, 0x20, 0x00, 0x00	/* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */
+	    , 0x00, 0x70, 0x00, 0x00	/* mask:0x0000_7000 */
+};
+
+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/* S: 0 */
+	    , 0x00		/* type: reg */
+	    , 0x00		/* rev */
+	    , 0x05		/* 5 registers */
+};
+#endif
+#endif
+
+#if CFG_WMT_CRYSTAL_TIMING_SET
+static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 };
+static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 };
+
+static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 };
+static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 };
+#endif
+
+#ifdef CFG_WMT_READ_EFUSE_VCN33
+static UINT8 WMT_GET_EFUSE_VCN33_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x04, 0x00 };
+static UINT8 WMT_GET_EFUSE_VCN33_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x04, 0x00 };
+#endif
+
+/* set sdio driving */
+#if CFG_WMT_SDIO_DRIVING_SET
+static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00	/*length */
+	    , 0x01		/* op: w */
+	    , 0x01		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+	    , 0x50, 0x00, 0x05, 0x80	/*addr:0x80050050 */
+	    , 0x44, 0x44, 0x04, 0x00	/*value:0x00044444 */
+	    , 0x77, 0x77, 0x07, 0x00	/*mask:0x00077777 */
+};
+
+static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00	/*length */
+	    , 0x00		/*S: 0 */
+	    , 0x00		/*type: reg */
+	    , 0x00		/*rev */
+	    , 0x01		/*1 registers */
+};
+#endif
+
+#if CFG_WMT_WIFI_5G_SUPPORT
+static UINT8 WMT_GET_SOC_ADIE_CHIPID_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 };
+static UINT8 WMT_GET_SOC_ADIE_CHIPID_EVT[] = {
+		0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24,
+		0x00, 0x00, 0x00, 0x00, 0x00
+};
+static UINT8 WMT_GET_SOC_6625_L_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x20, 0x01 };
+static UINT8 WMT_GET_SOC_6625_L_EVT[] = {
+		0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x20,
+		0x01, 0x00, 0x00, 0x00, 0x00
+};
+#endif
+
+#if CFG_WMT_PATCH_DL_OPTM
+static UINT8 WMT_SET_MCU_CLK_EN_CMD[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x34, 0x03, 0x00, 0x80,
+		0x00, 0x00, 0x01, 0x00,
+		0xff, 0xff, 0xff, 0xff
+};
+static UINT8 WMT_SET_MCU_CLK_EN_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+
+static UINT8 WMT_SET_MCU_CLK_138_CMD[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x0c, 0x01, 0x00, 0x80,
+		0x59, 0x4d, 0x84, 0x00,
+		0xff, 0xff, 0xff, 0xff
+};
+static UINT8 WMT_SET_MCU_CLK_138_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+
+static UINT8 WMT_SET_MCU_CLK_26_CMD[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x0c, 0x01, 0x00, 0x80,
+		0x00, 0x4d, 0x84, 0x00,
+		0xff, 0xff, 0xff, 0xff
+};
+static UINT8 WMT_SET_MCU_CLK_26_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+
+static UINT8 WMT_SET_MCU_CLK_DIS_CMD[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x34, 0x03, 0x00, 0x80,
+		0x00, 0x00, 0x00, 0x00,
+		0xff, 0xff, 0xff, 0xff
+};
+static UINT8 WMT_SET_MCU_CLK_DIS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+
+/*only for 6797,enable high clock frequency*/
+/*CLK EN*/
+static UINT8 WMT_SET_MCU_CLK_EN_6797[] = {
+	0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01,
+	0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x10,
+	0x00, 0x00, 0x00, 0x10
+};
+/*RATIO SET*/
+static UINT8 WMT_SET_MCU_RATIO_SET_6797[] = {
+	0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01,
+	0x0c, 0x01, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
+	0xc0, 0x00, 0x00, 0x00
+};
+/*DIV SET*/
+static UINT8 WMT_SET_MCU_DIV_SET_6797[] = {
+	0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01,
+	0x18, 0x11, 0x02, 0x80, 0x07, 0x00, 0x00, 0x00,
+	0x3f, 0x00, 0x00, 0x00
+};
+/*HCLK SET*/
+static UINT8 WMT_SET_MCU_HCLK_SET_6797[] = {
+	0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01,
+	0x00, 0x11, 0x02, 0x81, 0x04, 0x00, 0x00, 0x00,
+	0x07, 0x00, 0x00, 0x00
+};
+
+/*Change clock to 26MHz*/
+/*HCLK DIS*/
+static UINT8 WMT_SET_MCU_HCLK_DIS_6797[] = {
+	0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01,
+	0x00, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x00, 0x00, 0x00
+};
+/*RATIO DIS*/
+static UINT8 WMT_SET_MCU_RATIO_DIS_6797[] = {
+	0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01,
+	0x0c, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+	0xc0, 0x00, 0x00, 0x00
+};
+/*CLK DIS*/
+static UINT8 WMT_SET_MCU_CLK_DIS_6797[] = {
+	0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01,
+	0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10
+};
+
+static UINT8 WMT_SET_MCU_CLK_EVT_6797[] = {
+	0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+#endif
+
+#if CFG_WMT_FILTER_MODE_SETTING
+static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = {0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00};
+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = {
+		0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01,
+		0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63,
+		0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01,
+		0x01, 0x0e, 0x0e, 0x0e, 0x00, 0x0a, 0x0c, 0x0e,
+		0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = {
+		0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15,
+		0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xd4,
+		0x09, 0xe3, 0x09, 0x5a, 0x0a, 0x14, 0x09, 0x2d,
+		0x09, 0x46, 0x09, 0x60, 0x09, 0xd3, 0x09, 0xe2,
+		0x09, 0x59, 0x0a, 0x8B, 0x0a};
+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 };
+static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 };
+
+#if 0
+static UINT8 WMT_COEX_SPLIT_FILTER_CMD_TEST[] = {
+		0x01, 0x10, 0x19, 0x00, 0x0F, 0x00, 0x00, 0x00,
+		0x00, 0x6c, 0x09, 0x8a, 0x09, 0x8a, 0x09, 0x9e,
+		0x09, 0x01, 0x07, 0x07, 0x0b, 0x07, 0x07, 0x00,
+		0x32, 0x27, 0x4e, 0x27, 0x32
+};
+
+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = {
+		0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01,
+		0x00, 0x07, 0x07, 0x07, 0x54, 0x54, 0x00, 0x00,
+		0x00, 0x50, 0x50, 0x50, 0x54, 0x54, 0x39, 0x39,
+		0x39, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x01, 0x01,
+		0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x0a,
+		0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00
+};
+
+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST[] = {
+		0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15,
+		0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd,
+		0x09, 0xf6, 0x09, 0x0f, 0xaf, 0x14, 0x09, 0x2d,
+		0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5,
+		0x09, 0x0d, 0x0a, 0x27, 0x0a
+};
+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 };
+static UINT8 WMT_COEX_EXT_COMPONENT_CMD_TEST[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x7f, 0x03 };
+#endif
+
+static UINT8 WMT_COEX_FILTER_SPEC_CMD_0[] = {
+		0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01,
+		0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00,
+		0x00, 0x63, 0x63, 0x63, 0x63, 0x3c, 0x3c, 0x3c,
+		0x3c, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01,
+		0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, 0x0b,
+		0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00
+};
+
+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0[] = {
+		0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15,
+		0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd,
+		0x09, 0xf6, 0x09, 0x0f, 0x0a, 0x14, 0x09, 0x2d,
+		0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5,
+		0x09, 0x0d, 0x0a, 0x27, 0x0a
+};
+static UINT8 WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x14, 0x00 };
+static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 };
+static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 };
+
+static UINT8 WMT_COEX_FILTER_SPEC_CMD_6752[] = {
+		0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01,
+		0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63,
+		0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01,
+		0x01, 0x0E, 0x0E, 0x0E, 0x00, 0x0A, 0x0C, 0x0E,
+		0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00
+};
+
+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752[] = {
+		0x01, 0x10, 0x21, 0x00, 0x12, 0xFC, 0x08, 0x15,
+		0x09, 0x2E, 0x09, 0x47, 0x09, 0xC4, 0x09, 0xD4,
+		0x09, 0xE3, 0x09, 0x5A, 0x0A, 0x14, 0x09, 0x2D,
+		0x09, 0x46, 0x09, 0x60, 0x09, 0xD3, 0x09, 0xE2,
+		0x09, 0x59, 0x0A, 0x8B, 0x0A
+};
+#endif
+
+#if CFG_WMT_POWER_ON_DLM
+static UINT8 WMT_POWER_CTRL_DLM_CMD1[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x60, 0x00, 0x10, 0x80,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x0f, 0x00, 0x00
+};
+
+static UINT8 WMT_POWER_CTRL_DLM_CMD2[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x60, 0x00, 0x10, 0x80,
+		0x00, 0x00, 0x00, 0x00,
+		0xf0, 0x00, 0x00, 0x00
+};
+
+static UINT8 WMT_POWER_CTRL_DLM_CMD3[] = {
+		0x01, 0x08, 0x10, 0x00,
+		0x01, 0x01, 0x00, 0x01,
+		0x60, 0x00, 0x10, 0x80,
+		0x00, 0x00, 0x00, 0x00,
+		0x08, 0x00, 0x00, 0x00
+};
+static UINT8 WMT_POWER_CTRL_DLM_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 };
+#endif
+
+#if (!CFG_IC_SOC)
+
+/* stp sdio init scripts */
+static struct init_script init_table_1_1[] = {
+	/* table_1_1 is only applied to common SDIO interface */
+	INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"),
+	/* applied to MT6628 ? */
+	INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"),
+};
+
+#endif
+
+static struct init_script init_table_1_2[] = {
+	INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"),
+};
+
+#if CFG_WMT_UART_HIF_USE
+static struct init_script init_table_2[] = {
+	INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"),
+};
+#endif
+
+static struct init_script init_table_3[] = {
+	INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"),
+#if CFG_WMT_BT_PORT2
+	INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"),
+#endif
+};
+
+#if CFG_WMT_CRYSTAL_TIMING_SET
+static struct init_script set_crystal_timing_script[] = {
+	INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, "set crystal trim value"),
+};
+
+static struct init_script get_crystal_timing_script[] = {
+	INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, "get crystal trim value"),
+};
+#endif
+#ifdef CFG_WMT_READ_EFUSE_VCN33
+static struct init_script get_efuse_vcn33_script[] = {
+	INIT_CMD(WMT_GET_EFUSE_VCN33_CMD, WMT_GET_EFUSE_VCN33_EVT, "get efuse vcn33 value"),
+};
+#endif
+
+static struct init_script init_table_4[] = {
+	INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"),
+};
+
+static struct init_script init_table_5[] = {
+	INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT, "query stp"),
+};
+
+static struct init_script init_table_5_1[] = {
+	INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"),
+};
+
+static struct init_script init_table_6[] = {
+	INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"),
+};
+
+static struct init_script calibration_table[] = {
+	INIT_CMD(WMT_CORE_START_RF_CALIBRATION_CMD, WMT_CORE_START_RF_CALIBRATION_EVT, "start RF calibration data"),
+};
+
+#if CFG_WMT_PATCH_DL_OPTM
+static struct init_script set_mcuclk_table_1[] = {
+	INIT_CMD(WMT_SET_MCU_CLK_EN_CMD, WMT_SET_MCU_CLK_EN_EVT, "enable set mcu clk"),
+	INIT_CMD(WMT_SET_MCU_CLK_138_CMD, WMT_SET_MCU_CLK_138_EVT, "set mcu clk to 138.67MH"),
+};
+
+static struct init_script set_mcuclk_table_2[] = {
+	INIT_CMD(WMT_SET_MCU_CLK_26_CMD, WMT_SET_MCU_CLK_26_EVT, "set mcu clk to 26MH"),
+	INIT_CMD(WMT_SET_MCU_CLK_DIS_CMD, WMT_SET_MCU_CLK_DIS_EVT, "disable set mcu clk"),
+};
+
+static struct init_script set_mcuclk_table_3[] = {
+	INIT_CMD(WMT_SET_MCU_CLK_EN_6797, WMT_SET_MCU_CLK_EVT_6797, "enable set mcu clk"),
+	INIT_CMD(WMT_SET_MCU_RATIO_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu ratio set"),
+	INIT_CMD(WMT_SET_MCU_DIV_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu div set"),
+	INIT_CMD(WMT_SET_MCU_HCLK_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "set mcu clk to hclk"),
+};
+static struct init_script set_mcuclk_table_4[] = {
+	INIT_CMD(WMT_SET_MCU_HCLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu hclk"),
+	INIT_CMD(WMT_SET_MCU_RATIO_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu ratio set"),
+	INIT_CMD(WMT_SET_MCU_CLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu clk set"),
+};
+
+#endif
+
+#if CFG_WMT_FILTER_MODE_SETTING
+static struct init_script set_wifi_lte_coex_table_1[] = {
+	INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"),
+	INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"),
+	INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"),
+};
+
+static struct init_script set_wifi_lte_coex_table_2[] = {
+	INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"),
+	INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"),
+	INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"),
+	INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"),
+	INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"),
+};
+
+static struct init_script set_wifi_lte_coex_table_0[] = {
+#if 0
+	INIT_CMD(WMT_COEX_SPLIT_FILTER_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex split filter"),
+	INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"),
+	INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"),
+	INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte channel unsafe"),
+	INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi coex ext component"),
+#endif
+	INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte coex filter spec"),
+	INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte freq idx"),
+};
+
+static struct init_script get_tdm_req_antsel_num_table[] = {
+	INIT_CMD(WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD, WMT_COEX_SPLIT_MODE_EVT, "get tdm req antsel num"),
+};
+#endif
+
+#if CFG_SET_OPT_REG
+static struct init_script set_registers[] = {
+	/* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */
+	/* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */
+#if CFG_WMT_I2S_DBGUART_SUPPORT
+	INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"),
+#endif
+#if CFG_SET_OPT_REG_SWLA
+	INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"),
+#endif
+#if CFG_SET_OPT_REG_MCUCLK
+	INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"),
+#endif
+#if CFG_SET_OPT_REG_MCUIRQ
+	INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"),
+#endif
+};
+#endif
+
+static struct init_script coex_table[] = {
+	INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"),
+
+#if CFG_SUBSYS_COEX_NEED
+/* no need in MT6628 */
+	INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"),
+	INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"),
+	INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"),
+	INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"),
+#endif
+};
+
+static struct init_script osc_type_table[] = {
+	INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"),
+};
+
+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT)
+static struct init_script merge_pcm_table[] = {
+	INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"),
+	INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"),
+	INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"),
+};
+#endif
+
+#if CFG_WMT_SDIO_DRIVING_SET
+static struct init_script sdio_driving_table[] = {
+	INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"),
+};
+#endif
+
+#if CFG_WMT_POWER_ON_DLM
+static struct init_script wmt_power_on_dlm_table[] = {
+	INIT_CMD(WMT_POWER_CTRL_DLM_CMD1, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd1"),
+	INIT_CMD(WMT_POWER_CTRL_DLM_CMD2, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd2"),
+	INIT_CMD(WMT_POWER_CTRL_DLM_CMD3, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd3")
+};
+#endif
+
+/* SOC Chip Version and Info Table */
+static const WMT_IC_INFO_S mtk_wcn_soc_info_table[] = {
+	{
+	 .u4HwVer = 0x8A00,
+	 .cChipName = WMT_IC_NAME_DEFAULT,
+	 .cChipVersion = WMT_IC_VER_E1,
+	 .cPatchNameExt = WMT_IC_PATCH_E1_EXT,
+	 /* need to refine? */
+	 .eWmtHwVer = WMTHWVER_E1,
+	 .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE,
+	 .bPsmSupport = MTK_WCN_BOOL_TRUE,
+	 },
+	{
+	 .u4HwVer = 0x8A01,
+	 .cChipName = WMT_IC_NAME_DEFAULT,
+	 .cChipVersion = WMT_IC_VER_E2,
+	 .cPatchNameExt = WMT_IC_PATCH_E1_EXT,
+	 .eWmtHwVer = WMTHWVER_E2,
+	 .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE,
+	 .bPsmSupport = MTK_WCN_BOOL_TRUE,
+	 },
+	{
+	 .u4HwVer = 0x8B01,
+	 .cChipName = WMT_IC_NAME_DEFAULT,
+	 .cChipVersion = WMT_IC_VER_E3,
+	 .cPatchNameExt = WMT_IC_PATCH_E1_EXT,
+	 .eWmtHwVer = WMTHWVER_E3,
+	 .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE,
+	 .bPsmSupport = MTK_WCN_BOOL_TRUE,
+	 }
+};
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf);
+
+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf);
+
+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag);
+
+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag);
+
+static INT32 mtk_wcn_soc_ver_check(VOID);
+
+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver);
+
+static INT32 wmt_stp_init_coex(VOID);
+
+#if CFG_WMT_FILTER_MODE_SETTING
+static INT32 wmt_stp_wifi_lte_coex(VOID);
+#endif
+
+#if CFG_WMT_MULTI_PATCH
+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index);
+static INT32 mtk_wcn_soc_patch_info_prepare(VOID);
+#else
+static INT32 mtk_wcn_soc_patch_dwn(VOID);
+#endif
+
+static INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on);
+static WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID);
+
+#if CFG_WMT_CRYSTAL_TIMING_SET
+static INT32 mtk_wcn_soc_crystal_triming_set(VOID);
+#endif
+
+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID);
+
+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID);
+
+#if CFG_WMT_SDIO_DRIVING_SET
+static INT32 mtk_wcn_soc_set_sdio_driving(void);
+#endif
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/* SOC Operation Function Table */
+WMT_IC_OPS wmt_ic_ops_soc = {
+	.icId = 0x0000,		/* soc may have mt6572/82/71/83,but they have the same sw init flow */
+	.sw_init = mtk_wcn_soc_sw_init,
+	.sw_deinit = mtk_wcn_soc_sw_deinit,
+	.ic_pin_ctrl = mtk_wcn_soc_pin_ctrl,
+	.ic_ver_check = mtk_wcn_soc_ver_check,
+	.co_clock_ctrl = mtk_wcn_soc_co_clock_ctrl,
+	.is_quick_sleep = mtk_wcn_soc_quick_sleep_flag_get,
+	.is_aee_dump_support = mtk_wcn_soc_aee_dump_flag_get,
+};
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf)
+{
+	INT32 iRet = -1;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+	UINT32 hw_ver;
+	WMT_CTRL_DATA ctrlData;
+#ifdef CFG_WMT_READ_EFUSE_VCN33
+	UINT32 efuse_d3_vcn33 = 2; /*default voltage is 3.5V*/
+#endif
+#if CFG_WMT_MULTI_PATCH
+	UINT32 patch_num = 0;
+	UINT32 patch_index = 0;
+#endif
+#if CFG_WMT_WIFI_5G_SUPPORT
+	UINT32 dDieChipid = 0;
+	UINT32 aDieChipid = 0;
+	UINT8 evtbuf[20];
+	UINT32 u4Res;
+	UINT32 pmicChipid = 0;
+#endif
+	WMT_DBG_FUNC(" start\n");
+
+	osal_assert(NULL != gp_soc_info);
+	if ((NULL == gp_soc_info)
+	    || (NULL == pWmtHifConf)
+	    ) {
+		WMT_ERR_FUNC("null pointers: gp_soc_info(0x%p), pWmtHifConf(0x%p)\n", gp_soc_info, pWmtHifConf);
+		return -1;
+	}
+
+	hw_ver = gp_soc_info->u4HwVer;
+
+	/* 4 <3.2> start init for BTIF */
+	if (WMT_HIF_BTIF == pWmtHifConf->hifType) {
+		/* 1. Query chip STP default options (TEST-ONLY) */
+		/* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */
+		iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2));
+		if (iRet) {
+			WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet);
+			osal_assert(0);
+			return -2;
+		}
+		/* 2. Set chip STP options */
+		iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4));
+		if (iRet) {
+			WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet);
+			return -3;
+		}
+
+		/* 3. Enable host full mode */
+		ctrlPa1 = WMT_STP_CONF_MODE;
+		ctrlPa2 = MTKSTP_BTIF_FULL_MODE;
+		iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+		ctrlPa1 = WMT_STP_CONF_EN;
+		ctrlPa2 = 1;
+		iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
+		if (iRet) {
+			WMT_ERR_FUNC("enable host STP-BTIF-FULL mode fail(%d)\n", iRet);
+			return -4;
+		}
+		WMT_DBG_FUNC("enable host STP-BTIF-FULL mode\n");
+		/*4. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */
+		osal_sleep_ms(10);
+		/* 5. Query chip STP options (TEST-ONLY) */
+		iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5));
+		if (iRet) {
+			WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet);
+			return -5;
+		}
+	}
+#if CFG_WMT_POWER_ON_DLM
+	iRet = wmt_core_init_script(wmt_power_on_dlm_table, osal_array_size(wmt_power_on_dlm_table));
+	if (iRet)
+		WMT_ERR_FUNC("wmt_power_on_dlm_table fail(%d)\n", iRet);
+	WMT_DBG_FUNC("wmt_power_on_dlm_table ok\n");
+#endif
+	/* 6. download patch */
+#if CFG_WMT_MULTI_PATCH
+	/* 6.1 Let launcher to search patch info */
+	iRet = mtk_wcn_soc_patch_info_prepare();
+	if (iRet) {
+		WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet);
+		return -6;
+	}
+
+	/* 6.2 Read patch number */
+	ctrlPa1 = 0;
+	ctrlPa2 = 0;
+	wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2);
+	patch_num = ctrlPa1;
+	WMT_DBG_FUNC("patch total num = [%d]\n", patch_num);
+
+#if CFG_WMT_PATCH_DL_OPTM
+	if (0x0279 == wmt_ic_ops_soc.icId) {
+		iRet = wmt_core_init_script(set_mcuclk_table_3, osal_array_size(set_mcuclk_table_3));
+		if (iRet)
+			WMT_ERR_FUNC("set_mcuclk_table_3 fail(%d)\n", iRet);
+	} else {
+		iRet = wmt_core_init_script(set_mcuclk_table_1, osal_array_size(set_mcuclk_table_1));
+		if (iRet)
+			WMT_ERR_FUNC("set_mcuclk_table_1 fail(%d)\n", iRet);
+	}
+#endif
+	/* 6.3 Multi-patch Patch download */
+	for (patch_index = 0; patch_index < patch_num; patch_index++) {
+		iRet = mtk_wcn_soc_patch_dwn(patch_index);
+		if (iRet) {
+			WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index);
+			return -7;
+		}
+		iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3));
+		if (iRet) {
+			WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet);
+			return -8;
+		}
+	}
+
+#if CFG_WMT_PATCH_DL_OPTM
+	if (0x0279 == wmt_ic_ops_soc.icId) {
+		iRet = wmt_core_init_script(set_mcuclk_table_4, osal_array_size(set_mcuclk_table_4));
+		if (iRet)
+			WMT_ERR_FUNC("set_mcuclk_table_4 fail(%d)\n", iRet);
+	} else {
+		iRet = wmt_core_init_script(set_mcuclk_table_2, osal_array_size(set_mcuclk_table_2));
+		if (iRet)
+			WMT_ERR_FUNC("set_mcuclk_table_2 fail(%d)\n", iRet);
+	}
+#endif
+
+#else
+	/* 6.3 Patch download */
+	iRet = mtk_wcn_soc_patch_dwn();
+	/* If patch download fail, we just ignore this error and let chip init process goes on */
+	if (iRet)
+		WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet);
+
+	/* 6.4. WMT Reset command */
+	iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3));
+	if (iRet) {
+		WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet);
+		return -8;
+	}
+#endif
+
+#ifdef CFG_WMT_READ_EFUSE_VCN33
+	/*get CrystalTiming value before set it */
+	iRet = wmt_core_tx(get_efuse_vcn33_script[0].cmd, get_efuse_vcn33_script[0].cmdSz, &u4Res,
+			MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != get_efuse_vcn33_script[0].cmdSz)) {
+		WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n",
+				 get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].cmdSz);
+	}
+	/* EVENT BUF */
+	osal_memset(get_efuse_vcn33_script[0].evt, 0, get_efuse_vcn33_script[0].evtSz);
+	iRet = wmt_core_rx(get_efuse_vcn33_script[0].evt, get_efuse_vcn33_script[0].evtSz, &u4Res);
+	if (iRet || (u4Res != get_efuse_vcn33_script[0].evtSz)) {
+		WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n",
+				 get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].evtSz);
+		mtk_wcn_stp_dbg_dump_package();
+	}
+	efuse_d3_vcn33 = WMT_GET_EFUSE_VCN33_EVT[5] & 0x03;
+	WMT_INFO_FUNC("Read efuse to set PMIC voltage:(%d)\n", efuse_d3_vcn33);
+	wmt_set_pmic_voltage(efuse_d3_vcn33);
+#endif
+
+#if CFG_WMT_FILTER_MODE_SETTING
+	if ((0x6580 == wmt_ic_ops_soc.icId) ||
+	    (0x8163 == wmt_ic_ops_soc.icId) ||
+	    (0x6752 == wmt_ic_ops_soc.icId) ||
+	    (0x6582 == wmt_ic_ops_soc.icId) ||
+	    (0x6592 == wmt_ic_ops_soc.icId) ||
+	    (0x0279 == wmt_ic_ops_soc.icId) ||
+	    (0x0326 == wmt_ic_ops_soc.icId) ||
+	    (0x0321 == wmt_ic_ops_soc.icId) || (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) {
+		wmt_stp_wifi_lte_coex();
+		WMT_DBG_FUNC("wmt_stp_wifi_lte_coex done!\n");
+	}
+	if ((0x6582 == wmt_ic_ops_soc.icId) || (0x6592 == wmt_ic_ops_soc.icId)) {
+		/*get gpio tdm req antsel number */
+		ctrlPa1 = 0;
+		ctrlPa2 = 0;
+		wmt_core_ctrl(WMT_CTRL_GET_TDM_REQ_ANTSEL, &ctrlPa1, &ctrlPa2);
+		WMT_INFO_FUNC("get GPIO TDM REQ ANTSEL number(%d)\n", ctrlPa1);
+		/*set gpio tdm req antsel number to firmware */
+		WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[5] = ctrlPa1;
+		iRet = wmt_core_init_script(get_tdm_req_antsel_num_table,
+		    osal_array_size(get_tdm_req_antsel_num_table));
+		if (iRet)
+			WMT_ERR_FUNC("get_tdm_req_antsel_num_table fail(%d)\n", iRet);
+	}
+#endif
+	/* 7. start RF calibration data */
+	ctrlPa1 = BT_PALDO;
+	ctrlPa2 = PALDO_ON;
+	iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+	ctrlPa1 = WIFI_PALDO;
+	ctrlPa2 = PALDO_ON;
+	iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+
+	iRet = wmt_core_init_script(calibration_table, osal_array_size(calibration_table));
+	if (iRet) {
+		/* pwrap_read(0x0210,&ctrlPa1); */
+		/* pwrap_read(0x0212,&ctrlPa2); */
+		WMT_ERR_FUNC("power status: 210:(%d),212:(%d)!\n", ctrlPa1, ctrlPa2);
+		WMT_ERR_FUNC("calibration_table fail(%d)\n", iRet);
+		return -9;
+	}
+
+	ctrlPa1 = BT_PALDO;
+	ctrlPa2 = PALDO_OFF;
+	iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+	ctrlPa1 = WIFI_PALDO;
+	ctrlPa2 = PALDO_OFF;
+	iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+
+	iRet = wmt_stp_init_coex();
+	if (iRet) {
+		WMT_ERR_FUNC("init_coex fail(%d)\n", iRet);
+		return -10;
+	}
+	WMT_DBG_FUNC("init_coex ok\n");
+
+#if CFG_WMT_CRYSTAL_TIMING_SET
+	mtk_wcn_soc_crystal_triming_set();
+#endif
+
+#if CFG_WMT_SDIO_DRIVING_SET
+	mtk_wcn_soc_set_sdio_driving();
+#endif
+
+	if (WMT_CO_CLOCK_EN == mtk_wcn_soc_co_clock_get()) {
+		WMT_INFO_FUNC("co-clock enabled.\n");
+
+		iRet = wmt_core_init_script(osc_type_table, osal_array_size(osc_type_table));
+		if (iRet) {
+			WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet);
+			return -11;
+		}
+	} else {
+		WMT_WARN_FUNC("co-clock disabled.\n");
+	}
+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT)
+	iRet = wmt_core_init_script(merge_pcm_table, osal_array_size(merge_pcm_table));
+	if (iRet) {
+		WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet);
+		return -12;
+	}
+#endif
+
+	/* 15. Set FM strap */
+	WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0];
+	WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0];
+	iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1));
+	if (iRet) {
+		WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", pWmtHifConf->au4StrapConf[0], iRet);
+		return -13;
+	}
+	WMT_DBG_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]);
+
+#if CFG_SET_OPT_REG		/*set registers */
+	iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers));
+	if (iRet) {
+		WMT_ERR_FUNC("set_registers fail(%d)", iRet);
+		return -14;
+	}
+#endif
+
+#if CFG_WMT_COREDUMP_ENABLE
+	/*Open Core Dump Function @QC begin */
+	mtk_wcn_stp_coredump_flag_ctrl(1);
+#endif
+	if (0 != mtk_wcn_stp_coredump_flag_get()) {
+		iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6));
+		if (iRet) {
+			WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet);
+			return -15;
+		}
+		WMT_DBG_FUNC("enable soc_consys firmware coredump\n");
+	} else {
+		WMT_DBG_FUNC("disable soc_consys firmware coredump\n");
+	}
+
+#if CFG_WMT_WIFI_5G_SUPPORT
+	dDieChipid = wmt_ic_ops_soc.icId;
+	WMT_DBG_FUNC("current SOC chipid is 0x%x\n", dDieChipid);
+	if (0x6592 == dDieChipid) {
+		/* read A die chipid by wmt cmd */
+		iRet =
+		    wmt_core_tx((PUINT8) &WMT_GET_SOC_ADIE_CHIPID_CMD[0], sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD), &u4Res,
+				MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD))) {
+			WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res);
+			return -16;
+		}
+		osal_memset(evtbuf, 0, sizeof(evtbuf));
+		iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT), &u4Res);
+		if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT))) {
+			WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res);
+			return -17;
+		}
+
+		osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2);
+		WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid);
+
+		if (0x6625 == aDieChipid) {
+			iRet =
+			    wmt_core_tx((PUINT8) &WMT_GET_SOC_6625_L_CMD[0], sizeof(WMT_GET_SOC_6625_L_CMD), &u4Res,
+					MTK_WCN_BOOL_FALSE);
+			if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_CMD)))
+				WMT_ERR_FUNC("wmt_core:read A die efuse CMD fail(%d),size(%d)\n", iRet, u4Res);
+			osal_memset(evtbuf, 0, sizeof(evtbuf));
+			iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_6625_L_EVT), &u4Res);
+			if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_EVT)))
+				WMT_ERR_FUNC("wmt_core:read A die efuse EVT fail(%d),size(%d)\n", iRet, u4Res);
+
+			WMT_INFO_FUNC("read SOC Adie Efuse(0x120) value:0x%2x,0x%2x,0x%2x,0x%2x -> %s\n",
+				      evtbuf[u4Res - 4], evtbuf[u4Res - 3], evtbuf[u4Res - 2], evtbuf[u4Res - 1],
+				      evtbuf[u4Res - 2] == 0x31 ? "MT6625L" : "MT6625");
+		}
+		/* get PMIC chipid */
+
+		ctrlData.ctrlId = WMT_CTRL_SOC_PALDO_CTRL;
+		ctrlData.au4CtrlData[0] = PMIC_CHIPID_PALDO;
+		ctrlData.au4CtrlData[1] = 0;
+		iRet = wmt_ctrl(&ctrlData);
+		if (iRet < 0) {
+			WMT_ERR_FUNC("wmt_core: read PMIC chipid fail(%d)\n", iRet);
+			return -18;
+		}
+		pmicChipid = ctrlData.au4CtrlData[2];
+		WMT_INFO_FUNC("current PMIC chipid(0x%x)\n", pmicChipid);
+
+		/* MT6625 & MT6322, write 1 to 0x0414[12] */
+		/* MT6625 & MT6323, assert */
+		/* MT6627 & (MT6322 or MT6323),write 0 to 0x0414[12] */
+
+		switch (aDieChipid) {
+		case 0x6625:
+			if (0x6322 == pmicChipid) {
+				WMT_INFO_FUNC("wmt-core:enable wifi 5G support\n");
+				ctrlPa1 = WIFI_5G_PALDO;
+				ctrlPa2 = PALDO_ON;
+				wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+			} else if (0x6323 == pmicChipid) {
+				osal_assert(0);
+			} else {
+				WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n");
+			}
+			break;
+		case 0x6627:
+			if ((0x6322 == pmicChipid) || (0x6323 == pmicChipid)) {
+				WMT_INFO_FUNC("wmt-core: disable wifi 5G support\n");
+				ctrlPa1 = WIFI_5G_PALDO;
+				ctrlPa2 = PALDO_OFF;
+				wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2);
+			} else {
+				WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n");
+			}
+			break;
+		default:
+			WMT_WARN_FUNC("wmt-core: unknown A die chipid(0x%x)\n", aDieChipid);
+			break;
+		}
+	}
+#endif
+
+#if 1
+	ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO;
+	ctrlData.au4CtrlData[0] = wmt_ic_ops_soc.icId;
+	ctrlData.au4CtrlData[1] = (SIZE_T) gp_soc_info->cChipVersion;
+	ctrlData.au4CtrlData[2] = (SIZE_T) &gp_soc_patch_info;
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		WMT_ERR_FUNC("set dump info fail(%d)\n", iRet);
+		return -19;
+	}
+#endif
+
+#if CFG_WMT_PS_SUPPORT
+	osal_assert(NULL != gp_soc_info);
+	if (NULL != gp_soc_info) {
+		if (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport)
+			wmt_lib_ps_enable();
+		else
+			wmt_lib_ps_disable();
+	}
+#endif
+
+	return 0;
+}
+
+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf)
+{
+	WMT_DBG_FUNC(" start\n");
+
+#if CFG_WMT_PS_SUPPORT
+	osal_assert(NULL != gp_soc_info);
+	if ((NULL != gp_soc_info)
+	    && (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport)) {
+		wmt_lib_ps_disable();
+	}
+#endif
+
+	gp_soc_info = NULL;
+
+	return 0;
+}
+
+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag)
+{
+	INT32 ret = -1;
+	UINT32 val;
+
+	if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) {
+		WMT_INFO_FUNC("PCM & I2S PIN SHARE\n");
+#if 0
+		switch (state) {
+		case WMT_IC_AIF_0:
+			/* BT_PCM_OFF & FM line in/out */
+			val = 0x00000770;
+			ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0);
+			val = 0x00000000;
+			ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800);
+			break;
+
+		case WMT_IC_AIF_1:
+			/* BT_PCM_ON & FM line in/out */
+			val = 0x00000700;
+			ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0);
+			val = 0x00000000;
+			ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800);
+			break;
+
+		case WMT_IC_AIF_2:
+			/* BT_PCM_OFF & FM I2S */
+			val = 0x00000710;
+			ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0);
+			val = 0x00000800;	/* 800:3-wire, 000: 4-wire */
+			ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800);
+			break;
+		default:
+			WMT_ERR_FUNC("unsupported state (%d)\n", state);
+			ret = -1;
+			break;
+		}
+#else
+		WMT_WARN_FUNC("TBD!!");
+		ret = 0;
+#endif
+	} else {
+		/*PCM & I2S separate */
+		WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n");
+#if 0
+		switch (state) {
+		case WMT_IC_AIF_0:
+			/* BT_PCM_OFF & FM line in/out */
+			val = 0x00000770;
+			ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0);
+			val = 0x00000000;
+			ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800);
+			break;
+
+		case WMT_IC_AIF_1:
+			/* BT_PCM_ON & FM line in/out */
+			val = 0x00000700;
+			ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0);
+			val = 0x00000000;
+			ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800);
+			break;
+
+		case WMT_IC_AIF_2:
+			/* BT_PCM_OFF & FM I2S */
+			val = 0x00000070;
+			ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0);
+			val = 0x00000800;	/* 800:3-wire, 000: 4-wire */
+			ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800);
+
+			break;
+		case WMT_IC_AIF_3:
+			val = 0x00000000;
+			ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0);
+			val = 0x00000800;	/* 800:3-wire, 000: 4-wire */
+			ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800);
+
+			break;
+		default:
+			WMT_ERR_FUNC("unsupported state (%d)\n", state);
+			ret = -1;
+			break;
+		}
+#else
+		switch (state) {
+		case WMT_IC_AIF_0:
+			/* BT_PCM_OFF & FM line in/out */
+			ret = 0;
+			break;
+		case WMT_IC_AIF_1:
+			/* BT_PCM_ON & FM line in/out */
+			ret = 0;
+			break;
+
+		case WMT_IC_AIF_2:
+			/* BT_PCM_OFF & FM I2S */
+			val = 0x01110000;
+			ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000);
+
+			break;
+		case WMT_IC_AIF_3:
+			ret = 0;
+			break;
+
+		default:
+			WMT_ERR_FUNC("unsupported state (%d)\n", state);
+			ret = -1;
+			break;
+		}
+#endif
+	}
+
+	if (!ret)
+		WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret);
+	WMT_INFO_FUNC("new state(%d) ok\n", state);
+
+	return ret;
+}
+
+static INT32 mtk_wcn_soc_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag)
+{
+	INT32 iRet = -1;
+	UINT32 uVal = 0;
+
+	/* mt6797 can not access reg:0x80050078 and no need to do GPS SYNC */
+	if (0x0279 != wmt_ic_ops_soc.icId) {
+		if (WMT_IC_PIN_MUX == state)
+			uVal = 0x1 << 28;
+		else
+			uVal = 0x5 << 28;
+		iRet = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28);
+		if (iRet)
+			WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet);
+	} else
+		WMT_INFO_FUNC("This chip no need to sync GPS and MODEM!\n");
+
+	/* anyway, we return 0 */
+	return 0;
+}
+
+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag)
+{
+	INT32 ret;
+
+	WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag);
+
+	ret = -1;
+	switch (id) {
+	case WMT_IC_PIN_AUDIO:
+		ret = mtk_wcn_soc_aif_ctrl(state, flag);
+		break;
+
+	case WMT_IC_PIN_EEDI:
+		WMT_WARN_FUNC("TBD!!");
+		/* We just return 0 here, prevent from WMT-FUNC do other register read/write */
+		ret = 0;
+		break;
+
+	case WMT_IC_PIN_EEDO:
+		WMT_WARN_FUNC("TBD!!");
+		/* We just return 0 here, prevent from WMT-FUNC do other register read/write */
+		ret = 0;
+		break;
+	case WMT_IC_PIN_GSYNC:
+		ret = mtk_wcn_soc_gps_sync_ctrl(state, flag);
+		break;
+	default:
+		break;
+	}
+	WMT_INFO_FUNC("ret = (%d)\n", ret);
+
+	return ret;
+}
+
+INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on)
+{
+	INT32 iRet = 0;
+
+	if ((WMT_CO_CLOCK_DIS <= on) && (WMT_CO_CLOCK_MAX > on)) {
+		gCoClockEn = on;
+	} else {
+		WMT_DBG_FUNC("0x%x: error parameter:%d\n", wmt_ic_ops_soc.icId, on);
+		iRet = -1;
+	}
+	WMT_DBG_FUNC("0x%x: Co-clock %s\n", wmt_ic_ops_soc.icId,
+		     (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled");
+
+	return iRet;
+}
+
+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID)
+{
+	return MTK_WCN_BOOL_TRUE;
+}
+
+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID)
+{
+	return MTK_WCN_BOOL_FALSE;
+}
+
+WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID)
+{
+	return gCoClockEn;
+}
+
+static INT32 mtk_wcn_soc_ver_check(VOID)
+{
+	UINT32 hw_ver;
+	UINT32 fw_ver;
+	INT32 iret;
+	const WMT_IC_INFO_S *p_info;
+	unsigned long ctrlPa1;
+	unsigned long ctrlPa2;
+
+	/* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */
+	WMT_LOUD_FUNC("0x%x: before read hw_ver (hw version)\n", wmt_ic_ops_soc.icId);
+	iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK);
+	if (iret) {
+		WMT_ERR_FUNC("0x%x: read hw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret);
+		return -2;
+	}
+	WMT_WARN_FUNC("0x%x: read hw_ver (hw version) (0x%x)\n", wmt_ic_ops_soc.icId, hw_ver);
+
+	WMT_LOUD_FUNC("0x%x: before fw_ver (rom version)\n", wmt_ic_ops_soc.icId);
+	wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK);
+	if (iret) {
+		WMT_ERR_FUNC("0x%x: read fw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret);
+		return -2;
+	}
+	WMT_WARN_FUNC("0x%x: read fw_ver (rom version) (0x%x)\n", wmt_ic_ops_soc.icId, fw_ver);
+
+	p_info = mtk_wcn_soc_find_wmt_ic_info(hw_ver);
+	if (NULL == p_info) {
+		WMT_ERR_FUNC("0x%x: hw_ver(0x%x) find wmt ic info fail\n", wmt_ic_ops_soc.icId);
+		return -3;
+	}
+	WMT_WARN_FUNC("0x%x: ic info: %s.%s (0x%x/0x%x, WMTHWVER:%d, patch_ext:%s)\n",
+		      wmt_ic_ops_soc.icId, p_info->cChipName, p_info->cChipVersion,
+		      hw_ver, fw_ver, p_info->eWmtHwVer, p_info->cPatchNameExt);
+
+	/* hw id & version */
+	ctrlPa1 = (wmt_ic_ops_soc.icId << 16) | (hw_ver & 0x0000FFFF);
+	/* translated hw version & fw rom version */
+	ctrlPa2 = ((UINT32) (p_info->eWmtHwVer) << 16) | (fw_ver & 0x0000FFFF);
+
+	iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2);
+	if (iret)
+		WMT_WARN_FUNC("0x%x: WMT_CTRL_HWIDVER_SET fail(%d)\n", wmt_ic_ops_soc.icId, iret);
+
+	gp_soc_info = p_info;
+	return 0;
+}
+
+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver)
+{
+	/* match chipversion with u4HwVer item in mtk_wcn_soc_info_table */
+	const UINT32 size = osal_array_size(mtk_wcn_soc_info_table);
+	INT32 index = 0;
+
+	/* George: reverse the search order to favor newer version products
+	* TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver()
+	* is changed correctly in the future!!
+	* Leave full match here is a workaround for GPS to distinguish E3/E4 ICs.
+	*/
+	index = size - 1;
+	/* full match */
+	while ((0 <= index) && (hw_ver != mtk_wcn_soc_info_table[index].u4HwVer))
+		--index;
+	if (0 <= index) {
+		WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index);
+		return &mtk_wcn_soc_info_table[index];
+	}
+
+	WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver);
+
+	/* George: The ONLY CORRECT method to find supported hw table. Match MAJOR
+	 * NUM only can help us support future minor hw ECO, or fab switch, etc.
+	 * FULL matching eliminate such flexibility and software package have to be
+	 * updated EACH TIME even when minor hw ECO or fab switch!!!
+	 */
+	/* George: reverse the search order to favor newer version products */
+	index = size - 1;
+	/* major num match */
+	while ((0 <= index) &&
+		(MAJORNUM(hw_ver) != MAJORNUM(mtk_wcn_soc_info_table[index].u4HwVer))) {
+		--index;
+	}
+	if (0 <= index) {
+		WMT_DBG_FUNC("0x%x: found ic info for hw_ver(0x%x) by major num! index:%d\n",
+			wmt_ic_ops_soc.icId, hw_ver, index);
+		return &mtk_wcn_soc_info_table[index];
+	}
+
+	WMT_ERR_FUNC("0x%x: find no ic info for hw_ver(0x%x) by full match nor major num match!\n",
+			wmt_ic_ops_soc.icId, hw_ver);
+	WMT_ERR_FUNC("Set default chip version: E1!\n");
+	return &mtk_wcn_soc_info_table[0];
+}
+
+#if CFG_WMT_FILTER_MODE_SETTING
+static INT32 wmt_stp_wifi_lte_coex(VOID)
+{
+	INT32 iRet;
+	unsigned long addr;
+	WMT_GEN_CONF *pWmtGenConf;
+
+	/*Get wmt config */
+	iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0);
+	if (iRet) {
+		WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet);
+		return -2;
+	}
+	WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr);
+
+	pWmtGenConf = (P_WMT_GEN_CONF) addr;
+
+	/*Check if WMT.cfg exists */
+	if (pWmtGenConf->cfgExist == 0) {
+		WMT_INFO_FUNC("cfgExist == 0, skip config chip\n");
+		/*if WMT.cfg not existed, still return success and adopt the default value */
+		return 0;
+	}
+
+	osal_sleep_ms(5);
+
+	if (pWmtGenConf->coex_wmt_filter_mode == 0) {
+		if ((0x6752 == wmt_ic_ops_soc.icId) ||
+		    (0x6580 == wmt_ic_ops_soc.icId) ||
+		    (0x8163 == wmt_ic_ops_soc.icId) ||
+		    (0x0326 == wmt_ic_ops_soc.icId) ||
+		    (0x0321 == wmt_ic_ops_soc.icId) ||
+		    (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) {
+			iRet =
+			    wmt_core_init_script(set_wifi_lte_coex_table_1, osal_array_size(set_wifi_lte_coex_table_1));
+			WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_1 %s(%d)\n", iRet ? "fail" : "ok", iRet);
+		} else if (0x0279 == wmt_ic_ops_soc.icId) {
+			/* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/
+			if (pWmtGenConf->coex_wmt_ext_component) {
+				WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component);
+				set_wifi_lte_coex_table_2[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component;
+			}
+			iRet =
+			    wmt_core_init_script(set_wifi_lte_coex_table_2, osal_array_size(set_wifi_lte_coex_table_2));
+			WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_2 %s(%d)\n", iRet ? "fail" : "ok", iRet);
+		} else {
+			iRet =
+			    wmt_core_init_script(set_wifi_lte_coex_table_0, osal_array_size(set_wifi_lte_coex_table_0));
+			WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 %s(%d)\n", iRet ? "fail" : "ok", iRet);
+		}
+	}
+
+	return iRet;
+}
+#endif
+
+static INT32 wmt_stp_init_coex(VOID)
+{
+	INT32 iRet;
+	unsigned long addr;
+	WMT_GEN_CONF *pWmtGenConf;
+
+#define COEX_WMT  0
+
+#if CFG_SUBSYS_COEX_NEED
+	/* no need for MT6628 */
+#define COEX_BT   1
+#define COEX_WIFI 2
+#define COEX_PTA  3
+#define COEX_MISC 4
+#endif
+	/*Get wmt config */
+	iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0);
+	if (iRet) {
+		WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet);
+		return -2;
+	}
+	WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr);
+
+	pWmtGenConf = (P_WMT_GEN_CONF) addr;
+
+	/*Check if WMT.cfg exists */
+	if (pWmtGenConf->cfgExist == 0) {
+		WMT_INFO_FUNC("cfgExist == 0, skip config chip\n");
+		/*if WMT.cfg not existed, still return success and adopt the default value */
+		return 0;
+	}
+
+	/*Dump the coex-related info */
+	WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode);
+#if CFG_SUBSYS_COEX_NEED
+	WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+		     pWmtGenConf->coex_bt_rssi_upper_limit,
+		     pWmtGenConf->coex_bt_rssi_mid_limit,
+		     pWmtGenConf->coex_bt_rssi_lower_limit,
+		     pWmtGenConf->coex_bt_pwr_high, pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low);
+	WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+		     pWmtGenConf->coex_wifi_rssi_upper_limit,
+		     pWmtGenConf->coex_wifi_rssi_mid_limit,
+		     pWmtGenConf->coex_wifi_rssi_lower_limit,
+		     pWmtGenConf->coex_wifi_pwr_high, pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low);
+	WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+		     pWmtGenConf->coex_ext_pta_hi_tx_tag,
+		     pWmtGenConf->coex_ext_pta_hi_rx_tag,
+		     pWmtGenConf->coex_ext_pta_lo_tx_tag,
+		     pWmtGenConf->coex_ext_pta_lo_rx_tag,
+		     pWmtGenConf->coex_ext_pta_sample_t1,
+		     pWmtGenConf->coex_ext_pta_sample_t2, pWmtGenConf->coex_ext_pta_wifi_bt_con_trx);
+	WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n",
+		     pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set);
+#endif
+
+	/*command adjustion due to WMT.cfg */
+	coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode;
+	if (gWmtDbgLvl >= WMT_LOG_DBG)
+		wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz);
+
+#if CFG_SUBSYS_COEX_NEED
+	coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit;
+	coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit;
+	coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit;
+	coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high;
+	coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid;
+	coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low;
+	if (gWmtDbgLvl >= WMT_LOG_DBG)
+		wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz);
+
+	coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit;
+	coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit;
+	coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit;
+	coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high;
+	coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid;
+	coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low;
+	if (gWmtDbgLvl >= WMT_LOG_DBG)
+		wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0],
+				   coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz);
+
+	coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag;
+	coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag;
+	coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag;
+	coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag;
+	coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8);
+	coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0);
+	coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8);
+	coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0);
+	coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx;
+	if (gWmtDbgLvl >= WMT_LOG_DBG)
+		wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz);
+
+	osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on,
+		    sizeof(pWmtGenConf->coex_misc_ext_pta_on));
+	osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set,
+		    sizeof(pWmtGenConf->coex_misc_ext_feature_set));
+
+	wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, coex_table[COEX_MISC].cmdSz);
+#endif
+
+	iRet = wmt_core_init_script(coex_table, sizeof(coex_table) / sizeof(coex_table[0]));
+
+	return iRet;
+}
+
+#if CFG_WMT_SDIO_DRIVING_SET
+static INT32 mtk_wcn_soc_set_sdio_driving(void)
+{
+	INT32 ret = 0;
+
+	unsigned long addr;
+	WMT_GEN_CONF *pWmtGenConf;
+	UINT32 drv_val = 0;
+
+	/*Get wmt config */
+	ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0);
+	if (ret) {
+		WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret);
+		return -1;
+	}
+	WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr);
+
+	pWmtGenConf = (P_WMT_GEN_CONF) addr;
+
+	/*Check if WMT.cfg exists */
+	if (pWmtGenConf->cfgExist == 0) {
+		WMT_INFO_FUNC("cfgExist == 0, skip config chip\n");
+		/*if WMT.cfg not existed, still return success and adopt the default value */
+		return 0;
+	}
+
+	drv_val = pWmtGenConf->sdio_driving_cfg;
+
+	/*Dump the sdio driving related info */
+	WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val);
+
+	sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0);	/* DAT0 and DAT1 */
+	sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8);	/* DAT2 and DAT3 */
+	sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16);	/* CMD */
+
+	ret = wmt_core_init_script(sdio_driving_table, sizeof(sdio_driving_table) / sizeof(sdio_driving_table[0]));
+
+	return ret;
+}
+#endif
+
+#if CFG_WMT_CRYSTAL_TIMING_SET
+static INT32 mtk_wcn_soc_crystal_triming_set(VOID)
+{
+	INT32 iRet = 0;
+	PUINT8 pbuf = NULL;
+	UINT32 bufLen = 0;
+	WMT_CTRL_DATA ctrlData;
+	UINT32 uCryTimOffset = 0x6D;
+	MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE;
+	INT8 cCrystalTimingOffset = 0x0;
+	UINT8 cCrystalTiming = 0x0;
+	INT32 iCrystalTiming = 0x0;
+	MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE;
+	UINT32 u4Res;
+
+	bIsNvramExist = MTK_WCN_BOOL_FALSE;
+	 /**/ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET;
+	ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI";
+	ctrlData.au4CtrlData[1] = (UINT32) &pbuf;
+	ctrlData.au4CtrlData[2] = (UINT32) &bufLen;
+
+	iRet = wmt_ctrl(&ctrlData);
+	if (0 != iRet) {
+		WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", wmt_ic_ops_soc.icId, iRet);
+		bIsNvramExist = MTK_WCN_BOOL_FALSE;
+		bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE;
+		cCrystalTimingOffset = 0x0;
+		cCrystalTiming = 0x0;
+		iRet = -1;
+	} else {
+		WMT_DBG_FUNC("0x%x: nvram pBuf(0x%08x), bufLen(%d)\n", wmt_ic_ops_soc.icId, pbuf, bufLen);
+		if (bufLen < (uCryTimOffset + 1)) {
+			WMT_ERR_FUNC("0x%x: nvram len(%d) too short, crystalTimging value offset(%d)\n",
+				     wmt_ic_ops_soc.icId, bufLen, uCryTimOffset);
+			bIsNvramExist = MTK_WCN_BOOL_FALSE;
+			bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE;
+			cCrystalTimingOffset = 0x0;
+			cCrystalTiming = 0x0;
+		} else {
+			bIsNvramExist = MTK_WCN_BOOL_TRUE;
+			cCrystalTimingOffset = *(pbuf + uCryTimOffset);
+			if (cCrystalTimingOffset & 0x80) {
+				bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE;
+				cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f;
+			}
+			WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", cCrystalTimingOffset,
+				     bIsCrysTrimEnabled);
+		}
+		ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT;
+		ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI";
+		iRet = wmt_ctrl(&ctrlData);
+		if (0 != iRet) {
+			WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", wmt_ic_ops_soc.icId, iRet);
+			iRet = -2;
+		} else {
+			WMT_DBG_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n", wmt_ic_ops_soc.icId);
+		}
+	}
+	if ((MTK_WCN_BOOL_TRUE == bIsNvramExist) && (MTK_WCN_BOOL_TRUE == bIsCrysTrimEnabled)) {
+		/*get CrystalTiming value before set it */
+		iRet =
+		    wmt_core_tx(get_crystal_timing_script[0].cmd, get_crystal_timing_script[0].cmdSz, &u4Res,
+				MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) {
+			WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n",
+				     get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].cmdSz);
+			iRet = -3;
+			goto done;
+		}
+		/* EVENT BUF */
+		osal_memset(get_crystal_timing_script[0].evt, 0, get_crystal_timing_script[0].evtSz);
+		iRet = wmt_core_rx(get_crystal_timing_script[0].evt, get_crystal_timing_script[0].evtSz, &u4Res);
+		if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) {
+			WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n",
+				     get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].evtSz);
+			mtk_wcn_stp_dbg_dump_package();
+			iRet = -4;
+			goto done;
+		}
+
+		iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f;
+		if (cCrystalTimingOffset & 0x40) {
+			/*nagative offset value */
+			iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128;
+		} else {
+			iCrystalTiming += cCrystalTimingOffset;
+		}
+		WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming);
+		cCrystalTiming = iCrystalTiming > 0x7f ? 0x7f : iCrystalTiming;
+		cCrystalTiming = iCrystalTiming < 0 ? 0 : iCrystalTiming;
+		WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming);
+		/* set_crystal_timing_script */
+		WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming;
+		WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming;
+
+		iRet = wmt_core_init_script(set_crystal_timing_script, osal_array_size(set_crystal_timing_script));
+		if (iRet) {
+			WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet);
+			iRet = -5;
+		} else {
+			WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", WMT_SET_CRYSTAL_TRIMING_CMD[5]);
+			iRet =
+			    wmt_core_init_script(get_crystal_timing_script, osal_array_size(get_crystal_timing_script));
+			if (iRet) {
+				WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet);
+				iRet = -6;
+			} else {
+				WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n",
+					      WMT_GET_CRYSTAL_TRIMING_EVT[5]);
+				iRet = 0x0;
+			}
+		}
+	}
+done:
+	return iRet;
+}
+#endif
+
+#if CFG_WMT_MULTI_PATCH
+static INT32 mtk_wcn_soc_patch_info_prepare(VOID)
+{
+	INT32 iRet = -1;
+	WMT_CTRL_DATA ctrlData;
+
+	ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH;
+	iRet = wmt_ctrl(&ctrlData);
+
+	return iRet;
+}
+
+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index)
+{
+	INT32 iRet = -1;
+	P_WMT_PATCH patchHdr;
+	PUINT8 pbuf;
+	UINT32 patchSize;
+	UINT32 fragSeq;
+	UINT32 fragNum;
+	UINT16 fragSize = 0;
+	UINT16 cmdLen;
+	UINT32 offset;
+	UINT32 u4Res;
+	UINT8 evtBuf[8];
+	UINT8 addressevtBuf[12];
+	UINT8 addressByte[4];
+	PINT8 cDataTime = NULL;
+	/*PINT8 cPlat = NULL; */
+	UINT16 u2HwVer = 0;
+	UINT16 u2SwVer = 0;
+	UINT32 u4PatchVer = 0;
+	UINT32 patchSizePerFrag = 0;
+	WMT_CTRL_DATA ctrlData;
+
+	/*1.check hardware information */
+	if (NULL == gp_soc_info) {
+		WMT_ERR_FUNC("null gp_soc_info!\n");
+		return -1;
+	}
+
+	osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName));
+
+	ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO;
+	ctrlData.au4CtrlData[0] = index + 1;
+	ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName;
+	ctrlData.au4CtrlData[2] = (SIZE_T) &addressByte;
+	iRet = wmt_ctrl(&ctrlData);
+	WMT_DBG_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName);
+
+	/* <2.2> read patch content */
+	ctrlData.ctrlId = WMT_CTRL_GET_PATCH;
+	ctrlData.au4CtrlData[0] = (SIZE_T) NULL;
+	ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName;
+	ctrlData.au4CtrlData[2] = (SIZE_T) &pbuf;
+	ctrlData.au4CtrlData[3] = (SIZE_T) &patchSize;
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet);
+		iRet -= 1;
+		goto done;
+	}
+
+	/* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */
+	pbuf += BCNT_PATCH_BUF_HEADROOM;
+	/* patch file with header:
+	 * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->|
+	 */
+	patchHdr = (P_WMT_PATCH) pbuf;
+	/* check patch file information */
+
+	cDataTime = patchHdr->ucDateTime;
+	u2HwVer = patchHdr->u2HwVer;
+	u2SwVer = patchHdr->u2SwVer;
+	u4PatchVer = patchHdr->u4PatchVer;
+	/*cPlat = &patchHdr->ucPLat[0]; */
+
+	cDataTime[15] = '\0';
+	if (index == 0) {
+		WMT_DBG_FUNC("===========================================\n");
+		WMT_INFO_FUNC("[Patch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n",
+		cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8),
+		((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8),
+		((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16),
+		patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]);
+		WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8));
+		WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8));
+		WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n",
+			      ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16));
+		WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1],
+			      patchHdr->ucPLat[2], patchHdr->ucPLat[3]);
+		WMT_DBG_FUNC("===========================================\n");
+	}
+
+	/* remove patch header:
+	 * |<-patch body: X Bytes (X=patchSize)--->|
+	 */
+	patchSize -= sizeof(WMT_PATCH);
+	pbuf += sizeof(WMT_PATCH);
+	patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE;
+	/* reserve 1st patch cmd space before patch body
+	 *        |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->|
+	 */
+	/* gp_soc_patch_info = patchHdr; */
+	osal_memcpy(&gp_soc_patch_info, patchHdr, osal_sizeof(WMT_PATCH));
+	pbuf -= sizeof(WMT_PATCH_CMD);
+
+	fragNum = patchSize / patchSizePerFrag;
+	fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1;
+
+	WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum);
+
+	/*send wmt part patch address command */
+	if (0x6752 == wmt_ic_ops_soc.icId ||
+	    0x8127 == wmt_ic_ops_soc.icId ||
+	    0x7623 == wmt_ic_ops_soc.icId ||
+	    0x6571 == wmt_ic_ops_soc.icId ||
+	    0x0326 == wmt_ic_ops_soc.icId ||
+	    0x0321 == wmt_ic_ops_soc.icId ||
+	    0x0335 == wmt_ic_ops_soc.icId ||
+	    0x0337 == wmt_ic_ops_soc.icId || 0x8163 == wmt_ic_ops_soc.icId || 0x6580 == wmt_ic_ops_soc.icId) {
+		/* MT6571 patch RAM base */
+		WMT_PATCH_ADDRESS_CMD[8] = 0x40;
+		WMT_PATCH_P_ADDRESS_CMD[8] = 0xc8;
+	}
+	/*send wmt part patch address command */
+	if (0x0279 == wmt_ic_ops_soc.icId) {
+		/* MT6797 patch RAM base */
+		WMT_PATCH_ADDRESS_CMD[8] = 0x08;
+		WMT_PATCH_ADDRESS_CMD[9] = 0x05;
+		WMT_PATCH_P_ADDRESS_CMD[8] = 0x2c;
+		WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b;
+	}
+
+	/*send wmt part patch address command */
+	iRet =
+	    wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) {
+		WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res);
+		iRet -= 1;
+		goto done;
+	}
+	osal_memset(addressevtBuf, 0, sizeof(addressevtBuf));
+	iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res);
+	if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) {
+		WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res);
+		iRet -= 1;
+		goto done;
+	}
+#if CFG_CHECK_WMT_RESULT
+	if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) {
+		WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n");
+		iRet -= 1;
+		goto done;
+	}
+#endif
+
+	/*send part patch address command */
+	osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte));
+	WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x",
+		      WMT_PATCH_P_ADDRESS_CMD[12],
+		      WMT_PATCH_P_ADDRESS_CMD[13], WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]);
+	iRet =
+	    wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), &u4Res,
+			MTK_WCN_BOOL_FALSE);
+	if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) {
+		WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", iRet, u4Res, index);
+		iRet -= 1;
+		goto done;
+	}
+	osal_memset(addressevtBuf, 0, sizeof(addressevtBuf));
+	iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res);
+	if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) {
+		WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, u4Res, index);
+		iRet -= 1;
+		goto done;
+	}
+#if CFG_CHECK_WMT_RESULT
+	if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) {
+		WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", index);
+		iRet -= 1;
+		goto done;
+	}
+#endif
+
+	/* send all fragments */
+	offset = sizeof(WMT_PATCH_CMD);
+	fragSeq = 0;
+	while (fragSeq < fragNum) {
+		WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum);
+		if (fragSeq == (fragNum - 1)) {
+			/* last fragment */
+			fragSize = patchSize - fragSeq * patchSizePerFrag;
+			WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST;
+		} else {
+			fragSize = patchSizePerFrag;
+			WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID;
+		}
+		/* update length field in CMD:flag+frag */
+		cmdLen = 1 + fragSize;
+		osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2);
+		/* copy patch CMD to buf (overwrite last 5-byte in prev frag) */
+		osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD));
+
+		/* iRet =
+		*(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD),
+		*&u4Res);
+		*/
+		iRet =
+			wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD),
+				&u4Res, MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) {
+			WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq,
+				     fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet);
+			iRet -= 1;
+			break;
+		}
+		WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n",
+			     fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res);
+
+		osal_memset(evtBuf, 0, sizeof(evtBuf));
+		/* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */
+		iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res);
+		if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) {
+			WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT),
+				     u4Res, iRet);
+			iRet -= 1;
+			break;
+		}
+#if CFG_CHECK_WMT_RESULT
+		if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) {
+			WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+				u4Res,
+				evtBuf[0],
+				evtBuf[1],
+				evtBuf[2],
+				evtBuf[3],
+				evtBuf[4]);
+			WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+				sizeof(WMT_PATCH_EVT),
+				WMT_PATCH_EVT[0],
+				WMT_PATCH_EVT[1],
+				WMT_PATCH_EVT[2],
+				WMT_PATCH_EVT[3],
+				WMT_PATCH_EVT[4]);
+			iRet -= 1;
+			break;
+		}
+#endif
+		WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res);
+		offset += patchSizePerFrag;
+		++fragSeq;
+	}
+
+	WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n",
+		      iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail");
+
+	if (fragSeq != fragNum)
+		iRet -= 1;
+done:
+	/* WMT_CTRL_FREE_PATCH always return 0 */
+	/* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */
+	ctrlData.ctrlId = WMT_CTRL_FREE_PATCH;
+	ctrlData.au4CtrlData[0] = index + 1;
+	wmt_ctrl(&ctrlData);
+
+	return iRet;
+}
+
+#else
+static INT32 mtk_wcn_soc_patch_dwn(VOID)
+{
+	INT32 iRet = -1;
+	P_WMT_PATCH patchHdr;
+	PUINT8 pbuf;
+	UINT32 patchSize;
+	UINT32 fragSeq;
+	UINT32 fragNum;
+	UINT16 fragSize = 0;
+	UINT16 cmdLen;
+	UINT32 offset;
+	UINT32 u4Res;
+	UINT8 evtBuf[8];
+	PINT8 cDataTime = NULL;
+	/*PINT8 cPlat = NULL; */
+	UINT16 u2HwVer = 0;
+	UINT16 u2SwVer = 0;
+	UINT32 u4PatchVer = 0;
+	UINT32 patchSizePerFrag = 0;
+	WMT_CTRL_DATA ctrlData;
+
+	/*1.check hardware information */
+	if (NULL == gp_soc_info) {
+		WMT_ERR_FUNC("null gp_soc_info!\n");
+		return -1;
+	}
+	/* <2> search patch and read patch content */
+	/* <2.1> search patch */
+	ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH;
+	iRet = wmt_ctrl(&ctrlData);
+	if (0 == iRet) {
+		/* patch with correct Hw Ver Major Num found */
+		ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME;
+		ctrlData.au4CtrlData[0] = (UINT32) &gFullPatchName;
+		iRet = wmt_ctrl(&ctrlData);
+
+		WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName);
+		/* <2.2> read patch content */
+		ctrlData.ctrlId = WMT_CTRL_GET_PATCH;
+		ctrlData.au4CtrlData[0] = (UINT32) NULL;
+		ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName;
+
+	} else {
+		iRet -= 1;
+		return iRet;
+	}
+	ctrlData.au4CtrlData[2] = (UINT32) &pbuf;
+	ctrlData.au4CtrlData[3] = (UINT32) &patchSize;
+	iRet = wmt_ctrl(&ctrlData);
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet);
+		iRet -= 1;
+		goto done;
+	}
+
+	/* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */
+	pbuf += BCNT_PATCH_BUF_HEADROOM;
+	/* patch file with header:
+	 * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->|
+	 */
+	patchHdr = (P_WMT_PATCH) pbuf;
+	/* check patch file information */
+
+	cDataTime = patchHdr->ucDateTime;
+	u2HwVer = patchHdr->u2HwVer;
+	u2SwVer = patchHdr->u2SwVer;
+	u4PatchVer = patchHdr->u4PatchVer;
+	/*cPlat = &patchHdr->ucPLat[0]; */
+
+	cDataTime[15] = '\0';
+	WMT_DBG_FUNC("===========================================\n");
+	WMT_INFO_FUNC("[ConsysPatch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n",
+	cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8),
+	((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8),
+	((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16),
+	patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]);
+	WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8));
+	WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8));
+	WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n",
+		      ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16));
+	WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1],
+		      patchHdr->ucPLat[2], patchHdr->ucPLat[3]);
+	WMT_DBG_FUNC("===========================================\n");
+
+	/* remove patch header:
+	 * |<-patch body: X Bytes (X=patchSize)--->|
+	 */
+	patchSize -= sizeof(WMT_PATCH);
+	pbuf += sizeof(WMT_PATCH);
+	patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE;
+	/* reserve 1st patch cmd space before patch body
+	 *        |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->|
+	 */
+	pbuf -= sizeof(WMT_PATCH_CMD);
+
+	fragNum = patchSize / patchSizePerFrag;
+	fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1;
+
+	WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum);
+
+	/* send all fragments */
+	offset = sizeof(WMT_PATCH_CMD);
+	fragSeq = 0;
+	while (fragSeq < fragNum) {
+		WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum);
+		if (fragSeq == (fragNum - 1)) {
+			/* last fragment */
+			fragSize = patchSize - fragSeq * patchSizePerFrag;
+			WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST;
+		} else {
+			fragSize = patchSizePerFrag;
+			WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID;
+		}
+		/* update length field in CMD:flag+frag */
+		cmdLen = 1 + fragSize;
+		osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2);
+		/* copy patch CMD to buf (overwrite last 5-byte in prev frag) */
+		osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD));
+
+		/* iRet =
+		*	(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD),
+		*	&u4Res);
+		*/
+		iRet =
+		    wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), &u4Res,
+				MTK_WCN_BOOL_FALSE);
+		if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) {
+			WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq,
+				     fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet);
+			iRet -= 1;
+			break;
+		}
+		WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n",
+			     fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res);
+
+		osal_memset(evtBuf, 0, sizeof(evtBuf));
+		/* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */
+		iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res);
+		if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) {
+			WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT),
+				     u4Res, iRet);
+			iRet -= 1;
+			break;
+		}
+#if CFG_CHECK_WMT_RESULT
+		if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) {
+			WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+				u4Res,
+				evtBuf[0],
+				evtBuf[1],
+				evtBuf[2],
+				evtBuf[3],
+				evtBuf[4]);
+			WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
+				sizeof(WMT_PATCH_EVT),
+				WMT_PATCH_EVT[0],
+				WMT_PATCH_EVT[1],
+				WMT_PATCH_EVT[2],
+				WMT_PATCH_EVT[3],
+				WMT_PATCH_EVT[4]);
+			iRet -= 1;
+			break;
+		}
+#endif
+		WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res);
+		offset += patchSizePerFrag;
+		++fragSeq;
+	}
+
+	WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n",
+		      iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail");
+
+	if (fragSeq != fragNum)
+		iRet -= 1;
+done:
+	/* WMT_CTRL_FREE_PATCH always return 0 */
+	wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL);
+
+	return iRet;
+}
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c
new file mode 100644
index 0000000000000..747ed64af2d2d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c
@@ -0,0 +1,1938 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-LIB]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+
+#include "wmt_dev.h"
+#include "wmt_lib.h"
+#include "wmt_conf.h"
+#include "wmt_core.h"
+#include "wmt_plat.h"
+
+#include "stp_core.h"
+#include "btm_core.h"
+#include "psm_core.h"
+#include "stp_dbg.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/* A table for translation: CMB_STUB_AIF_X=>WMT_IC_PIN_STATE */
+static const WMT_IC_PIN_STATE cmb_aif2pin_stat[] = {
+	[CMB_STUB_AIF_0] = WMT_IC_AIF_0,
+	[CMB_STUB_AIF_1] = WMT_IC_AIF_1,
+	[CMB_STUB_AIF_2] = WMT_IC_AIF_2,
+	[CMB_STUB_AIF_3] = WMT_IC_AIF_3,
+};
+
+#if CFG_WMT_PS_SUPPORT
+static UINT32 gPsIdleTime = STP_PSM_IDLE_TIME_SLEEP;
+static UINT32 gPsEnable = 1;
+static PF_WMT_SDIO_PSOP sdio_own_ctrl;
+#endif
+
+#define WMT_STP_CPUPCR_BUF_SIZE 6144
+static UINT8 g_cpupcr_buf[WMT_STP_CPUPCR_BUF_SIZE] = { 0 };
+
+static UINT32 g_quick_sleep_ctrl = 1;
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+DEV_WMT gDevWmt;
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+#if CFG_WMT_PS_SUPPORT
+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action);
+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID);
+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID);
+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID);
+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action);
+#endif
+
+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pLxOp);
+
+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ);
+
+static INT32 wmtd_thread(PVOID pvData);
+
+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag);
+static MTK_WCN_BOOL wmt_lib_hw_state_show(VOID);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+INT32 wmt_lib_idc_lock_aquire(VOID)
+{
+	return osal_lock_sleepable_lock(&gDevWmt.idc_lock);
+}
+
+VOID wmt_lib_idc_lock_release(VOID)
+{
+	osal_unlock_sleepable_lock(&gDevWmt.idc_lock);
+}
+INT32 wmt_lib_psm_lock_aquire(void)
+{
+	return osal_lock_sleepable_lock(&gDevWmt.psm_lock);
+}
+
+void wmt_lib_psm_lock_release(void)
+{
+	osal_unlock_sleepable_lock(&gDevWmt.psm_lock);
+}
+
+INT32 DISABLE_PSM_MONITOR(void)
+{
+	INT32 ret = 0;
+
+	/* osal_lock_sleepable_lock(&gDevWmt.psm_lock); */
+	ret = wmt_lib_psm_lock_aquire();
+	if (ret) {
+		WMT_ERR_FUNC("--->lock psm_lock failed, ret=%d\n", ret);
+		return ret;
+	}
+#if CFG_WMT_PS_SUPPORT
+	ret = wmt_lib_ps_disable();
+	if (ret) {
+		WMT_ERR_FUNC("wmt_lib_ps_disable fail, ret=%d\n", ret);
+		wmt_lib_psm_lock_release();
+	}
+#endif
+
+	return ret;
+}
+
+void ENABLE_PSM_MONITOR(void)
+{
+#if CFG_WMT_PS_SUPPORT
+	wmt_lib_ps_enable();
+#endif
+	/* osal_unlock_sleepable_lock(&gDevWmt.psm_lock); */
+	wmt_lib_psm_lock_release();
+}
+
+INT32 wmt_lib_init(VOID)
+{
+	INT32 iRet;
+	UINT32 i;
+	P_DEV_WMT pDevWmt;
+	P_OSAL_THREAD pThraed;
+
+	/* create->init->start */
+	/* 1. create: static allocation with zero initialization */
+	pDevWmt = &gDevWmt;
+	osal_memset(&gDevWmt, 0, sizeof(gDevWmt));
+
+	iRet = wmt_conf_read_file();
+	if (iRet) {
+		WMT_ERR_FUNC("read wmt config file fail(%d)\n", iRet);
+		return -1;
+	}
+
+	pThraed = &gDevWmt.thread;
+
+	/* Create mtk_wmtd thread */
+	osal_strncpy(pThraed->threadName, "mtk_wmtd", sizeof(pThraed->threadName));
+	pThraed->pThreadData = (VOID *) pDevWmt;
+	pThraed->pThreadFunc = (VOID *) wmtd_thread;
+	iRet = osal_thread_create(pThraed);
+	if (iRet) {
+		WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThraed, iRet);
+		return -2;
+	}
+
+	/* 2. initialize */
+	/* Initialize wmt_core */
+
+	iRet = wmt_core_init();
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_core_init() fail(%d)\n", iRet);
+		return -1;
+	}
+
+	/* Initialize WMTd Thread Information: Thread */
+	osal_event_init(&pDevWmt->rWmtdWq);
+	osal_sleepable_lock_init(&pDevWmt->psm_lock);
+	osal_sleepable_lock_init(&pDevWmt->idc_lock);
+	osal_sleepable_lock_init(&pDevWmt->rActiveOpQ.sLock);
+	osal_sleepable_lock_init(&pDevWmt->rFreeOpQ.sLock);
+	pDevWmt->state.data = 0;
+
+	/* Initialize op queue */
+	RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE);
+	RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE);
+	/* Put all to free Q */
+	for (i = 0; i < WMT_OP_BUF_SIZE; i++) {
+		osal_signal_init(&(pDevWmt->arQue[i].signal));
+		wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i]));
+	}
+
+	/* initialize stp resources */
+	osal_event_init(&pDevWmt->rWmtRxWq);
+
+	/*function driver callback */
+	for (i = 0; i < WMTDRV_TYPE_WIFI; i++)
+		pDevWmt->rFdrvCb.fDrvRst[i] = NULL;
+
+	pDevWmt->hw_ver = WMTHWVER_MAX;
+	WMT_INFO_FUNC("***********Init, hw->ver = %x\n", pDevWmt->hw_ver);
+
+	/* TODO:[FixMe][GeorgeKuo]: wmt_lib_conf_init */
+	/* initialize default configurations */
+	/* i4Result = wmt_lib_conf_init(VOID); */
+	/* WMT_WARN_FUNC("wmt_drv_conf_init(%d)\n", i4Result); */
+
+	osal_signal_init(&pDevWmt->cmdResp);
+	osal_event_init(&pDevWmt->cmdReq);
+
+	/* initialize platform resources */
+	if (0 != gDevWmt.rWmtGenConf.cfgExist)
+		iRet = wmt_plat_init(gDevWmt.rWmtGenConf.co_clock_flag & 0x0f);
+	else
+		iRet = wmt_plat_init(0);
+
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_plat_init() fail(%d)\n", iRet);
+		return -3;
+	}
+#if CFG_WMT_PS_SUPPORT
+	iRet = wmt_lib_ps_init();
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_lib_ps_init() fail(%d)\n", iRet);
+		return -4;
+	}
+#endif
+
+	/* 3. start: start running mtk_wmtd */
+	iRet = osal_thread_run(pThraed);
+	if (iRet) {
+		WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThraed, iRet);
+		return -5;
+	}
+
+	/*4. register irq callback to WMT-PLAT */
+	wmt_plat_irq_cb_reg(wmt_lib_ps_irq_cb);
+
+	/*5. register audio if control callback to WMT-PLAT */
+	wmt_plat_aif_cb_reg(wmt_lib_set_aif);
+
+	/*6. register function control callback to WMT-PLAT */
+	wmt_plat_func_ctrl_cb_reg(mtk_wcn_wmt_func_ctrl_for_plat);
+
+	wmt_plat_deep_idle_ctrl_cb_reg(mtk_wcn_consys_stp_btif_dpidle_ctrl);
+	/*7 reset gps/bt state */
+
+	mtk_wcn_wmt_system_state_reset();
+
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+	mtk_wcn_wmt_exp_init();
+#endif
+
+#if CFG_WMT_LTE_COEX_HANDLING
+	wmt_idc_init();
+#endif
+	WMT_DBG_FUNC("init success\n");
+	return 0;
+}
+
+INT32 wmt_lib_deinit(VOID)
+{
+	INT32 iRet;
+	P_DEV_WMT pDevWmt;
+	P_OSAL_THREAD pThraed;
+	INT32 i;
+	INT32 iResult;
+
+	pDevWmt = &gDevWmt;
+	pThraed = &gDevWmt.thread;
+	iResult = 0;
+
+	/* stop->deinit->destroy */
+
+	/* 1. stop: stop running mtk_wmtd */
+	iRet = osal_thread_stop(pThraed);
+	if (iRet) {
+		WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet);
+		iResult += 1;
+	}
+
+	/* 2. deinit: */
+
+#if CFG_WMT_PS_SUPPORT
+	iRet = wmt_lib_ps_deinit();
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_lib_ps_deinit fail(%d)\n", iRet);
+		iResult += 2;
+	}
+#endif
+
+	iRet = wmt_plat_deinit();
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_plat_deinit fail(%d)\n", iRet);
+		iResult += 4;
+	}
+
+	osal_event_deinit(&pDevWmt->cmdReq);
+	osal_signal_deinit(&pDevWmt->cmdResp);
+
+	/* de-initialize stp resources */
+	osal_event_deinit(&pDevWmt->rWmtRxWq);
+
+	for (i = 0; i < WMT_OP_BUF_SIZE; i++)
+		osal_signal_deinit(&(pDevWmt->arQue[i].signal));
+
+
+	osal_sleepable_lock_deinit(&pDevWmt->rFreeOpQ.sLock);
+	osal_sleepable_lock_deinit(&pDevWmt->rActiveOpQ.sLock);
+	osal_sleepable_lock_deinit(&pDevWmt->idc_lock);
+	osal_sleepable_lock_deinit(&pDevWmt->psm_lock);
+	osal_event_deinit(&pDevWmt->rWmtdWq);
+
+	iRet = wmt_core_deinit();
+	if (iRet) {
+		WMT_ERR_FUNC("wmt_core_deinit fail(%d)\n", iRet);
+		iResult += 8;
+	}
+
+	/* 3. destroy */
+	iRet = osal_thread_destroy(pThraed);
+	if (iRet) {
+		WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet);
+		iResult += 16;
+	}
+	osal_memset(&gDevWmt, 0, sizeof(gDevWmt));
+
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+	mtk_wcn_wmt_exp_deinit();
+#endif
+
+#if CFG_WMT_LTE_COEX_HANDLING
+	wmt_idc_deinit();
+#endif
+
+	return iResult;
+}
+
+VOID wmt_lib_flush_rx(VOID)
+{
+	mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX);
+}
+
+INT32 wmt_lib_trigger_cmd_signal(INT32 result)
+{
+	P_OSAL_SIGNAL pSignal = &gDevWmt.cmdResp;
+
+	gDevWmt.cmdResult = result;
+	osal_raise_signal(pSignal);
+	WMT_DBG_FUNC("wakeup cmdResp\n");
+	return 0;
+}
+
+P_OSAL_EVENT wmt_lib_get_cmd_event(VOID)
+{
+	return &gDevWmt.cmdReq;
+}
+
+INT32 wmt_lib_set_patch_name(PUINT8 cPatchName)
+{
+	osal_strncpy(gDevWmt.cPatchName, cPatchName, NAME_MAX);
+	return 0;
+}
+
+INT32 wmt_lib_set_hif(unsigned long hifconf)
+{
+	UINT32 val;
+	P_WMT_HIF_CONF pHif = &gDevWmt.rWmtHifConf;
+
+	val = hifconf & 0xF;
+	if (STP_UART_FULL == val) {
+		pHif->hifType = WMT_HIF_UART;
+		val = (hifconf >> 8);
+		pHif->au4HifConf[0] = val;
+		pHif->au4HifConf[1] = val;
+		mtk_wcn_stp_set_if_tx_type(STP_UART_IF_TX);
+	} else if (STP_SDIO == val) {
+		pHif->hifType = WMT_HIF_SDIO;
+		mtk_wcn_stp_set_if_tx_type(STP_SDIO_IF_TX);
+	} else if (STP_BTIF_FULL == val) {
+		pHif->hifType = WMT_HIF_BTIF;
+		mtk_wcn_stp_set_if_tx_type(STP_BTIF_IF_TX);
+	} else {
+		WMT_WARN_FUNC("invalid stp mode: %u\n", val);
+		mtk_wcn_stp_set_if_tx_type(STP_MAX_IF_TX);
+		return -1;
+	}
+
+	val = (hifconf & 0xF0) >> 4;
+	if (WMT_FM_COMM == val) {
+		pHif->au4StrapConf[0] = WMT_FM_COMM;
+	} else if (WMT_FM_I2C == val) {
+		pHif->au4StrapConf[0] = WMT_FM_I2C;
+	} else {
+		WMT_WARN_FUNC("invalid fm mode: %u\n", val);
+		return -2;
+	}
+
+	WMT_WARN_FUNC("new hifType: %d, fm:%d\n", pHif->hifType, pHif->au4StrapConf[0]);
+	return 0;
+}
+
+P_WMT_HIF_CONF wmt_lib_get_hif(VOID)
+{
+	return &gDevWmt.rWmtHifConf;
+}
+
+PUINT8 wmt_lib_get_cmd(VOID)
+{
+	if (osal_test_and_clear_bit(WMT_STAT_CMD, &gDevWmt.state))
+		return gDevWmt.cCmd;
+
+	return NULL;
+}
+
+MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID)
+{
+	return osal_test_bit(WMT_STAT_CMD, &gDevWmt.state) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE;
+}
+
+#if CFG_WMT_PS_SUPPORT
+INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime)
+{
+	gPsIdleTime = psIdleTime;
+	return gPsIdleTime;
+}
+
+INT32 wmt_lib_ps_ctrl(UINT32 state)
+{
+	if (0 == state) {
+		wmt_lib_ps_disable();
+		gPsEnable = 0;
+	} else {
+		gPsEnable = 1;
+		wmt_lib_ps_enable();
+	}
+	return 0;
+}
+
+INT32 wmt_lib_ps_enable(VOID)
+{
+	if (gPsEnable)
+		mtk_wcn_stp_psm_enable(gPsIdleTime);
+
+	return 0;
+}
+
+INT32 wmt_lib_ps_disable(VOID)
+{
+	if (gPsEnable)
+		return mtk_wcn_stp_psm_disable();
+
+	return 0;
+}
+
+INT32 wmt_lib_ps_init(VOID)
+{
+	/* mtk_wcn_stp_psm_register_wmt_cb(wmt_lib_ps_stp_cb); */
+	return 0;
+}
+
+INT32 wmt_lib_ps_deinit(VOID)
+{
+	/* mtk_wcn_stp_psm_unregister_wmt_cb(); */
+	return 0;
+}
+
+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action)
+{
+	P_OSAL_OP lxop;
+	MTK_WCN_BOOL bRet;
+	UINT32 u4Wait;
+	P_OSAL_SIGNAL pSignal;
+
+	lxop = wmt_lib_get_free_op();
+	if (!lxop) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+	pSignal = &lxop->signal;
+	pSignal->timeoutValue = 0;
+	lxop->op.opId = WMT_OPID_PWR_SV;
+	lxop->op.au4OpData[0] = action;
+	lxop->op.au4OpData[1] = (SIZE_T) mtk_wcn_stp_psm_notify_stp;
+	u4Wait = 0;
+	bRet = wmt_lib_put_act_op(lxop);
+	return bRet;
+}
+
+#if CFG_WMT_LTE_COEX_HANDLING
+MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor)
+{
+	P_OSAL_OP lxop;
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	P_OSAL_SIGNAL pSignal;
+	INT32 ret = 0;
+	UINT16 msg_len = 0;
+	static UINT8 msg_local_buffer[1300];
+#if	CFG_WMT_LTE_ENABLE_MSGID_MAPPING
+	MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE;
+#endif
+	WMT_DBG_FUNC("idc_infor from conn_md is 0x%p\n", idc_infor);
+	ret = wmt_lib_idc_lock_aquire();
+	if (ret) {
+		WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", ret);
+		return MTK_WCN_BOOL_FALSE;
+	}
+	msg_len = idc_infor->local_para_ptr->msg_len - osal_sizeof(local_para_struct);
+	osal_memcpy(&msg_local_buffer[0], &msg_len, osal_sizeof(msg_len));
+	osal_memcpy(&msg_local_buffer[osal_sizeof(msg_len)],
+			&(idc_infor->local_para_ptr->data[0]), msg_len - 1);
+	wmt_lib_idc_lock_release();
+	lxop = wmt_lib_get_free_op();
+	if (!lxop) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+	pSignal = &lxop->signal;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+	lxop->op.opId = WMT_OPID_IDC_MSG_HANDLING;
+	lxop->op.au4OpData[0] = (size_t) msg_local_buffer;
+	/*msg opcode fill rule is still not clrear,need scott comment */
+	/***********************************************************/
+	WMT_DBG_FUNC("ilm msg id is (0x%08x)\n", idc_infor->msg_id);
+
+#if	CFG_WMT_LTE_ENABLE_MSGID_MAPPING
+	switch (idc_infor->msg_id) {
+	case IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND:
+		lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_PARA;
+		break;
+	case IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND:
+		lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_FREQ;
+		break;
+	case IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND:
+		lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_WIFI_MAX_POWER;
+		break;
+	case IPC_MSG_ID_EL1_LTE_TX_IND:
+		lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_INDICATION;
+		break;
+	case IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND:
+		lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS;
+		break;
+	default:
+		unknown_msgid = MTK_WCN_BOOL_TRUE;
+		break;
+	}
+
+	if (MTK_WCN_BOOL_FALSE == unknown_msgid) {
+		/*wake up chip first */
+		if (DISABLE_PSM_MONITOR()) {
+			WMT_ERR_FUNC("wake up failed\n");
+			wmt_lib_put_op_to_free_queue(lxop);
+			return MTK_WCN_BOOL_FALSE;
+		}
+
+		bRet = wmt_lib_put_act_op(lxop);
+		ENABLE_PSM_MONITOR();
+		if (MTK_WCN_BOOL_FALSE == bRet)
+			WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet);
+		else
+			WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", lxop->op.opId, lxop->op.au4OpData[1]);
+	} else {
+		bRet = MTK_WCN_BOOL_FALSE;
+		wmt_lib_put_op_to_free_queue(lxop);
+		WMT_ERR_FUNC("unknown msgid from LTE(%d)\n", idc_infor->msg_id);
+	}
+#else
+	if ((idc_infor->msg_id >= IPC_EL1_MSG_ID_BEGIN)
+	    && (idc_infor->msg_id <= IPC_EL1_MSG_ID_BEGIN + IPC_EL1_MSG_ID_RANGE)) {
+		lxop->op.au4OpData[1] = idc_infor->msg_id - IPC_EL1_MSG_ID_BEGIN + LTE_MSG_ID_OFFSET - 1;
+
+		WMT_DBG_FUNC("LTE->CONN:(0x%x->0x%zx)\n", idc_infor->msg_id, lxop->op.au4OpData[1]);
+		/*wake up chip first */
+		if (DISABLE_PSM_MONITOR()) {
+			WMT_ERR_FUNC("wake up failed\n");
+			wmt_lib_put_op_to_free_queue(lxop);
+			return MTK_WCN_BOOL_FALSE;
+		}
+
+		bRet = wmt_lib_put_act_op(lxop);
+		ENABLE_PSM_MONITOR();
+		if (MTK_WCN_BOOL_FALSE == bRet) {
+			WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet);
+		} else {
+			WMT_DBG_FUNC("wmt_lib_handle_idc_msg OPID(%d) type(%d) ok\n",
+				     lxop->op.opId, lxop->op.au4OpData[1]);
+		}
+	} else {
+		wmt_lib_put_op_to_free_queue(lxop);
+		WMT_ERR_FUNC("msgid(%d) out of range,wmt drop it!\n", idc_infor->msg_id);
+	}
+#endif
+
+	return bRet;
+}
+#endif
+
+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID)
+{
+	return wmt_lib_ps_action(SLEEP);
+}
+
+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID)
+{
+	return wmt_lib_ps_action(WAKEUP);
+}
+
+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID)
+{
+#if 1
+	return wmt_lib_ps_action(WAKEUP);
+#else
+	return wmt_lib_ps_action(HOST_AWAKE);
+#endif
+}
+
+/* extern int g_block_tx; */
+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action)
+{
+	INT32 ret;
+
+	ret = 0;		/* TODO:[FixMe][George] initial value or compile warning? */
+	/* if(g_block_tx && (action == SLEEP)) */
+	if ((0 != mtk_wcn_stp_coredump_start_get()) && (action == SLEEP)) {
+		mtk_wcn_stp_psm_notify_stp(SLEEP);
+		return ret;
+	}
+
+	/*MT662x Not Ready */
+	if (!mtk_wcn_stp_is_ready()) {
+		WMT_DBG_FUNC("MT662x Not Ready, Dont Send Sleep/Wakeup Command\n");
+		mtk_wcn_stp_psm_notify_stp(ROLL_BACK);
+		return 0;
+	}
+
+	if (SLEEP == action) {
+		WMT_DBG_FUNC("send op-----------> sleep job\n");
+
+		if (!mtk_wcn_stp_is_sdio_mode()) {
+			ret = wmt_lib_ps_do_sleep();
+			WMT_DBG_FUNC("enable host eirq\n");
+			wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_EN);
+#if CFG_WMT_DUMP_INT_STATUS
+			if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status())
+				wmt_plat_BGF_irq_dump_status();
+#endif
+		} else {
+			/* ret = mtk_wcn_stp_sdio_do_own_set(); */
+			if (sdio_own_ctrl) {
+				ret = (*sdio_own_ctrl) (OWN_SET);
+			} else {
+				WMT_ERR_FUNC("sdio_own_ctrl is not registered\n");
+				ret = -1;
+			}
+
+			if (!ret) {
+				mtk_wcn_stp_psm_notify_stp(SLEEP);
+			} else if (ret == -2) {
+				mtk_wcn_stp_psm_notify_stp(ROLL_BACK);
+				WMT_WARN_FUNC("===[SDIO-PS] rollback due to tx busy===%%\n");
+			} else {
+				mtk_wcn_stp_psm_notify_stp(SLEEP);
+				WMT_ERR_FUNC("===[SDIO-PS] set own fails!===%%\n");
+			}
+		}
+
+		WMT_DBG_FUNC("send op<---------- sleep job\n");
+	} else if (WAKEUP == action) {
+		WMT_DBG_FUNC("send op --------> wake job\n");
+
+		if (!mtk_wcn_stp_is_sdio_mode()) {
+			WMT_DBG_FUNC("disable host eirq\n");
+#if CFG_WMT_DUMP_INT_STATUS
+			if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status())
+				wmt_plat_BGF_irq_dump_status();
+#endif
+			wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS);
+			ret = wmt_lib_ps_do_wakeup();
+		} else {
+			/* ret = mtk_wcn_stp_sdio_do_own_clr(); */
+
+			if (sdio_own_ctrl) {
+				ret = (*sdio_own_ctrl) (OWN_CLR);
+			} else {
+				WMT_ERR_FUNC("sdio_own_ctrl is not registered\n");
+				ret = -1;
+			}
+
+			if (!ret) {
+				mtk_wcn_stp_psm_notify_stp(WAKEUP);
+			} else {
+				mtk_wcn_stp_psm_notify_stp(WAKEUP);
+				WMT_ERR_FUNC("===[SDIO-PS] set own back fails!===%%\n");
+			}
+		}
+
+		WMT_DBG_FUNC("send op<---------- wake job\n");
+	} else if (HOST_AWAKE == action) {
+		WMT_DBG_FUNC("send op-----------> host awake job\n");
+
+		if (!mtk_wcn_stp_is_sdio_mode()) {
+			WMT_DBG_FUNC("disable host eirq\n");
+			/* IRQ already disabled */
+			/* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */
+#if 0
+			if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status())
+				wmt_plat_BGF_irq_dump_status();
+#endif
+			ret = wmt_lib_ps_do_host_awake();
+		} else {
+			WMT_DBG_FUNC("[SDIO-PS] SDIO host awake! ####\n");
+
+			/* ret = mtk_wcn_stp_sdio_do_own_clr(); */
+
+			if (sdio_own_ctrl) {
+				ret = (*sdio_own_ctrl) (OWN_CLR);
+			} else {
+				WMT_ERR_FUNC("sdio_own_ctrl is not registered\n");
+				ret = -1;
+			}
+
+			/* Here we set ret to 0 directly */
+			ret = 0;
+			if (!ret) {
+				mtk_wcn_stp_psm_notify_stp(HOST_AWAKE);
+			} else {
+				mtk_wcn_stp_psm_notify_stp(HOST_AWAKE);
+				WMT_ERR_FUNC("===[SDIO-PS]set own back fails!===%%\n");
+			}
+		}
+
+		WMT_DBG_FUNC("send op<----------- host awake job\n");
+	} else if (EIRQ == action) {
+		WMT_DBG_FUNC("send op -------------> eirq job\n");
+
+		if (!mtk_wcn_stp_is_sdio_mode()) {
+			WMT_DBG_FUNC("disable host eirq\n");
+			/* Disable interrupt */
+			/* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */
+			ret = mtk_wcn_stp_psm_notify_stp(EIRQ);
+		} else {
+			WMT_ERR_FUNC("[SDIO-PS]sdio own-back eirq!######\n");
+			ret = mtk_wcn_stp_psm_notify_stp(EIRQ);
+		}
+
+		WMT_DBG_FUNC("send op<----------- eirq job\n");
+	}
+
+	return ret;
+}
+#endif /* end of CFG_WMT_PS_SUPPORT */
+
+INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action)
+{
+#if CFG_WMT_PS_SUPPORT
+	return wmt_lib_ps_handler(action);
+#else
+	WMT_WARN_FUNC("CFG_WMT_PS_SUPPORT is not set\n");
+	return 0;
+#endif
+}
+
+MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID)
+{
+	if ((g_quick_sleep_ctrl) && (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_TRUE))
+		return wmt_core_is_quick_ps_support();
+	else
+		return MTK_WCN_BOOL_FALSE;
+}
+
+VOID wmt_lib_ps_irq_cb(VOID)
+{
+#if CFG_WMT_PS_SUPPORT
+	wmt_lib_ps_handler(EIRQ);
+#else
+	WMT_DBG_FUNC("CFG_WMT_PS_SUPPORT is not set\n");
+	return;
+#endif
+}
+
+VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb)
+{
+#if CFG_WMT_PS_SUPPORT
+	sdio_own_ctrl = own_cb;
+#endif
+}
+
+UINT32 wmt_lib_wait_event_checker(P_OSAL_THREAD pThread)
+{
+	P_DEV_WMT pDevWmt;
+
+	if (pThread) {
+		pDevWmt = (P_DEV_WMT) (pThread->pThreadData);
+		return !RB_EMPTY(&pDevWmt->rActiveOpQ);
+	}
+	WMT_ERR_FUNC("pThread(NULL)\n");
+	return 0;
+}
+
+static INT32 wmtd_thread(void *pvData)
+{
+	P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData;
+	P_OSAL_EVENT pEvent = NULL;
+	P_OSAL_OP pOp;
+	INT32 iResult;
+
+	if (NULL == pWmtDev) {
+		WMT_ERR_FUNC("pWmtDev(NULL)\n");
+		return -1;
+	}
+	WMT_INFO_FUNC("wmtd thread starts\n");
+
+	pEvent = &(pWmtDev->rWmtdWq);
+
+	for (;;) {
+		pOp = NULL;
+		pEvent->timeoutValue = 0;
+/*        osal_thread_wait_for_event(&pWmtDev->thread, pEvent);*/
+		osal_thread_wait_for_event(&pWmtDev->thread, pEvent, wmt_lib_wait_event_checker);
+
+		if (osal_thread_should_stop(&pWmtDev->thread)) {
+			WMT_INFO_FUNC("wmtd thread should stop now...\n");
+			/* TODO: clean up active opQ */
+			break;
+		}
+
+		/* get Op from activeQ */
+		pOp = wmt_lib_get_op(&pWmtDev->rActiveOpQ);
+		if (!pOp) {
+			WMT_WARN_FUNC("get_lxop activeQ fail\n");
+			continue;
+		}
+#if 0				/* wmt_core_opid_handler will do sanity check on opId, so no usage here */
+		id = lxop_get_opid(pLxOp);
+		if (id >= WMT_OPID_MAX) {
+			WMT_WARN_FUNC("abnormal opid id: 0x%x\n", id);
+			iResult = -1;
+			goto handlerDone;
+		}
+#endif
+
+		if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) {
+			/* when whole chip reset, only HW RST and SW RST cmd can execute */
+			if ((pOp->op.opId == WMT_OPID_HW_RST) || (pOp->op.opId == WMT_OPID_SW_RST)
+			    || (pOp->op.opId == WMT_OPID_GPIO_STATE)) {
+				iResult = wmt_core_opid(&pOp->op);
+			} else {
+				iResult = -2;
+				WMT_WARN_FUNC("Whole chip resetting, opid (%d) failed, iRet(%d)\n", pOp->op.opId,
+					      iResult);
+			}
+		} else {
+			wmt_lib_set_current_op(pWmtDev, pOp);
+			iResult = wmt_core_opid(&pOp->op);
+			wmt_lib_set_current_op(pWmtDev, NULL);
+		}
+
+		if (iResult)
+			WMT_WARN_FUNC("opid (%d) failed, iRet(%d)\n", pOp->op.opId, iResult);
+
+		if (osal_op_is_wait_for_signal(pOp)) {
+			osal_op_raise_signal(pOp, iResult);
+		} else {
+			/* put Op back to freeQ */
+			wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp);
+		}
+
+		if (WMT_OPID_EXIT == pOp->op.opId) {
+			WMT_INFO_FUNC("wmtd thread received exit signal\n");
+			break;
+		}
+	}
+
+	WMT_INFO_FUNC("wmtd thread exits succeed\n");
+
+	return 0;
+};
+
+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp)
+{
+	INT32 iRet;
+
+	if (!pOpQ || !pOp) {
+		WMT_WARN_FUNC("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", pOpQ, pOp);
+		osal_assert(pOpQ);
+		osal_assert(pOp);
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	iRet = osal_lock_sleepable_lock(&pOpQ->sLock);
+	if (iRet) {
+		WMT_WARN_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet);
+		return MTK_WCN_BOOL_FALSE;
+	}
+#if 0
+	if (pOpQ == &gDevWmt.rFreeOpQ)
+		WMT_INFO_FUNC("current wmt free queue count is(%d),opid(%d)\n", RB_COUNT(pOpQ), pOp->op.opId);
+#endif
+	/* acquire lock success */
+	if (!RB_FULL(pOpQ))
+		RB_PUT(pOpQ, pOp);
+	else
+		iRet = -1;
+
+	osal_unlock_sleepable_lock(&pOpQ->sLock);
+
+	if (iRet) {
+		WMT_WARN_FUNC("RB_FULL(0x%p)\n", pOpQ);
+		return MTK_WCN_BOOL_FALSE;
+	} else {
+		return MTK_WCN_BOOL_TRUE;
+	}
+}
+
+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ)
+{
+	P_OSAL_OP pOp;
+	INT32 iRet;
+
+	if (NULL == pOpQ) {
+		WMT_ERR_FUNC("pOpQ = NULL\n");
+		osal_assert(pOpQ);
+		return NULL;
+	}
+
+	iRet = osal_lock_sleepable_lock(&pOpQ->sLock);
+	if (iRet) {
+		WMT_ERR_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet);
+		return NULL;
+	}
+
+	/* acquire lock success */
+	RB_GET(pOpQ, pOp);
+	osal_unlock_sleepable_lock(&pOpQ->sLock);
+
+	if (NULL == pOp) {
+		WMT_WARN_FUNC("RB_GET return NULL\n");
+		osal_assert(pOp);
+	}
+
+	return pOp;
+}
+
+INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp)
+{
+	P_DEV_WMT pWmtDev = &gDevWmt;
+
+	if (MTK_WCN_BOOL_FALSE == wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp))
+		return -1;
+	else
+		return 0;
+}
+
+P_OSAL_OP wmt_lib_get_free_op(VOID)
+{
+	P_OSAL_OP pOp = NULL;
+	P_DEV_WMT pDevWmt = &gDevWmt;
+
+	osal_assert(pDevWmt);
+
+	pOp = wmt_lib_get_op(&pDevWmt->rFreeOpQ);
+	if (pOp)
+		osal_memset(&pOp->op, 0, osal_sizeof(pOp->op));
+	return pOp;
+}
+
+MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp)
+{
+	P_DEV_WMT pWmtDev = &gDevWmt;
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	MTK_WCN_BOOL bCleanup = MTK_WCN_BOOL_FALSE;
+	P_OSAL_SIGNAL pSignal = NULL;
+	long waitRet = -1;
+	P_OSAL_THREAD pThread;
+
+	osal_assert(pWmtDev);
+	osal_assert(pOp);
+
+	do {
+		if (!pWmtDev || !pOp) {
+			WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp);
+			break;
+		}
+		if ((0 != mtk_wcn_stp_coredump_start_get()) &&
+		    (WMT_OPID_HW_RST != pOp->op.opId) &&
+		    (WMT_OPID_SW_RST != pOp->op.opId) && (WMT_OPID_GPIO_STATE != pOp->op.opId)) {
+			bCleanup = MTK_WCN_BOOL_TRUE;
+			WMT_WARN_FUNC("block tx flag is set\n");
+			break;
+		}
+		pSignal = &pOp->signal;
+/* pOp->u4WaitMs = u4WaitMs; */
+		if (pSignal->timeoutValue) {
+			pOp->result = -9;
+			osal_signal_init(pSignal);
+		}
+
+		/* put to active Q */
+		bRet = wmt_lib_put_op(&pWmtDev->rActiveOpQ, pOp);
+		if (MTK_WCN_BOOL_FALSE == bRet) {
+			WMT_WARN_FUNC("put to active queue fail\n");
+			bCleanup = MTK_WCN_BOOL_TRUE;
+			break;
+		}
+
+		/* wake up wmtd */
+		/* wake_up_interruptible(&pWmtDev->rWmtdWq); */
+		osal_trigger_event(&pWmtDev->rWmtdWq);
+
+		if (0 == pSignal->timeoutValue) {
+			bRet = MTK_WCN_BOOL_TRUE;
+			/* clean it in wmtd */
+			break;
+		}
+		/* wait result, clean it here */
+		bCleanup = MTK_WCN_BOOL_TRUE;
+
+		/* check result */
+		/* wait_ret = wait_for_completion_interruptible_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */
+		/* wait_ret = wait_for_completion_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */
+		waitRet = osal_wait_for_signal_timeout(pSignal);
+		WMT_DBG_FUNC("osal_wait_for_signal_timeout:%ld\n", waitRet);
+
+		/* if (unlikely(!wait_ret)) { */
+		if (0 == waitRet) {
+			pThread = &gDevWmt.thread;
+			WMT_ERR_FUNC
+				("wait completion timeout, opId(%d), show wmtd_thread stack!\n", pOp->op.opId);
+			/* TODO: how to handle it? retry? */
+			wcn_wmtd_timeout_collect_ftrace();	/* trigger collect SYS_FTRACE */
+			osal_thread_show_stack(pThread);
+		} else {
+			if (pOp->result)
+				WMT_WARN_FUNC("opId(%d) result:%d\n", pOp->op.opId, pOp->result);
+		}
+		/* op completes, check result */
+		bRet = (pOp->result) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE;
+	} while (0);
+
+	if (bCleanup) {
+		/* put Op back to freeQ */
+		wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp);
+	}
+
+	return bRet;
+}
+
+/* TODO:[ChangeFeature][George] is this function obsoleted? */
+#if 0
+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask)
+{
+	P_WMT_LXOP lxop;
+	MTK_WCN_BOOL bRet;
+	PUINT32 plv = NULL;
+	UINT32 pbuf[2];
+	P_OSAL_EVENT pSignal = NULL;
+
+	if (!pvalue) {
+		WMT_WARN_FUNC("!pvalue\n");
+		return -1;
+	}
+	lxop = wmt_lib_get_free_lxop();
+	if (!lxop) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+
+		return -1;
+	}
+
+	plv = (PUINT32) (((UINT32) pbuf + 0x3) & ~0x3UL);
+	*plv = *pvalue;
+	pSignal = &lxop->signal;
+	WMT_DBG_FUNC("OPID_REG_RW isWrite(%d) offset(0x%x) value(0x%x) mask(0x%x)\n", isWrite, offset, *pvalue, mask);
+
+	lxop->op.opId = WMT_OPID_REG_RW;
+	lxop->op.au4OpData[0] = isWrite;
+	lxop->op.au4OpData[1] = offset;
+	lxop->op.au4OpData[2] = (UINT32) plv;
+	lxop->op.au4OpData[3] = mask;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+
+	DISABLE_PSM_MONITOR();
+	bRet = wmt_lib_put_act_lxop(lxop);
+	ENABLE_PSM_MONITOR();
+
+	if (MTK_WCN_BOOL_FALSE != bRet) {
+		WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n",
+			     isWrite, offset, *plv, mask);
+		if (!isWrite)
+			*pvalue = *plv;
+	} else {
+		WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n",
+			      isWrite, offset, *plv, mask, bRet);
+	}
+
+	return bRet;
+}
+#endif
+
+/* TODO:[ChangeFeature][George] is this function obsoleted? */
+#if 0
+static VOID wmt_lib_clear_chip_id(VOID)
+{
+/*
+    gDevWmt.pChipInfo = NULL;
+*/
+	gDevWmt.hw_ver = WMTHWVER_INVALID;
+}
+#endif
+
+/* TODO: [FixMe][GeorgeKuo]: change this API to report real chip id, hw_ver, and */
+/* fw_ver instead of WMT-translated WMTHWVER */
+ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver(VOID)
+{
+/*
+    P_WMT_CMB_CHIP_INFO_S pChipInfo = NULL;
+    P_DEV_WMT pWmtDev = gpDevWmt;
+       pChipInfo = wmt_lib_get_chip_info(pWmtDev);
+    return pChipInfo != NULL ? pChipInfo->eHwVersion : WMTHWVER_INVALID;
+    */
+	return gDevWmt.eWmtHwVer;
+}
+
+UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T index)
+{
+	if (WMTCHIN_CHIPID == index)
+		return gDevWmt.chip_id;
+	else if (WMTCHIN_HWVER == index)
+		return gDevWmt.hw_ver;
+	else if (WMTCHIN_MAPPINGHWVER == index)
+		return gDevWmt.eWmtHwVer;
+	else if (WMTCHIN_FWVER == index)
+		return gDevWmt.fw_ver;
+
+	return 0;
+
+}
+
+PUINT8 wmt_lib_def_patch_name(VOID)
+{
+	WMT_INFO_FUNC("wmt-lib: use default patch name (%s)\n", gDevWmt.cPatchName);
+	return gDevWmt.cPatchName;
+}
+
+MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID)
+{
+	MTK_WCN_BOOL bIsSupportTherm = MTK_WCN_BOOL_TRUE;
+	/* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */
+	if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer))
+	    || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) {
+		WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer);
+		bIsSupportTherm = MTK_WCN_BOOL_FALSE;
+	}
+	if (!mtk_wcn_stp_is_ready()) {
+		WMT_ERR_FUNC("thermal command can not be send: STP is not ready\n");
+		bIsSupportTherm = MTK_WCN_BOOL_FALSE;
+	}
+
+	return bIsSupportTherm;
+}
+
+MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID)
+{
+	/* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */
+	if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer))
+	    || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) {
+		WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer);
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	return MTK_WCN_BOOL_TRUE;
+}
+
+/*!
+ * \brief Update combo chip pin settings (GPIO)
+ *
+ * An internal library function to support various settings for chip GPIO. It is
+ * updated in a grouping way: configure all required pins in a single call.
+ *
+ * \param id desired pin ID to be controlled
+ * \param stat desired pin states to be set
+ * \param flag supplementary options for this operation
+ *
+ * \retval 0 operation success
+ * \retval -1 invalid id
+ * \retval -2 invalid stat
+ * \retval < 0 error for operation fail
+ */
+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag)
+{
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+
+	/* input sanity check */
+	if (WMT_IC_PIN_MAX <= id) {
+		WMT_ERR_FUNC("invalid ic pin id(%d)\n", id);
+		return -1;
+	}
+	if (WMT_IC_PIN_STATE_MAX <= stat) {
+		WMT_ERR_FUNC("invalid ic pin state (%d)\n", stat);
+		return -2;
+	}
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	WMT_DBG_FUNC("call WMT_OPID_GPIO_CTRL (ic pin id:%d, stat:%d, flag:0x%x)\n", id, stat, flag);
+
+	pSignal = &pOp->signal;
+	pOp->op.opId = WMT_OPID_GPIO_CTRL;
+	pOp->op.au4OpData[0] = id;
+	pOp->op.au4OpData[1] = stat;
+	pOp->op.au4OpData[2] = flag;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+
+	/*wake up chip first */
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed\n");
+		wmt_lib_put_op_to_free_queue(pOp);
+		return -1;
+	}
+
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+	if (MTK_WCN_BOOL_FALSE == bRet)
+		WMT_WARN_FUNC("PIN_ID(%d) PIN_STATE(%d) flag(%d) fail\n", id, stat, flag);
+	else
+		WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]);
+
+	return 0;
+}
+
+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask)
+{
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	UINT32 value;
+	P_OSAL_SIGNAL pSignal;
+
+	if (!pvalue) {
+		WMT_WARN_FUNC("!pvalue\n");
+		return -1;
+	}
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return -1;
+	}
+
+	pSignal = &pOp->signal;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+	value = *pvalue;
+	WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", isWrite, offset, *pvalue, mask);
+	pOp->op.opId = WMT_OPID_REG_RW;
+	pOp->op.au4OpData[0] = isWrite;
+	pOp->op.au4OpData[1] = offset;
+	pOp->op.au4OpData[2] = (SIZE_T)&value;
+	pOp->op.au4OpData[3] = mask;
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed\n");
+		wmt_lib_put_op_to_free_queue(pOp);
+		return -1;
+	}
+
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+
+	if (MTK_WCN_BOOL_FALSE != bRet) {
+		WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n",
+			     isWrite, offset, value, mask);
+		if (!isWrite)
+			*pvalue = value;
+
+		return 0;
+	}
+	WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n",
+		      isWrite, offset, value, mask, bRet);
+	return -1;
+}
+
+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask)
+{
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	UINT32 value;
+	P_OSAL_SIGNAL pSignal;
+
+	if (!pvalue) {
+		WMT_WARN_FUNC("!pvalue\n");
+		return -1;
+	}
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return -1;
+	}
+
+	pSignal = &pOp->signal;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+	value = *pvalue;
+	WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n",
+		     isWrite, offset, *pvalue, mask);
+	pOp->op.opId = WMT_OPID_EFUSE_RW;
+	pOp->op.au4OpData[0] = isWrite;
+	pOp->op.au4OpData[1] = offset;
+	pOp->op.au4OpData[2] = (SIZE_T)&value;
+	pOp->op.au4OpData[3] = mask;
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed\n");
+		wmt_lib_put_op_to_free_queue(pOp);
+		return -1;
+	}
+
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+
+	if (MTK_WCN_BOOL_FALSE != bRet) {
+		WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n",
+			     isWrite, offset, value, mask);
+		if (!isWrite)
+			*pvalue = value;
+
+		return 0;
+	}
+	WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n",
+		      isWrite, offset, value, mask, bRet);
+	return -1;
+
+}
+
+/*!
+ * \brief update combo chip AUDIO Interface (AIF) settings
+ *
+ * A library function to support updating chip AUDIO pin settings. A group of
+ * pins is updated as a whole.
+ *
+ * \param aif desired audio interface state to use
+ * \param flag whether audio pin is shared or not
+ *
+ * \retval 0 operation success
+ * \retval -1 invalid aif
+ * \retval < 0 error for invalid parameters or operation fail
+ */
+INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share)
+{
+	if (CMB_STUB_AIF_MAX <= aif) {
+		WMT_ERR_FUNC("invalid aif (%d)\n", aif);
+		return -1;
+	}
+	WMT_DBG_FUNC("call pin_ctrl for aif:%d, share:%d\n", aif, (MTK_WCN_BOOL_TRUE == share) ? 1 : 0);
+	/* Translate CMB_STUB_AIF_X into WMT_IC_PIN_STATE by array */
+	return wmt_lib_pin_ctrl(WMT_IC_PIN_AUDIO,
+				cmb_aif2pin_stat[aif],
+				(MTK_WCN_BOOL_TRUE == share) ? WMT_LIB_AIF_FLAG_SHARE : WMT_LIB_AIF_FLAG_SEPARATE);
+}
+
+INT32 wmt_lib_host_awake_get(VOID)
+{
+	return wmt_plat_wake_lock_ctrl(WL_OP_GET);
+}
+
+INT32 wmt_lib_host_awake_put(VOID)
+{
+	return wmt_plat_wake_lock_ctrl(WL_OP_PUT);
+}
+
+MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op)
+{
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+
+	if (op == BTM_RST_OP) {
+		/* high priority, not to enqueue into the queue of wmtd */
+		WMT_INFO_FUNC("Invoke whole chip reset from stp_btm!!!\n");
+		wmt_lib_cmb_rst(WMTRSTSRC_RESET_STP);
+		bRet = MTK_WCN_BOOL_TRUE;
+	} else if (op == BTM_DMP_OP) {
+
+		WMT_WARN_FUNC("TBD!!!\n");
+	} else if (op == BTM_GET_AEE_SUPPORT_FLAG) {
+		bRet = wmt_core_get_aee_dump_flag();
+	}
+	return bRet;
+}
+
+MTK_WCN_BOOL wmt_cdev_rstmsg_snd(ENUM_WMTRSTMSG_TYPE_T msg)
+{
+
+	INT32 i = 0;
+	P_DEV_WMT pDevWmt = &gDevWmt;
+	PUINT8 drv_name[] = {
+		"DRV_TYPE_BT",
+		"DRV_TYPE_FM",
+		"DRV_TYPE_GPS",
+		"DRV_TYPE_WIFI"
+	};
+
+	for (i = 0; i <= WMTDRV_TYPE_WIFI; i++) {
+		/* <1> check if reset callback is registered */
+		if (pDevWmt->rFdrvCb.fDrvRst[i]) {
+			/* <2> send the msg to this subfucntion */
+			/*src, dst, msg_type, msg_data, msg_size */
+			pDevWmt->rFdrvCb.fDrvRst[i] (WMTDRV_TYPE_WMT, i, WMTMSG_TYPE_RESET, &msg,
+						     sizeof(ENUM_WMTRSTMSG_TYPE_T));
+			WMT_INFO_FUNC("type = %s, msg sent\n", drv_name[i]);
+		} else {
+			WMT_DBG_FUNC("type = %s, unregistered\n", drv_name[i]);
+		}
+	}
+
+	return MTK_WCN_BOOL_TRUE;
+}
+
+VOID wmt_lib_state_init(VOID)
+{
+	/* UINT32 i = 0; */
+	P_DEV_WMT pDevWmt = &gDevWmt;
+	P_OSAL_OP pOp;
+
+	/* Initialize op queue */
+	/* RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); */
+	/* RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); */
+
+	while (!RB_EMPTY(&pDevWmt->rActiveOpQ)) {
+#if 0
+		osal_signal_init(&(pOp->signal));
+		wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp);
+#endif
+		pOp = wmt_lib_get_op(&pDevWmt->rActiveOpQ);
+		if (pOp) {
+			if (osal_op_is_wait_for_signal(pOp))
+				osal_op_raise_signal(pOp, -1);
+			else
+				wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp);
+		}
+	}
+
+	/* Put all to free Q */
+	/*
+	   for (i = 0; i < WMT_OP_BUF_SIZE; i++) {
+	   osal_signal_init(&(pDevWmt->arQue[i].signal));
+	   wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i]));
+	   } */
+}
+
+#if 0
+INT32 wmt_lib_sdio_ctrl(UINT32 on)
+{
+
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	WMT_DBG_FUNC("call WMT_OPID_SDIO_CTRL\n");
+
+	pSignal = &pOp->signal;
+	pOp->op.opId = WMT_OPID_SDIO_CTRL;
+	pOp->op.au4OpData[0] = on;
+	pSignal->timeoutValue = MAX_GPIO_CTRL_TIME;
+
+	bRet = wmt_lib_put_act_op(pOp);
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		WMT_WARN_FUNC("WMT_OPID_SDIO_CTRL failed\n");
+		return -1;
+	}
+	WMT_DBG_FUNC("OPID(WMT_OPID_SDIO_CTRL)ok\n");
+
+	return 0;
+}
+#endif
+
+MTK_WCN_BOOL wmt_lib_hw_state_show(VOID)
+{
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	WMT_DBG_FUNC("call WMT_OPID_HW_STATE_SHOW\n");
+
+	pSignal = &pOp->signal;
+	pOp->op.opId = WMT_OPID_GPIO_STATE;
+	pSignal->timeoutValue = MAX_GPIO_CTRL_TIME;
+
+	bRet = wmt_lib_put_act_op(pOp);
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		WMT_WARN_FUNC("WMT_OPID_HW_STATE_SHOW failed\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+	WMT_DBG_FUNC("OPID(WMT_OPID_HW_STATE_SHOW)ok\n");
+	return MTK_WCN_BOOL_TRUE;
+}
+
+MTK_WCN_BOOL wmt_lib_hw_rst(VOID)
+{
+
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+	P_DEV_WMT pDevWmt = &gDevWmt;
+
+	wmt_lib_state_init();
+
+	osal_clear_bit(WMT_STAT_STP_REG, &pDevWmt->state);
+	osal_clear_bit(WMT_STAT_STP_OPEN, &pDevWmt->state);
+	osal_clear_bit(WMT_STAT_STP_EN, &pDevWmt->state);
+	osal_clear_bit(WMT_STAT_STP_RDY, &pDevWmt->state);
+	osal_clear_bit(WMT_STAT_RX, &pDevWmt->state);
+	osal_clear_bit(WMT_STAT_CMD, &pDevWmt->state);
+
+	/*Before do hardware reset, we show GPIO state to check if others modified our pin state accidentially */
+	wmt_lib_hw_state_show();
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	WMT_DBG_FUNC("call WMT_OPID_HW_RST\n");
+
+	pSignal = &pOp->signal;
+	pOp->op.opId = WMT_OPID_HW_RST;
+	pSignal->timeoutValue = MAX_GPIO_CTRL_TIME;
+
+	bRet = wmt_lib_put_act_op(pOp);
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		WMT_WARN_FUNC("WMT_OPID_HW_RST failed\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+	WMT_DBG_FUNC("OPID(WMT_OPID_HW_RST)ok\n");
+	return MTK_WCN_BOOL_TRUE;
+}
+
+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst)
+{
+
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+
+	/* <1> wmt state reset */
+	wmt_lib_state_init();
+
+	/* <2> Reset STP data structure */
+	WMT_DBG_FUNC("Cleanup STP context\n");
+	mtk_wcn_stp_flush_context();
+	/* <3> Reset STP-PSM data structure */
+	WMT_DBG_FUNC("Cleanup STP-PSM context\n");
+	mtk_wcn_stp_psm_reset();
+
+	/* <4> do sw reset in wmt-core */
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	WMT_DBG_FUNC("call WMT_OPID_SW_RST\n");
+
+	pSignal = &pOp->signal;
+	pSignal->timeoutValue = MAX_FUNC_ON_TIME;
+
+	pOp->op.opId = WMT_OPID_SW_RST;
+	pOp->op.au4OpData[0] = baudRst;
+
+	bRet = wmt_lib_put_act_op(pOp);
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		WMT_WARN_FUNC("WMT_OPID_SW_RST failed\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+	WMT_DBG_FUNC("OPID(WMT_OPID_SW_RST)ok\n");
+	return MTK_WCN_BOOL_TRUE;
+}
+
+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src)
+{
+#define RETRYTIMES 10
+	MTK_WCN_BOOL bRet;
+	ENUM_WMTRSTRET_TYPE_T retval = WMTRSTRET_MAX;
+	ENUM_WMTRSTMSG_TYPE_T rstMsg = WMTRSTMSG_RESET_MAX;
+	INT32 retries = RETRYTIMES;
+	P_DEV_WMT pDevWmt = &gDevWmt;
+	P_OSAL_OP pOp;
+	PUINT8 srcName[] = { "WMTRSTSRC_RESET_BT",
+		"WMTRSTSRC_RESET_FM",
+		"WMTRSTSRC_RESET_GPS",
+		"WMTRSTSRC_RESET_WIFI",
+		"WMTRSTSRC_RESET_STP",
+		"WMTRSTSRC_RESET_TEST"
+	};
+
+	if (src < WMTRSTSRC_RESET_MAX)
+		WMT_INFO_FUNC("reset source = %s\n", srcName[src]);
+
+	if (WMTRSTSRC_RESET_TEST == src) {
+		pOp = wmt_lib_get_current_op(pDevWmt);
+		if (pOp && ((WMT_OPID_FUNC_ON == pOp->op.opId)
+			    || (WMT_OPID_FUNC_OFF == pOp->op.opId))) {
+			WMT_INFO_FUNC("can't do reset by test src when func on/off\n");
+			return -1;
+		}
+	}
+	/* <1> Consider the multi-context combo_rst case. */
+	if (osal_test_and_set_bit(WMT_STAT_RST_ON, &pDevWmt->state)) {
+		retval = WMTRSTRET_ONGOING;
+		goto rstDone;
+	}
+	/* <2> Block all STP request */
+	mtk_wcn_stp_enable(0);
+
+	/* <3> RESET_START notification */
+	bRet = wmt_cdev_rstmsg_snd(WMTRSTMSG_RESET_START);
+	if (bRet == MTK_WCN_BOOL_FALSE) {
+		WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n");
+		retval = WMTRSTRET_FAIL;
+		goto rstDone;
+	}
+	/* wakeup blocked opid */
+	pOp = wmt_lib_get_current_op(pDevWmt);
+	if (osal_op_is_wait_for_signal(pOp))
+		osal_op_raise_signal(pOp, -1);
+
+	/* wakeup blocked cmd */
+	wmt_dev_rx_event_cb();
+
+	/* <4> retry until reset flow successful */
+	while (retries > 0) {
+		/* <4.1> reset combo hw */
+		bRet = wmt_lib_hw_rst();
+		if (bRet == MTK_WCN_BOOL_FALSE) {
+			WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_hw_rst!\n");
+			retries--;
+			continue;
+		}
+		/* <4.2> reset driver/combo sw */
+		bRet = wmt_lib_sw_rst(1);
+		if (bRet == MTK_WCN_BOOL_FALSE) {
+			WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_sw_rst!\n");
+			retries--;
+			continue;
+		}
+		break;
+	}
+
+	osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state);
+
+	if (bRet == MTK_WCN_BOOL_FALSE) {
+		rstMsg = WMTRSTMSG_RESET_END_FAIL;
+		WMT_WARN_FUNC("[whole chip reset] fail! retries = %d\n", RETRYTIMES - retries);
+	} else {
+		rstMsg = WMTRSTMSG_RESET_END;
+		WMT_INFO_FUNC("[whole chip reset] ok! retries = %d\n", RETRYTIMES - retries);
+	}
+
+	/* <5> RESET_END notification */
+	bRet = wmt_cdev_rstmsg_snd(rstMsg);
+	if (bRet == MTK_WCN_BOOL_FALSE) {
+		WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n");
+		retval = WMTRSTRET_FAIL;
+	} else {
+		retval = WMTRSTMSG_RESET_END == rstMsg ? WMTRSTRET_SUCCESS : WMTRSTRET_FAIL;
+	}
+	mtk_wcn_stp_coredump_start_ctrl(0);
+	mtk_wcn_stp_set_wmt_evt_err_trg_assert(0);
+rstDone:
+	if (osal_test_and_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state))
+		WMT_WARN_FUNC("[whole chip reset] retval = %d\n", retval);
+
+	return retval;
+}
+
+MTK_WCN_BOOL wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb)
+{
+
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	P_DEV_WMT pWmtDev = &gDevWmt;
+
+	if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) {
+		WMT_DBG_FUNC("reg ok!\n");
+		pWmtDev->rFdrvCb.fDrvRst[eType] = pCb;
+		bRet = MTK_WCN_BOOL_TRUE;
+	} else {
+		WMT_WARN_FUNC("reg fail!\n");
+	}
+
+	return bRet;
+}
+
+MTK_WCN_BOOL wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType)
+{
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	P_DEV_WMT pWmtDev = &gDevWmt;
+
+	if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) {
+		WMT_DBG_FUNC("unreg ok!\n");
+		pWmtDev->rFdrvCb.fDrvRst[eType] = NULL;
+		bRet = MTK_WCN_BOOL_TRUE;
+	} else {
+		WMT_WARN_FUNC("unreg fail!\n");
+	}
+
+	return bRet;
+}
+
+UINT32 wmt_lib_dbg_level_set(UINT32 level)
+{
+	gWmtDbgLvl = level > WMT_LOG_LOUD ? WMT_LOG_LOUD : level;
+	return 0;
+}
+
+INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value)
+{
+	return mtk_wcn_stp_set_wmt_last_close(value);
+}
+
+INT32 wmt_lib_notify_stp_sleep(void)
+{
+	INT32 iRet = 0x0;
+
+	iRet = wmt_lib_psm_lock_aquire();
+	if (iRet) {
+		WMT_ERR_FUNC("--->lock psm_lock failed, iRet=%d\n", iRet);
+		return iRet;
+	}
+
+	iRet = mtk_wcn_stp_notify_sleep_for_thermal();
+	wmt_lib_psm_lock_release();
+
+	return iRet;
+}
+
+VOID wmt_lib_set_patch_num(UINT32 num)
+{
+	P_DEV_WMT pWmtDev = &gDevWmt;
+
+	pWmtDev->patchNum = num;
+}
+
+VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo)
+{
+	P_DEV_WMT pWmtDev = &gDevWmt;
+
+	if (pPatchinfo)
+		pWmtDev->pWmtPatchInfo = pPatchinfo;
+
+}
+
+INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp)
+{
+	if (pWmtDev) {
+		pWmtDev->pCurOP = pOp;
+		WMT_DBG_FUNC("pOp=0x%p\n", pOp);
+		return 0;
+	}
+	WMT_ERR_FUNC("Invalid pointer\n");
+	return -1;
+}
+
+P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev)
+{
+	if (pWmtDev)
+		return pWmtDev->pCurOP;
+
+	WMT_ERR_FUNC("Invalid pointer\n");
+	return NULL;
+}
+
+UINT8 *wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, UINT8 *buf, UINT32 len)
+{
+	UINT8 *pAddr = NULL;
+	UINT32 sublen1 = 0;
+	UINT32 sublen2 = 0;
+	P_CONSYS_EMI_ADDR_INFO p_consys_info;
+
+	p_consys_info = wmt_plat_get_emi_phy_add();
+	osal_assert(p_consys_info);
+
+	if (section == 0) {
+		pAddr = wmt_plat_get_emi_virt_add(0x0);
+		if (len > 1024)
+			len = 1024;
+		if (!pAddr) {
+			WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n");
+		} else {
+			WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr);
+			osal_memcpy(&buf[0], pAddr, len);
+		}
+	} else {
+		if (offset >= 0x7fff)
+			offset = 0x0;
+
+		if (offset + len > 32768) {
+			pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off);
+			if (!pAddr) {
+				WMT_ERR_FUNC("wmt-lib: get part1 EMI virtual base address fail\n");
+			} else {
+				WMT_INFO_FUNC("part1 vir addr(0x%p)\n", pAddr);
+				sublen1 = 0x7fff - offset;
+				osal_memcpy(&buf[0], pAddr, sublen1);
+			}
+			pAddr = wmt_plat_get_emi_virt_add(p_consys_info->paged_trace_off);
+			if (!pAddr) {
+				WMT_ERR_FUNC("wmt-lib: get part2 EMI virtual base address fail\n");
+			} else {
+				WMT_INFO_FUNC("part2 vir addr(0x%p)\n", pAddr);
+				sublen2 = len - sublen1;
+				osal_memcpy(&buf[sublen1], pAddr, sublen2);
+			}
+		} else {
+			pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off);
+			if (!pAddr) {
+				WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n");
+			} else {
+				WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr);
+				osal_memcpy(&buf[0], pAddr, len);
+			}
+		}
+	}
+
+	return 0;
+}
+
+INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee)
+{
+	ENUM_STP_FW_ISSUE_TYPE issue_type;
+
+	issue_type = STP_DBG_PROC_TEST;
+
+	stp_dbg_poll_cpupcr(count, sleep, 1);
+
+	if (toAee) {
+		stp_dbg_set_fw_info("STP ProcTest", osal_strlen("STP ProcTest"), issue_type);
+		osal_dbg_assert_aee("[SOC_CONSYS]ProcTest",
+				    "**[WCN_ISSUE_INFO]STP Tx Timeout**\n Polling CPUPCR for FW debug usage\n");
+	} else {
+		WMT_INFO_FUNC("wmt_lib:do not pass cpupcr to AEE\n");
+	}
+	return 0;
+}
+
+UINT8 *wmt_lib_get_cpupcr_xml_format(UINT32 *len)
+{
+	PUINT8 temp;
+	UINT32 i = 0;
+
+	osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE);
+	temp = g_cpupcr_buf;
+	stp_dbg_cpupcr_infor_format(&temp, len);
+
+	pr_debug("print xml buffer,len(%d):\n\n", *len);
+	for (i = 0; i < *len; i++)
+		pr_cont("%c", g_cpupcr_buf[i]);
+
+	return &g_cpupcr_buf[0];
+}
+
+UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en)
+{
+	return stp_dbg_set_host_assert_info(type, reason, en);
+}
+
+INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl)
+{
+	wmt_plat_thermal_ctrl_cb_reg(thermal_ctrl);
+	return 0;
+}
+
+INT8 wmt_lib_co_clock_get(void)
+{
+	if (gDevWmt.rWmtGenConf.cfgExist)
+		return gDevWmt.rWmtGenConf.co_clock_flag;
+	else
+		return -1;
+}
+
+#if CFG_WMT_PS_SUPPORT
+UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en)
+{
+	WMT_WARN_FUNC("%s quick sleep mode\n", en ? "enable" : "disable");
+	g_quick_sleep_ctrl = en;
+	return 0;
+}
+#endif
+
+#if CONSYS_ENALBE_SET_JTAG
+UINT32 wmt_lib_jtag_flag_set(UINT32 en)
+{
+	return wmt_plat_jtag_flag_ctrl(en);
+}
+#endif
+
+UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver)
+{
+	return stp_dbg_set_wifiver(wifiver);
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h
new file mode 100644
index 0000000000000..b1b5285638f96
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h
@@ -0,0 +1,252 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _STP_EXP_H_
+#define _STP_EXP_H_
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "wmt_stp_exp.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+
+#define BT_TASK_INDX        (0)
+#define FM_TASK_INDX        (1)
+#define GPS_TASK_INDX       (2)
+#define WIFI_TASK_INDX      (3)
+#define WMT_TASK_INDX       (4)
+#define STP_TASK_INDX       (5)
+#define INFO_TASK_INDX      (6)
+#define ANT_TASK_INDX       (7)
+#if CFG_WMT_LTE_COEX_HANDLING
+#define COEX_TASK_INDX		(8)
+#define MTKSTP_MAX_TASK_NUM (9)
+#else
+#define MTKSTP_MAX_TASK_NUM	(8)
+#endif
+
+#define MTKSTP_BUFFER_SIZE  (16384)	/* Size of RX Queue */
+
+#define STP_EXP_HID_API_EXPORT 0
+
+#else
+
+#define STP_EXP_HID_API_EXPORT 1
+
+#endif
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+typedef void (*MTK_WCN_STP_EVENT_CB) (void);
+typedef INT32 (*MTK_WCN_STP_IF_TX) (const UINT8 *data, const UINT32 size, UINT32 *written_size);
+/* export for HIF driver */
+typedef void (*MTK_WCN_STP_IF_RX) (const UINT8 *data, INT32 size);
+
+typedef enum {
+	STP_UART_IF_TX = 0,
+	STP_SDIO_IF_TX = 1,
+	STP_BTIF_IF_TX = 2,
+	STP_MAX_IF_TX
+} ENUM_STP_TX_IF_TYPE;
+#endif
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_receive_data
+* DESCRIPTION
+*  receive data from serial protocol engine
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  INT32    >= 0: size of data received; < 0: error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_send_data
+* DESCRIPTION
+*  subfunction send data through STP
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    >= 0: length transmitted; < 0: error
+*****************************************************************************/
+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_rxqueue_empty
+* DESCRIPTION
+*  Is certain rx queue empty?
+* PARAMETERS
+*  type        [IN]        subfunction type
+* RETURNS
+*  INT32    0: queue is NOT empyt; !0: queue is empty
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_is_enable
+* DESCRIPTION
+*  Is STP ready?
+* PARAMETERS
+*  none.
+* RETURNS
+*  MTK_WCN_BOOL    TRUE:ready, FALSE:not ready
+*****************************************************************************/
+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_parser_data
+* DESCRIPTION
+*  push data to serial transport protocol parser engine
+* PARAMETERS
+*  buffer      [IN]        data buffer
+*  length      [IN]        data buffer length
+* RETURNS
+*  void
+*****************************************************************************/
+extern int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length);
+
+/*****************************************************************************
+* FUNCTION
+*  set_bluetooth_rx_interface
+* DESCRIPTION
+*  Set bluetooth rx interface
+* PARAMETERS
+*  rx interface type
+* RETURNS
+*  void
+*****************************************************************************/
+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_tx_event_cb
+* DESCRIPTION
+*  regiter Tx event callback function
+* PARAMETERS
+*  func
+* RETURNS
+*  int: 0:successful , -1: fail
+*****************************************************************************/
+extern int mtk_wcn_stp_register_tx_event_cb(int type, MTK_WCN_STP_EVENT_CB func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_event_cb
+* DESCRIPTION
+*  regiter Rx event callback function
+* PARAMETERS
+*  func
+* RETURNS
+*  int: 0:successful , -1: fail
+*****************************************************************************/
+extern int mtk_wcn_stp_register_event_cb(int type, MTK_WCN_STP_EVENT_CB func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_if_tx
+* DESCRIPTION
+*  regiter Tx event callback function
+* PARAMETERS
+*  stp_if: SDIO or UART, fnnc: Call back function
+* RETURNS
+*  int: 0:successful , -1: fail
+*****************************************************************************/
+extern int mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func);
+
+/*****************************************************************************
+* FUNCTION
+*  mtk_wcn_stp_register_if_rx
+* DESCRIPTION
+*  regiter Rx event callback function
+* PARAMETERS
+*  stp_if: SDIO or UART, fnnc: Call back function
+* RETURNS
+*  int: 0:successful , -1: fail
+*****************************************************************************/
+extern int mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#else
+extern INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type);
+extern INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type);
+extern INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type);
+extern MTK_WCN_BOOL _mtk_wcn_stp_is_rxqueue_empty(UINT8 type);
+extern MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void);
+extern INT32 _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length);
+extern void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag);
+extern INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func);
+extern INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func);
+extern INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func);
+extern INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func);
+extern INT32 _mtk_wcn_stp_coredump_start_get(VOID);
+
+#endif
+
+#endif /* _WMT_EXP_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h
new file mode 100644
index 0000000000000..6d10c3ff26590
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h
@@ -0,0 +1,19 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _MTKWMT_H_
+#define _MTKWMT_H_
+#include "wmt_core.h"
+
+#endif /*_MTKWMT_H_*/
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h
new file mode 100644
index 0000000000000..06238e07879fe
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h
@@ -0,0 +1,329 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_EXP_H_
+#define _WMT_EXP_H_
+
+#include <mtk_wcn_cmb_stub.h>
+#include "osal.h"
+#include "wmt_plat.h"
+#include "wmt_stp_exp.h"
+/* not to reference to internal wmt */
+/* #include "wmt_core.h" */
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#if 1				/* moved from wmt_lib.h */
+#ifndef DFT_TAG
+#define DFT_TAG         "[WMT-DFT]"
+#endif
+
+#define WMT_LOUD_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDbgLvl >= WMT_LOG_LOUD) \
+		osal_dbg_print(DFT_TAG "[L]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_INFO_FUNC(fmt, arg...)  \
+do { \
+	if (gWmtDbgLvl >= WMT_LOG_INFO) \
+		osal_dbg_print(DFT_TAG "[I]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_WARN_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDbgLvl >= WMT_LOG_WARN) \
+		osal_warn_print(DFT_TAG "[W]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_ERR_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDbgLvl >= WMT_LOG_ERR) \
+		osal_err_print(DFT_TAG "[E]%s(%d):"  fmt, __func__ , __LINE__, ##arg); \
+} while (0)
+#define WMT_DBG_FUNC(fmt, arg...) \
+do { \
+	if (gWmtDbgLvl >= WMT_LOG_DBG) \
+		osal_dbg_print(DFT_TAG "[D]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_TRC_FUNC(f) \
+do { \
+	if (gWmtDbgLvl >= WMT_LOG_DBG) \
+		osal_dbg_print(DFT_TAG "<%s> <%d>\n", __func__, __LINE__); \
+} while (0)
+
+#endif
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#if 1				/* moved from wmt_lib.h */
+extern UINT32 gWmtDbgLvl;
+#endif
+extern OSAL_BIT_OP_VAR gBtWifiGpsState;
+extern OSAL_BIT_OP_VAR gGpsFmState;
+extern UINT32 gWifiProbed;
+extern MTK_WCN_BOOL g_pwr_off_flag;
+extern UINT32 g_IsNeedDoChipReset;
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#if 1				/* moved from wmt_lib.h */
+#define WMT_LOG_LOUD    4
+#define WMT_LOG_DBG     3
+#define WMT_LOG_INFO    2
+#define WMT_LOG_WARN    1
+#define WMT_LOG_ERR     0
+#endif
+#define CFG_CORE_INTERNAL_TXRX 0	/*just do TX/RX in host side */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+typedef enum _ENUM_WMTDRV_TYPE_T {
+	WMTDRV_TYPE_BT = 0,
+	WMTDRV_TYPE_FM = 1,
+	WMTDRV_TYPE_GPS = 2,
+	WMTDRV_TYPE_WIFI = 3,
+	WMTDRV_TYPE_WMT = 4,
+	WMTDRV_TYPE_STP = 5,
+	WMTDRV_TYPE_LPBK = 6,
+	WMTDRV_TYPE_COREDUMP = 7,
+	WMTDRV_TYPE_MAX
+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T;
+
+/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */
+/* TODO: how do we extend for new chip and newer revision? */
+/* TODO: This way is hard to extend */
+typedef enum _ENUM_WMTHWVER_TYPE_T {
+	WMTHWVER_E1 = 0x0,
+	WMTHWVER_E2 = 0x1,
+	WMTHWVER_E3 = 0x2,
+	WMTHWVER_E4 = 0x3,
+	WMTHWVER_E5 = 0x4,
+	WMTHWVER_E6 = 0x5,
+	WMTHWVER_MAX,
+	WMTHWVER_INVALID = 0xff
+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T;
+
+typedef enum _ENUM_WMTDSNS_TYPE_T {
+	WMTDSNS_FM_DISABLE = 0,
+	WMTDSNS_FM_ENABLE = 1,
+	WMTDSNS_FM_GPS_DISABLE = 2,
+	WMTDSNS_FM_GPS_ENABLE = 3,
+	WMTDSNS_MAX
+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T;
+
+typedef enum _ENUM_WMTTHERM_TYPE_T {
+	WMTTHERM_ZERO = 0,
+	WMTTHERM_ENABLE = WMTTHERM_ZERO + 1,
+	WMTTHERM_READ = WMTTHERM_ENABLE + 1,
+	WMTTHERM_DISABLE = WMTTHERM_READ + 1,
+	WMTTHERM_MAX
+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T;
+
+typedef enum _ENUM_WMTMSG_TYPE_T {
+	WMTMSG_TYPE_POWER_ON = 0,
+	WMTMSG_TYPE_POWER_OFF = 1,
+	WMTMSG_TYPE_RESET = 2,
+	WMTMSG_TYPE_STP_RDY = 3,
+	WMTMSG_TYPE_HW_FUNC_ON = 4,
+	WMTMSG_TYPE_MAX
+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T;
+
+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T,	/* Source driver type */
+			   ENUM_WMTDRV_TYPE_T,	/* Destination driver type */
+			   ENUM_WMTMSG_TYPE_T,	/* Message type */
+			   VOID *,	/* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client
+					   can't touch this buffer after this function return. */
+			   UINT32	/* Buffer size in unit of byte */
+);
+
+typedef enum _SDIO_PS_OP {
+	OWN_SET = 0,
+	OWN_CLR = 1,
+	OWN_STATE = 2,
+} SDIO_PS_OP;
+
+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP);
+
+typedef enum _ENUM_WMTCHIN_TYPE_T {
+	WMTCHIN_CHIPID = 0x0,
+	WMTCHIN_HWVER = WMTCHIN_CHIPID + 1,
+	WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1,
+	WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1,
+	WMTCHIN_MAX,
+
+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T;
+
+#endif
+
+typedef enum _ENUM_WMTRSTMSG_TYPE_T {
+	WMTRSTMSG_RESET_START = 0x0,
+	WMTRSTMSG_RESET_END = 0x1,
+	WMTRSTMSG_RESET_END_FAIL = 0x2,
+	WMTRSTMSG_RESET_MAX,
+	WMTRSTMSG_RESET_INVALID = 0xff
+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T;
+
+typedef enum _ENUM_BT_GPS_ONOFF_STATE_T {
+	WMT_BT_ON = 0,
+	WMT_GPS_ON = 1,
+	WMT_WIFI_ON = 2,
+	WMT_FM_ON = 3,
+	WMT_BT_GPS_STATE_MAX,
+	WMT_BT_GPS_STATE_INVALID = 0xff
+} ENUM_BT_GPS_ONOFF_STATE_T, *P_ENUM_BT_GPS_ONOFF_STATE_T;
+
+#if 1				/* moved from wmt_core.h */
+typedef enum {
+	WMT_SDIO_SLOT_INVALID = 0,
+	WMT_SDIO_SLOT_SDIO1 = 1,	/* Wi-Fi dedicated SDIO1 */
+	WMT_SDIO_SLOT_SDIO2 = 2,
+	WMT_SDIO_SLOT_MAX
+} WMT_SDIO_SLOT_NUM;
+
+typedef enum {
+	WMT_SDIO_FUNC_STP = 0,
+	WMT_SDIO_FUNC_WIFI = 1,
+	WMT_SDIO_FUNC_MAX
+} WMT_SDIO_FUNC_TYPE;
+#endif
+
+typedef INT32(*wmt_wlan_probe_cb) (VOID);
+typedef INT32(*wmt_wlan_remove_cb) (VOID);
+typedef INT32(*wmt_wlan_bus_cnt_get_cb) (VOID);
+typedef INT32(*wmt_wlan_bus_cnt_clr_cb) (VOID);
+
+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO {
+	wmt_wlan_probe_cb wlan_probe_cb;
+	wmt_wlan_remove_cb wlan_remove_cb;
+	wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb;
+	wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb;
+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO;
+
+#ifdef CONFIG_MTK_COMBO_ANT
+typedef enum _ENUM_WMT_ANT_RAM_CTRL_T {
+	WMT_ANT_RAM_GET_STATUS = 0,
+	WMT_ANT_RAM_DOWNLOAD = WMT_ANT_RAM_GET_STATUS + 1,
+	WMT_ANT_RAM_CTRL_MAX
+} ENUM_WMT_ANT_RAM_CTRL, *P_ENUM_WMT_ANT_RAM_CTRL;
+
+typedef enum _ENUM_WMT_ANT_RAM_SEQ_T {
+	WMT_ANT_RAM_START_PKT = 1,
+	WMT_ANT_RAM_CONTINUE_PKT = WMT_ANT_RAM_START_PKT + 1,
+	WMT_ANT_RAM_END_PKT = WMT_ANT_RAM_CONTINUE_PKT + 1,
+	WMT_ANT_RAM_SEQ_MAX
+} ENUM_WMT_ANT_RAM_SEQ, *P_ENUM_WMT_ANT_RAM_SEQ;
+
+typedef enum _ENUM_WMT_ANT_RAM_STATUS_T {
+	WMT_ANT_RAM_NOT_EXIST = 0,
+	WMT_ANT_RAM_EXIST = WMT_ANT_RAM_NOT_EXIST + 1,
+	WMT_ANT_RAM_DOWN_OK = WMT_ANT_RAM_EXIST + 1,
+	WMT_ANT_RAM_DOWN_FAIL = WMT_ANT_RAM_DOWN_OK + 1,
+	WMT_ANT_RAM_PARA_ERR = WMT_ANT_RAM_DOWN_FAIL + 1,
+	WMT_ANT_RAM_OP_ERR = WMT_ANT_RAM_PARA_ERR + 1,
+	WMT_ANT_RAM_MAX
+} ENUM_WMT_ANT_RAM_STATUS, *P_ENUM_WMT_ANT_RAM_STATUS;
+#endif
+
+extern INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo);
+extern INT32 mtk_wcn_wmt_wlan_unreg(VOID);
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+extern wmt_wlan_probe_cb mtk_wcn_wlan_probe;
+extern wmt_wlan_remove_cb mtk_wcn_wlan_remove;
+extern wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt;
+extern wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr;
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*subsystem function ctrl APIs*/
+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason);
+
+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+#define WMT_EXP_HID_API_EXPORT 0
+
+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type);
+
+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type);
+
+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType);
+
+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason);
+
+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb);
+
+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType);
+
+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb);
+
+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID);
+/*
+return value:
+enable/disable thermal sensor function: true(1)/false(0)
+read thermal sensor function: thermal value
+
+*/
+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType);
+
+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID);
+
+#else
+#define WMT_EXP_HID_API_EXPORT 1
+#endif
+
+#ifdef CONFIG_MTK_COMBO_ANT
+extern ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf,
+							UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq);
+#endif
+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share);	/* set AUDIO interface options */
+extern VOID wmt_lib_ps_irq_cb(VOID);
+
+extern VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type);
+
+extern INT32 mtk_wcn_wmt_system_state_reset(VOID);
+extern MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value);
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+extern VOID mtk_wcn_wmt_exp_init(VOID);
+extern VOID mtk_wcn_wmt_exp_deinit(VOID);
+#endif
+extern INT8 mtk_wcn_wmt_co_clock_flag_get(VOID);
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WMT_EXP_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h
new file mode 100644
index 0000000000000..075496cac54f9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h
@@ -0,0 +1,295 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _WMT_PLAT_H_
+#define _WMT_PLAT_H_
+#include "osal_typedef.h"
+#include "stp_exp.h"
+#include <mtk_wcn_cmb_stub.h>
+
+/* #include "mtk_wcn_consys_hw.h" */
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#if 1				/* moved from wmt_exp.h */
+#ifndef DFT_TAG
+#define DFT_TAG         "[WMT-DFT]"
+#endif
+
+#define WMT_PLAT_LOG_LOUD                 4
+#define WMT_PLAT_LOG_DBG                  3
+#define WMT_PLAT_LOG_INFO                 2
+#define WMT_PLAT_LOG_WARN                 1
+#define WMT_PLAT_LOG_ERR                  0
+
+extern UINT32 wmtPlatLogLvl;
+
+#define WMT_PLAT_LOUD_FUNC(fmt, arg...) \
+do { \
+	if (wmtPlatLogLvl >= WMT_PLAT_LOG_LOUD) \
+		pr_debug(DFT_TAG "[L]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_PLAT_INFO_FUNC(fmt, arg...) \
+do { \
+	if (wmtPlatLogLvl >= WMT_PLAT_LOG_INFO) \
+		pr_debug(DFT_TAG "[I]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_PLAT_WARN_FUNC(fmt, arg...) \
+do { \
+	if (wmtPlatLogLvl >= WMT_PLAT_LOG_WARN) \
+		pr_warn(DFT_TAG "[W]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+#define WMT_PLAT_ERR_FUNC(fmt, arg...) \
+do { \
+	if (wmtPlatLogLvl >= WMT_PLAT_LOG_ERR) \
+		pr_err(DFT_TAG "[E]%s(%d):"  fmt, __func__ , __LINE__, ##arg); \
+} while (0)
+#define WMT_PLAT_DBG_FUNC(fmt, arg...) \
+do { \
+	if (wmtPlatLogLvl >= WMT_PLAT_LOG_DBG) \
+		pr_debug(DFT_TAG "[D]%s:"  fmt, __func__ , ##arg); \
+} while (0)
+
+#endif
+
+#define CFG_WMT_PS_SUPPORT 1	/* moved from wmt_exp.h */
+
+#define CFG_WMT_DUMP_INT_STATUS 0
+#define CONSYS_ENALBE_SET_JTAG 1
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _ENUM_FUNC_STATE_ {
+	FUNC_ON = 0,
+	FUNC_OFF = 1,
+	FUNC_RST = 2,
+	FUNC_STAT = 3,
+	FUNC_CTRL_MAX,
+} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE;
+
+typedef enum _ENUM_PIN_ID_ {
+	PIN_BGF_EINT = 0,
+	PIN_I2S_GRP = 1,
+	PIN_GPS_SYNC = 2,
+	PIN_GPS_LNA = 3,
+#if CFG_WMT_LTE_COEX_HANDLING
+	PIN_TDM_REQ = 4,
+#endif
+	PIN_ID_MAX
+} ENUM_PIN_ID, *P_ENUM_PIN_ID;
+
+typedef enum _ENUM_PIN_STATE_ {
+	PIN_STA_INIT = 0,
+	PIN_STA_OUT_L = 1,
+	PIN_STA_OUT_H = 2,
+	PIN_STA_IN_L = 3,
+	PIN_STA_MUX = 4,
+	PIN_STA_EINT_EN = 5,
+	PIN_STA_EINT_DIS = 6,
+	PIN_STA_DEINIT = 7,
+	PIN_STA_SHOW = 8,
+	PIN_STA_MAX
+} ENUM_PIN_STATE, *P_ENUM_PIN_STATE;
+
+typedef enum _CMB_IF_TYPE_ {
+	CMB_IF_UART = 0,
+	CMB_IF_WIFI_SDIO = 1,
+	CMB_IF_BGF_SDIO = 2,
+	CMB_IF_BGWF_SDIO = 3,
+	CMB_IF_TYPE_MAX
+} CMB_IF_TYPE, *P_CMB_IF_TYPE;
+
+typedef INT32(*fp_set_pin) (ENUM_PIN_STATE);
+
+typedef enum _ENUM_WL_OP_ {
+	WL_OP_GET = 0,
+	WL_OP_PUT = 1,
+	WL_OP_MAX
+} ENUM_WL_OP, *P_ENUM_WL_OP;
+
+typedef enum _ENUM_PALDO_TYPE_ {
+	BT_PALDO = 0,
+	WIFI_PALDO = 1,
+	FM_PALDO = 2,
+	GPS_PALDO = 3,
+	PMIC_CHIPID_PALDO = 4,
+	WIFI_5G_PALDO = 5,
+	PALDO_TYPE_MAX
+} ENUM_PALDO_TYPE, *P_ENUM_PALDO_TYPE;
+
+typedef enum _ENUM_PALDO_OP_ {
+	PALDO_OFF = 0,
+	PALDO_ON = 1,
+	PALDO_OP_MAX
+} ENUM_PALDO_OP, *P_ENUM_PALDO_OP;
+
+typedef enum _ENUM_HOST_DUMP_STATE_T {
+	STP_HOST_DUMP_NOT_START = 0,
+	STP_HOST_DUMP_GET = 1,
+	STP_HOST_DUMP_GET_DONE = 2,
+	STP_HOST_DUMP_END = 3,
+	STP_HOST_DUMP_MAX
+} ENUM_HOST_DUMP_STATE, *P_ENUM_HOST_DUMP_STATE_T;
+
+typedef enum _ENUM_FORCE_TRG_ASSERT_T {
+	STP_FORCE_TRG_ASSERT_EMI = 0,
+	STP_FORCE_TRG_ASSERT_DEBUG_PIN = 1,
+	STP_FORCE_TRG_ASSERT_MAX = 2
+} ENUM_FORCE_TRG_ASSERT_T, *P_ENUM_FORCE_TRG_ASSERT_T;
+
+typedef enum _ENUM_CHIP_DUMP_STATE_T {
+	STP_CHIP_DUMP_NOT_START = 0,
+	STP_CHIP_DUMP_PUT = 1,
+	STP_CHIP_DUMP_PUT_DONE = 2,
+	STP_CHIP_DUMP_END = 3,
+	STP_CHIP_DUMP_MAX
+} ENUM_CHIP_DUMP_STATE, *P_ENUM_CHIP_DUMP_STATE_T;
+
+typedef struct _EMI_CTRL_STATE_OFFSET_ {
+	UINT32 emi_apmem_ctrl_state;
+	UINT32 emi_apmem_ctrl_host_sync_state;
+	UINT32 emi_apmem_ctrl_host_sync_num;
+	UINT32 emi_apmem_ctrl_chip_sync_state;
+	UINT32 emi_apmem_ctrl_chip_sync_num;
+	UINT32 emi_apmem_ctrl_chip_sync_addr;
+	UINT32 emi_apmem_ctrl_chip_sync_len;
+	UINT32 emi_apmem_ctrl_chip_print_buff_start;
+	UINT32 emi_apmem_ctrl_chip_print_buff_len;
+	UINT32 emi_apmem_ctrl_chip_print_buff_idx;
+	UINT32 emi_apmem_ctrl_chip_int_status;
+	UINT32 emi_apmem_ctrl_chip_paded_dump_end;
+	UINT32 emi_apmem_ctrl_host_outband_assert_w1;
+	UINT32 emi_apmem_ctrl_chip_page_dump_num;
+} EMI_CTRL_STATE_OFFSET, *P_EMI_CTRL_STATE_OFFSET;
+
+typedef struct _BGF_IRQ_BALANCE_ {
+	UINT32 counter;
+	unsigned long flags;
+	spinlock_t lock;
+} BGF_IRQ_BALANCE, *P_BGF_IRQ_BALANCE;
+
+typedef struct _CONSYS_EMI_ADDR_INFO_ {
+	UINT32 emi_phy_addr;
+	UINT32 paged_trace_off;
+	UINT32 paged_dump_off;
+	UINT32 full_dump_off;
+	P_EMI_CTRL_STATE_OFFSET p_ecso;
+} CONSYS_EMI_ADDR_INFO, *P_CONSYS_EMI_ADDR_INFO;
+
+typedef struct _GPIO_TDM_REQ_INFO_ {
+	UINT32 ant_sel_index;
+	UINT32 gpio_number;
+	UINT32 cr_address;
+} GPIO_TDM_REQ_INFO, *P_GPIO_TDM_REQ_INFO;
+
+typedef VOID(*irq_cb) (VOID);
+typedef INT32(*device_audio_if_cb) (CMB_STUB_AIF_X aif, MTK_WCN_BOOL share);
+typedef VOID(*func_ctrl_cb) (UINT32 on, UINT32 type);
+typedef long (*thermal_query_ctrl_cb) (VOID);
+typedef INT32(*deep_idle_ctrl_cb) (UINT32);
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+extern UINT32 gWmtDbgLvl;
+extern struct device *wmt_dev;
+#ifdef CFG_WMT_READ_EFUSE_VCN33
+extern INT32 wmt_set_pmic_voltage(UINT32 level);
+#endif
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+INT32 wmt_plat_init(UINT32 co_clock_type);
+
+INT32 wmt_plat_deinit(VOID);
+
+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state);
+
+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state);
+
+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state);
+
+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId);
+
+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl);
+
+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb);
+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb);
+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl);
+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl);
+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl);
+
+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo);
+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset);
+#if CONSYS_ENALBE_SET_JTAG
+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en);
+#endif
+#if CFG_WMT_DUMP_INT_STATUS
+VOID wmt_plat_BGF_irq_dump_status(VOID);
+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID);
+#endif
+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID);
+UINT32 wmt_plat_read_cpupcr(VOID);
+UINT32 wmt_plat_read_dmaregs(UINT32);
+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state);
+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type);
+INT32 wmt_plat_update_host_sync_num(VOID);
+INT32 wmt_plat_get_dump_info(UINT32 offset);
+UINT32 wmt_plat_get_soc_chipid(VOID);
+INT32 wmt_plat_set_dbg_mode(UINT32 flag);
+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf);
+#if CFG_WMT_LTE_COEX_HANDLING
+INT32 wmt_plat_get_tdm_antsel_index(VOID);
+#endif
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WMT_PLAT_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile
new file mode 100644
index 0000000000000..9052071189386
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile
@@ -0,0 +1,6 @@
+ifeq ($(CONFIG_MTK_COMBO), y)
+
+obj-y += pub/
+obj-y += pri/
+
+endif
\ No newline at end of file
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h
new file mode 100644
index 0000000000000..95d1ab02a9fa4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h
@@ -0,0 +1,74 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __BGW_DESENSE_H_
+#define __BGW_DESENSE_H_
+
+#ifdef MSG
+#undef MSG
+#endif
+
+#ifdef ERR
+#undef ERR
+#endif
+
+#define PFX1                         "[BWG] "
+#define MSG(fmt, arg ...) pr_debug(PFX1 "[D]%s: "  fmt, __func__ , ##arg)
+#define ERR(fmt, arg ...) pr_debug(PFX1 "[D]%s: "  fmt, __func__ , ##arg)
+
+#ifdef NETLINK_TEST
+#undef NETLINK_TEST
+#endif
+
+#define NETLINK_TEST 17
+
+#ifdef MAX_NL_MSG_LEN
+#undef MAX_NL_MSG_LEN
+#endif
+
+#define MAX_NL_MSG_LEN 1024
+
+
+#ifdef ON
+#undef ON
+#endif
+#ifdef OFF
+#undef OFF
+#endif
+#ifdef ACK
+#undef ACK
+#endif
+
+#define ON 1
+#define OFF 0
+#define ACK 2
+
+/*
+used send command to native process
+
+parameter: command could be macro ON: enable co-exist; OFF: disable co-exist;
+ACK: after get native process init message send ACK
+
+*/
+extern void send_command_to_daemon(const int command);
+
+/*
+before use kernel socket, please call init socket first
+return value: 0: ok; -1: fail
+*/
+extern int bgw_init_socket(void);
+
+extern void bgw_destroy_netlink_kernel(void);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h
new file mode 100644
index 0000000000000..cf3e830003ac8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h
@@ -0,0 +1,349 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _OSAL_H_
+#define _OSAL_H_
+
+#include <osal_typedef.h>
+#include <linux/sched/debug.h>
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define OS_BIT_OPS_SUPPORT 1
+
+#define _osal_inline_ inline
+
+#define MAX_THREAD_NAME_LEN 16
+#define MAX_WAKE_LOCK_NAME_LEN 16
+#define OSAL_OP_BUF_SIZE    64
+
+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD))
+#define OSAL_OP_DATA_SIZE   8
+#else
+#define OSAL_OP_DATA_SIZE   32
+#endif
+
+#define DBG_LOG_STR_SIZE    256
+
+#define osal_sizeof(x) sizeof(x)
+
+#define osal_array_size(x) (sizeof(x)/sizeof(x[0]))
+
+#ifndef NAME_MAX
+#define NAME_MAX 256
+#endif
+
+#define WMT_OP_BIT(x) (0x1UL << x)
+#define WMT_OP_HIF_BIT WMT_OP_BIT(0)
+
+#define RB_SIZE(prb) ((prb)->size)
+#define RB_MASK(prb) (RB_SIZE(prb) - 1)
+#define RB_COUNT(prb) ((prb)->write - (prb)->read)
+#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb))
+#define RB_EMPTY(prb) ((prb)->write == (prb)->read)
+
+#define RB_INIT(prb, qsize) \
+do { \
+	(prb)->read = (prb)->write = 0; \
+	(prb)->size = (qsize); \
+} while (0)
+
+#define RB_PUT(prb, value) \
+do { \
+	if (!RB_FULL(prb)) { \
+		(prb)->queue[(prb)->write & RB_MASK(prb)] = value; \
+		++((prb)->write); \
+	} \
+	else { \
+		osal_assert(!RB_FULL(prb)); \
+	} \
+} while (0)
+
+#define RB_GET(prb, value) \
+do { \
+	if (!RB_EMPTY(prb)) { \
+		value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \
+		++((prb)->read); \
+		if (RB_EMPTY(prb)) { \
+			(prb)->read = (prb)->write = 0; \
+		} \
+	} \
+	else { \
+		value = NULL; \
+		osal_assert(!RB_EMPTY(prb)); \
+	} \
+} while (0)
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+//typedef VOID(*P_TIMEOUT_HANDLER) (unsigned long);
+typedef VOID(*P_TIMEOUT_HANDLER) (struct timer_list *t);
+typedef INT32(*P_COND) (VOID *);
+
+typedef struct _OSAL_TIMER_ {
+	struct timer_list timer;
+	P_TIMEOUT_HANDLER timeoutHandler;
+	unsigned long timeroutHandlerData;
+} OSAL_TIMER, *P_OSAL_TIMER;
+
+typedef struct _OSAL_UNSLEEPABLE_LOCK_ {
+	spinlock_t lock;
+	unsigned long flag;
+} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK;
+
+typedef struct _OSAL_SLEEPABLE_LOCK_ {
+	struct mutex lock;
+} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK;
+
+typedef struct _OSAL_SIGNAL_ {
+	struct completion comp;
+	UINT32 timeoutValue;
+} OSAL_SIGNAL, *P_OSAL_SIGNAL;
+
+typedef struct _OSAL_EVENT_ {
+	wait_queue_head_t waitQueue;
+/* VOID *pWaitQueueData; */
+	UINT32 timeoutValue;
+	INT32 waitFlag;
+
+} OSAL_EVENT, *P_OSAL_EVENT;
+
+typedef struct _OSAL_THREAD_ {
+	struct task_struct *pThread;
+	VOID *pThreadFunc;
+	VOID *pThreadData;
+	char threadName[MAX_THREAD_NAME_LEN];
+} OSAL_THREAD, *P_OSAL_THREAD;
+
+typedef struct _OSAL_FIFO_ {
+	/*fifo definition */
+	VOID *pFifoBody;
+	spinlock_t fifoSpinlock;
+	/*fifo operations */
+	 INT32 (*FifoInit)(struct _OSAL_FIFO_ *pFifo, UINT8 *buf, UINT32);
+	 INT32 (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo);
+	 INT32 (*FifoReset)(struct _OSAL_FIFO_ *pFifo);
+	 INT32 (*FifoSz)(struct _OSAL_FIFO_ *pFifo);
+	 INT32 (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo);
+	 INT32 (*FifoLen)(struct _OSAL_FIFO_ *pFifo);
+	 INT32 (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo);
+	 INT32 (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo);
+	 INT32 (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const VOID *buf, UINT32 len);
+	 INT32 (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, UINT32 len);
+} OSAL_FIFO, *P_OSAL_FIFO;
+
+typedef struct firmware osal_firmware;
+
+typedef struct _OSAL_OP_DAT {
+	UINT32 opId;		/* Event ID */
+	UINT32 u4InfoBit;	/* Reserved */
+	SIZE_T au4OpData[OSAL_OP_DATA_SIZE];	/* OP Data */
+} OSAL_OP_DAT, *P_OSAL_OP_DAT;
+
+typedef struct _OSAL_LXOP_ {
+	OSAL_OP_DAT op;
+	OSAL_SIGNAL signal;
+	INT32 result;
+} OSAL_OP, *P_OSAL_OP;
+
+typedef struct _OSAL_LXOP_Q {
+	OSAL_SLEEPABLE_LOCK sLock;
+	UINT32 write;
+	UINT32 read;
+	UINT32 size;
+	P_OSAL_OP queue[OSAL_OP_BUF_SIZE];
+} OSAL_OP_Q, *P_OSAL_OP_Q;
+
+typedef struct _OSAL_WAKE_LOCK_ {
+	#ifdef CONFIG_PM_WAKELOCKS
+	struct wakeup_source wake_lock;
+	#else
+	struct wake_lock wake_lock;
+	#endif
+	UINT8 name[MAX_WAKE_LOCK_NAME_LEN];
+} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK;
+#if 1
+typedef struct _OSAL_BIT_OP_VAR_ {
+	unsigned long data;
+	OSAL_UNSLEEPABLE_LOCK opLock;
+} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR;
+#else
+#define OSAL_BIT_OP_VAR unsigned long
+#define P_OSAL_BIT_OP_VAR unsigned long *
+
+#endif
+typedef UINT32(*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread);
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+extern UINT32 osal_strlen(const char *str);
+extern INT32 osal_strcmp(const char *dst, const char *src);
+extern INT32 osal_strncmp(const char *dst, const char *src, UINT32 len);
+extern char *osal_strcpy(char *dst, const char *src);
+extern char *osal_strncpy(char *dst, const char *src, UINT32 len);
+extern char *osal_strcat(char *dst, const char *src);
+extern char *osal_strncat(char *dst, const char *src, UINT32 len);
+extern char *osal_strchr(const char *str, UINT8 c);
+extern char *osal_strsep(char **str, const char *c);
+extern int osal_strtol(const char *str, UINT32 adecimal, long *res);
+extern INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...);
+extern char *osal_strstr(char *str1, const char *str2);
+
+extern INT32 osal_err_print(const char *str, ...);
+extern INT32 osal_dbg_print(const char *str, ...);
+extern INT32 osal_warn_print(const char *str, ...);
+
+extern INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line);
+extern INT32 osal_sprintf(char *str, const char *format, ...);
+extern VOID *osal_malloc(UINT32 size);
+extern VOID osal_free(const VOID *dst);
+extern VOID *osal_memset(VOID *buf, INT32 i, UINT32 len);
+extern VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len);
+extern INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len);
+
+extern INT32 osal_sleep_ms(UINT32 ms);
+extern INT32 osal_udelay(UINT32 us);
+extern INT32 osal_timer_create(P_OSAL_TIMER);
+extern INT32 osal_timer_start(P_OSAL_TIMER, UINT32);
+extern INT32 osal_timer_stop(P_OSAL_TIMER);
+extern INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer);
+extern INT32 osal_timer_modify(P_OSAL_TIMER, UINT32);
+extern INT32 osal_timer_delete(P_OSAL_TIMER);
+
+extern INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size);
+extern VOID osal_fifo_deinit(P_OSAL_FIFO pFifo);
+extern INT32 osal_fifo_reset(P_OSAL_FIFO pFifo);
+extern UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size);
+extern UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size);
+extern UINT32 osal_fifo_len(P_OSAL_FIFO pFifo);
+extern UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo);
+extern UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo);
+extern UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo);
+extern UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo);
+
+extern INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK plock);
+extern INT32 osal_wake_lock(P_OSAL_WAKE_LOCK plock);
+extern INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK plock);
+extern INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK plock);
+extern INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK plock);
+
+#if defined(CONFIG_PROVE_LOCKING)
+#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); }
+#else
+extern INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK);
+#endif
+extern INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK);
+extern INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK);
+extern INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK);
+
+#if defined(CONFIG_PROVE_LOCKING)
+#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); }
+#else
+extern INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK);
+#endif
+extern INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK);
+extern INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK);
+extern INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK);
+
+extern INT32 osal_signal_init(P_OSAL_SIGNAL);
+extern INT32 osal_wait_for_signal(P_OSAL_SIGNAL);
+extern INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL);
+extern INT32 osal_raise_signal(P_OSAL_SIGNAL);
+extern INT32 osal_signal_deinit(P_OSAL_SIGNAL);
+
+extern INT32 osal_event_init(P_OSAL_EVENT);
+extern INT32 osal_wait_for_event(P_OSAL_EVENT, P_COND, void *);
+extern INT32 osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void *);
+extern INT32 osal_trigger_event(P_OSAL_EVENT);
+
+extern INT32 osal_event_deinit(P_OSAL_EVENT);
+
+extern INT32 osal_thread_create(P_OSAL_THREAD);
+extern INT32 osal_thread_run(P_OSAL_THREAD);
+extern INT32 osal_thread_should_stop(P_OSAL_THREAD);
+extern INT32 osal_thread_stop(P_OSAL_THREAD);
+/*extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/
+extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER);
+/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/
+extern INT32 osal_thread_destroy(P_OSAL_THREAD);
+
+extern INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData);
+extern INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData);
+extern INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData);
+extern INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData);
+extern INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData);
+
+extern INT32 osal_dbg_assert_aee(const char *module, const char *detail_description);
+extern INT32 osal_gettimeofday(PINT32 sec, PINT32 usec);
+extern INT32 osal_printtimeofday(const PUINT8 prefix);
+
+extern VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, UINT32 len, UINT32 limit);
+
+extern UINT32 osal_op_get_id(P_OSAL_OP pOp);
+extern MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp);
+extern VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result);
+extern VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result);
+extern UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length);
+extern VOID osal_thread_show_stack(P_OSAL_THREAD pThread);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#define osal_assert(condition) \
+do { \
+	if (!(condition)) \
+		osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition); \
+} while (0)
+
+#endif /* _OSAL_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h
new file mode 100644
index 0000000000000..b3a9c57e062dd
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h
@@ -0,0 +1,90 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _OSAL_TYPEDEF_H_
+#define _OSAL_TYPEDEF_H_
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/proc_fs.h>
+#include <linux/workqueue.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/kthread.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#ifdef CONFIG_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#else
+#include <linux/fb.h>
+#endif
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#ifdef WMT_PLAT_ALPS
+#include <aee.h>
+#endif
+#include <linux/kfifo.h>
+#ifdef CONFIG_PM_WAKELOCKS
+#include <linux/pm_wakeup.h>
+#else
+#include <linux/wakelock.h>
+#endif
+#include <linux/log2.h>
+
+#ifndef _TYPEDEFS_H		/*fix redifine */
+typedef char INT8;
+#endif
+
+typedef void VOID, *PVOID, **PPVOID;
+typedef char *PINT8, **PPINT8;
+typedef short INT16, *PINT16, **PPINT16;
+typedef int INT32, *PINT32, **PPINT32;
+typedef long long INT64, *PINT64, **PPINT64;
+
+typedef unsigned char UINT8, *PUINT8, **PPUINT8;
+typedef unsigned short UINT16, *PUINT16, **PPUINT16;
+typedef unsigned int UINT32, *PUINT32, **PPUINT32;
+typedef unsigned long long UINT64, *PUINT64, **PPUINT64;
+
+typedef size_t SIZE_T;
+
+typedef int MTK_WCN_BOOL;
+#ifndef MTK_WCN_BOOL_TRUE
+#define MTK_WCN_BOOL_FALSE               ((MTK_WCN_BOOL) 0)
+#define MTK_WCN_BOOL_TRUE                ((MTK_WCN_BOOL) 1)
+#endif
+
+#endif /*_OSAL_TYPEDEF_H_*/
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h
new file mode 100644
index 0000000000000..17be778484c17
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h
@@ -0,0 +1,97 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WMT_IDC_H_
+#define _WMT_IDC_H_
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "wmt_stp_exp.h"
+
+#if CFG_WMT_LTE_COEX_HANDLING
+
+#include "wmt_stp_exp.h"
+#include "conn_md_exp.h"
+
+#define LTE_IDC_BUFFER_MAX_SIZE 1024
+/*comment from firmware owner,max pckage num is 5,but should not happened*/
+#define WMT_IDC_RX_MAX_LEN 384
+#define LTE_MSG_ID_OFFSET 0x30
+
+typedef enum {
+	WMT_IDC_TX_OPCODE_MIN = 0,
+	WMT_IDC_TX_OPCODE_LTE_PARA = 0x0a,
+	WMT_IDC_TX_OPCODE_LTE_FREQ = 0x0b,
+	WMT_IDC_TX_OPCODE_WIFI_MAX_POWER = 0x0c,
+	WMT_IDC_TX_OPCODE_DEBUG_MONITOR = 0x0e,
+	WMT_IDC_TX_OPCODE_SPLIT_FILTER = 0x0f,
+	WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS = 0x16,
+	WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION = 0x17,
+	WMT_IDC_TX_OPCODE_LTE_INDICATION = 0x20,
+	WMT_IDC_TX_OPCODE_MAX
+} WMT_IDC_TX_OPCODE;
+
+typedef enum {
+	WMT_IDC_RX_OPCODE_BTWF_DEF_PARA = 0x0,
+	WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN = 0x1,
+	/* WMT_IDC_RX_OPCODE_TDM_REQ = 0x10, */
+	WMT_IDC_RX_OPCODE_DEBUG_MONITOR = 0x02,
+	WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE = 0x03,
+	WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND = 0x04,
+	WMT_IDC_RX_OPCODE_UART_PIN_SEL = 0x05,
+	WMT_IDC_RX_OPCODE_MAX
+} WMT_IDC_RX_OPCODE;
+
+#if (CFG_WMT_LTE_ENABLE_MSGID_MAPPING == 0)
+typedef enum {
+	IPC_L4C_MSG_ID_INVALID = IPC_L4C_MSG_ID_BEGIN,
+	IPC_L4C_MSG_ID_END,
+	IPC_EL1_MSG_ID_INVALID = IPC_EL1_MSG_ID_BEGIN,
+	/* below are EL1 IPC messages sent from AP */
+	IPC_MSG_ID_EL1_LTE_TX_ALLOW_IND,
+	IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND,
+	IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND,
+	IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND,
+	IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND,
+
+	/* below are EL1 messages sent to AP */
+	IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND,
+	IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND,
+	IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND,
+	IPC_MSG_ID_EL1_LTE_TX_IND,
+	IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND,
+	IPC_MSG_ID_EL1_PIN_TYPE_IND,
+	IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND,
+	IPC_MSG_ID_EL1_DUMMY13_IND,
+	IPC_MSG_ID_EL1_DUMMY14_IND,
+	IPC_MSG_ID_EL1_DUMMY15_IND,
+	IPC_EL1_MSG_ID_END,
+} IPC_MSG_ID_CODE;
+#endif
+
+typedef struct _MTK_WCN_WMT_IDC_INFO_ {
+	ipc_ilm_t iit;
+	CONN_MD_BRIDGE_OPS ops;
+	UINT8 buffer[LTE_IDC_BUFFER_MAX_SIZE];
+} MTK_WCN_WMT_IDC_INFO, *P_MTK_WCN_WMT_IDC_INFO;
+
+extern INT32 wmt_idc_init(VOID);
+extern INT32 wmt_idc_deinit(VOID);
+extern INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm);
+extern INT32 wmt_idc_msg_to_lte_handing(VOID);
+extern UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len);
+
+#endif /* endif CFG_WMT_LTE_COEX_HANDLING */
+
+#endif /* _WMT_IDC_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile
new file mode 100644
index 0000000000000..ff0f0b0aefda7
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile
@@ -0,0 +1,21 @@
+ifeq ($(CONFIG_MTK_COMBO), y)
+
+ccflags-y += \
+	-I$(src)/../../linux/include \
+	-I$(src)/../../linux/pri/include \
+	-I$(src)/../../core/include \
+	-I$(src)/../../include \
+	-I$(src)/../include \
+	-I$(src)/../../../common_detect \
+	-I$(srctree)/drivers/misc/mediatek/btif/common/inc \
+	-I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach
+
+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1
+
+obj-y += stp_btif.o \
+         stp_dbg.o \
+         stp_exp.o \
+         wmt_dev.o \
+         wmt_exp.o
+
+endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h
new file mode 100644
index 0000000000000..3730fbba69289
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h
@@ -0,0 +1,31 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _STP_BTIF_H_
+#define _STP_BTIF_H_
+
+#include "osal_typedef.h"
+#include "mtk_btif_exp.h"
+
+extern INT32 mtk_wcn_consys_stp_btif_open(VOID);
+extern INT32 mtk_wcn_consys_stp_btif_close(VOID);
+extern INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb);
+extern INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len);
+extern INT32 mtk_wcn_consys_stp_btif_wakeup(VOID);
+extern INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag);
+extern INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode);
+extern INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag);
+extern MTK_WCN_BOOL mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h
new file mode 100644
index 0000000000000..de5684a168537
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h
@@ -0,0 +1,316 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _STP_DEBUG_H_
+#define _STP_DEBUG_H_
+
+#include <linux/time.h>
+#include "osal.h"
+
+#define CONFIG_LOG_STP_INTERNAL
+
+#if 1				/* #ifndef CONFIG_LOG_STP_INTERNAL */
+#define STP_PKT_SZ  16
+#define STP_DMP_SZ 2048
+#define STP_PKT_NO 2048
+
+#define STP_DBG_LOG_ENTRY_NUM 60
+#define STP_DBG_LOG_ENTRY_SZ  64
+
+#else
+
+#define STP_PKT_SZ  16
+#define STP_DMP_SZ 16
+#define STP_PKT_NO 16
+
+#define STP_DBG_LOG_ENTRY_NUM 28
+#define STP_DBG_LOG_ENTRY_SZ 64
+
+#endif
+
+typedef enum {
+	STP_DBG_EN = 0,
+	STP_DBG_PKT = 1,
+	STP_DBG_DR = 2,
+	STP_DBG_FW_ASSERT = 3,
+	STP_DBG_FW_LOG = 4,
+	STP_DBG_FW_DMP = 5,
+	STP_DBG_MAX
+} STP_DBG_OP_T;
+
+typedef enum {
+	STP_DBG_PKT_FIL_ALL = 0,
+	STP_DBG_PKT_FIL_BT = 1,
+	STP_DBG_PKT_FIL_GPS = 2,
+	STP_DBG_PKT_FIL_FM = 3,
+	STP_DBG_PKT_FIL_WMT = 4,
+	STP_DBG_PKT_FIL_MAX
+} STP_DBG_PKT_FIL_T;
+
+static char *const gStpDbgType[] = {
+	"< BT>",
+	"< FM>",
+	"<GPS>",
+	"<WiFi>",
+	"<WMT>",
+	"<STP>",
+	"<DBG>",
+	"<WAKEINT>",
+	"<UNKNOWN>"
+};
+
+typedef enum {
+	STP_DBG_DR_MAX = 0,
+} STP_DBG_DR_FIL_T;
+
+typedef enum {
+	STP_DBG_FW_MAX = 0,
+} STP_DBG_FW_FIL_T;
+
+typedef enum {
+	PKT_DIR_RX = 0,
+	PKT_DIR_TX
+} STP_DBG_PKT_DIR_T;
+
+/*simple log system ++*/
+
+typedef struct {
+	/*type: 0. pkt trace 1. fw info
+	* 2. assert info 3. trace32 dump .
+	* -1. linked to the the previous
+	*/
+	int id;
+	int len;
+	char buffer[STP_DBG_LOG_ENTRY_SZ];
+} MTKSTP_LOG_ENTRY_T;
+
+typedef struct log_sys {
+	MTKSTP_LOG_ENTRY_T queue[STP_DBG_LOG_ENTRY_NUM];
+	unsigned int size;
+	unsigned int in;
+	unsigned int out;
+	spinlock_t lock;
+} MTKSTP_LOG_SYS_T;
+/*--*/
+
+typedef struct stp_dbg_pkt_hdr {
+	/* packet information */
+	unsigned int sec;
+	unsigned int usec;
+	unsigned int dbg_type;
+	unsigned int dmy;
+	unsigned int no;
+	unsigned int dir;
+
+	/* packet content */
+	unsigned int type;
+	unsigned int len;
+	unsigned int ack;
+	unsigned int seq;
+	unsigned int chs;
+	unsigned int crc;
+} STP_DBG_HDR_T;
+
+typedef struct stp_dbg_pkt {
+	struct stp_dbg_pkt_hdr hdr;
+	unsigned char raw[STP_DMP_SZ];
+} STP_PACKET_T;
+
+typedef struct mtkstp_dbg_t {
+	/*log_sys */
+	int pkt_trace_no;
+	void *btm;
+	int is_enable;
+	MTKSTP_LOG_SYS_T *logsys;
+} MTKSTP_DBG_T;
+
+/* extern void aed_combo_exception(const int *, int, const int *, int, const char *); */
+
+#define STP_CORE_DUMP_TIMEOUT (5*60*1000)	/* default 5minutes */
+#define STP_OJB_NAME_SZ 20
+#define STP_CORE_DUMP_INFO_SZ 500
+#define STP_CORE_DUMP_INIT_SIZE 1
+typedef enum wcn_compress_algorithm_t {
+	GZIP = 0,
+	BZIP2 = 1,
+	RAR = 2,
+	LMA = 3,
+	MAX
+} WCN_COMPRESS_ALG_T;
+
+typedef INT32 (*COMPRESS_HANDLER) (void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz,
+				  INT32 finish);
+typedef struct wcn_compressor_t {
+	/* current object name */
+	UINT8 name[STP_OJB_NAME_SZ + 1];
+
+	/* buffer for raw data, named L1 */
+	PUINT8 L1_buf;
+	INT32 L1_buf_sz;
+	INT32 L1_pos;
+
+	/* target buffer, named L2 */
+	PUINT8 L2_buf;
+	INT32 L2_buf_sz;
+	INT32 L2_pos;
+
+	/* compress state */
+	UINT8 f_done;
+	UINT16 reserved;
+	UINT32 uncomp_size;
+	UINT32 crc32;
+
+	/* compress algorithm */
+	UINT8 f_compress_en;
+	WCN_COMPRESS_ALG_T compress_type;
+	void *worker;
+	COMPRESS_HANDLER handler;
+} WCN_COMPRESSOR_T, *P_WCN_COMPRESSOR_T;
+
+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz);
+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T compressor);
+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T compressor, PUINT8 buf, INT32 len, INT32 finish);
+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T compressor, PUINT8 *pbuf, PINT32 len);
+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T compressor, UINT8 enable, WCN_COMPRESS_ALG_T type);
+
+typedef enum core_dump_state_t {
+	CORE_DUMP_INIT = 0,
+	CORE_DUMP_DOING,
+	CORE_DUMP_TIMEOUT,
+	CORE_DUMP_DONE,
+	CORE_DUMP_MAX
+} CORE_DUMP_STA;
+
+typedef struct core_dump_t {
+	/* compress dump data and buffered */
+	P_WCN_COMPRESSOR_T compressor;
+
+	/* timer for monitor timeout */
+	OSAL_TIMER dmp_timer;
+	UINT32 timeout;
+
+	OSAL_SLEEPABLE_LOCK dmp_lock;
+
+	/* state machine for core dump flow */
+	CORE_DUMP_STA sm;
+
+	/* dump info */
+	INT8 info[STP_CORE_DUMP_INFO_SZ + 1];
+} WCN_CORE_DUMP_T, *P_WCN_CORE_DUMP_T;
+
+typedef enum _ENUM_STP_FW_ISSUE_TYPE_ {
+	STP_FW_ISSUE_TYPE_INVALID = 0x0,
+	STP_FW_ASSERT_ISSUE = 0x1,
+	STP_FW_NOACK_ISSUE = 0x2,
+	STP_FW_WARM_RST_ISSUE = 0x3,
+	STP_DBG_PROC_TEST = 0x4,
+	STP_HOST_TRIGGER_FW_ASSERT = 0x5,
+	STP_HOST_TRIGGER_ASSERT_TIMEOUT = 0x6,
+	STP_FW_ISSUE_TYPE_MAX
+} ENUM_STP_FW_ISSUE_TYPE, *P_ENUM_STP_FW_ISSUE_TYPE;
+
+/* this was added for support dmareg's issue */
+typedef enum _ENUM_DMA_ISSUE_TYPE_ {
+	CONNSYS_CLK_GATE_STATUS = 0x00,
+	CONSYS_EMI_STATUS,
+	SYSRAM1,
+	SYSRAM2,
+	SYSRAM3,
+	DMA_REGS_MAX
+} ENUM_DMA_ISSUE_TYPE;
+#define STP_PATCH_TIME_SIZE 12
+#define STP_DBG_CPUPCR_NUM 512
+#define STP_DBG_DMAREGS_NUM 16
+#define STP_PATCH_BRANCH_SZIE 8
+#define STP_ASSERT_INFO_SIZE 64
+#define STP_DBG_ROM_VER_SIZE 4
+#define STP_ASSERT_TYPE_SIZE 32
+
+typedef struct stp_dbg_host_assert_t {
+	UINT32 drv_type;
+	UINT32 reason;
+	UINT32 assert_from_host;
+} STP_DBG_HOST_ASSERT_T, *P_STP_DBG_HOST_ASSERT_T;
+
+typedef struct stp_dbg_cpupcr_t {
+	UINT32 chipId;
+	UINT8 romVer[STP_DBG_ROM_VER_SIZE];
+	UINT8 patchVer[STP_PATCH_TIME_SIZE];
+	UINT8 branchVer[STP_PATCH_BRANCH_SZIE];
+	UINT32 wifiVer;
+	UINT32 count;
+	UINT32 stop_flag;
+	UINT32 buffer[STP_DBG_CPUPCR_NUM];
+	UINT8 assert_info[STP_ASSERT_INFO_SIZE];
+	UINT32 fwTaskId;
+	UINT32 fwRrq;
+	UINT32 fwIsr;
+	STP_DBG_HOST_ASSERT_T host_assert_info;
+	UINT8 assert_type[STP_ASSERT_TYPE_SIZE];
+	ENUM_STP_FW_ISSUE_TYPE issue_type;
+	OSAL_SLEEPABLE_LOCK lock;
+} STP_DBG_CPUPCR_T, *P_STP_DBG_CPUPCR_T;
+
+typedef struct stp_dbg_dmaregs_t {
+	UINT32 count;
+	UINT32 dmaIssue[DMA_REGS_MAX][STP_DBG_DMAREGS_NUM];
+	OSAL_SLEEPABLE_LOCK lock;
+} STP_DBG_DMAREGS_T, *P_STP_DBG_DMAREGS_T;
+
+typedef enum _ENUM_ASSERT_INFO_PARSER_TYPE_ {
+	STP_DBG_ASSERT_INFO = 0x0,
+	STP_DBG_FW_TASK_ID = 0x1,
+	STP_DBG_FW_ISR = 0x2,
+	STP_DBG_FW_IRQ = 0x3,
+	STP_DBG_ASSERT_TYPE = 0x4,
+	STP_DBG_PARSER_TYPE_MAX
+} ENUM_ASSERT_INFO_PARSER_TYPE, *P_ENUM_ASSERT_INFO_PARSER_TYPE;
+
+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout);
+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp);
+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len);
+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 len);
+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout);
+INT32 wcn_core_dump_timeout(void);
+INT32 wcn_wmtd_timeout_collect_ftrace(void);
+
+extern INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout);
+extern INT32 wcn_core_dump_deinit_gcoredump(VOID);
+extern INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL is_coredump_timeout);
+extern int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg);
+extern int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg);
+extern MTKSTP_DBG_T *stp_dbg_init(void *);
+extern int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg);
+extern int stp_dbg_dmp_out_ex(char *buf, int *len);
+extern int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len);
+extern int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg);
+extern char stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len);
+
+extern INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd);
+extern INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len);
+extern int
+stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg,
+		int dbg_type, int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body);
+extern int stp_dbg_log_ctrl(unsigned int on);
+extern INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd);
+extern INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep);
+extern INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en);
+extern INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer,
+				      PUINT8 pPatchBrh);
+extern INT32 stp_dbg_set_wifiver(UINT32 wifiver);
+extern INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 len);
+extern INT32 stp_dbg_set_fw_info(PUINT8 assert_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type);
+extern INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en);
+extern UINT32 stp_dbg_get_host_trigger_assert(VOID);
+#endif /* end of _STP_DEBUG_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h
new file mode 100644
index 0000000000000..5788eb355549a
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h
@@ -0,0 +1,71 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WMT_DEV_H_
+#define _WMT_DEV_H_
+
+#include "osal.h"
+
+#define STP_UART_FULL 0x01
+#define STP_UART_MAND 0x02
+#define STP_BTIF_FULL 0x03
+#define STP_SDIO      0x04
+
+#define CFG_WMT_DBG_SUPPORT 1	/* support wmt_dbg or not */
+#define CFG_WMT_PROC_FOR_AEE 1
+
+extern VOID wmt_dev_rx_event_cb(VOID);
+extern INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent);
+extern INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf);
+extern INT32 wmt_dev_patch_put(osal_firmware **ppPatch);
+extern VOID wmt_dev_patch_info_free(VOID);
+extern VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd);
+extern MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID);
+
+#if CFG_WMT_DBG_SUPPORT
+typedef struct _COEX_BUF {
+	UINT8 buffer[128];
+	INT32 availSize;
+} COEX_BUF, *P_COEX_BUF;
+
+typedef enum _ENUM_CMD_TYPE_T {
+	WMTDRV_CMD_ASSERT = 0,
+	WMTDRV_CMD_EXCEPTION = 1,
+	WMTDRV_CMD_COEXDBG_00 = 2,
+	WMTDRV_CMD_COEXDBG_01 = 3,
+	WMTDRV_CMD_COEXDBG_02 = 4,
+	WMTDRV_CMD_COEXDBG_03 = 5,
+	WMTDRV_CMD_COEXDBG_04 = 6,
+	WMTDRV_CMD_COEXDBG_05 = 7,
+	WMTDRV_CMD_COEXDBG_06 = 8,
+	WMTDRV_CMD_COEXDBG_07 = 9,
+	WMTDRV_CMD_COEXDBG_08 = 10,
+	WMTDRV_CMD_COEXDBG_09 = 11,
+	WMTDRV_CMD_COEXDBG_10 = 12,
+	WMTDRV_CMD_COEXDBG_11 = 13,
+	WMTDRV_CMD_COEXDBG_12 = 14,
+	WMTDRV_CMD_COEXDBG_13 = 15,
+	WMTDRV_CMD_COEXDBG_14 = 16,
+	WMTDRV_CMD_COEXDBG_15 = 17,
+	WMTDRV_CMD_NOACK_TEST = 18,
+	WMTDRV_CMD_WARNRST_TEST = 19,
+	WMTDRV_CMD_FWTRACE_TEST = 20,
+	WMTDRV_CMD_MAX
+} ENUM_WMTDRV_CMD_T, *P_ENUM_WMTDRV_CMD_T;
+
+#endif
+
+typedef INT32(*WMT_DEV_DBG_FUNC) (INT32 par1, INT32 par2, INT32 par3);
+
+#endif /*_WMT_DEV_H_*/
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c
new file mode 100644
index 0000000000000..76debb4674f9c
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c
@@ -0,0 +1,279 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*file: stp_btif, mainly control stp & btif interaction*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG "[STP-BTIF]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+#include "wmt_exp.h"
+#include "stp_exp.h"
+#include "stp_btif.h"
+
+#include <asm/current.h>
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define BTIF_OWNER_NAME "CONSYS_STP"
+
+#define STP_MAX_PACKAGE_ALLOWED (2000)
+
+#define STP_BTIF_TX_RTY_LMT (10)
+#define STP_BTIF_TX_RTY_DLY (5)
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+unsigned long stpBtifId = 0;
+unsigned long *pBtifRef = &stpBtifId;
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+INT32 mtk_wcn_consys_stp_btif_open(VOID)
+{
+	INT32 iRet = -1;
+
+	iRet = mtk_wcn_btif_open(BTIF_OWNER_NAME, pBtifRef);
+	if (iRet) {
+		WMT_WARN_FUNC("STP open btif fail(%d)\n", iRet);
+		return -1;
+	}
+	WMT_DBG_FUNC("STP open bitf OK\n");
+
+	mtk_wcn_stp_register_if_tx(STP_BTIF_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_consys_stp_btif_tx);
+
+	return 0;
+}
+
+INT32 mtk_wcn_consys_stp_btif_close(VOID)
+{
+	INT32 iRet = 0;
+
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference!\n");
+		iRet = -1;
+	} else {
+		iRet = mtk_wcn_btif_close(stpBtifId);
+		if (iRet) {
+			WMT_WARN_FUNC("STP close btif fail(%d)\n", iRet);
+			iRet = -2;
+		} else {
+			stpBtifId = 0;
+			WMT_DBG_FUNC("STP close btif OK\n");
+		}
+	}
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb)
+{
+	INT32 iRet = 0;
+
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference\n!");
+		iRet = -1;
+	} else {
+		iRet = mtk_wcn_btif_rx_cb_register(stpBtifId, rx_cb);
+		if (iRet) {
+			WMT_WARN_FUNC("STP register rxcb to btif fail(%d)\n", iRet);
+			iRet = -2;
+		} else {
+			WMT_DBG_FUNC("STP register rxcb to  btif OK\n");
+		}
+	}
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len)
+{
+	INT32 retry_left = STP_BTIF_TX_RTY_LMT;
+	INT32 wr_count = 0;
+	INT32 written = 0;
+
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference!\n");
+		return -1;
+	}
+
+	if (len == 0) {
+		*written_len = 0;
+		WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf);
+		return 0;
+	}
+
+	*written_len = 0;
+
+	if (len > STP_MAX_PACKAGE_ALLOWED) {
+		WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm);
+		return -2;
+	}
+	wr_count = mtk_wcn_btif_write(stpBtifId, pBuf, len);
+
+	if (wr_count < 0) {
+		WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count);
+		*written_len = 0;
+		return -3;
+	}
+	if (wr_count == len) {
+		/*perfect case */
+		*written_len = wr_count;
+		return wr_count;
+	}
+
+	while ((retry_left--) && (wr_count < len)) {
+		osal_sleep_ms(STP_BTIF_TX_RTY_DLY);
+		written = mtk_wcn_btif_write(stpBtifId, pBuf + wr_count, len - wr_count);
+		if (written < 0) {
+			WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written);
+			break;
+		}
+		wr_count += written;
+	}
+
+	if (wr_count == len) {
+		WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left);
+		/*recovered case */
+		*written_len = wr_count;
+		return wr_count;
+	}
+
+	WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n",
+		     len, wr_count, retry_left, current->pid, current->comm);
+	*written_len = 0;
+	return -wr_count;
+}
+
+INT32 mtk_wcn_consys_stp_btif_rx(UINT8 *pBuf, UINT32 len)
+{
+	return 0;
+}
+
+INT32 mtk_wcn_consys_stp_btif_wakeup(VOID)
+{
+	INT32 iRet = 0;
+
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference!\n");
+		iRet = -1;
+	} else {
+		iRet = mtk_wcn_btif_wakeup_consys(stpBtifId);
+		if (iRet) {
+			WMT_WARN_FUNC("STP btif wakeup consys fail(%d)\n", iRet);
+			iRet = -2;
+		} else {
+			WMT_DBG_FUNC("STP btif wakeup consys ok\n");
+		}
+	}
+
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag)
+{
+	INT32 iRet = 0;
+
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference!\n");
+		iRet = -1;
+	} else {
+		mtk_wcn_btif_dpidle_ctrl(stpBtifId, en_flag);
+		WMT_DBG_FUNC("stp btif dpidle ctrl done,en_flag(%d)\n", en_flag);
+	}
+
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode)
+{
+	INT32 iRet = 0;
+
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference!\n");
+		iRet = -1;
+	} else {
+		iRet = mtk_wcn_btif_loopback_ctrl(stpBtifId, mode);
+		if (iRet) {
+			WMT_WARN_FUNC("STP btif lpbk ctrl fail(%d)\n", iRet);
+			iRet = -2;
+		} else {
+			WMT_INFO_FUNC("stp btif lpbk ctrl ok,mode(%d)\n", mode);
+		}
+	}
+
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag)
+{
+	INT32 iRet = 0;
+
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference!\n");
+		iRet = -1;
+	} else {
+		iRet = mtk_wcn_btif_dbg_ctrl(stpBtifId, flag);
+		if (iRet) {
+			WMT_WARN_FUNC("STP btif log dbg ctrl fail(%d)\n", iRet);
+			iRet = -2;
+		} else {
+			WMT_INFO_FUNC("stp btif log dbg ctrl ok,flag(%d)\n", flag);
+		}
+	}
+
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len)
+{
+	if (!stpBtifId) {
+		WMT_WARN_FUNC("NULL BTIF ID reference!\n");
+		return -1;
+	} else {
+		return (INT32) mtk_wcn_btif_parser_wmt_evt(stpBtifId, str, len);
+	}
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c
new file mode 100644
index 0000000000000..fdb610cc3897d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c
@@ -0,0 +1,2061 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <linux/kernel.h>	/* GFP_KERNEL */
+#include <linux/timer.h>	/* init_timer, add_time, del_timer_sync */
+#include <linux/time.h>		/* gettimeofday */
+#include <linux/delay.h>
+#include <linux/slab.h>		/* kzalloc */
+#include <linux/sched.h>	/* task's status */
+#include <linux/vmalloc.h>
+#include <linux/err.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+
+#include <net/sock.h>
+#include <net/netlink.h>
+#include <linux/skbuff.h>
+#include <net/genetlink.h>
+
+#include <linux/zlib.h>
+#include <linux/uaccess.h>
+#include <linux/crc32.h>
+
+#include "osal_typedef.h"
+#include "stp_dbg.h"
+/* #include "stp_btm.h" */
+#include "btm_core.h"
+#include "wmt_plat.h"
+
+#define PFX_STP_DBG                      "[STPDbg]"
+#define STP_DBG_LOG_LOUD                 4
+#define STP_DBG_LOG_DBG                  3
+#define STP_DBG_LOG_INFO                 2
+#define STP_DBG_LOG_WARN                 1
+#define STP_DBG_LOG_ERR                  0
+
+unsigned int gStpDbgDbgLevel = STP_DBG_LOG_INFO;
+unsigned int gStpDbgLogOut = 0;
+
+#define STP_DBG_LOUD_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgDbgLevel >= STP_DBG_LOG_LOUD) \
+		pr_debug(PFX_STP_DBG "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_DBG_DBG_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \
+		pr_debug(PFX_STP_DBG "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_DBG_INFO_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgDbgLevel >= STP_DBG_LOG_INFO) \
+		pr_debug(PFX_STP_DBG "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_DBG_WARN_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgDbgLevel >= STP_DBG_LOG_WARN) \
+		pr_warn(PFX_STP_DBG "%s: "  fmt, __func__ , ##arg); \
+} while (0)
+#define STP_DBG_ERR_FUNC(fmt, arg...) \
+do { \
+	if (gStpDbgDbgLevel >= STP_DBG_LOG_ERR) \
+		pr_err(PFX_STP_DBG "%s: "   fmt, __func__ , ##arg); \
+} while (0)
+#define STP_DBG_TRC_FUNC(f) \
+do { \
+	if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \
+		pr_debug(PFX_STP_DBG "<%s> <%d>\n", __func__, __LINE__); \
+} while (0)
+
+MTKSTP_DBG_T *g_stp_dbg = NULL;
+
+#define STP_DBG_FAMILY_NAME        "STP_DBG"
+#define MAX_BIND_PROCESS    (4)
+#ifdef WMT_PLAT_ALPS
+#define STP_DBG_AEE_EXP_API (1)
+#else
+#define STP_DBG_AEE_EXP_API (0)
+#endif
+enum {
+	__STP_DBG_ATTR_INVALID,
+	STP_DBG_ATTR_MSG,
+	__STP_DBG_ATTR_MAX,
+};
+#define STP_DBG_ATTR_MAX       (__STP_DBG_ATTR_MAX - 1)
+
+enum {
+	__STP_DBG_COMMAND_INVALID,
+	STP_DBG_COMMAND_BIND,
+	STP_DBG_COMMAND_RESET,
+	__STP_DBG_COMMAND_MAX,
+};
+#define MTK_WIFI_COMMAND_MAX    (__STP_DBG_COMMAND_MAX - 1)
+
+static struct genl_family stp_dbg_gnl_family = {
+	.id = GENL_ID_GENERATE,
+	.hdrsize = 0,
+	.name = STP_DBG_FAMILY_NAME,
+	.version = 1,
+	.maxattr = STP_DBG_ATTR_MAX,
+};
+
+static void stp_dbg_nl_init(void);
+static void stp_dbg_nl_deinit(void);
+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info);
+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info);
+
+/* attribute policy */
+static struct nla_policy stp_dbg_genl_policy[STP_DBG_ATTR_MAX + 1] = {
+	[STP_DBG_ATTR_MSG] = {.type = NLA_NUL_STRING},
+};
+
+/* operation definition */
+#if 0
+static struct genl_ops stp_dbg_gnl_ops_bind = {
+	.cmd = STP_DBG_COMMAND_BIND,
+	.flags = 0,
+	.policy = stp_dbg_genl_policy,
+	.doit = stp_dbg_nl_bind,
+	.dumpit = NULL,
+};
+
+static struct genl_ops stp_dbg_gnl_ops_reset = {
+	.cmd = STP_DBG_COMMAND_RESET,
+	.flags = 0,
+	.policy = stp_dbg_genl_policy,
+	.doit = stp_dbg_nl_reset,
+	.dumpit = NULL,
+};
+#endif
+static struct genl_ops stp_dbg_gnl_ops_array[] = {
+	{
+		.cmd = STP_DBG_COMMAND_BIND,
+		.flags = 0,
+		.policy = stp_dbg_genl_policy,
+		.doit = stp_dbg_nl_bind,
+		.dumpit = NULL,
+	},
+	{
+		.cmd = STP_DBG_COMMAND_RESET,
+		.flags = 0,
+		.policy = stp_dbg_genl_policy,
+		.doit = stp_dbg_nl_reset,
+		.dumpit = NULL,
+	},
+};
+
+#if 0
+#define E2S(x) #x
+static char *dmaRegsStr[] = {
+	E2S(CONNSYS_CLK_GATE_STATUS),
+	E2S(CONSYS_EMI_STATUS),
+	E2S(SYSRAM1),
+	E2S(SYSRAM2),
+	E2S(SYSRAM3)
+};
+#endif
+static unsigned int stp_dbg_seqnum;
+static int num_bind_process;
+static pid_t bind_pid[MAX_BIND_PROCESS];
+
+static P_WCN_CORE_DUMP_T g_core_dump;
+
+static P_STP_DBG_CPUPCR_T g_stp_dbg_cpupcr;
+
+/* just show in log at present */
+static P_STP_DBG_DMAREGS_T g_stp_dbg_dmaregs;
+
+/* core_dump_timeout_handler - handler of coredump timeout
+ * @ data - core dump object's pointer
+ *
+ * No return value
+ */
+static void core_dump_timeout_handler(/*unsigned long data*/struct timer_list *t)
+{
+	//P_WCN_CORE_DUMP_T dmp = (P_WCN_CORE_DUMP_T) data;
+	P_WCN_CORE_DUMP_T dmp = from_timer(dmp,t,dmp_timer.timer);
+
+	STP_DBG_INFO_FUNC(" start\n");
+
+	stp_btm_notify_coredump_timeout_wq(g_stp_dbg->btm);
+
+	STP_DBG_INFO_FUNC(" end\n");
+
+	if (dmp)
+		dmp->sm = CORE_DUMP_TIMEOUT;
+}
+
+/* wcn_core_dump_init - create core dump sys
+ * @ timeout - core dump time out value
+ *
+ * Return object pointer if success, else NULL
+ */
+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout)
+{
+#define KBYTES (1024*sizeof(char))
+#define L1_BUF_SIZE (32*KBYTES)
+
+	P_WCN_CORE_DUMP_T core_dmp = NULL;
+
+	core_dmp = (P_WCN_CORE_DUMP_T) osal_malloc(sizeof(WCN_CORE_DUMP_T));
+	if (!core_dmp) {
+		STP_DBG_ERR_FUNC("alloc mem failed!\n");
+		goto fail;
+	}
+
+	osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T));
+
+	core_dmp->compressor = wcn_compressor_init("core_dump_compressor", L1_BUF_SIZE, 18*packet_num*KBYTES);
+	if (!core_dmp->compressor) {
+		STP_DBG_ERR_FUNC("create compressor failed!\n");
+		goto fail;
+	}
+	wcn_compressor_reset(core_dmp->compressor, 1, GZIP);
+
+	core_dmp->dmp_timer.timeoutHandler = core_dump_timeout_handler;
+	core_dmp->dmp_timer.timeroutHandlerData = (unsigned long)core_dmp;
+	osal_timer_create(&core_dmp->dmp_timer);
+	core_dmp->timeout = timeout;
+
+	osal_sleepable_lock_init(&core_dmp->dmp_lock);
+
+	core_dmp->sm = CORE_DUMP_INIT;
+	STP_DBG_INFO_FUNC("create coredump object OK!\n");
+
+	return core_dmp;
+
+fail:
+	if (core_dmp && core_dmp->compressor) {
+		wcn_compressor_deinit(core_dmp->compressor);
+		core_dmp->compressor = NULL;
+	}
+	if (core_dmp)
+		osal_free(core_dmp);
+
+	return NULL;
+}
+INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout)
+{
+	INT32 Ret = 0;
+
+	g_core_dump = wcn_core_dump_init(packet_num, timeout);
+	if (g_core_dump == NULL)
+		Ret = -1;
+	return Ret;
+}
+
+/* wcn_core_dump_deinit - destroy core dump object
+ * @ dmp - pointer of object
+ *
+ * Retunr 0 if success, else error code
+ */
+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp)
+{
+	if (dmp && dmp->compressor) {
+		wcn_compressor_deinit(dmp->compressor);
+		dmp->compressor = NULL;
+	}
+
+	if (dmp) {
+		osal_sleepable_lock_deinit(&dmp->dmp_lock);
+		osal_timer_stop(&dmp->dmp_timer);
+		osal_free(dmp);
+	}
+
+	return 0;
+}
+
+INT32 wcn_core_dump_deinit_gcoredump(VOID)
+{
+	wcn_core_dump_deinit(g_core_dump);
+	return 0;
+}
+
+static INT32 wcn_core_dump_check_end(PUINT8 buf, INT32 len)
+{
+	if (strnstr(buf, "coredump end", len))
+		return 1;
+	else
+		return 0;
+}
+
+/* wcn_core_dump_in - add a packet to compressor buffer
+ * @ dmp - pointer of object
+ * @ buf - input buffer
+ * @ len - data length
+ *
+ * Retunr 0 if success; return 1 if find end string; else error code
+ */
+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len)
+{
+	INT32 ret = 0;
+	INT32 tmp;
+
+#define INFO_HEAD ";SOC_CONSYS FW CORE, "
+
+	if ((!dmp) || (!buf)) {
+		STP_DBG_ERR_FUNC("invalid pointer!\n");
+		return -1;
+	}
+
+	ret = osal_lock_sleepable_lock(&dmp->dmp_lock);
+	if (ret) {
+		STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret);
+		return ret;
+	}
+
+	switch (dmp->sm) {
+	case CORE_DUMP_INIT:
+		wcn_compressor_reset(dmp->compressor, 1, GZIP);
+		osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT);
+
+		/* first package, copy to info buffer */
+		osal_strcpy(&dmp->info[0], INFO_HEAD);
+
+		if (NULL == (strnstr(buf, "<ASSERT>", 32))) {
+			osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw warm reset exception...",
+				    osal_strlen("Fw warm reset exception..."));
+			dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw warm reset exception...") + 1] = '\0';
+		} else {
+			char *pStr = buf;
+			char *pDtr = NULL;
+
+			pDtr = osal_strchr(pStr, '-');
+			if (NULL != pDtr) {
+				tmp = pDtr - pStr;
+				osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp);
+				dmp->info[osal_strlen(dmp->info) + 1] = '\0';
+			} else {
+				tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD);
+				tmp = (len > tmp) ? tmp : len;
+				osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp);
+				dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0';
+			}
+
+		}
+		/* show coredump start info on UI */
+		/* osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); */
+#if STP_DBG_AEE_EXP_API
+		aee_kernel_dal_show("SOC_CONSYS coredump start ....\n");
+#endif
+		/* parsing data, and check end srting */
+		ret = wcn_core_dump_check_end(buf, len);
+		if (ret == 1) {
+			STP_DBG_INFO_FUNC("core dump end!\n");
+			dmp->sm = CORE_DUMP_DONE;
+			wcn_compressor_in(dmp->compressor, buf, len, 0);
+		} else {
+			dmp->sm = CORE_DUMP_DOING;
+			wcn_compressor_in(dmp->compressor, buf, len, 0);
+		}
+		break;
+
+	case CORE_DUMP_DOING:
+		/* parsing data, and check end srting */
+		ret = wcn_core_dump_check_end(buf, len);
+		if (ret == 1) {
+			STP_DBG_INFO_FUNC("core dump end!\n");
+			dmp->sm = CORE_DUMP_DONE;
+			wcn_compressor_in(dmp->compressor, buf, len, 0);
+		} else {
+			dmp->sm = CORE_DUMP_DOING;
+			wcn_compressor_in(dmp->compressor, buf, len, 0);
+		}
+		break;
+
+	case CORE_DUMP_DONE:
+		wcn_compressor_reset(dmp->compressor, 1, GZIP);
+		osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT);
+		wcn_compressor_in(dmp->compressor, buf, len, 0);
+		dmp->sm = CORE_DUMP_DOING;
+		break;
+
+	case CORE_DUMP_TIMEOUT:
+		break;
+	default:
+		break;
+	}
+
+	osal_unlock_sleepable_lock(&dmp->dmp_lock);
+
+	return ret;
+}
+
+/* wcn_core_dump_out - get compressed data from compressor buffer
+ * @ dmp - pointer of object
+ * @ pbuf - target buffer's pointer
+ * @ len - data length
+ *
+ * Retunr 0 if success;  else error code
+ */
+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 plen)
+{
+	INT32 ret = 0;
+
+	if ((!dmp) || (!pbuf) || (!plen)) {
+		STP_DBG_ERR_FUNC("invalid pointer!\n");
+		return -1;
+	}
+
+	ret = osal_lock_sleepable_lock(&dmp->dmp_lock);
+	if (ret) {
+		STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret);
+		return ret;
+	}
+
+	ret = wcn_compressor_out(dmp->compressor, pbuf, plen);
+
+	osal_unlock_sleepable_lock(&dmp->dmp_lock);
+
+	return ret;
+}
+
+/* wcn_core_dump_reset - reset core dump sys
+ * @ dmp - pointer of object
+ * @ timeout - core dump time out value
+ *
+ * Retunr 0 if success, else error code
+ */
+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout)
+{
+	if (!dmp) {
+		STP_DBG_ERR_FUNC("invalid pointer!\n");
+		return -1;
+	}
+
+	dmp->sm = CORE_DUMP_INIT;
+	dmp->timeout = timeout;
+	osal_timer_stop(&dmp->dmp_timer);
+	wcn_compressor_reset(dmp->compressor, 1, GZIP);
+	osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1);
+
+	wcn_core_dump_deinit(dmp);
+	g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT);
+
+	return 0;
+}
+
+/* wcn_wmtd_timeout_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE
+ *
+ * Retunr 0 if success
+ */
+#define WMTD_TIMEOUT_INFO_HEAD "Wait wmtd complation timeout ,just collect SYS_FTRACE to DB"
+INT32 wcn_wmtd_timeout_collect_ftrace(void)
+{
+	PUINT8 pbuf;
+	INT32 len;
+
+	pbuf = "Wait wmtd complation timeout";
+	len = osal_strlen("Wait wmtd complation timeout");
+	osal_strcpy(&g_core_dump->info[0], WMTD_TIMEOUT_INFO_HEAD);
+#ifdef WMT_PLAT_ALPS
+	aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info);
+#endif
+	return 0;
+}
+/* wcn_psm_flag_trigger_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE
+ *
+ * Retunr 0 if success
+ */
+#define PSM_ABNORMAL_FLAG_INFO_HEAD "Abnormal PSM flag be set ,just collect SYS_FTRACE to DB"
+INT32 wcn_psm_flag_trigger_collect_ftrace(void)
+{
+	PUINT8 pbuf;
+	INT32 len;
+
+	pbuf = "Abnormal PSM flag be set";
+	len = osal_strlen("Abnormal PSM flag be set");
+	osal_strcpy(&g_core_dump->info[0], PSM_ABNORMAL_FLAG_INFO_HEAD);
+#ifdef WMT_PLAT_ALPS
+	aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info);
+#endif
+	return 0;
+}
+#if BTIF_RXD_BE_BLOCKED_DETECT
+MTK_WCN_BOOL is_btif_rxd_be_blocked(void)
+{
+	MTK_WCN_BOOL flag = MTK_WCN_BOOL_FALSE;
+
+	if (mtk_btif_rxd_be_blocked_flag_get())
+		flag = MTK_WCN_BOOL_TRUE;
+	return flag;
+}
+/* wcn_btif_rxd_blocked_collect_ftrace - btif rxd be blocked,this func can collect SYS_FTRACE
+ *
+ * Retunr 0 if success
+ */
+#define BTIF_RXD_BLOCKED_INFO_HEAD "Btif_rxd thread be blocked too long,just collect SYS_FTRACE to DB"
+INT32 wcn_btif_rxd_blocked_collect_ftrace(void)
+{
+	PUINT8 pbuf;
+	INT32 len;
+
+	pbuf = "Btif_rxd thread be blocked too long";
+	len = osal_strlen("Btif_rxd thread be blocked too long");
+	osal_strcpy(&g_core_dump->info[0], BTIF_RXD_BLOCKED_INFO_HEAD);
+#ifdef WMT_PLAT_ALPS
+	aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info);
+#endif
+	return 0;
+}
+#endif
+/* wcn_core_dump_timeout - wait for FW assert info timeout ,this func can collect SYS_FTRACE
+ *
+ * Retunr 0 if success
+ */
+#define TIMEOUT_INFO_HEAD "Trigger assert timeout ,just collect SYS_FTRACE to DB"
+INT32 wcn_core_dump_timeout(void)
+{
+	PUINT8 pbuf;
+	INT32 len;
+
+	pbuf = "Trigger assert timeout";
+	len = osal_strlen("Trigger assert timeout");
+	osal_strcpy(&g_core_dump->info[0], TIMEOUT_INFO_HEAD);
+#ifdef WMT_PLAT_ALPS
+	aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info);
+#endif
+	return 0;
+}
+
+#define ENABLE_F_TRACE 0
+/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys
+ *
+ * Retunr 0 if success, else error code
+ */
+INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout)
+{
+	PUINT8 pbuf = NULL;
+	INT32 len = 0;
+
+	if (!g_core_dump) {
+		STP_DBG_ERR_FUNC("invalid pointer!\n");
+		return -1;
+	}
+
+	wcn_core_dump_out(g_core_dump, &pbuf, &len);
+	STP_DBG_INFO_FUNC("buf 0x%zx, len %d\n", (SIZE_T) pbuf, len);
+#ifdef WMT_PLAT_ALPS
+	/* show coredump end info on UI */
+	/* osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); */
+#if STP_DBG_AEE_EXP_API
+	if (coredump_is_timeout)
+		aee_kernel_dal_show("++ SOC_CONSYS coredump tiemout ,pass received coredump to AEE ++\n");
+	else
+		aee_kernel_dal_show("++ SOC_CONSYS coredump get successfully ++\n");
+	/* call AEE driver API */
+#if ENABLE_F_TRACE
+	aed_combo_exception_api(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info, DB_OPT_FTRACE);
+#else
+	aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info);
+#endif
+
+#endif
+
+#endif  // WMT_PLAT_ALPS
+
+	/* reset */
+	wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT);
+
+	return 0;
+}
+
+static INT32 wcn_gzip_compressor(void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz,
+				 INT32 finish)
+{
+	INT32 ret = 0;
+	z_stream *stream = NULL;
+	INT32 tmp = *out_sz;
+
+	STP_DBG_INFO_FUNC("need to compressor :buf 0x%zx, size %d\n", (SIZE_T) in_buf, in_sz);
+	STP_DBG_INFO_FUNC("before compressor,avalible buf: 0x%zx, size %d\n", (SIZE_T) out_buf, tmp);
+
+	stream = (z_stream *) worker;
+	if (!stream) {
+		STP_DBG_ERR_FUNC("invalid workspace!\n");
+		return -1;
+	}
+
+	if (in_sz > 0) {
+#if 0
+		ret = zlib_deflateReset(stream);
+		if (ret != Z_OK) {
+			STP_DBG_ERR_FUNC("reset failed!\n");
+			return -2;
+		}
+#endif
+
+		stream->next_in = in_buf;
+		stream->avail_in = in_sz;
+		stream->next_out = out_buf;
+		stream->avail_out = tmp;
+
+		zlib_deflate(stream, Z_FULL_FLUSH);
+
+		if (finish) {
+			while (1) {
+				int val = zlib_deflate(stream, Z_FINISH);
+
+				if (val == Z_OK)
+					continue;
+				else if (val == Z_STREAM_END)
+					break;
+				STP_DBG_ERR_FUNC("finish operation failed %d\n", val);
+				return -3;
+			}
+		}
+
+		*out_sz = tmp - stream->avail_out;
+	}
+
+	STP_DBG_INFO_FUNC("after compressor,avalible buf: 0x%zx, compress rate %d -> %d\n", (SIZE_T) out_buf, in_sz,
+			  *out_sz);
+
+	return ret;
+}
+
+/* wcn_compressor_init - create a compressor and do init
+ * @ name - compressor's name
+ * @ L1_buf_sz - L1 buffer size
+ * @ L2_buf_sz - L2 buffer size
+ *
+ * Retunr object's pointer if success, else NULL
+ */
+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz)
+{
+	z_stream *pstream = NULL;
+	P_WCN_COMPRESSOR_T compress = NULL;
+
+	compress = (P_WCN_COMPRESSOR_T) osal_malloc(sizeof(WCN_COMPRESSOR_T));
+	if (!compress) {
+		STP_DBG_ERR_FUNC("alloc compressor failed!\n");
+		goto fail;
+	}
+
+	osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T));
+	osal_memcpy(compress->name, name, STP_OJB_NAME_SZ);
+
+	compress->f_compress_en = 0;
+	compress->compress_type = GZIP;
+
+	if (compress->compress_type == GZIP) {
+		compress->worker = osal_malloc(sizeof(z_stream));
+		if (!compress->worker) {
+			STP_DBG_ERR_FUNC("alloc stream failed!\n");
+			goto fail;
+		}
+		pstream = (z_stream *) compress->worker;
+
+		pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL));
+		if (!pstream->workspace) {
+			STP_DBG_ERR_FUNC("alloc workspace failed!\n");
+			goto fail;
+		}
+		zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS,
+				  DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+	}
+
+	compress->handler = wcn_gzip_compressor;
+	compress->L1_buf_sz = L1_buf_sz;
+	compress->L2_buf_sz = L2_buf_sz;
+	compress->L1_pos = 0;
+	compress->L2_pos = 0;
+	compress->uncomp_size = 0;
+	compress->crc32 = 0xffffffffUL;
+
+	compress->L1_buf = osal_malloc(compress->L1_buf_sz);
+	if (!compress->L1_buf) {
+		STP_DBG_ERR_FUNC("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz);
+		goto fail;
+	}
+
+	compress->L2_buf = osal_malloc(compress->L2_buf_sz);
+	if (!compress->L2_buf) {
+		STP_DBG_ERR_FUNC("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz);
+		goto fail;
+	}
+
+	STP_DBG_INFO_FUNC("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz);
+	return compress;
+
+fail:
+	if (compress) {
+		if (compress->L2_buf) {
+			osal_free(compress->L2_buf);
+			compress->L2_buf = NULL;
+		}
+
+		if (compress->L1_buf) {
+			osal_free(compress->L1_buf);
+			compress->L1_buf = NULL;
+		}
+
+		if (compress->worker) {
+			pstream = (z_stream *) compress->worker;
+			if ((compress->compress_type == GZIP) && pstream->workspace) {
+				zlib_deflateEnd(pstream);
+				osal_free(pstream->workspace);
+			}
+			osal_free(compress->worker);
+			compress->worker = NULL;
+		}
+
+		if (compress->worker) {
+			osal_free(compress->worker);
+			compress->worker = NULL;
+		}
+
+		osal_free(compress);
+		compress = NULL;
+	}
+
+	STP_DBG_ERR_FUNC("init failed!\n");
+
+	return NULL;
+}
+
+/* wcn_compressor_deinit - distroy a compressor
+ * @ cprs - compressor's pointer
+ *
+ * Retunr 0 if success, else NULL
+ */
+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T cprs)
+{
+	z_stream *pstream = NULL;
+
+	if (cprs) {
+		if (cprs->L2_buf) {
+			osal_free(cprs->L2_buf);
+			cprs->L2_buf = NULL;
+		}
+
+		if (cprs->L1_buf) {
+			osal_free(cprs->L1_buf);
+			cprs->L1_buf = NULL;
+		}
+
+		if (cprs->worker) {
+			pstream = (z_stream *) cprs->worker;
+			if ((cprs->compress_type == GZIP) && pstream->workspace) {
+				zlib_deflateEnd(pstream);
+				osal_free(pstream->workspace);
+			}
+			osal_free(cprs->worker);
+			cprs->worker = NULL;
+		}
+
+		cprs->handler = NULL;
+
+		osal_free(cprs);
+	}
+
+	STP_DBG_INFO_FUNC("destroy OK\n");
+
+	return 0;
+}
+
+/* wcn_compressor_in - put in a raw data, and compress L1 buffer if need
+ * @ cprs - compressor's pointer
+ * @ buf - raw data buffer
+ * @ len - raw data length
+ * @ finish - core dump finish or not, 1: finished; 0: not finish
+ *
+ * Retunr 0 if success, else NULL
+ */
+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, INT32 finish)
+{
+	INT32 tmp_len = 0;
+	INT32 ret = 0;
+
+	if (!cprs) {
+		STP_DBG_ERR_FUNC("invalid para!\n");
+		return -1;
+	}
+
+	cprs->uncomp_size += len;
+
+	/* check L1 buf valid space */
+	if (len > (cprs->L1_buf_sz - cprs->L1_pos)) {
+		STP_DBG_INFO_FUNC("L1 buffer full\n");
+
+		if (cprs->f_compress_en && cprs->handler) {
+			/* need compress */
+			/* compress L1 buffer, and put result to L2 buffer */
+			tmp_len = cprs->L2_buf_sz - cprs->L2_pos;
+			ret =
+			    cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos],
+					  &tmp_len, finish);
+			if (!ret) {
+				cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos));
+				cprs->L2_pos += tmp_len;
+				if (cprs->L2_pos > cprs->L2_buf_sz)
+					STP_DBG_ERR_FUNC("coredump size too large(%d), L2 buf overflow\n",
+					cprs->L2_pos);
+
+				if (finish) {
+					/* Add 8 byte suffix
+					   ===
+					   32 bits UNCOMPRESS SIZE
+					   32 bits CRC
+					 */
+					*(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL);
+					*(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size;
+					cprs->L2_pos += 8;
+				}
+				STP_DBG_INFO_FUNC("compress OK!\n");
+			} else
+				STP_DBG_ERR_FUNC("compress error!\n");
+		} else {
+			/* no need compress */
+			/* Flush L1 buffer to L2 buffer */
+			STP_DBG_INFO_FUNC("No need do compress, Put to L2 buf\n");
+
+			tmp_len = cprs->L2_buf_sz - cprs->L2_pos;
+			tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos;
+			osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len);
+			cprs->L2_pos += tmp_len;
+		}
+
+		/* reset L1 buf pos */
+		cprs->L1_pos = 0;
+
+		/* put curren data to L1 buf */
+		if (len > cprs->L1_buf_sz) {
+			STP_DBG_ERR_FUNC("len=%d, too long err!\n", len);
+		} else {
+			STP_DBG_INFO_FUNC("L1 Flushed, and Put %d bytes to L1 buf\n", len);
+			osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len);
+			cprs->L1_pos += len;
+		}
+	} else {
+		/* put to L1 buffer */
+		STP_DBG_INFO_FUNC("Put %d bytes to L1 buf\n", len);
+
+		osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len);
+		cprs->L1_pos += len;
+	}
+
+	return ret;
+}
+
+/* wcn_compressor_out - get the result data from L2 buffer
+ * @ cprs - compressor's pointer
+ * @ pbuf - point to L2 buffer
+ * @ plen - out len
+ *
+ * Retunr 0 if success, else NULL
+ */
+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T cprs, PUINT8 *pbuf, PINT32 plen)
+{
+	INT32 ret = 0;
+	INT32 tmp_len = 0;
+
+	if ((!cprs) || (!pbuf) || (!plen)) {
+		STP_DBG_ERR_FUNC("invalid para!\n");
+		return -1;
+	}
+	/* check if there's L1 data need flush to L2 buffer */
+	if (cprs->L1_pos > 0) {
+		tmp_len = cprs->L2_buf_sz - cprs->L2_pos;
+
+		if (cprs->f_compress_en && cprs->handler) {
+			/* need compress */
+			ret =
+			    cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos],
+					  &tmp_len, 1);
+
+			if (!ret) {
+				cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos));
+				cprs->L2_pos += tmp_len;
+
+				/* Add 8 byte suffix
+				   ===
+				   32 bits UNCOMPRESS SIZE
+				   32 bits CRC
+				 */
+				*(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL);
+				*(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size;
+				cprs->L2_pos += 8;
+
+				STP_DBG_INFO_FUNC("compress OK!\n");
+			} else {
+				STP_DBG_ERR_FUNC("compress error!\n");
+			}
+		} else {
+			/* no need compress */
+			tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos;
+			osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len);
+			cprs->L2_pos += tmp_len;
+		}
+
+		cprs->L1_pos = 0;
+	}
+
+	*pbuf = cprs->L2_buf;
+	*plen = cprs->L2_pos;
+
+	STP_DBG_INFO_FUNC("0x%zx, len %d\n", (SIZE_T)*pbuf, *plen);
+
+	return 0;
+}
+
+/* wcn_compressor_reset - reset compressor
+ * @ cprs - compressor's pointer
+ * @ enable - enable/disable compress
+ * @ type - compress algorithm
+ *
+ * Retunr 0 if success, else NULL
+ */
+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type)
+{
+	if (!cprs) {
+		STP_DBG_ERR_FUNC("invalid para!\n");
+		return -1;
+	}
+
+	cprs->f_compress_en = enable;
+	/* cprs->f_compress_en = 0; // disable compress for test */
+	cprs->compress_type = type;
+	cprs->L1_pos = 0;
+	cprs->L2_pos = 0;
+	cprs->uncomp_size = 0;
+	cprs->crc32 = 0xffffffffUL;
+
+	/* zlib_deflateEnd((z_stream*)cprs->worker); */
+
+	STP_DBG_INFO_FUNC("OK! compress algorithm %d\n", type);
+
+	return 0;
+}
+
+static void stp_dbg_dump_data(unsigned char *pBuf, char *title, int len)
+{
+	int k = 0;
+
+	pr_debug(" %s-len:%d\n", title, len);
+
+	for (k = 0; k < len; k++) {
+		if (k % 16 == 0 && k != 0)
+			pr_cont("\n    ");
+		pr_cont("0x%02x ", pBuf[k]);
+	}
+	pr_debug("--end\n");
+}
+
+static int _stp_dbg_enable(MTKSTP_DBG_T *stp_dbg)
+{
+
+	unsigned long flags;
+
+	spin_lock_irqsave(&(stp_dbg->logsys->lock), flags);
+	stp_dbg->pkt_trace_no = 0;
+	stp_dbg->is_enable = 1;
+	spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags);
+
+	return 0;
+}
+
+static int _stp_dbg_disable(MTKSTP_DBG_T *stp_dbg)
+{
+
+	unsigned long flags;
+
+	spin_lock_irqsave(&(stp_dbg->logsys->lock), flags);
+	stp_dbg->pkt_trace_no = 0;
+	memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T));
+	stp_dbg->is_enable = 0;
+	spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags);
+
+	return 0;
+}
+
+static int _stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len)
+{
+	unsigned long flags;
+	STP_DBG_HDR_T *pHdr = NULL;
+	char *pBuf = NULL;
+	unsigned int length = 0;
+	unsigned int internalFlag = stp_dbg->logsys->size < STP_DBG_LOG_ENTRY_NUM;
+	/* #ifdef CONFIG_LOG_STP_INTERNAL */
+	/* Here we record log in this circle buffer, if buffer is full ,
+	select to overlap earlier log, logic should be okay */
+	internalFlag = 1;
+	/* #endif */
+	spin_lock_irqsave(&(stp_dbg->logsys->lock), flags);
+
+	if (internalFlag) {
+		stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0;
+		stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len;
+		memset(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]),
+		       0, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len)));
+		memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]),
+		       buf, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len)));
+
+		stp_dbg->logsys->size++;
+		stp_dbg->logsys->size =
+		    (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size;
+
+		if (0 != gStpDbgLogOut) {
+			pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]);
+			pBuf = (char *)&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]) + sizeof(STP_DBG_HDR_T);
+			length = stp_dbg->logsys->queue[stp_dbg->logsys->in].len - sizeof(STP_DBG_HDR_T);
+			pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n",
+			       pHdr->sec,
+			       pHdr->usec,
+			       pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx",
+			       gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack);
+			if (0 < length)
+				stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", length);
+		}
+		stp_dbg->logsys->in =
+		    (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->in + 1);
+		STP_DBG_DBG_FUNC("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in);
+	} else {
+		STP_DBG_WARN_FUNC("logsys FULL!\n");
+	}
+
+	spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags);
+
+	return 0;
+}
+
+int stp_gdb_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg)
+{
+	int retval = 0;
+/* #ifndef CONFIG_LOG_STP_INTERNAL */
+
+	if (stp_dbg->btm != NULL)
+		retval += stp_btm_notify_wmt_dmp_wq((MTKSTP_BTM_T *) stp_dbg->btm);
+/* #endif */
+
+	return retval;
+}
+
+int stp_dbg_log_ctrl(unsigned int on)
+{
+	if (on != 0) {
+		gStpDbgLogOut = 1;
+		pr_debug("STP-DBG: enable pkt log dump out.\n");
+	} else {
+		gStpDbgLogOut = 0;
+		pr_debug("STP-DBG: disable pkt log dump out.\n");
+	}
+	return 0;
+}
+
+int stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len)
+{
+	return _stp_dbg_dmp_in(stp_dbg, buf, len);
+}
+
+int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg)
+{
+#define MAX_DMP_NUM 80
+	unsigned long flags;
+	char *pBuf = NULL;
+	int len = 0;
+	STP_DBG_HDR_T *pHdr = NULL;
+	UINT32 dumpSize = 0;
+	UINT32 inIndex = 0;
+	UINT32 outIndex = 0;
+
+	spin_lock_irqsave(&(stp_dbg->logsys->lock), flags);
+	/* Not to dequeue from loging system */
+	inIndex = stp_dbg->logsys->in;
+	dumpSize = stp_dbg->logsys->size;
+	if (STP_DBG_LOG_ENTRY_NUM == dumpSize)
+		outIndex = inIndex;
+	else
+		outIndex = ((inIndex + STP_DBG_LOG_ENTRY_NUM) - dumpSize) % STP_DBG_LOG_ENTRY_NUM;
+
+	if (dumpSize > MAX_DMP_NUM) {
+
+		outIndex += (dumpSize - MAX_DMP_NUM);
+		outIndex %= STP_DBG_LOG_ENTRY_NUM;
+		dumpSize = MAX_DMP_NUM;
+
+	}
+	STP_DBG_INFO_FUNC("loged packet size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex);
+	while (dumpSize > 0) {
+		pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[outIndex].buffer[0]);
+		pBuf = &(stp_dbg->logsys->queue[outIndex].buffer[0]) + sizeof(STP_DBG_HDR_T);
+		len = stp_dbg->logsys->queue[outIndex].len - sizeof(STP_DBG_HDR_T);
+		len = len > STP_PKT_SZ ? STP_PKT_SZ : len;
+		pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n",
+		       pHdr->sec,
+		       pHdr->usec,
+		       pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx",
+		       gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack);
+
+		if (0 < len)
+			stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len);
+		outIndex = (outIndex >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (outIndex + 1);
+		dumpSize--;
+
+	}
+
+	spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags);
+
+	return 0;
+}
+
+int stp_dbg_dmp_out_ex(char *buf, int *len)
+{
+	return stp_dbg_dmp_out(g_stp_dbg, buf, len);
+}
+
+int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len)
+{
+
+	unsigned long flags;
+	int remaining = 0;
+	*len = 0;
+	spin_lock_irqsave(&(stp_dbg->logsys->lock), flags);
+
+	if (stp_dbg->logsys->size > 0) {
+		memcpy(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]),
+		       stp_dbg->logsys->queue[stp_dbg->logsys->out].len);
+
+		(*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len;
+		stp_dbg->logsys->out =
+		    (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->out + 1);
+		stp_dbg->logsys->size--;
+
+		STP_DBG_DBG_FUNC("logsys size = %d, out = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->out);
+	} else {
+		STP_DBG_LOUD_FUNC("logsys EMPTY!\n");
+	}
+
+	remaining = (stp_dbg->logsys->size == 0) ? (0) : (1);
+
+	spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags);
+
+	return remaining;
+}
+
+static int stp_dbg_fill_hdr(struct stp_dbg_pkt_hdr *hdr, int type, int ack, int seq, int crc, int dir, int len,
+			    int dbg_type)
+{
+
+	struct timeval now;
+
+	if (!hdr) {
+		STP_DBG_ERR_FUNC("function invalid\n");
+		return -EINVAL;
+	}
+	do_gettimeofday(&now);
+	hdr->dbg_type = dbg_type;
+	hdr->ack = ack;
+	hdr->seq = seq;
+	hdr->sec = now.tv_sec;
+	hdr->usec = now.tv_usec;
+	hdr->crc = crc;
+	hdr->dir = dir;	/* rx */
+	hdr->dmy = 0xffffffff;
+	hdr->len = len;
+	hdr->type = type;
+	return 0;
+
+}
+
+static int stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, struct stp_dbg_pkt_hdr *hdr, const unsigned char *body)
+{
+	/* fix the frame size large issues. */
+	static struct stp_dbg_pkt stp_pkt;
+	uint32_t hdr_sz = sizeof(struct stp_dbg_pkt_hdr);
+	uint32_t body_sz = 0;
+
+	BUG_ON(!stp_dbg);
+
+	if (hdr->dbg_type == STP_DBG_PKT)
+		body_sz = (hdr->len <= STP_PKT_SZ) ? (hdr->len) : (STP_PKT_SZ);
+	else
+		body_sz = (hdr->len <= STP_DMP_SZ) ? (hdr->len) : (STP_DMP_SZ);
+
+	hdr->no = stp_dbg->pkt_trace_no++;
+	memcpy((uint8_t *) &stp_pkt.hdr, (uint8_t *) hdr, hdr_sz);
+	if (body != NULL)
+		memcpy((uint8_t *) &stp_pkt.raw[0], body, body_sz);
+
+	_stp_dbg_dmp_in(stp_dbg, (char *)&stp_pkt, hdr_sz + body_sz);
+	/* Only FW DMP MSG should inform BTM-CORE to dump packet to native process */
+	if (hdr->dbg_type == STP_DBG_FW_DMP)
+		stp_gdb_notify_btm_dmp_wq(stp_dbg);
+
+	return 0;
+}
+
+int stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, int dbg_type,
+		    int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body)
+{
+
+	struct stp_dbg_pkt_hdr hdr;
+
+	if (stp_dbg->is_enable == 0) {
+		/*dbg is disable,and not to log */
+	} else {
+		hdr.no = 0;
+		hdr.chs = 0;
+		stp_dbg_fill_hdr(&hdr,
+				 (int)type, (int)ack_no, (int)seq_no, (int)crc, (int)dir, (int)len, (int)dbg_type);
+
+		stp_dbg_add_pkt(stp_dbg, &hdr, body);
+	}
+
+	return 0;
+}
+
+int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg)
+{
+	return _stp_dbg_enable(stp_dbg);
+}
+
+int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg)
+{
+	return _stp_dbg_disable(stp_dbg);
+}
+
+static void stp_dbg_nl_init(void)
+{
+#if 0
+	if (genl_register_family(&stp_dbg_gnl_family) != 0) {
+		STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__);
+	} else {
+		if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0)
+			STP_DBG_ERR_FUNC("%s(): BIND operation registration fail\n", __func__);
+
+		if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0)
+			STP_DBG_ERR_FUNC("%s(): RESET operation registration fail\n", __func__);
+
+	}
+#endif
+	if (genl_register_family_with_ops(&stp_dbg_gnl_family, stp_dbg_gnl_ops_array) != 0)
+		STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__);
+}
+
+static void stp_dbg_nl_deinit(void)
+{
+	genl_unregister_family(&stp_dbg_gnl_family);
+}
+
+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info)
+{
+	struct nlattr *na;
+	char *mydata;
+
+	if (info == NULL)
+		goto out;
+
+	STP_DBG_INFO_FUNC("%s():->\n", __func__);
+
+	na = info->attrs[STP_DBG_ATTR_MSG];
+
+	if (na)
+		mydata = (char *)nla_data(na);
+
+	if (num_bind_process < MAX_BIND_PROCESS) {
+		bind_pid[num_bind_process] = info->snd_portid;
+		num_bind_process++;
+		STP_DBG_INFO_FUNC("%s():-> pid  = %d\n", __func__, info->snd_portid);
+	} else {
+		STP_DBG_ERR_FUNC("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS);
+	}
+
+out:
+	return 0;
+}
+
+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info)
+{
+	STP_DBG_ERR_FUNC("%s(): should not be invoked\n", __func__);
+
+	return 0;
+}
+
+INT8 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len)
+{
+	struct sk_buff *skb = NULL;
+	void *msg_head = NULL;
+	int rc = -1;
+	int i;
+
+	if (num_bind_process == 0) {
+		/* no listening process */
+		STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__);
+		return 0;
+	}
+
+	for (i = 0; i < num_bind_process; i++) {
+		skb = genlmsg_new(2048, GFP_KERNEL);
+
+		if (skb) {
+			msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd);
+			if (msg_head == NULL) {
+				nlmsg_free(skb);
+				STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__);
+				return -1;
+			}
+
+			rc = nla_put(skb, STP_DBG_ATTR_MSG, len, aucMsg);
+			if (rc != 0) {
+				nlmsg_free(skb);
+				STP_DBG_ERR_FUNC("%s(): nla_put_string fail...%d\n", __func__, rc);
+				return -1;
+			}
+
+			/* finalize the message */
+			genlmsg_end(skb, msg_head);
+
+			/* sending message */
+			rc = genlmsg_unicast(&init_net, skb, bind_pid[i]);
+			if (rc != 0) {
+				STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__);
+				return -1;
+			}
+		} else {
+			STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd)
+{
+	INT32 ret = 0;
+
+	/* buffered to compressor */
+	ret = wcn_core_dump_in(g_core_dump, aucMsg, len);
+	if (ret == 1)
+		wcn_core_dump_flush(0, MTK_WCN_BOOL_FALSE);
+
+	return ret;
+}
+
+UINT8 *_stp_dbg_id_to_task(UINT32 id)
+{
+	UINT8 *taskStr[] = {
+		"Task_WMT",
+		"Task_BT",
+		"Task_Wifi",
+		"Task_Tst",
+		"Task_FM",
+		"Task_Idle",
+		"Task_DrvStp",
+		"Task_DrvBtif",
+		"Task_NatBt"
+	};
+	return taskStr[id];
+}
+
+INT32 _stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type)
+{
+	char *pStr = NULL;
+	char *pDtr = NULL;
+	char *pTemp = NULL;
+	char *pTemp2 = NULL;
+	char tempBuf[64] = { 0 };
+	UINT32 len = 0;
+	long res;
+	INT32 ret;
+
+	PUINT8 parser_sub_string[] = {
+		"<ASSERT> ",
+		"id=",
+		"isr=",
+		"irq=",
+		"rc="
+	};
+
+	if (!str) {
+		STP_DBG_ERR_FUNC("NULL string source\n");
+		return -1;
+	}
+
+	if (!g_stp_dbg_cpupcr) {
+		STP_DBG_ERR_FUNC("NULL pointer\n");
+		return -2;
+	}
+
+	pStr = str;
+	STP_DBG_DBG_FUNC("source infor:%s\n", pStr);
+	switch (type) {
+	case STP_DBG_ASSERT_INFO:
+		pDtr = osal_strstr(pStr, parser_sub_string[type]);
+		if (NULL != pDtr) {
+			pDtr += osal_strlen(parser_sub_string[type]);
+			pTemp = osal_strchr(pDtr, ' ');
+		} else {
+			STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]);
+			return -3;
+		}
+		len = pTemp - pDtr;
+		osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@"));
+		osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len);
+		g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_';
+
+		pTemp = osal_strchr(pDtr, '#');
+		pTemp += 1;
+
+		pTemp2 = osal_strchr(pTemp, ' ');
+		osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, pTemp2 - pTemp);
+		g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0';
+		STP_DBG_INFO_FUNC("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]);
+		break;
+	case STP_DBG_FW_TASK_ID:
+		pDtr = osal_strstr(pStr, parser_sub_string[type]);
+		if (NULL != pDtr) {
+			pDtr += osal_strlen(parser_sub_string[type]);
+			pTemp = osal_strchr(pDtr, ' ');
+		} else {
+			STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]);
+			return -3;
+		}
+		len = pTemp - pDtr;
+		osal_memcpy(&tempBuf[0], pDtr, len);
+		tempBuf[len] = '\0';
+		ret = osal_strtol(tempBuf, 16, &res);
+		if (ret) {
+			STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret);
+			return -4;
+		}
+		g_stp_dbg_cpupcr->fwTaskId = (UINT32)res;
+
+		STP_DBG_INFO_FUNC("fw task id :%x\n", (UINT32)res);
+		break;
+	case STP_DBG_FW_ISR:
+		pDtr = osal_strstr(pStr, parser_sub_string[type]);
+		if (NULL != pDtr) {
+			pDtr += osal_strlen(parser_sub_string[type]);
+			pTemp = osal_strchr(pDtr, ',');
+		} else {
+			STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]);
+			return -3;
+		}
+		len = pTemp - pDtr;
+		osal_memcpy(&tempBuf[0], pDtr, len);
+		tempBuf[len] = '\0';
+		ret = osal_strtol(tempBuf, 16, &res);
+		if (ret) {
+			STP_DBG_ERR_FUNC("get fw isr id fail(%d)\n", ret);
+			return -4;
+		}
+		g_stp_dbg_cpupcr->fwIsr = (UINT32)res;
+
+		STP_DBG_INFO_FUNC("fw isr str:%x\n", (UINT32)res);
+		break;
+	case STP_DBG_FW_IRQ:
+		pDtr = osal_strstr(pStr, parser_sub_string[type]);
+		if (NULL != pDtr) {
+			pDtr += osal_strlen(parser_sub_string[type]);
+			pTemp = osal_strchr(pDtr, ',');
+		} else {
+			STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]);
+			return -3;
+		}
+		len = pTemp - pDtr;
+		osal_memcpy(&tempBuf[0], pDtr, len);
+		tempBuf[len] = '\0';
+		ret = osal_strtol(tempBuf, 16, &res);
+		if (ret) {
+			STP_DBG_ERR_FUNC("get fw irq id fail(%d)\n", ret);
+			return -4;
+		}
+		g_stp_dbg_cpupcr->fwRrq = (UINT32)res;
+
+		STP_DBG_INFO_FUNC("fw irq value:%x\n", (UINT32)res);
+		break;
+	case STP_DBG_ASSERT_TYPE:
+		pDtr = osal_strstr(pStr, parser_sub_string[type]);
+		if (NULL != pDtr) {
+			pDtr += osal_strlen(parser_sub_string[type]);
+			pTemp = osal_strchr(pDtr, ',');
+		} else {
+			STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]);
+			return -3;
+		}
+		len = pTemp - pDtr;
+		osal_memcpy(&tempBuf[0], pDtr, len);
+		tempBuf[len] = '\0';
+
+		if (0 == osal_memcmp(tempBuf, "*", len))
+			osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", osal_strlen("general assert"));
+		if (0 == osal_memcmp(tempBuf, "Watch Dog Timeout", len))
+			osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt"));
+		if (0 == osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL"))) {
+			osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len);
+
+			pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL(");
+			if (NULL != pDtr) {
+				pDtr += osal_strlen("RB_FULL(");
+				pTemp = osal_strchr(pDtr, ')');
+			} else {
+				STP_DBG_ERR_FUNC("parser str is NULL,substring(RB_FULL()\n");
+				return -4;
+			}
+			len = pTemp - pDtr;
+			osal_memcpy(&tempBuf[0], pDtr, len);
+			tempBuf[len] = '\0';
+			ret = osal_strtol(tempBuf, 16, &res);
+			if (ret) {
+				STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret);
+				return -5;
+			}
+			g_stp_dbg_cpupcr->fwTaskId = (UINT32)res;
+
+			STP_DBG_INFO_FUNC("update fw task id :%x\n", (UINT32)res);
+		}
+
+		STP_DBG_INFO_FUNC("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type);
+		break;
+	default:
+		STP_DBG_ERR_FUNC("unknown parser type\n");
+		break;
+	}
+
+	return 0;
+}
+
+P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID)
+{
+	P_STP_DBG_CPUPCR_T pSdCpupcr = NULL;
+
+	pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T));
+	if (!pSdCpupcr) {
+		STP_DBG_ERR_FUNC("stp dbg cpupcr allocate memory fail!\n");
+		return NULL;
+	}
+
+	osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T));
+
+	osal_sleepable_lock_init(&pSdCpupcr->lock);
+
+	return pSdCpupcr;
+}
+
+P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID)
+{
+	P_STP_DBG_DMAREGS_T pDmaRegs = NULL;
+
+	pDmaRegs = (P_STP_DBG_DMAREGS_T) osal_malloc(osal_sizeof(STP_DBG_DMAREGS_T));
+	if (!pDmaRegs) {
+		STP_DBG_ERR_FUNC("stp dbg dmareg allocate memory fail!\n");
+		return NULL;
+	}
+
+	osal_memset(pDmaRegs, 0, osal_sizeof(STP_DBG_DMAREGS_T));
+
+	osal_sleepable_lock_init(&pDmaRegs->lock);
+
+	return pDmaRegs;
+}
+
+VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr)
+{
+	if (pCpupcr) {
+		osal_sleepable_lock_deinit(&pCpupcr->lock);
+		osal_free(pCpupcr);
+		pCpupcr = NULL;
+	}
+}
+
+VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs)
+{
+	if (pDmaRegs) {
+		osal_sleepable_lock_deinit(&pDmaRegs->lock);
+		osal_free(pDmaRegs);
+		pDmaRegs = NULL;
+	}
+}
+
+INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd)
+{
+	INT32 i = 0;
+
+	if (!g_stp_dbg_cpupcr) {
+		STP_DBG_ERR_FUNC("NULL reference pointer\n");
+		return -1;
+	}
+
+	if (!cmd) {
+		if (g_stp_dbg_cpupcr->count + times > STP_DBG_CPUPCR_NUM)
+			times = STP_DBG_CPUPCR_NUM - g_stp_dbg_cpupcr->count;
+
+		osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+
+		for (i = 0; i < times; i++) {
+			STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr());
+			/* osal_memcpy(
+			* &g_stp_dbg_cpupcr->buffer[i],
+			* (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)),
+			* osal_sizeof(UINT32));
+			*/
+			g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count + i] = wmt_plat_read_cpupcr();
+			osal_sleep_ms(sleep);
+		}
+		g_stp_dbg_cpupcr->count += times;
+
+		osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	} else {
+		STP_DBG_INFO_FUNC("stp-dbg: for proc test polling cpupcr\n");
+		if (times > STP_DBG_CPUPCR_NUM)
+			times = STP_DBG_CPUPCR_NUM;
+
+		osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+		g_stp_dbg_cpupcr->count = 0;
+		for (i = 0; i < times; i++) {
+			STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr());
+			/* osal_memcpy(
+			* &g_stp_dbg_cpupcr->buffer[i],
+			* (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)),
+			* osal_sizeof(UINT32));
+			*/
+			g_stp_dbg_cpupcr->buffer[i] = wmt_plat_read_cpupcr();
+			osal_sleep_ms(sleep);
+		}
+		g_stp_dbg_cpupcr->count = times;
+
+		osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+
+	}
+	return 0;
+}
+
+INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep)
+{
+#if 0
+	INT32 i = 0;
+
+	if (!g_stp_dbg_dmaregs) {
+		STP_DBG_ERR_FUNC("NULL reference pointer\n");
+		return -1;
+	}
+
+	osal_lock_sleepable_lock(&g_stp_dbg_dmaregs->lock);
+
+	if (g_stp_dbg_dmaregs->count + times > STP_DBG_DMAREGS_NUM) {
+		if (g_stp_dbg_dmaregs->count > STP_DBG_DMAREGS_NUM) {
+			STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count:%d must less than STP_DBG_DMAREGS_NUM:%d\n",
+				g_stp_dbg_dmaregs->count, STP_DBG_DMAREGS_NUM);
+			g_stp_dbg_dmaregs->count = 0;
+			STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count be set default value 0\n");
+		}
+		times = STP_DBG_DMAREGS_NUM - g_stp_dbg_dmaregs->count;
+	}
+	if (times > STP_DBG_DMAREGS_NUM) {
+		STP_DBG_ERR_FUNC("times overflow, set default value:0\n");
+		times = 0;
+	}
+	STP_DBG_WARN_FUNC("---------Now Polling DMA relative Regs -------------\n");
+	for (i = 0; i < times; i++) {
+		INT32 k = 0;
+
+		for (; k < DMA_REGS_MAX; k++) {
+			STP_DBG_WARN_FUNC("times:%d,i:%d reg: %s, regs:%08x\n", times, i, dmaRegsStr[k],
+					  wmt_plat_read_dmaregs(k));
+			/* g_stp_dbg_dmaregs->dmaIssue[k][g_stp_dbg_dmaregs->count + i] = wmt_plat_read_dmaregs(k); */
+		}
+		osal_sleep_ms(sleep);
+	}
+	STP_DBG_WARN_FUNC("---------Polling DMA relative Regs End-------------\n");
+	g_stp_dbg_dmaregs->count += times;
+
+	osal_unlock_sleepable_lock(&g_stp_dbg_dmaregs->lock);
+#else
+	return 0;
+#endif
+}
+
+INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en)
+{
+
+	STP_DBG_INFO_FUNC("%s polling cpupcr\n", en == 0 ? "start" : "stop");
+
+	osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	g_stp_dbg_cpupcr->stop_flag = en;
+	osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	return 0;
+}
+
+INT32 stp_dbg_set_version_info(UINT32 chipid, UINT8 *pRomVer, UINT8 *pPatchVer, UINT8 *pPatchBrh)
+{
+	if (g_stp_dbg_cpupcr) {
+		osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+		g_stp_dbg_cpupcr->chipId = chipid;
+
+		if (pRomVer)
+			osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2);
+		if (pPatchVer)
+			osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8);
+		if (pPatchBrh)
+			osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4);
+
+		osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	} else {
+		STP_DBG_ERR_FUNC("NULL pointer\n");
+		return -1;
+	}
+	STP_DBG_INFO_FUNC("chipid(0x%x),romver(%s),patchver(%s),branchver(%s)\n", g_stp_dbg_cpupcr->chipId,
+		&g_stp_dbg_cpupcr->romVer[0], &g_stp_dbg_cpupcr->patchVer[0], &g_stp_dbg_cpupcr->branchVer[0]);
+	return 0;
+}
+INT32 stp_dbg_set_wifiver(UINT32 wifiver)
+{
+	if (g_stp_dbg_cpupcr) {
+		osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+		g_stp_dbg_cpupcr->wifiVer = wifiver;
+		osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	} else {
+		STP_DBG_ERR_FUNC("NULL pointer\n");
+		return -1;
+	}
+	STP_DBG_INFO_FUNC("wifiver(%x)\n", g_stp_dbg_cpupcr->wifiVer);
+	return 0;
+}
+
+INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en)
+{
+	osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+
+	g_stp_dbg_cpupcr->host_assert_info.assert_from_host = en;
+	g_stp_dbg_cpupcr->host_assert_info.drv_type = drv_type;
+	g_stp_dbg_cpupcr->host_assert_info.reason = reason;
+
+	osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+
+	return 0;
+}
+
+UINT32 stp_dbg_get_host_trigger_assert(VOID)
+{
+	return g_stp_dbg_cpupcr->host_assert_info.assert_from_host;
+}
+
+INT32 stp_dbg_set_fw_info(UINT8 *issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type)
+{
+	ENUM_ASSERT_INFO_PARSER_TYPE type_index;
+	PUINT8 tempbuf = NULL;
+	UINT32 i = 0;
+	INT32 iRet = 0;
+
+	if (NULL == issue_info) {
+		STP_DBG_ERR_FUNC("null issue infor\n");
+		return -1;
+	}
+	STP_DBG_INFO_FUNC("issue type(%d)\n", issue_type);
+	g_stp_dbg_cpupcr->issue_type = issue_type;
+	osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE);
+
+	/*print patch version when assert happened */
+	STP_DBG_INFO_FUNC("=======================================\n");
+	STP_DBG_INFO_FUNC("[consys patch]patch version:%s\n", g_stp_dbg_cpupcr->patchVer);
+	STP_DBG_INFO_FUNC("[consys patch]ALPS branch:%s\n", g_stp_dbg_cpupcr->branchVer);
+	STP_DBG_INFO_FUNC("=======================================\n");
+
+	if ((STP_FW_ASSERT_ISSUE == issue_type) ||
+	    (STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) {
+		if ((STP_FW_ASSERT_ISSUE == issue_type) || (STP_HOST_TRIGGER_FW_ASSERT == issue_type)) {
+			tempbuf = osal_malloc(len + 1);
+			if (!tempbuf)
+				return -2;
+
+			osal_memcpy(&tempbuf[0], issue_info, len);
+
+			for (i = 0; i < len; i++) {
+				if (tempbuf[i] == '\0')
+					tempbuf[i] = '?';
+			}
+
+			tempbuf[len] = '\0';
+
+			for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; type_index++)
+				iRet += _stp_dbg_parser_assert_str(&tempbuf[0], type_index);
+
+			if (iRet)
+				STP_DBG_ERR_FUNC("passert assert infor fail(%d)\n", iRet);
+
+		}
+		if ((STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) {
+			switch (g_stp_dbg_cpupcr->host_assert_info.drv_type) {
+			case 0:
+				STP_DBG_INFO_FUNC("BT trigger assert\n");
+				osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+				if (31 != g_stp_dbg_cpupcr->host_assert_info.reason)
+					/*BT firmware trigger assert */
+				{
+					g_stp_dbg_cpupcr->fwTaskId = 1;
+
+				} else
+					/*BT stack trigger assert */
+				{
+					g_stp_dbg_cpupcr->fwTaskId = 8;
+				}
+
+				g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0;
+				/* g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; */
+				/* g_stp_dbg_cpupcr->host_assert_info.reason = 0; */
+
+				osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+
+				break;
+			case 4:
+				STP_DBG_INFO_FUNC("WMT trigger assert\n");
+				osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+				if (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)
+					osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len);
+
+				if ((38 == g_stp_dbg_cpupcr->host_assert_info.reason) ||
+				    (39 == g_stp_dbg_cpupcr->host_assert_info.reason) ||
+				    (40 == g_stp_dbg_cpupcr->host_assert_info.reason))
+					g_stp_dbg_cpupcr->fwTaskId = 6;	/* HOST schedule reason trigger */
+				else
+					g_stp_dbg_cpupcr->fwTaskId = 0;	/* Must be firmware reason */
+				g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0;
+				osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+				break;
+			default:
+				break;
+			}
+
+		}
+		osal_free(tempbuf);
+	} else if (STP_FW_NOACK_ISSUE == issue_type) {
+		osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+		osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len);
+		g_stp_dbg_cpupcr->fwTaskId = 6;
+		g_stp_dbg_cpupcr->fwRrq = 0;
+		g_stp_dbg_cpupcr->fwIsr = 0;
+		osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	} else if (STP_DBG_PROC_TEST == issue_type) {
+		osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+		osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len);
+		g_stp_dbg_cpupcr->fwTaskId = 0;
+		g_stp_dbg_cpupcr->fwRrq = 0;
+		g_stp_dbg_cpupcr->fwIsr = 0;
+		osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	} else if (STP_FW_WARM_RST_ISSUE == issue_type) {
+		osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+		osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len);
+		g_stp_dbg_cpupcr->fwTaskId = 0;
+		g_stp_dbg_cpupcr->fwRrq = 0;
+		g_stp_dbg_cpupcr->fwIsr = 0;
+		osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	} else {
+		STP_DBG_ERR_FUNC("invalid issue type(%d)\n", issue_type);
+		return -3;
+	}
+
+	return iRet;
+}
+
+INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 str_len)
+{
+	UINT32 len = 0;
+	UINT32 i = 0;
+
+	if (!g_stp_dbg_cpupcr) {
+		STP_DBG_ERR_FUNC("NULL pointer\n");
+		return -1;
+	}
+
+	/*format common information about issue */
+	len = osal_sprintf(*buf, "<main>\n\t");
+	len += osal_sprintf(*buf + len, "<chipid>\n\t\tMT%x\n\t</chipid>\n\t", g_stp_dbg_cpupcr->chipId);
+	len += osal_sprintf(*buf + len, "<version>\n\t\t");
+	len += osal_sprintf(*buf + len, "<rom>%s</rom>\n\t\t", g_stp_dbg_cpupcr->romVer);
+	if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", strlen("ALPS"))))
+		len += osal_sprintf(*buf + len, "<branch>Internal Dev</branch>\n\t\t", g_stp_dbg_cpupcr->branchVer);
+	else
+		len += osal_sprintf(*buf + len, "<branch>W%sMP</branch>\n\t\t", g_stp_dbg_cpupcr->branchVer);
+
+	len += osal_sprintf(*buf + len, "<patch>%s</patch>\n\t\t", g_stp_dbg_cpupcr->patchVer);
+
+	if (0 == g_stp_dbg_cpupcr->wifiVer)
+		len += osal_sprintf(*buf + len, "<wifi>NULL</wifi>\n\t");
+	else
+		len += osal_sprintf(*buf + len, "<wifi>0x%X.%X</wifi>\n\t",
+		(UINT8)((g_stp_dbg_cpupcr->wifiVer & 0xFF00)>>8), (UINT8)(g_stp_dbg_cpupcr->wifiVer & 0xFF));
+
+	len += osal_sprintf(*buf + len, "</version>\n\t");
+
+	/*format issue information: no ack, assert */
+	len += osal_sprintf(*buf + len, "<issue>\n\t\t<classification>\n\t\t\t");
+	if ((STP_FW_NOACK_ISSUE == g_stp_dbg_cpupcr->issue_type) ||
+	    (STP_DBG_PROC_TEST == g_stp_dbg_cpupcr->issue_type) ||
+	    (STP_FW_WARM_RST_ISSUE == g_stp_dbg_cpupcr->issue_type)) {
+		len +=
+		    osal_sprintf(*buf + len, "%s\n\t\t</classification>\n\t\t<rc>\n\t\t\t",
+				 g_stp_dbg_cpupcr->assert_info);
+		len += osal_sprintf(*buf + len, "NULL\n\t\t</rc>\n\t</issue>\n\t");
+		len += osal_sprintf(*buf + len, "<hint>\n\t\t<time_align>NULL</time_align>\n\t\t");
+		len += osal_sprintf(*buf + len, "<host>NULL</host>\n\t\t");
+		len +=
+		    osal_sprintf(*buf + len, "<client>\n\t\t\t<task>%s</task>\n\t\t\t",
+				 _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId));
+		len += osal_sprintf(*buf + len, "<irqx>IRQ_0x%x</irqx>\n\t\t\t", g_stp_dbg_cpupcr->fwRrq);
+		len += osal_sprintf(*buf + len, "<isr>0x%x</isr>\n\t\t\t", g_stp_dbg_cpupcr->fwIsr);
+		len += osal_sprintf(*buf + len, "<drv_type>NULL</drv_type>\n\t\t\t");
+		len += osal_sprintf(*buf + len, "<reason>NULL</reason>\n\t\t\t");
+	} else if ((STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) ||
+		   (STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) ||
+		   (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) {
+		len +=
+		    osal_sprintf(*buf + len, "%s\n\t\t</classification>\n\t\t<rc>\n\t\t\t",
+				 g_stp_dbg_cpupcr->assert_info);
+		len += osal_sprintf(*buf + len, "%s\n\t\t</rc>\n\t</issue>\n\t", g_stp_dbg_cpupcr->assert_type);
+		len += osal_sprintf(*buf + len, "<hint>\n\t\t<time_align>NULL</time_align>\n\t\t");
+		len += osal_sprintf(*buf + len, "<host>NULL</host>\n\t\t");
+		len +=
+		    osal_sprintf(*buf + len, "<client>\n\t\t\t<task>%s</task>\n\t\t\t",
+				 _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId));
+		if (32 == g_stp_dbg_cpupcr->host_assert_info.reason || 33 == g_stp_dbg_cpupcr->host_assert_info.reason
+		    || 34 == g_stp_dbg_cpupcr->host_assert_info.reason
+		    || 35 == g_stp_dbg_cpupcr->host_assert_info.reason
+		    || 36 == g_stp_dbg_cpupcr->host_assert_info.reason
+		    || 37 == g_stp_dbg_cpupcr->host_assert_info.reason
+		    || 38 == g_stp_dbg_cpupcr->host_assert_info.reason
+		    || 39 == g_stp_dbg_cpupcr->host_assert_info.reason
+		    || 40 == g_stp_dbg_cpupcr->host_assert_info.reason) {
+			/*handling wmt turn on/off bt cmd has ack but no evt issue */
+			/*one of both the irqx and irs is nULL, then use task to find MOF */
+			len += osal_sprintf(*buf + len, "<irqx>NULL</irqx>\n\t\t\t");
+		} else {
+			len += osal_sprintf(*buf + len, "<irqx>IRQ_0x%x</irqx>\n\t\t\t", g_stp_dbg_cpupcr->fwRrq);
+		}
+		len += osal_sprintf(*buf + len, "<isr>0x%x</isr>\n\t\t\t", g_stp_dbg_cpupcr->fwIsr);
+
+		if (STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) {
+			len += osal_sprintf(*buf + len, "<drv_type>NULL</drv_type>\n\t\t\t");
+			len += osal_sprintf(*buf + len, "<reason>NULL</reason>\n\t\t\t");
+		}
+
+		if ((STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) ||
+		    (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) {
+			len +=
+			    osal_sprintf(*buf + len, "<drv_type>%d</drv_type>\n\t\t\t",
+					 g_stp_dbg_cpupcr->host_assert_info.drv_type);
+			len +=
+			    osal_sprintf(*buf + len, "<reason>%d</reason>\n\t\t\t",
+					 g_stp_dbg_cpupcr->host_assert_info.reason);
+		}
+	} else {
+		len += osal_sprintf(*buf + len, "NULL\n\t\t</classification>\n\t\t<rc>\n\t\t\t");
+		len += osal_sprintf(*buf + len, "NULL\n\t\t</rc>\n\t</issue>\n\t");
+		len += osal_sprintf(*buf + len, "<hint>\n\t\t<time_align>NULL</time_align>\n\t\t");
+		len += osal_sprintf(*buf + len, "<host>NULL</host>\n\t\t");
+		len += osal_sprintf(*buf + len, "<client>\n\t\t\t<task>NULL</task>\n\t\t\t");
+		len += osal_sprintf(*buf + len, "<irqx>NULL</irqx>\n\t\t\t");
+		len += osal_sprintf(*buf + len, "<isr>NULL</isr>\n\t\t\t");
+		len += osal_sprintf(*buf + len, "<drv_type>NULL</drv_type>\n\t\t\t");
+		len += osal_sprintf(*buf + len, "<reason>NULL</reason>\n\t\t\t");
+	}
+
+	len += osal_sprintf(*buf + len, "<pctrace>");
+	STP_DBG_INFO_FUNC("stp-dbg:sub len1 for debug(%d)\n", len);
+
+	if (!g_stp_dbg_cpupcr->count)
+		len += osal_sprintf(*buf + len, "NULL");
+	else {
+		for (i = 0; i < g_stp_dbg_cpupcr->count; i++)
+			len += osal_sprintf(*buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]);
+	}
+	STP_DBG_INFO_FUNC("stp-dbg:sub len2 for debug(%d)\n", len);
+	len += osal_sprintf(*buf + len, "</pctrace>\n\t\t\t");
+	len += osal_sprintf(*buf + len, "<extension>NULL</extension>\n\t\t</client>\n\t</hint>\n</main>\n");
+	STP_DBG_INFO_FUNC("buffer len[%d]\n", len);
+	/* STP_DBG_INFO_FUNC("Format infor:\n%s\n",*buf); */
+	*str_len = len;
+
+	osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+	osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM);
+	g_stp_dbg_cpupcr->count = 0;
+	g_stp_dbg_cpupcr->host_assert_info.reason = 0;
+	g_stp_dbg_cpupcr->host_assert_info.drv_type = 0;
+	osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock);
+
+	return 0;
+
+}
+
+MTKSTP_DBG_T *stp_dbg_init(void *btm_half)
+{
+
+	MTKSTP_DBG_T *stp_dbg = NULL;
+
+	STP_DBG_INFO_FUNC("stp-dbg init\n");
+
+	stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL);
+	if (stp_dbg == NULL)
+		goto ERR_EXIT1;
+	if (IS_ERR(stp_dbg)) {
+		STP_DBG_ERR_FUNC("-ENOMEM\n");
+		goto ERR_EXIT1;
+	}
+
+	stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T));
+	if (stp_dbg->logsys == NULL)
+		goto ERR_EXIT2;
+	if (IS_ERR(stp_dbg->logsys)) {
+		STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n");
+		goto ERR_EXIT2;
+	}
+	memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T));
+	spin_lock_init(&(stp_dbg->logsys->lock));
+	stp_dbg->pkt_trace_no = 0;
+	stp_dbg->is_enable = 0;
+	g_stp_dbg = stp_dbg;
+
+	if (btm_half != NULL)
+		stp_dbg->btm = btm_half;
+	else
+		stp_dbg->btm = NULL;
+
+
+	/* bind to netlink */
+	stp_dbg_nl_init();
+	g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT);
+	g_stp_dbg_cpupcr = stp_dbg_cpupcr_init();
+	g_stp_dbg_dmaregs = stp_dbg_dmaregs_init();
+
+	return stp_dbg;
+
+ERR_EXIT2:
+	kfree(stp_dbg);
+	return NULL;
+
+ERR_EXIT1:
+	kfree(stp_dbg);
+	return NULL;
+}
+
+int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg)
+{
+
+	STP_DBG_INFO_FUNC("stp-dbg deinit\n");
+
+	wcn_core_dump_deinit(g_core_dump);
+
+	stp_dbg_cpupcr_deinit(g_stp_dbg_cpupcr);
+	stp_dbg_dmaregs_deinit(g_stp_dbg_dmaregs);
+	/* unbind with netlink */
+	stp_dbg_nl_deinit();
+
+	if (stp_dbg->logsys)
+		vfree(stp_dbg->logsys);
+
+	kfree(stp_dbg);
+
+	return 0;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c
new file mode 100644
index 0000000000000..f7f4aff010d4a
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c
@@ -0,0 +1,279 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*******************************************************************************
+*                E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/timer.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/audit.h>
+#include <linux/file.h>
+#include <linux/module.h>
+
+#include <linux/spinlock.h>
+#include <linux/delay.h>	/* udelay() */
+
+#include <asm/uaccess.h>
+
+
+#include "osal_typedef.h"
+#include "stp_core.h"
+#include "stp_exp.h"
+
+/*******************************************************************************
+*                          C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                        P U B L I C   D A T A
+********************************************************************************
+*/
+/*******************************************************************************
+*                       P R I V A T E   D A T A
+********************************************************************************
+*/
+static MTK_WCN_STP_IF_TX stp_uart_if_tx;
+static MTK_WCN_STP_IF_TX stp_sdio_if_tx;
+static MTK_WCN_STP_IF_TX stp_btif_if_tx;
+static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX;
+static MTK_WCN_STP_IF_RX stp_if_rx;
+static MTK_WCN_STP_EVENT_CB event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 };
+static MTK_WCN_STP_EVENT_CB tx_event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 };
+
+/******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+*******************************************************************************
+*/
+
+/*******************************************************************************
+*                          F U N C T I O N S
+********************************************************************************
+*/
+
+INT32 mtk_wcn_sys_if_rx(UINT8 *data, INT32 size)
+{
+	if (stp_if_rx == 0x0)
+		return -1;
+
+	(*stp_if_rx) (data, size);
+	return 0;
+}
+
+static INT32 mtk_wcn_sys_if_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size)
+{
+
+	if (STP_UART_IF_TX == g_stp_if_type)
+		return stp_uart_if_tx != NULL ? (*stp_uart_if_tx) (data, size, written_size) : -1;
+	else if (STP_SDIO_IF_TX == g_stp_if_type)
+		return stp_sdio_if_tx != NULL ? (*stp_sdio_if_tx) (data, size, written_size) : -1;
+	else if (STP_BTIF_IF_TX == g_stp_if_type)
+		return stp_btif_if_tx != NULL ? (*stp_btif_if_tx) (data, size, written_size) : -1;
+	/*if (g_stp_if_type >= STP_MAX_IF_TX) *//* George: remove ALWAYS TRUE condition */
+	return -1;
+}
+
+static INT32 mtk_wcn_sys_event_set(UINT8 function_type)
+{
+	if ((function_type < MTKSTP_MAX_TASK_NUM) && (event_callback_tbl[function_type] != 0x0)) {
+		(*event_callback_tbl[function_type]) ();
+	} else {
+		/* FIXME: error handling */
+		pr_err("[%s] STP set event fail. It seems the function is not active.\n", __func__);
+	}
+
+	return 0;
+}
+
+static INT32 mtk_wcn_sys_event_tx_resume(UINT8 winspace)
+{
+	int type = 0;
+
+	for (type = 0; type < MTKSTP_MAX_TASK_NUM; type++) {
+		if (tx_event_callback_tbl[type])
+			tx_event_callback_tbl[type] ();
+	}
+
+	return 0;
+}
+
+static INT32 mtk_wcn_sys_check_function_status(UINT8 type, UINT8 op)
+{
+
+	/* op == FUNCTION_ACTIVE, to check if funciton[type] is active ? */
+	if (!(type < MTKSTP_MAX_TASK_NUM))
+		return STATUS_FUNCTION_INVALID;
+
+	if (op == OP_FUNCTION_ACTIVE) {
+		if (event_callback_tbl[type] != 0x0)
+			return STATUS_FUNCTION_ACTIVE;
+		else
+			return STATUS_FUNCTION_INACTIVE;
+
+	}
+	/* you can define more operation here ..., to queury function's status/information */
+
+	return STATUS_OP_INVALID;
+}
+
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func)
+#else
+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func)
+#endif
+{
+	stp_if_rx = func;
+
+	return 0;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx);
+#endif
+
+VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type)
+{
+	static const char * const ifType[] = {
+		"UART",
+		"SDIO",
+		"BTIF",
+		"UNKNOWN"
+	};
+	g_stp_if_type = stp_if_type;
+	pr_debug("[%s] set STP_IF_TX to %s.\n", __func__, ifType[stp_if_type]);
+}
+
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func)
+#else
+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func)
+#endif
+{
+	if (STP_UART_IF_TX == stp_if) {
+		stp_uart_if_tx = func;
+	} else if (STP_SDIO_IF_TX == stp_if) {
+		stp_sdio_if_tx = func;
+	} else if (STP_BTIF_IF_TX == stp_if) {
+		stp_btif_if_tx = func;
+	} else {
+		pr_debug("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if);
+		return -1;
+	}
+
+	return 0;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx);
+#endif
+
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func)
+#else
+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func)
+#endif
+{
+	if (type < MTKSTP_MAX_TASK_NUM) {
+		event_callback_tbl[type] = func;
+
+		/*clear rx queue */
+		pr_debug("Flush type = %d Rx Queue\n", type);
+		mtk_wcn_stp_flush_rx_queue(type);
+	}
+
+	return 0;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb);
+#endif
+
+#if STP_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func)
+#else
+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func)
+#endif
+{
+	if (type < MTKSTP_MAX_TASK_NUM)
+		tx_event_callback_tbl[type] = func;
+	else
+		BUG_ON(0);
+
+	return 0;
+}
+#if !STP_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb);
+#endif
+
+INT32 stp_drv_init(VOID)
+{
+	INT32 ret = 0;
+
+	mtkstp_callback cb = {
+		.cb_if_tx = mtk_wcn_sys_if_tx,
+		.cb_event_set = mtk_wcn_sys_event_set,
+		.cb_event_tx_resume = mtk_wcn_sys_event_tx_resume,
+		.cb_check_funciton_status = mtk_wcn_sys_check_function_status
+	};
+
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+	MTK_WCN_STP_EXP_CB_INFO stpExpCb = {
+		.stp_send_data_cb = _mtk_wcn_stp_send_data,
+		.stp_send_data_raw_cb = _mtk_wcn_stp_send_data_raw,
+		.stp_parser_data_cb = _mtk_wcn_stp_parser_data,
+		.stp_receive_data_cb = _mtk_wcn_stp_receive_data,
+		.stp_is_rxqueue_empty_cb = _mtk_wcn_stp_is_rxqueue_empty,
+		.stp_is_ready_cb = _mtk_wcn_stp_is_ready,
+		.stp_set_bluez_cb = _mtk_wcn_stp_set_bluez,
+		.stp_if_tx_cb = _mtk_wcn_stp_register_if_tx,
+		.stp_if_rx_cb = _mtk_wcn_stp_register_if_rx,
+		.stp_reg_event_cb = _mtk_wcn_stp_register_event_cb,
+		.stp_reg_tx_event_cb = _mtk_wcn_stp_register_tx_event_cb,
+		.stp_coredump_start_get_cb = _mtk_wcn_stp_coredump_start_get,
+	};
+#endif
+
+	ret = mtk_wcn_stp_init(&cb);
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+	mtk_wcn_stp_exp_cb_reg(&stpExpCb);
+#endif
+	return ret;
+}
+
+VOID stp_drv_exit(VOID)
+{
+	mtk_wcn_stp_deinit();
+
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+	mtk_wcn_stp_exp_cb_unreg();
+#endif
+
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c
new file mode 100644
index 0000000000000..f70c88796f091
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c
@@ -0,0 +1,2566 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief brief description
+
+    Detailed descriptions here.
+
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-DEV]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "osal_typedef.h"
+#include "osal.h"
+#include "wmt_dev.h"
+#include "wmt_core.h"
+#include "wmt_exp.h"
+#include "wmt_lib.h"
+#include "wmt_conf.h"
+#include "psm_core.h"
+#include "stp_core.h"
+#include "stp_exp.h"
+#include "bgw_desense.h"
+#include <mtk_wcn_cmb_stub.h>
+#include "wmt_idc.h"
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+#if WMT_CREATE_NODE_DYNAMIC
+#include <linux/device.h>
+#endif
+#define BUF_LEN_MAX 384
+#include <linux/proc_fs.h>
+#ifdef CONFIG_COMPAT
+#define COMPAT_WMT_IOCTL_SET_PATCH_NAME		_IOW(WMT_IOC_MAGIC, 4, compat_uptr_t)
+#define COMPAT_WMT_IOCTL_LPBK_TEST			_IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t)
+#define COMPAT_WMT_IOCTL_SET_PATCH_INFO		_IOW(WMT_IOC_MAGIC, 15, compat_uptr_t)
+#define COMPAT_WMT_IOCTL_PORT_NAME			_IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t)
+#define COMPAT_WMT_IOCTL_WMT_CFG_NAME			_IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t)
+#define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD		_IOW(WMT_IOC_MAGIC, 25, compat_uptr_t)
+#define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST		_IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t)
+#endif
+
+#define WMT_IOC_MAGIC        0xa0
+#define WMT_IOCTL_SET_PATCH_NAME		_IOW(WMT_IOC_MAGIC, 4, char*)
+#define WMT_IOCTL_SET_STP_MODE			_IOW(WMT_IOC_MAGIC, 5, int)
+#define WMT_IOCTL_FUNC_ONOFF_CTRL		_IOW(WMT_IOC_MAGIC, 6, int)
+#define WMT_IOCTL_LPBK_POWER_CTRL		_IOW(WMT_IOC_MAGIC, 7, int)
+#define WMT_IOCTL_LPBK_TEST				_IOWR(WMT_IOC_MAGIC, 8, char*)
+#define WMT_IOCTL_GET_CHIP_INFO			_IOR(WMT_IOC_MAGIC, 12, int)
+#define WMT_IOCTL_SET_LAUNCHER_KILL		_IOW(WMT_IOC_MAGIC, 13, int)
+#define WMT_IOCTL_SET_PATCH_NUM			_IOW(WMT_IOC_MAGIC, 14, int)
+#define WMT_IOCTL_SET_PATCH_INFO		_IOW(WMT_IOC_MAGIC, 15, char*)
+#define WMT_IOCTL_PORT_NAME			_IOWR(WMT_IOC_MAGIC, 20, char*)
+#define WMT_IOCTL_WMT_CFG_NAME			_IOWR(WMT_IOC_MAGIC, 21, char*)
+#define WMT_IOCTL_WMT_QUERY_CHIPID	_IOR(WMT_IOC_MAGIC, 22, int)
+#define WMT_IOCTL_WMT_TELL_CHIPID	_IOW(WMT_IOC_MAGIC, 23, int)
+#define WMT_IOCTL_WMT_COREDUMP_CTRL     _IOW(WMT_IOC_MAGIC, 24, int)
+#define WMT_IOCTL_SEND_BGW_DS_CMD		_IOW(WMT_IOC_MAGIC, 25, char*)
+#define WMT_IOCTL_ADIE_LPBK_TEST		_IOWR(WMT_IOC_MAGIC, 26, char*)
+#define WMT_IOCTL_FW_DBGLOG_CTRL		_IOR(WMT_IOC_MAGIC, 29, int)
+#define WMT_IOCTL_DYNAMIC_DUMP_CTRL     _IOR(WMT_IOC_MAGIC, 30, char*)
+
+#define MTK_WMT_VERSION  "SOC Consys WMT Driver - v1.0"
+#define MTK_WMT_DATE     "2013/01/20"
+#define WMT_DEV_MAJOR 190	/* never used number */
+#define WMT_DEV_NUM 1
+#define WMT_DEV_INIT_TO_MS (2 * 1000)
+#define DYNAMIC_DUMP_BUF 109
+
+#if CFG_WMT_DBG_SUPPORT
+#define WMT_DBG_PROCNAME "driver/wmt_dbg"
+#endif
+
+#define WMT_DRIVER_NAME "mtk_stp_wmt"
+
+P_OSAL_EVENT gpRxEvent = NULL;
+
+UINT32 u4RxFlag = 0x0;
+static atomic_t gRxCount = ATOMIC_INIT(0);
+
+/* Linux UINT8 device */
+static int gWmtMajor = WMT_DEV_MAJOR;
+static struct cdev gWmtCdev;
+static atomic_t gWmtRefCnt = ATOMIC_INIT(0);
+/* WMT driver information */
+static UINT8 gLpbkBuf[1024+5] = { 0 };
+
+static UINT32 gLpbkBufLog;	/* George LPBK debug */
+static INT32 gWmtInitDone;
+static wait_queue_head_t gWmtInitWq;
+
+P_WMT_PATCH_INFO pPatchInfo = NULL;
+UINT32 pAtchNum = 0;
+
+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD))
+#define WMT_EMI_DEBUG_BUF_SIZE (8*1024)
+#else
+#define WMT_EMI_DEBUG_BUF_SIZE (32*1024)
+#endif
+
+static UINT8 gEmiBuf[WMT_EMI_DEBUG_BUF_SIZE];
+UINT8 *buf_emi;
+
+#if CFG_WMT_PROC_FOR_AEE
+static struct proc_dir_entry *gWmtAeeEntry;
+#define WMT_AEE_PROCNAME "driver/wmt_aee"
+#define WMT_PROC_AEE_SIZE 3072
+static UINT32 g_buf_len;
+static UINT8 *pBuf;
+#endif
+
+#if WMT_CREATE_NODE_DYNAMIC
+struct class *wmt_class = NULL;
+struct device *wmt_dev = NULL;
+#endif
+
+#if CFG_WMT_DBG_SUPPORT
+static struct proc_dir_entry *gWmtDbgEntry;
+COEX_BUF gCoexBuf;
+
+static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd);
+static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3);
+
+#if CFG_CORE_INTERNAL_TXRX
+static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3);
+#endif
+static INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3);
+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3);
+#if CONSYS_ENALBE_SET_JTAG
+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3);
+#endif
+#if CFG_WMT_LTE_COEX_HANDLING
+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3);
+#endif
+#endif
+static void wmt_dbg_fwinfor_print_buff(UINT32 len)
+{
+	UINT32 i = 0;
+	UINT32 idx = 0;
+
+	for (i = 0; i < len; i++) {
+					buf_emi[idx] = gEmiBuf[i];
+					if (gEmiBuf[i] == '\n') {
+						pr_cont("%s", buf_emi);
+						osal_memset(buf_emi, 0, BUF_LEN_MAX);
+						idx = 0;
+					} else {
+						idx++;
+					}
+					if (idx == BUF_LEN_MAX-1) {
+						buf_emi[idx] = '\0';
+						pr_cont("%s", buf_emi);
+						osal_memset(buf_emi, 0, BUF_LEN_MAX);
+						idx = 0;
+					}
+				}
+}
+
+/*LCM on/off ctrl for wmt varabile*/
+static struct work_struct gPwrOnOffWork;
+UINT32 g_es_lr_flag_for_quick_sleep = 1;	/* for ctrl quick sleep flag */
+UINT32 g_es_lr_flag_for_lpbk_onoff = 0;	/* for ctrl lpbk on off */
+OSAL_SLEEPABLE_LOCK g_es_lr_lock;
+
+#ifdef CONFIG_EARLYSUSPEND
+
+static void wmt_dev_early_suspend(struct early_suspend *h)
+{
+	osal_lock_sleepable_lock(&g_es_lr_lock);
+	g_es_lr_flag_for_quick_sleep = 1;
+	g_es_lr_flag_for_lpbk_onoff = 0;
+	osal_unlock_sleepable_lock(&g_es_lr_lock);
+
+	WMT_WARN_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n");
+
+	schedule_work(&gPwrOnOffWork);
+}
+
+static void wmt_dev_late_resume(struct early_suspend *h)
+{
+	osal_lock_sleepable_lock(&g_es_lr_lock);
+	g_es_lr_flag_for_quick_sleep = 0;
+	g_es_lr_flag_for_lpbk_onoff = 1;
+	osal_unlock_sleepable_lock(&g_es_lr_lock);
+
+	WMT_WARN_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n");
+
+	schedule_work(&gPwrOnOffWork);
+
+}
+
+struct early_suspend wmt_early_suspend_handler = {
+	.suspend = wmt_dev_early_suspend,
+	.resume = wmt_dev_late_resume,
+};
+
+#else
+
+static struct notifier_block wmt_fb_notifier;
+static int wmt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data)
+{
+	struct fb_event *evdata = data;
+	INT32 blank;
+
+	WMT_DBG_FUNC("wmt_fb_notifier_callback\n");
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;
+
+	blank = *(INT32 *)evdata->data;
+	WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank);
+
+	switch (blank) {
+	case FB_BLANK_UNBLANK:
+		osal_lock_sleepable_lock(&g_es_lr_lock);
+		g_es_lr_flag_for_quick_sleep = 0;
+		g_es_lr_flag_for_lpbk_onoff = 1;
+		osal_unlock_sleepable_lock(&g_es_lr_lock);
+		WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n");
+		schedule_work(&gPwrOnOffWork);
+		break;
+	case FB_BLANK_POWERDOWN:
+		osal_lock_sleepable_lock(&g_es_lr_lock);
+		g_es_lr_flag_for_quick_sleep = 1;
+		g_es_lr_flag_for_lpbk_onoff = 0;
+		osal_unlock_sleepable_lock(&g_es_lr_lock);
+		WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n");
+		schedule_work(&gPwrOnOffWork);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+#endif
+/*******************************************************************************
+*                          F U N C T I O N S
+********************************************************************************
+*/
+
+static void wmt_pwr_on_off_handler(struct work_struct *work)
+{
+	INT32 retryCounter = 1;
+
+	WMT_DBG_FUNC("wmt_pwr_on_off_handler start to run\n");
+
+	osal_lock_sleepable_lock(&g_es_lr_lock);
+
+	if (g_es_lr_flag_for_lpbk_onoff) {
+		do {
+			if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) {
+				WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter);
+				retryCounter--;
+				osal_sleep_ms(1000);
+			} else {
+				WMT_INFO_FUNC("WMT turn on LPBK suceed\n");
+				break;
+			}
+		} while (retryCounter > 0);
+	} else {
+		if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK))
+			WMT_WARN_FUNC("WMT turn off LPBK fail\n");
+		else
+			WMT_DBG_FUNC("WMT turn off LPBK suceed\n");
+
+	}
+
+	osal_unlock_sleepable_lock(&g_es_lr_lock);
+
+}
+
+
+MTK_WCN_BOOL wmt_dev_get_early_suspend_state(void)
+{
+	MTK_WCN_BOOL bRet = (0 == g_es_lr_flag_for_quick_sleep) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE;
+	/* WMT_INFO_FUNC("bRet:%d\n", bRet); */
+	return bRet;
+}
+
+#if CFG_WMT_DBG_SUPPORT
+
+static const WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] = {
+	[0] = wmt_dbg_psm_ctrl,
+	[1] = wmt_dbg_quick_sleep_ctrl,
+	[2] = wmt_dbg_dsns_ctrl,
+	[3] = wmt_dbg_hwver_get,
+	[4] = wmt_dbg_assert_test,
+	[5] = wmt_dbg_inband_rst,
+	[6] = wmt_dbg_chip_rst,
+	[7] = wmt_dbg_func_ctrl,
+	[8] = wmt_dbg_raed_chipid,
+	[9] = wmt_dbg_wmt_dbg_level,
+	[0xa] = wmt_dbg_stp_dbg_level,
+	[0xb] = wmt_dbg_reg_read,
+	[0xc] = wmt_dbg_reg_write,
+	[0xd] = wmt_dbg_coex_test,
+	[0xe] = wmt_dbg_rst_ctrl,
+	[0xf] = wmt_dbg_ut_test,
+	[0x10] = wmt_dbg_efuse_read,
+	[0x11] = wmt_dbg_efuse_write,
+	[0x12] = wmt_dbg_sdio_ctrl,
+	[0x13] = wmt_dbg_stp_dbg_ctrl,
+	[0x14] = wmt_dbg_stp_dbg_log_ctrl,
+	[0x15] = wmt_dbg_wmt_assert_ctrl,
+	[0x16] = wmt_dbg_fwinfor_from_emi,
+	[0x17] = wmt_dbg_set_mcu_clock,
+	[0x18] = wmt_dbg_poll_cpupcr,
+	[0x19] = wmt_dbg_jtag_flag_ctrl,
+#if CFG_WMT_LTE_COEX_HANDLING
+	[0x20] = wmt_dbg_lte_coex_test,
+#endif
+};
+
+INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+#if CFG_WMT_PS_SUPPORT
+	if (0 == par2) {
+		wmt_lib_ps_ctrl(0);
+		WMT_INFO_FUNC("disable PSM\n");
+	} else {
+		par2 = (1 > par2 || 20000 < par2) ? STP_PSM_IDLE_TIME_SLEEP : par2;
+		wmt_lib_ps_set_idle_time(par2);
+		wmt_lib_ps_ctrl(1);
+		WMT_WARN_FUNC("enable PSM, idle to sleep time = %d ms\n", par2);
+	}
+#else
+	WMT_INFO_FUNC("WMT PS not supported\n");
+#endif
+	return 0;
+}
+
+INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+#if CFG_WMT_PS_SUPPORT
+	UINT32 en_flag = par2;
+
+	wmt_lib_quick_sleep_ctrl(en_flag);
+#else
+	WMT_WARN_FUNC("WMT PS not supported\n");
+#endif
+	return 0;
+}
+
+INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+	if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2) {
+		WMT_INFO_FUNC("DSNS type (%d)\n", par2);
+		mtk_wcn_wmt_dsns_ctrl(par2);
+	} else {
+		WMT_WARN_FUNC("invalid DSNS type\n");
+	}
+	return 0;
+}
+
+INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3)
+{
+	WMT_INFO_FUNC("query chip version\n");
+	mtk_wcn_wmt_hwver_get();
+	return 0;
+}
+
+INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3)
+{
+	if (0 == par3) {
+		/* par2 = 0:  send assert command */
+		/* par2 != 0: send exception command */
+		return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1);
+	} else if (1 == par3) {
+		/* send noack command */
+		return wmt_dbg_cmd_test_api(18);
+	} else if (2 == par3) {
+		/* warn reset test */
+		return wmt_dbg_cmd_test_api(19);
+	} else if (3 == par3) {
+		/* firmware trace test */
+		return wmt_dbg_cmd_test_api(20);
+	}
+	{
+		INT32 sec = 8;
+		INT32 times = 0;
+
+		times = par3;
+		do {
+			WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n");
+			wmt_dbg_cmd_test_api(0);
+			osal_sleep_ms(sec * 1000);
+		} while (--times);
+	}
+	return 0;
+}
+
+INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd)
+{
+
+	P_OSAL_OP pOp = NULL;
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	P_OSAL_SIGNAL pSignal;
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	pSignal = &pOp->signal;
+
+	pOp->op.opId = WMT_OPID_CMD_TEST;
+
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+	/*this test command should be run with usb cable connected, so no host awake is needed */
+	/* wmt_lib_host_awake_get(); */
+	switch (cmd) {
+	case WMTDRV_CMD_ASSERT:
+		pOp->op.au4OpData[0] = 0;
+		break;
+	case WMTDRV_CMD_EXCEPTION:
+		pOp->op.au4OpData[0] = 1;
+		break;
+	case WMTDRV_CMD_NOACK_TEST:
+		pOp->op.au4OpData[0] = 3;
+		break;
+	case WMTDRV_CMD_WARNRST_TEST:
+		pOp->op.au4OpData[0] = 4;
+		break;
+	case WMTDRV_CMD_FWTRACE_TEST:
+		pOp->op.au4OpData[0] = 5;
+		break;
+	default:
+		if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd) {
+			pOp->op.au4OpData[0] = 2;
+			pOp->op.au4OpData[1] = cmd - 2;
+		} else {
+			pOp->op.au4OpData[0] = 0xff;
+			pOp->op.au4OpData[1] = 0xff;
+		}
+		pOp->op.au4OpData[2] = (SIZE_T) gCoexBuf.buffer;
+		pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer);
+		break;
+	}
+	WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]);
+	/*wake up chip first */
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed\n");
+		wmt_lib_put_op_to_free_queue(pOp);
+		return -1;
+	}
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+	if ((cmd != WMTDRV_CMD_ASSERT) &&
+	    (cmd != WMTDRV_CMD_EXCEPTION) &&
+	    (cmd != WMTDRV_CMD_NOACK_TEST) && (cmd != WMTDRV_CMD_WARNRST_TEST) && (cmd != WMTDRV_CMD_FWTRACE_TEST)) {
+		if (MTK_WCN_BOOL_FALSE == bRet) {
+			gCoexBuf.availSize = 0;
+		} else {
+			gCoexBuf.availSize = pOp->op.au4OpData[3];
+			WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize);
+		}
+	}
+	/* wmt_lib_host_awake_put(); */
+	WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n",
+		      pOp->op.opId,
+		      pOp->op.au4OpData[0],
+		      pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed");
+
+	return 0;
+}
+
+INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3)
+{
+	if (0 == par2) {
+		WMT_INFO_FUNC("inband reset test!!\n");
+		mtk_wcn_stp_inband_reset();
+	} else {
+		WMT_INFO_FUNC("STP context reset in host side!!\n");
+		mtk_wcn_stp_flush_context();
+	}
+
+	return 0;
+}
+
+INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3)
+{
+	if (0 == par2) {
+		if (mtk_wcn_stp_is_ready()) {
+			WMT_INFO_FUNC("whole chip reset test\n");
+			wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST);
+		} else {
+			WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n");
+		}
+	} else if (1 == par2) {
+		WMT_INFO_FUNC("chip hardware reset test\n");
+		wmt_lib_hw_rst();
+	} else {
+		WMT_INFO_FUNC("chip software reset test\n");
+		wmt_lib_sw_rst(1);
+	}
+	return 0;
+}
+
+INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+	if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2) {
+		if (0 == par3) {
+			WMT_INFO_FUNC("function off test, type(%d)\n", par2);
+			mtk_wcn_wmt_func_off(par2);
+		} else {
+			WMT_INFO_FUNC("function on test, type(%d)\n", par2);
+			mtk_wcn_wmt_func_on(par2);
+		}
+	} else {
+		WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2);
+	}
+	return 0;
+}
+
+INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3)
+{
+	WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER));
+	return 0;
+}
+
+INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3)
+{
+	par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO;
+	wmt_lib_dbg_level_set(par2);
+	WMT_INFO_FUNC("set wmt log level to %d\n", par2);
+	return 0;
+}
+
+INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3)
+{
+	par2 = (0 <= par2 && 4 >= par2) ? par2 : 2;
+	mtk_wcn_stp_dbg_level(par2);
+	WMT_INFO_FUNC("set stp log level to %d\n", par2);
+	return 0;
+
+}
+
+INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3)
+{
+	/* par2-->register address */
+	/* par3-->register mask */
+	UINT32 value = 0x0;
+	UINT32 iRet = -1;
+#if 0
+	DISABLE_PSM_MONITOR();
+	iRet = wmt_core_reg_rw_raw(0, par2, &value, par3);
+	ENABLE_PSM_MONITOR();
+#endif
+	iRet = wmt_lib_reg_rw(0, par2, &value, par3);
+	WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n",
+		      par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value);
+	return 0;
+}
+
+INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3)
+{
+	/* par2-->register address */
+	/* par3-->value to set */
+	UINT32 iRet = -1;
+#if 0
+	DISABLE_PSM_MONITOR();
+	iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff);
+	ENABLE_PSM_MONITOR();
+#endif
+	iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff);
+	WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n",
+		      par2, par3, iRet != 0 ? "failed" : "succeed");
+	return 0;
+}
+
+INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3)
+{
+	/* par2-->efuse address */
+	/* par3-->register mask */
+	UINT32 value = 0x0;
+	UINT32 iRet = -1;
+
+	iRet = wmt_lib_efuse_rw(0, par2, &value, par3);
+	WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n",
+		      par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value);
+	return 0;
+}
+
+INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3)
+{
+	/* par2-->efuse address */
+	/* par3-->value to set */
+	UINT32 iRet = -1;
+
+	iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff);
+	WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n",
+		      par2, par3, iRet != 0 ? "failed" : "succeed");
+	return 0;
+}
+
+INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+/*remove sdio card detect/remove control because of btif is used*/
+#if 0
+	INT32 iRet = -1;
+
+	iRet = wmt_lib_sdio_ctrl(0 != par2 ? 1 : 0);
+	WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed");
+#endif
+	return 0;
+}
+
+INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+	if (1 < par2) {
+		mtk_wcn_stp_dbg_dump_package();
+		return 0;
+	}
+	WMT_INFO_FUNC("%s stp debug function\n", 0 == par2 ? "disable" : "enable");
+	if (0 == par2)
+		mtk_wcn_stp_dbg_disable();
+	else if (1 == par2)
+		mtk_wcn_stp_dbg_enable();
+
+	return 0;
+}
+
+INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+	mtk_wcn_stp_dbg_log_ctrl(0 != par2 ? 1 : 0);
+	return 0;
+}
+
+INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+	mtk_wcn_stp_coredump_flag_ctrl(0 != par2 ? 1 : 0);
+	return 0;
+}
+
+INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3)
+{
+	UINT32 offset = 0;
+	UINT32 len = 0;
+	UINT32 *pAddr = NULL;
+	UINT32 cur_idx_pagedtrace;
+	static UINT32 prev_idx_pagedtrace;
+	MTK_WCN_BOOL isBreak = MTK_WCN_BOOL_TRUE;
+
+	offset = par2;
+	len = par3;
+
+	buf_emi = kmalloc(sizeof(UINT8) * BUF_LEN_MAX, GFP_KERNEL);
+	if (!buf_emi) {
+			WMT_ERR_FUNC("buf kmalloc memory fail\n");
+			return 0;
+		}
+	osal_memset(buf_emi, 0, BUF_LEN_MAX);
+	osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE);
+	wmt_lib_get_fwinfor_from_emi(0, offset, &gEmiBuf[0], 0x100);
+
+	if (offset == 1) {
+		do {
+			pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24);
+			cur_idx_pagedtrace = *pAddr;
+
+			if (cur_idx_pagedtrace > prev_idx_pagedtrace) {
+				len = cur_idx_pagedtrace - prev_idx_pagedtrace;
+				wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len);
+				wmt_dbg_fwinfor_print_buff(len);
+				prev_idx_pagedtrace = cur_idx_pagedtrace;
+			}
+
+			if (cur_idx_pagedtrace < prev_idx_pagedtrace) {
+				if (prev_idx_pagedtrace >= 0x8000) {
+					pr_debug("++ prev_idx_pagedtrace invalid ...++\n\\n");
+					prev_idx_pagedtrace = 0x8000 - 1;
+					continue;
+				}
+
+				len = 0x8000 - prev_idx_pagedtrace - 1;
+				wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len);
+				pr_debug("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n");
+				wmt_dbg_fwinfor_print_buff(len);
+
+				len = cur_idx_pagedtrace;
+				wmt_lib_get_fwinfor_from_emi(1, 0x0, &gEmiBuf[0], len);
+				pr_debug("\n\n -- CONNSYS paged trace ascii output (end) --\n\n");
+				wmt_dbg_fwinfor_print_buff(len);
+				prev_idx_pagedtrace = cur_idx_pagedtrace;
+			}
+			msleep(100);
+		} while (isBreak);
+	}
+
+	pr_debug("\n\n -- control word --\n\n");
+	wmt_dbg_fwinfor_print_buff(256);
+	if (len > 1024 * 4)
+		len = 1024 * 4;
+
+	WMT_WARN_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n", offset, len);
+	osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE);
+	wmt_lib_get_fwinfor_from_emi(1, offset, &gEmiBuf[0], len);
+
+	pr_debug("\n\n -- paged trace hex output --\n\n");
+	wmt_dbg_fwinfor_print_buff(len);
+	pr_debug("\n\n -- paged trace ascii output --\n\n");
+	wmt_dbg_fwinfor_print_buff(len);
+	kfree(buf_emi);
+	return 0;
+}
+
+INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3)
+{
+	WMT_INFO_FUNC("coexistance test cmd!!\n");
+	return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00);
+}
+
+INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+	WMT_INFO_FUNC("%s audo rst\n", 0 == par2 ? "disable" : "enable");
+	mtk_wcn_stp_set_auto_rst(0 == par2 ? 0 : 1);
+	return 0;
+}
+
+INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3)
+{
+
+	INT32 i = 0;
+	INT32 j = 0;
+	INT32 iRet = 0;
+
+	i = 20;
+	while ((i--) > 0) {
+		WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i);
+		j = 10;
+		while ((j--) > 0) {
+			WMT_INFO_FUNC("#### BT  On .... (%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+			WMT_INFO_FUNC("#### GPS On .... (%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+			WMT_INFO_FUNC("#### FM  On .... (%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+			WMT_INFO_FUNC("#### WIFI On .... (%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+			WMT_INFO_FUNC("#### BT  Off .... (%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+			WMT_INFO_FUNC("#### GPS  Off ....(%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+			WMT_INFO_FUNC("#### FM  Off .... (%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+			WMT_INFO_FUNC("#### WIFI  Off ....(%d, %d)\n", i, j);
+			iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI);
+			if (iRet == MTK_WCN_BOOL_FALSE)
+				break;
+
+		}
+		if (iRet == MTK_WCN_BOOL_FALSE)
+			break;
+
+	}
+	if (iRet == MTK_WCN_BOOL_FALSE)
+		WMT_INFO_FUNC("#### UT FAIL!!\n");
+	else
+		WMT_INFO_FUNC("#### UT PASS!!\n");
+
+	return iRet;
+}
+
+#if CFG_CORE_INTERNAL_TXRX
+
+struct lpbk_package {
+	long payload_length;
+	unsigned char out_payload[2048];
+	unsigned char in_payload[2048];
+};
+
+static INT32 wmt_internal_loopback(INT32 count, INT32 max)
+{
+	int ret = 0;
+	int loop;
+	int offset;
+	struct lpbk_package lpbk_buffer;
+	P_OSAL_OP pOp;
+	P_OSAL_SIGNAL pSignal = NULL;
+
+	for (loop = 0; loop < count; loop++) {
+		/* <1> init buffer */
+		osal_memset((void *)&lpbk_buffer, 0, sizeof(struct lpbk_package));
+		lpbk_buffer.payload_length = max;
+		for (offset = 0; offset < max; offset++)
+			lpbk_buffer.out_payload[offset] = (offset + 1) /*for test use: begin from 1 */ & 0xFF;
+
+
+		memcpy(&gLpbkBuf[0], &lpbk_buffer.out_payload[0], max);
+
+		pOp = wmt_lib_get_free_op();
+		if (!pOp) {
+			WMT_WARN_FUNC("get_free_lxop fail\n");
+			ret = -1;
+			break;
+		}
+		pSignal = &pOp->signal;
+		pOp->op.opId = WMT_OPID_LPBK;
+		pOp->op.au4OpData[0] = lpbk_buffer.payload_length;	/* packet length */
+		pOp->op.au4OpData[1] = (UINT32) &gLpbkBuf[0];
+		pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+		WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]);
+		if (DISABLE_PSM_MONITOR()) {
+			WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]);
+			wmt_lib_put_op_to_free_queue(pOp);
+			ret = -2;
+		}
+
+		ret = wmt_lib_put_act_op(pOp);
+		ENABLE_PSM_MONITOR();
+		if (MTK_WCN_BOOL_FALSE == ret) {
+			WMT_WARN_FUNC("OPID(%d) type(%d)fail\n", pOp->op.opId, pOp->op.au4OpData[0]);
+			ret = -3;
+			break;
+		}
+		WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]);
+
+		memcpy(&lpbk_buffer.in_payload[0], &gLpbkBuf[0], max);
+
+		ret = pOp->op.au4OpData[0];
+		/*<3> compare result */
+		if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) {
+			WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __func__);
+			ret = -4;
+			break;
+		}
+		WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld)\n", __func__, loop,
+			     lpbk_buffer.payload_length);
+
+	}
+
+	if (loop != count)
+		WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max);
+
+
+	return ret;
+}
+
+INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3)
+{
+	UINT32 count;
+	UINT32 length;
+
+	count = par1;
+	length = par2;
+
+	WMT_INFO_FUNC("count[%d],length[%d]\n", count, length);
+
+	wmt_core_lpbk_do_stp_init();
+
+	wmt_internal_loopback(count, length);
+
+	wmt_core_lpbk_do_stp_deinit();
+	return 0;
+}
+#endif
+
+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3)
+{
+	int ret = 0;
+	P_OSAL_OP pOp;
+	P_OSAL_SIGNAL pSignal = NULL;
+	UINT32 kind = 0;
+
+	kind = par2;
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return -1;
+	}
+	pSignal = &pOp->signal;
+	pOp->op.opId = WMT_OPID_SET_MCU_CLK;
+	pOp->op.au4OpData[0] = kind;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+
+	WMT_INFO_FUNC("OPID(%d) kind(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]);
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed,OPID(%d) kind(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]);
+		wmt_lib_put_op_to_free_queue(pOp);
+		return -2;
+	}
+
+	ret = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+	if (MTK_WCN_BOOL_FALSE == ret) {
+		WMT_WARN_FUNC("OPID(%d) kind(%d)fail(%d)\n", pOp->op.opId, pOp->op.au4OpData[0], ret);
+		return -3;
+	}
+	WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]);
+
+	return ret;
+}
+
+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3)
+{
+	UINT32 count = 0;
+	UINT16 sleep = 0;
+	UINT16 toAee = 0;
+
+	count = par2;
+	sleep = (par3 & 0xF0) >> 4;
+	toAee = (par3 & 0x0F);
+
+	WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n", count, sleep, toAee);
+	wmt_lib_poll_cpupcr(count, sleep, toAee);
+
+	return 0;
+}
+
+#if CONSYS_ENALBE_SET_JTAG
+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3)
+{
+	UINT32 en_flag = par2;
+
+	wmt_lib_jtag_flag_set(en_flag);
+	return 0;
+}
+#endif
+
+#if CFG_WMT_LTE_COEX_HANDLING
+static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode, UINT32 msg_len)
+{
+	ipc_ilm_t ilm;
+	local_para_struct *p_buf_str;
+	INT32 i = 0;
+	INT32 iRet = -1;
+
+	WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n", opcode, msg_len);
+	p_buf_str = osal_malloc(osal_sizeof(local_para_struct) + msg_len);
+	if (NULL == p_buf_str) {
+		WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n");
+		return -1;
+	}
+	p_buf_str->msg_len = msg_len;
+	for (i = 0; i < msg_len; i++)
+		p_buf_str->data[i] = i;
+
+	ilm.local_para_ptr = p_buf_str;
+	ilm.msg_id = opcode;
+
+	iRet = wmt_lib_handle_idc_msg(&ilm);
+	osal_free(p_buf_str);
+	return iRet;
+
+}
+
+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3)
+{
+	UINT8 *local_buffer = NULL;
+	UINT32 handle_len;
+	INT32 iRet = -1;
+	static UINT8 wmt_to_lte_test_evt1[] = { 0x02, 0x16, 0x0d, 0x00,
+		0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+		0xa, 0xb
+	};
+	static UINT8 wmt_to_lte_test_evt2[] = { 0x02, 0x16, 0x09, 0x00,
+		0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+	};
+	static UINT8 wmt_to_lte_test_evt3[] = { 0x02, 0x16, 0x02, 0x00,
+		0x02, 0xff
+	};
+	static UINT8 wmt_to_lte_test_evt4[] = { 0x02, 0x16, 0x0d, 0x00,
+		0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+		0xa, 0xb
+	};
+
+	local_buffer = kmalloc(512, GFP_KERNEL);
+	if (!local_buffer) {
+		WMT_ERR_FUNC("local_buffer kmalloc memory fail\n");
+		return 0;
+	}
+
+	if (par2 == 1) {
+		handle_len =
+		    wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1));
+		if (handle_len != osal_sizeof(wmt_to_lte_test_evt1)) {
+			WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n",
+				     handle_len, osal_sizeof(wmt_to_lte_test_evt1));
+		} else {
+			WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len);
+		}
+	}
+	if (par2 == 2) {
+		osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1));
+		osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)],
+			    &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2));
+
+		handle_len =
+		    wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0],
+							osal_sizeof(wmt_to_lte_test_evt1) +
+							osal_sizeof(wmt_to_lte_test_evt2));
+		if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)) {
+			WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n",
+				     handle_len, osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2));
+		} else {
+			WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len);
+		}
+	}
+	if (par2 == 3) {
+		osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1));
+		osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)],
+			    &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2));
+		osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)],
+			    &wmt_to_lte_test_evt3[0], osal_sizeof(wmt_to_lte_test_evt3));
+
+		handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], osal_sizeof(wmt_to_lte_test_evt1) +
+								 osal_sizeof(wmt_to_lte_test_evt2) +
+								 osal_sizeof(wmt_to_lte_test_evt3));
+		if (handle_len !=
+		    osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) +
+		    osal_sizeof(wmt_to_lte_test_evt3)) {
+			WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", handle_len,
+				     osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) +
+				     osal_sizeof(wmt_to_lte_test_evt3));
+		} else {
+			WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n", handle_len);
+		}
+	}
+	if (par2 == 4) {
+		handle_len =
+		    wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt4[0], osal_sizeof(wmt_to_lte_test_evt4));
+		if (handle_len != osal_sizeof(wmt_to_lte_test_evt4)) {
+			WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n",
+				     handle_len, osal_sizeof(wmt_to_lte_test_evt4));
+		} else {
+			WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len);
+		}
+	}
+	if (par2 == 5) {
+		if (par3 >= 1024)
+			par3 = 1024;
+
+		iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, par3);
+		WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n", iRet);
+	}
+	if (par2 == 6) {
+		if (par3 >= 1024)
+			par3 = 1024;
+
+		iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, par3);
+		WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n", iRet);
+	}
+	if (par2 == 7) {
+		if (par3 >= 1024)
+			par3 = 1024;
+
+		iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, par3);
+		WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n", iRet);
+	}
+	if (par2 == 8) {
+		if (par3 >= 1024)
+			par3 = 1024;
+
+		iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND, par3);
+		WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n", iRet);
+	}
+	if (par2 == 9) {
+		if (par3 > 0)
+			wmt_core_set_flag_for_test(1);
+		else
+			wmt_core_set_flag_for_test(0);
+	}
+	return 0;
+	kfree(local_buffer);
+}
+#endif
+
+static ssize_t wmt_dev_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+
+	INT32 retval = 0;
+	INT32 i_ret = 0;
+	PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n";
+
+	if (*f_pos > 0) {
+		retval = 0;
+	} else {
+		/*len = sprintf(page, "%d\n", g_psm_enable); */
+		if (gCoexBuf.availSize <= 0) {
+			WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n");
+			retval = osal_strlen(warn_msg) + 1;
+			if (count < retval)
+				retval = count;
+
+			i_ret = copy_to_user(buf, warn_msg, retval);
+			if (i_ret) {
+				WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
+				retval = -EFAULT;
+				goto err_exit;
+			}
+			*f_pos += retval;
+		} else {
+			INT32 i = 0;
+			INT32 len = 0;
+			INT8 msg_info[128];
+			INT32 max_num = 0;
+			/*we do not check page buffer, because there are only
+			* 100 bytes in g_coex_buf, no reason page buffer is not
+			* enough, a bomb is placed here on unexpected condition
+			*/
+
+			WMT_INFO_FUNC("%d bytes available\n", gCoexBuf.availSize);
+			max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) - 1) / 5;
+
+			if (max_num > gCoexBuf.availSize)
+				max_num = gCoexBuf.availSize;
+			else
+				WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num);
+
+
+			for (i = 0; i < max_num; i++)
+				len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]);
+
+
+			len += osal_sprintf(msg_info + len, "\n");
+			retval = len;
+
+			i_ret = copy_to_user(buf, msg_info, retval);
+			if (i_ret) {
+				WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
+				retval = -EFAULT;
+				goto err_exit;
+			}
+			*f_pos += retval;
+
+		}
+	}
+	gCoexBuf.availSize = 0;
+err_exit:
+
+	return retval;
+}
+
+static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
+{
+	INT8 buf[256];
+	PINT8 pBuf;
+	ssize_t len = count;
+	INT32 x = 0, y = 0, z = 0;
+	PINT8 pToken = NULL;
+	PINT8 pDelimiter = " \t";
+	long res;
+	INT32 ret;
+
+	WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len);
+	if (len >= osal_sizeof(buf)) {
+		WMT_ERR_FUNC("input handling fail!\n");
+		len = osal_sizeof(buf) - 1;
+		return -1;
+	}
+
+	if (copy_from_user(buf, buffer, len))
+		return -EFAULT;
+
+	buf[len] = '\0';
+	WMT_INFO_FUNC("write parameter data = %s\n\r", buf);
+
+	pBuf = buf;
+	pToken = osal_strsep(&pBuf, pDelimiter);
+
+	if (pToken != NULL) {
+		ret = osal_strtol(pToken, 16, &res);
+		if (ret) {
+			WMT_ERR_FUNC("get x fail(%d)\n", ret);
+			x = 0;
+		}
+		x = res;
+	} else {
+		x = 0;
+	}
+
+	pToken = osal_strsep(&pBuf, "\t\n ");
+	if (pToken != NULL) {
+		ret = osal_strtol(pToken, 16, &res);
+		if (ret) {
+			WMT_ERR_FUNC("get y fail(%d)\n", ret);
+			y = 0;
+		}
+		y = res;
+		WMT_INFO_FUNC("y = 0x%08x\n\r", y);
+	} else {
+		y = 3000;
+		/*efuse, register read write default value */
+		if (0x11 == x || 0x12 == x || 0x13 == x)
+			y = 0x80000000;
+
+	}
+
+	pToken = osal_strsep(&pBuf, "\t\n ");
+	if (pToken != NULL) {
+		ret = osal_strtol(pToken, 16, &res);
+		if (ret) {
+			WMT_ERR_FUNC("get z fail(%d)\n", ret);
+			z = 0;
+		}
+		z = res;
+	} else {
+		z = 10;
+		/*efuse, register read write default value */
+		if (0x11 == x || 0x12 == x || 0x13 == x)
+			z = 0xffffffff;
+
+	}
+
+	WMT_WARN_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);
+
+	if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x])
+		(*wmt_dev_dbg_func[x]) (x, y, z);
+	else
+		WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x);
+
+	return len;
+}
+
+INT32 wmt_dev_dbg_setup(VOID)
+{
+	static const struct file_operations wmt_dbg_fops = {
+		.owner = THIS_MODULE,
+		.read = wmt_dev_dbg_read,
+		.write = wmt_dev_dbg_write,
+	};
+	gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops);
+	if (gWmtDbgEntry == NULL) {
+		WMT_ERR_FUNC("Unable to create /proc entry\n\r");
+		return -1;
+	}
+	return 0;
+}
+
+INT32 wmt_dev_dbg_remove(VOID)
+{
+	if (NULL != gWmtDbgEntry)
+		remove_proc_entry(WMT_DBG_PROCNAME, NULL);
+
+#if CFG_WMT_PS_SUPPORT
+	wmt_lib_ps_deinit();
+#endif
+	return 0;
+}
+#endif
+
+#if CFG_WMT_PROC_FOR_AEE
+
+static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	INT32 retval = 0;
+	UINT32 len = 0;
+
+	WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos);
+
+	if (0 == *f_pos) {
+		pBuf = wmt_lib_get_cpupcr_xml_format(&len);
+		g_buf_len = len;
+		WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len);
+	}
+
+	if (g_buf_len >= count) {
+
+		retval = copy_to_user(buf, pBuf, count);
+		if (retval) {
+			WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval);
+			retval = -EFAULT;
+			goto err_exit;
+		}
+
+		*f_pos += count;
+		g_buf_len -= count;
+		pBuf += count;
+		WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len);
+
+		retval = count;
+	} else if (0 != g_buf_len) {
+
+		retval = copy_to_user(buf, pBuf, g_buf_len);
+		if (retval) {
+			WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval);
+			retval = -EFAULT;
+			goto err_exit;
+		}
+
+		*f_pos += g_buf_len;
+		len = g_buf_len;
+		g_buf_len = 0;
+		pBuf += len;
+		retval = len;
+		WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len);
+	} else {
+		WMT_INFO_FUNC("wmt_dev: no data available for aee\n");
+		retval = 0;
+	}
+err_exit:
+	return retval;
+}
+
+static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+	WMT_TRC_FUNC();
+	return 0;
+}
+
+INT32 wmt_dev_proc_for_aee_setup(VOID)
+{
+	static const struct file_operations wmt_aee_fops = {
+		.owner = THIS_MODULE,
+		.read = wmt_dev_proc_for_aee_read,
+		.write = wmt_dev_proc_for_aee_write,
+	};
+
+	gWmtDbgEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops);
+	if (gWmtDbgEntry == NULL) {
+		WMT_ERR_FUNC("Unable to create /proc entry\n\r");
+		return -1;
+	}
+
+	return 0;
+}
+
+INT32 wmt_dev_proc_for_aee_remove(VOID)
+{
+	if (NULL != gWmtAeeEntry)
+		remove_proc_entry(WMT_AEE_PROCNAME, NULL);
+
+	return 0;
+}
+#endif
+
+VOID wmt_dev_rx_event_cb(VOID)
+{
+	u4RxFlag = 1;
+	atomic_inc(&gRxCount);
+	if (NULL != gpRxEvent) {
+		/* u4RxFlag = 1; */
+		/* atomic_inc(&gRxCount); */
+		wake_up_interruptible(&gpRxEvent->waitQueue);
+	} else {
+		/* WMT_ERR_FUNC("null gpRxEvent, flush rx!\n"); */
+		/* wmt_lib_flush_rx(); */
+	}
+}
+
+INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent)
+{
+
+	UINT32 ms = pEvent->timeoutValue;
+	long lRet = 0;
+
+	gpRxEvent = pEvent;
+	if (0 != ms)
+		lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, msecs_to_jiffies(ms));
+	else
+		lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0);
+
+	u4RxFlag = 0;
+/* gpRxEvent = NULL; */
+	if (atomic_dec_return(&gRxCount)) {
+		WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount));
+		atomic_set(&gRxCount, 0);
+	}
+
+	return lRet;
+}
+
+INT32 wmt_dev_read_file(PUINT8 pName, const PPUINT8 ppBufPtr, INT32 offset, INT32 padSzBuf)
+{
+	INT32 iRet = -1;
+	struct file *fd;
+	/* ssize_t iRet; */
+	INT32 file_len;
+	INT32 read_len;
+	PVOID pBuf;
+        mm_segment_t fs;
+
+	/* struct cred *cred = get_task_cred(current); */
+	//const struct cred *cred = get_current_cred();
+
+	if (!ppBufPtr) {
+		WMT_ERR_FUNC("invalid ppBufptr!\n");
+		return -1;
+	}
+	*ppBufPtr = NULL;
+
+	fd = filp_open(pName, O_RDONLY, 0);
+        if (IS_ERR(fd)) {
+            WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd));
+            return -2;
+        }
+
+        if(fd->f_op == NULL) {
+            printk(KERN_ERR "invalid file op \r\n");
+            return -3;
+        }
+
+#if 0
+	if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) {
+		WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d, %d)\n", fd, PTR_ERR(fd), cred->fsuid, cred->fsgid);
+		if (IS_ERR(fd))
+			WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd));
+		return -1;
+	}
+#endif
+	file_len = fd->f_path.dentry->d_inode->i_size;
+	file_len = fd->f_op->llseek(fd, 0, 2);
+	fd->f_op->llseek(fd, 0, 0);
+	pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL);
+	if (!pBuf) {
+		WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32) ((file_len + 3) & ~0x3UL));
+		goto read_file_done;
+	}
+
+	do {
+		if (fd->f_pos != offset) {
+			if (fd->f_op->llseek) {
+				if (fd->f_op->llseek(fd, offset, 0) != offset) {
+					WMT_ERR_FUNC("failed to seek!!\n");
+					goto read_file_done;
+				}
+			} else {
+				fd->f_pos = offset;
+			}
+		}
+
+                fs=get_fs();
+		read_len = vfs_read(fd, pBuf + padSzBuf, file_len, &fd->f_pos);
+                set_fs(fs);
+		if (read_len != file_len)
+			WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len);
+
+	} while (false);
+
+	iRet = 0;
+	*ppBufPtr = pBuf;
+
+read_file_done:
+	if (iRet) {
+		if (pBuf)
+			vfree(pBuf);
+
+	}
+
+	filp_close(fd, NULL);
+
+	return (iRet) ? iRet : read_len;
+}
+
+/* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */
+INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf)
+{
+	INT32 iRet = -1;
+	osal_firmware *pfw;
+	uid_t orig_uid;
+	gid_t orig_gid;
+
+	/* struct cred *cred = get_task_cred(current); */
+	struct cred *cred = (struct cred *)get_current_cred();
+
+	mm_segment_t orig_fs = get_fs();
+
+	if (*ppPatch) {
+		WMT_WARN_FUNC("f/w patch already exists\n");
+		if ((*ppPatch)->data)
+			vfree((*ppPatch)->data);
+
+		kfree(*ppPatch);
+		*ppPatch = NULL;
+	}
+
+	if (!osal_strlen(pPatchName)) {
+		WMT_ERR_FUNC("empty f/w name\n");
+		osal_assert((osal_strlen(pPatchName) > 0));
+		return -1;
+	}
+
+	pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL */ GFP_ATOMIC);
+	if (!pfw) {
+		WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware));
+		return -2;
+	}
+
+	orig_uid = cred->fsuid.val;
+	orig_gid = cred->fsgid.val;
+	cred->fsuid.val = cred->fsgid.val = 0;
+
+	set_fs(get_ds());
+
+	/* load patch file from fs */
+	iRet = wmt_dev_read_file(pPatchName, (const PPUINT8)&pfw->data, 0, padSzBuf);
+	set_fs(orig_fs);
+
+	cred->fsuid.val = orig_uid;
+	cred->fsgid.val = orig_gid;
+
+
+	if (iRet > 0) {
+		pfw->size = iRet;
+		*ppPatch = pfw;
+		WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data);
+		return 0;
+	}
+	kfree(pfw);
+	*ppPatch = NULL;
+	WMT_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet);
+	return -1;
+}
+
+INT32 wmt_dev_patch_put(osal_firmware **ppPatch)
+{
+	if (NULL != *ppPatch) {
+		if ((*ppPatch)->data)
+			vfree((*ppPatch)->data);
+
+		kfree(*ppPatch);
+		*ppPatch = NULL;
+	}
+	return 0;
+}
+
+VOID wmt_dev_patch_info_free(VOID)
+{
+
+	kfree(pPatchInfo);
+	pPatchInfo = NULL;
+
+}
+
+MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName)
+{
+	struct file *fd = NULL;
+	/* ssize_t iRet; */
+	INT32 fileLen = -1;
+	const struct cred *cred = get_current_cred();
+
+	if (pFileName == NULL) {
+		WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName);
+		return MTK_WCN_BOOL_FALSE;
+	}
+	if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) {
+		WMT_ERR_FUNC("invalid file name(%s)\n", pFileName);
+		return MTK_WCN_BOOL_FALSE;
+	}
+	/* struct cred *cred = get_task_cred(current); */
+
+	fd = filp_open(pFileName, O_RDONLY, 0);
+	if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) {
+		WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd, cred->fsuid, cred->fsgid);
+		return MTK_WCN_BOOL_FALSE;
+	}
+	fileLen = fd->f_path.dentry->d_inode->i_size;
+	filp_close(fd, NULL);
+	fd = NULL;
+	if (fileLen <= 0) {
+		WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen);
+		return MTK_WCN_BOOL_FALSE;
+	}
+	WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen);
+	return true;
+
+}
+
+/* static unsigned long count_last_access_sdio = 0; */
+static unsigned long count_last_access_btif;
+static unsigned long jiffies_last_poll;
+
+#if 0
+static INT32 wmt_dev_tra_sdio_update(void)
+{
+	count_last_access_sdio += 1;
+	/* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */
+
+	return 0;
+}
+#endif
+
+extern INT32 wmt_dev_tra_bitf_update(void)
+{
+	count_last_access_btif += 1;
+	/* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */
+
+	return 0;
+}
+
+static UINT32 wmt_dev_tra_ahb_poll(void)
+{
+#define TIME_THRESHOLD_TO_TEMP_QUERY 3000
+#define COUNT_THRESHOLD_TO_TEMP_QUERY 200
+
+	unsigned long ahb_during_count = 0;
+	unsigned long poll_during_time = 0;
+
+	/* if (jiffies > jiffies_last_poll) */
+	if (time_after(jiffies, jiffies_last_poll))
+		poll_during_time = jiffies - jiffies_last_poll;
+	else
+		poll_during_time = 0xffffffff;
+
+
+	WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n", jiffies_to_msecs(0xffffffff));
+
+	if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) {
+		WMT_DBG_FUNC("**poll_during_time = %lu < %lu, not to query\n",
+			     jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY);
+		return -1;
+	}
+	/* ahb_during_count = count_last_access_sdio; */
+	if (NULL == mtk_wcn_wlan_bus_tx_cnt) {
+		WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n");
+		return -1;
+	}
+	ahb_during_count = (*mtk_wcn_wlan_bus_tx_cnt) ();
+
+	if (ahb_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) {
+		WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n",
+			     ahb_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY);
+		return -2;
+	}
+
+	if (NULL == mtk_wcn_wlan_bus_tx_cnt_clr) {
+		WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n");
+		return -3;
+	}
+	(*mtk_wcn_wlan_bus_tx_cnt_clr) ();
+	/* count_last_access_sdio = 0; */
+	jiffies_last_poll = jiffies;
+
+	WMT_INFO_FUNC("**poll_during_time = %lu > %lu, ahb_during_count = %lu > %lu, query\n",
+		      jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY,
+		      jiffies_to_msecs(ahb_during_count), COUNT_THRESHOLD_TO_TEMP_QUERY);
+
+	return 0;
+}
+
+long wmt_dev_tm_temp_query(void)
+{
+#define HISTORY_NUM       5
+#define TEMP_THRESHOLD   65
+#define REFRESH_TIME    300	/* sec */
+
+	static INT32 temp_table[HISTORY_NUM] = { 99 };	/* not query yet. */
+	static INT32 idx_temp_table;
+	static struct timeval query_time, now_time;
+
+	INT8 query_cond = 0;
+	INT32 current_temp = 0;
+	INT32 index = 0;
+	long return_temp = 0;
+	/* Query condition 1: */
+	/* If we have the high temperature records on the past, we continue to query/monitor */
+	/* the real temperature until cooling */
+	for (index = 0; index < HISTORY_NUM; index++) {
+		if (temp_table[index] >= TEMP_THRESHOLD) {
+			query_cond = 1;
+			WMT_DBG_FUNC("temperature table is still initial value, we should query temp temperature..\n");
+		}
+	}
+
+	do_gettimeofday(&now_time);
+#if 1
+	/* Query condition 2: */
+	/* Moniter the ahb bus activity to decide if we have the need to query temperature. */
+	if (!query_cond) {
+		if (wmt_dev_tra_ahb_poll() == 0) {
+			query_cond = 1;
+			WMT_INFO_FUNC("ahb traffic , we must query temperature..\n");
+		} else {
+			WMT_DBG_FUNC("ahb idle traffic ....\n");
+		}
+
+		/* only WIFI tx power might make temperature varies largely */
+#if 0
+		if (!query_cond) {
+			last_access_time = wmt_dev_tra_uart_poll();
+			if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) {
+				query_cond = 1;
+				WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n");
+			} else {
+				WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n");
+			}
+		}
+#endif
+	}
+#endif
+	/* Query condition 3: */
+	/* If the query time exceeds the a certain of period, refresh temp table. */
+	/*  */
+	if (!query_cond) {
+		/* time overflow, we refresh temp table again for simplicity! */
+		if ((now_time.tv_sec < query_time.tv_sec) ||
+		    ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) {
+			query_cond = 1;
+
+			WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n",
+				      REFRESH_TIME);
+			for (index = 0; index < HISTORY_NUM; index++)
+				temp_table[index] = 99;
+
+		}
+	}
+
+	if (query_cond) {
+		/* update the temperature record */
+		mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE);
+		current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ);
+		mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE);
+		idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM;
+		temp_table[idx_temp_table] = current_temp;
+		do_gettimeofday(&query_time);
+
+		WMT_INFO_FUNC("[Thermal] current_temp = 0x%x\n", (current_temp & 0xFF));
+	} else {
+		current_temp = temp_table[idx_temp_table];
+		idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM;
+		temp_table[idx_temp_table] = current_temp;
+	}
+
+	/*  */
+	/* Dump information */
+	/*  */
+	WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table);
+	WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec,
+		     query_time.tv_sec, REFRESH_TIME);
+
+	WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n",
+		     temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]);
+
+	return_temp = ((current_temp & 0x80) == 0x0) ? current_temp : (-1) * (current_temp & 0x7f);
+
+	return return_temp;
+}
+
+ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+	INT32 iRet = 0;
+	UINT8 wrBuf[NAME_MAX + 1] = { 0 };
+	INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX;
+
+	WMT_LOUD_FUNC("count:%d copySize:%d\n", count, copySize);
+
+	if (copySize > 0) {
+		if (copy_from_user(wrBuf, buf, copySize)) {
+			iRet = -EFAULT;
+			goto write_done;
+		}
+		iRet = copySize;
+		wrBuf[NAME_MAX] = '\0';
+
+		if (!strncasecmp(wrBuf, "ok", NAME_MAX)) {
+			WMT_DBG_FUNC("resp str ok\n");
+			/* pWmtDevCtx->cmd_result = 0; */
+			wmt_lib_trigger_cmd_signal(0);
+		} else {
+			WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf);
+			/* pWmtDevCtx->cmd_result = -1; */
+			wmt_lib_trigger_cmd_signal(-1);
+		}
+		/* complete(&pWmtDevCtx->cmd_comp); */
+
+	}
+
+write_done:
+	return iRet;
+}
+
+ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	INT32 iRet = 0;
+	PUINT8 pCmd = NULL;
+	UINT32 cmdLen = 0;
+
+	pCmd = wmt_lib_get_cmd();
+
+	if (pCmd != NULL) {
+		cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX;
+		WMT_DBG_FUNC("cmd str(%s)\n", pCmd);
+		if (copy_to_user(buf, pCmd, cmdLen))
+			iRet = -EFAULT;
+		else
+			iRet = cmdLen;
+
+	}
+#if 0
+	if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) {
+		iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX;
+		/* we got something from STP driver */
+		WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf);
+		if (copy_to_user(buf, localBuf, iRet)) {
+			iRet = -EFAULT;
+			goto read_done;
+		}
+	}
+#endif
+	return iRet;
+}
+
+unsigned int WMT_poll(struct file *filp, poll_table *wait)
+{
+	UINT32 mask = 0;
+	P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event();
+
+	poll_wait(filp, &pEvent->waitQueue, wait);
+	/* empty let select sleep */
+	if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status())
+		mask |= POLLIN | POLLRDNORM;	/* readable */
+
+#if 0
+	if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state))
+		mask |= POLLIN | POLLRDNORM;	/* readable */
+
+#endif
+	mask |= POLLOUT | POLLWRNORM;	/* writable */
+	return mask;
+}
+
+/* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */
+long WMT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+
+	INT32 iRet = 0;
+	UINT8 *pBuffer = NULL;
+
+	WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg);
+	switch (cmd) {
+	case WMT_IOCTL_SET_PATCH_NAME:	/* patch location */
+		{
+
+			pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL);
+			if (!pBuffer) {
+				WMT_ERR_FUNC("pBuffer kmalloc memory fail\n");
+				return 0;
+			}
+			if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) {
+				iRet = -EFAULT;
+				kfree(pBuffer);
+				break;
+			}
+			pBuffer[NAME_MAX] = '\0';
+			wmt_lib_set_patch_name(pBuffer);
+			kfree(pBuffer);
+		}
+		break;
+
+	case WMT_IOCTL_SET_STP_MODE:	/* stp/hif/fm mode */
+
+		/* set hif conf */
+		do {
+			P_OSAL_OP pOp;
+			MTK_WCN_BOOL bRet;
+			P_OSAL_SIGNAL pSignal = NULL;
+			P_WMT_HIF_CONF pHif = NULL;
+
+			iRet = wmt_lib_set_hif(arg);
+			if (0 != iRet) {
+				WMT_INFO_FUNC("wmt_lib_set_hif fail\n");
+				break;
+			}
+
+			pOp = wmt_lib_get_free_op();
+			if (!pOp) {
+				WMT_INFO_FUNC("get_free_lxop fail\n");
+				break;
+			}
+			pSignal = &pOp->signal;
+			pOp->op.opId = WMT_OPID_HIF_CONF;
+
+			pHif = wmt_lib_get_hif();
+
+			osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF));
+			pOp->op.u4InfoBit = WMT_OP_HIF_BIT;
+			pSignal->timeoutValue = 0;
+
+			bRet = wmt_lib_put_act_op(pOp);
+			WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet);
+			iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
+		} while (0);
+
+		break;
+
+	case WMT_IOCTL_FUNC_ONOFF_CTRL:	/* test turn on/off func */
+
+		do {
+			MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+
+			if (arg & 0x80000000)
+				bRet = mtk_wcn_wmt_func_on(arg & 0xF);
+			else
+				bRet = mtk_wcn_wmt_func_off(arg & 0xF);
+
+			iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
+		} while (0);
+
+		break;
+
+	case WMT_IOCTL_LPBK_POWER_CTRL:
+		/*switch Loopback function on/off
+		   arg:     bit0 = 1:turn loopback function on
+		   bit0 = 0:turn loopback function off
+		 */
+		do {
+			MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+
+			if (arg & 0x01)
+				bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK);
+			else
+				bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK);
+
+			iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
+		} while (0);
+
+		break;
+
+	case WMT_IOCTL_LPBK_TEST:
+		do {
+			P_OSAL_OP pOp;
+			MTK_WCN_BOOL bRet;
+			UINT32 u4Wait;
+			/* UINT8 lpbk_buf[1024] = {0}; */
+			UINT32 effectiveLen = 0;
+			P_OSAL_SIGNAL pSignal = NULL;
+
+			if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) {
+				iRet = -EFAULT;
+				WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
+				break;
+			}
+			if (effectiveLen > sizeof(gLpbkBuf)) {
+				iRet = -EFAULT;
+				WMT_ERR_FUNC("length is too long\n");
+				break;
+			}
+			WMT_DBG_FUNC("len = %d\n", effectiveLen);
+
+			pOp = wmt_lib_get_free_op();
+			if (!pOp) {
+				WMT_WARN_FUNC("get_free_lxop fail\n");
+				iRet = -EFAULT;
+				break;
+			}
+			u4Wait = 2000;
+			if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) {
+				WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
+				iRet = -EFAULT;
+				break;
+			}
+			pSignal = &pOp->signal;
+			pOp->op.opId = WMT_OPID_LPBK;
+			pOp->op.au4OpData[0] = effectiveLen;	/* packet length */
+			pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0];	/* packet buffer pointer */
+			memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4);
+			pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+			WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]);
+			if (DISABLE_PSM_MONITOR()) {
+				WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n",
+					     pOp->op.opId, pOp->op.au4OpData[0]);
+				wmt_lib_put_op_to_free_queue(pOp);
+				return -1;
+			}
+
+			bRet = wmt_lib_put_act_op(pOp);
+			ENABLE_PSM_MONITOR();
+			if (MTK_WCN_BOOL_FALSE == bRet) {
+				WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n",
+					      pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog);
+				iRet = -1;
+				break;
+			}
+			WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]);
+			iRet = pOp->op.au4OpData[0];
+			if (copy_to_user((void *)arg + sizeof(SIZE_T) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) {
+				iRet = -EFAULT;
+				break;
+			}
+
+		} while (0);
+
+		break;
+
+	case WMT_IOCTL_ADIE_LPBK_TEST:
+		do {
+			P_OSAL_OP pOp;
+			MTK_WCN_BOOL bRet;
+			P_OSAL_SIGNAL pSignal = NULL;
+
+			pOp = wmt_lib_get_free_op();
+			if (!pOp) {
+				WMT_WARN_FUNC("get_free_lxop fail\n");
+				iRet = -EFAULT;
+				break;
+			}
+
+			pSignal = &pOp->signal;
+			pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST;
+			pOp->op.au4OpData[0] = 0;
+			pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0];
+			pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+			WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId);
+			if (DISABLE_PSM_MONITOR()) {
+				WMT_ERR_FUNC("wake up failed,OPID(%d)abort\n", pOp->op.opId);
+				wmt_lib_put_op_to_free_queue(pOp);
+				return -1;
+			}
+
+			bRet = wmt_lib_put_act_op(pOp);
+			ENABLE_PSM_MONITOR();
+			if (MTK_WCN_BOOL_FALSE == bRet) {
+				WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId);
+				iRet = -1;
+				break;
+			}
+			WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]);
+			iRet = pOp->op.au4OpData[0];
+			if (copy_to_user((void *)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) {
+				iRet = -EFAULT;
+				break;
+			}
+
+		} while (0);
+
+		break;
+
+	case 10:
+		{
+			pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL);
+			if (!pBuffer) {
+				WMT_ERR_FUNC("pBuffer kmalloc memory fail\n");
+				return 0;
+			}
+			wmt_lib_host_awake_get();
+			mtk_wcn_stp_coredump_start_ctrl(1);
+			osal_strcpy(pBuffer, "MT662x f/w coredump start-");
+			if (copy_from_user
+			    (pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) {
+				/* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */
+				WMT_ERR_FUNC("copy assert string failed\n");
+			}
+			pBuffer[NAME_MAX] = '\0';
+			osal_dbg_assert_aee(pBuffer, pBuffer);
+			kfree(pBuffer);
+		}
+		break;
+	case 11:
+		{
+			osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends");
+			wmt_lib_host_awake_put();
+		}
+		break;
+
+	case WMT_IOCTL_GET_CHIP_INFO:
+		{
+			if (0 == arg)
+				return wmt_lib_get_icinfo(WMTCHIN_CHIPID);
+			else if (1 == arg)
+				return wmt_lib_get_icinfo(WMTCHIN_HWVER);
+			else if (2 == arg)
+				return wmt_lib_get_icinfo(WMTCHIN_FWVER);
+
+		}
+		break;
+
+	case WMT_IOCTL_SET_LAUNCHER_KILL:{
+			if (1 == arg) {
+				WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n");
+				wmt_lib_set_stp_wmt_last_close(1);
+			} else {
+				wmt_lib_set_stp_wmt_last_close(0);
+			}
+
+		}
+		break;
+
+	case WMT_IOCTL_SET_PATCH_NUM:{
+			pAtchNum = arg;
+			WMT_DBG_FUNC(" get patch num from launcher = %d\n", pAtchNum);
+			wmt_lib_set_patch_num(pAtchNum);
+			pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC);
+			if (!pPatchInfo) {
+				WMT_ERR_FUNC("allocate memory fail!\n");
+				break;
+			}
+		}
+		break;
+
+	case WMT_IOCTL_SET_PATCH_INFO:{
+			WMT_PATCH_INFO wMtPatchInfo;
+			P_WMT_PATCH_INFO pTemp = NULL;
+			UINT32 dWloadSeq;
+			static UINT32 counter;
+
+			if (!pPatchInfo) {
+				WMT_ERR_FUNC("NULL patch info pointer\n");
+				break;
+			}
+
+			if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) {
+				WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
+				iRet = -EFAULT;
+				break;
+			}
+
+			dWloadSeq = wMtPatchInfo.dowloadSeq;
+			WMT_DBG_FUNC(
+				"patch dl seq %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n",
+			     dWloadSeq, wMtPatchInfo.patchName,
+			     wMtPatchInfo.addRess[0],
+			     wMtPatchInfo.addRess[1],
+			     wMtPatchInfo.addRess[2],
+			     wMtPatchInfo.addRess[3]);
+			osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo, sizeof(WMT_PATCH_INFO));
+			pTemp = pPatchInfo + dWloadSeq - 1;
+			if (++counter == pAtchNum) {
+				wmt_lib_set_patch_info(pPatchInfo);
+				counter = 0;
+			}
+		}
+		break;
+
+	case WMT_IOCTL_WMT_COREDUMP_CTRL:
+			mtk_wcn_stp_coredump_flag_ctrl(arg);
+		break;
+	case WMT_IOCTL_WMT_QUERY_CHIPID:
+		{
+			iRet = mtk_wcn_wmt_chipid_query();
+			WMT_WARN_FUNC("chipid = 0x%x\n", iRet);
+		}
+		break;
+	case WMT_IOCTL_SEND_BGW_DS_CMD:
+		do {
+			P_OSAL_OP pOp;
+			MTK_WCN_BOOL bRet;
+			UINT8 desense_buf[14] = { 0 };
+			UINT32 effectiveLen = 14;
+			P_OSAL_SIGNAL pSignal = NULL;
+
+			pOp = wmt_lib_get_free_op();
+			if (!pOp) {
+				WMT_WARN_FUNC("get_free_lxop fail\n");
+				iRet = -EFAULT;
+				break;
+			}
+			if (copy_from_user(&desense_buf[0], (void *)arg, effectiveLen)) {
+				WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
+				iRet = -EFAULT;
+				break;
+			}
+			pSignal = &pOp->signal;
+			pOp->op.opId = WMT_OPID_BGW_DS;
+			pOp->op.au4OpData[0] = effectiveLen;	/* packet length */
+			pOp->op.au4OpData[1] = (SIZE_T) &desense_buf[0];	/* packet buffer pointer */
+			pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+			WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId);
+			if (DISABLE_PSM_MONITOR()) {
+				WMT_ERR_FUNC("wake up failed,opid(%d) abort\n", pOp->op.opId);
+				wmt_lib_put_op_to_free_queue(pOp);
+				return -1;
+			}
+
+			bRet = wmt_lib_put_act_op(pOp);
+			ENABLE_PSM_MONITOR();
+			if (MTK_WCN_BOOL_FALSE == bRet) {
+				WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId);
+				iRet = -1;
+				break;
+			}
+			WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]);
+			iRet = pOp->op.au4OpData[0];
+
+		} while (0);
+
+		break;
+	case WMT_IOCTL_FW_DBGLOG_CTRL:
+		{
+			iRet = wmt_plat_set_dbg_mode(arg);
+			if (iRet == 0)
+				wmt_dbg_fwinfor_from_emi(0, 1, 0);
+		}
+		break;
+	case WMT_IOCTL_DYNAMIC_DUMP_CTRL:
+		{
+			UINT32 i = 0, j = 0, k = 0;
+			UINT8 *pBuf = NULL;
+			UINT32 int_buf[10];
+			char Buffer[10][11];
+
+			pBuf = kmalloc(DYNAMIC_DUMP_BUF + 1, GFP_KERNEL);
+			if (!pBuf) {
+				WMT_ERR_FUNC("pBuf kmalloc memory fail\n");
+				return 0;
+			}
+			if (copy_from_user(pBuf, (void *)arg, DYNAMIC_DUMP_BUF)) {
+				iRet = -EFAULT;
+				kfree(pBuf);
+				break;
+			}
+			pBuf[DYNAMIC_DUMP_BUF] = '\0';
+			WMT_INFO_FUNC("get dynamic dump data from property(%s)\n", pBuf);
+			memset(Buffer, 0, 10*11);
+			for (i = 0; i < DYNAMIC_DUMP_BUF; i++) {
+				if (pBuf[i] == '/') {
+					k = 0;
+					j++;
+				} else {
+					Buffer[j][k] = pBuf[i];
+					k++;
+				}
+			}
+			for (j = 0; j < 10; j++) {
+				iRet = kstrtou32(Buffer[j], 0, &int_buf[j]);
+				if (iRet) {
+					WMT_ERR_FUNC("string convert fail(%d)\n", iRet);
+					break;
+				}
+				WMT_INFO_FUNC("dynamic dump data buf[%d]:(0x%x)\n", j, int_buf[j]);
+			}
+			wmt_plat_set_dynamic_dumpmem(int_buf);
+			kfree(pBuf);
+		}
+		break;
+	default:
+		iRet = -EINVAL;
+		WMT_WARN_FUNC("unknown cmd (%d)\n", cmd);
+		break;
+	}
+
+	return iRet;
+}
+#ifdef CONFIG_COMPAT
+long WMT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+	WMT_INFO_FUNC("cmd[0x%x]\n", cmd);
+		switch (cmd) {
+		case COMPAT_WMT_IOCTL_SET_PATCH_NAME:
+			ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (unsigned long)compat_ptr(arg));
+			break;
+		case COMPAT_WMT_IOCTL_LPBK_TEST:
+			ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (unsigned long)compat_ptr(arg));
+			break;
+		case COMPAT_WMT_IOCTL_SET_PATCH_INFO:
+			ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (unsigned long)compat_ptr(arg));
+			break;
+		case COMPAT_WMT_IOCTL_PORT_NAME:
+			ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (unsigned long)compat_ptr(arg));
+			break;
+		case COMPAT_WMT_IOCTL_WMT_CFG_NAME:
+			ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (unsigned long)compat_ptr(arg));
+			break;
+		case COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD:
+			ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SEND_BGW_DS_CMD, (unsigned long)compat_ptr(arg));
+			break;
+		default: {
+			ret = WMT_unlocked_ioctl(filp, cmd, arg);
+			break;
+			}
+		}
+	return ret;
+}
+#endif
+static int WMT_open(struct inode *inode, struct file *file)
+{
+	long ret;
+
+	WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid);
+	ret = wait_event_timeout(gWmtInitWq, gWmtInitDone != 0, msecs_to_jiffies(WMT_DEV_INIT_TO_MS));
+	if (!ret) {
+		WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n",
+			      WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS));
+		return -EIO;
+	}
+
+	if (atomic_inc_return(&gWmtRefCnt) == 1)
+		WMT_INFO_FUNC("1st call\n");
+
+	return 0;
+}
+
+static int WMT_close(struct inode *inode, struct file *file)
+{
+	WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid);
+
+	if (atomic_dec_return(&gWmtRefCnt) == 0)
+		WMT_INFO_FUNC("last call\n");
+
+	return 0;
+}
+
+const struct file_operations gWmtFops = {
+	.open = WMT_open,
+	.release = WMT_close,
+	.read = WMT_read,
+	.write = WMT_write,
+/* .ioctl = WMT_ioctl, */
+	.unlocked_ioctl = WMT_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = WMT_compat_ioctl,
+#endif
+	.poll = WMT_poll,
+};
+
+void wmt_dev_bgw_desense_init(VOID)
+{
+	bgw_init_socket();
+}
+
+void wmt_dev_bgw_desense_deinit(VOID)
+{
+	bgw_destroy_netlink_kernel();
+}
+
+void wmt_dev_send_cmd_to_daemon(UINT32 cmd)
+{
+	send_command_to_daemon(cmd);
+}
+
+static int WMT_init(void)
+{
+	dev_t devID = MKDEV(gWmtMajor, 0);
+	INT32 cdevErr = -1;
+	INT32 ret = -1;
+
+	WMT_INFO_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE);
+	/* Prepare a UINT8 device */
+	/*static allocate chrdev */
+	gWmtInitDone = 0;
+	init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq);
+	stp_drv_init();
+
+	ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME);
+	if (ret) {
+		WMT_ERR_FUNC("fail to register chrdev\n");
+		return ret;
+	}
+	cdev_init(&gWmtCdev, &gWmtFops);
+	gWmtCdev.owner = THIS_MODULE;
+	cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM);
+	if (cdevErr) {
+		WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr);
+		goto error;
+	}
+	WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor);
+#if WMT_CREATE_NODE_DYNAMIC
+	wmt_class = class_create(THIS_MODULE, "stpwmt");
+	if (IS_ERR(wmt_class))
+		goto error;
+	wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt");
+	if (IS_ERR(wmt_dev))
+		goto error;
+#endif
+
+#if 0
+	pWmtDevCtx = wmt_drv_create();
+	if (!pWmtDevCtx) {
+		WMT_ERR_FUNC("wmt_drv_create() fails\n");
+		goto error;
+	}
+	ret = wmt_drv_init(pWmtDevCtx);
+	if (ret) {
+		WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret);
+		goto error;
+	}
+	WMT_INFO_FUNC("stp_btmcb_reg\n");
+	wmt_cdev_btmcb_reg();
+	ret = wmt_drv_start(pWmtDevCtx);
+	if (ret) {
+		WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret);
+		goto error;
+	}
+#endif
+	ret = wmt_lib_init();
+	if (ret) {
+		WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret);
+		goto error;
+	}
+#if CFG_WMT_DBG_SUPPORT
+	wmt_dev_dbg_setup();
+#endif
+
+#if CFG_WMT_PROC_FOR_AEE
+	wmt_dev_proc_for_aee_setup();
+#endif
+
+	WMT_INFO_FUNC("wmt_dev register thermal cb\n");
+	wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query);
+	wmt_dev_bgw_desense_init();
+	gWmtInitDone = 1;
+	wake_up(&gWmtInitWq);
+	osal_sleepable_lock_init(&g_es_lr_lock);
+	INIT_WORK(&gPwrOnOffWork, wmt_pwr_on_off_handler);
+#ifdef CONFIG_EARLYSUSPEND
+	register_early_suspend(&wmt_early_suspend_handler);
+	WMT_INFO_FUNC("register_early_suspend finished\n");
+#else
+	wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback;
+	ret = fb_register_client(&wmt_fb_notifier);
+	if (ret)
+		WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret);
+	else
+		WMT_INFO_FUNC("wmt register fb_notifier OK!\n");
+#endif
+	WMT_INFO_FUNC("success\n");
+	return 0;
+
+error:
+	wmt_lib_deinit();
+#if CFG_WMT_DBG_SUPPORT
+	wmt_dev_dbg_remove();
+#endif
+#if WMT_CREATE_NODE_DYNAMIC
+	if (!(IS_ERR(wmt_dev)))
+		device_destroy(wmt_class, devID);
+	if (!(IS_ERR(wmt_class))) {
+		class_destroy(wmt_class);
+		wmt_class = NULL;
+	}
+#endif
+
+	if (cdevErr == 0)
+		cdev_del(&gWmtCdev);
+
+	if (ret == 0) {
+		unregister_chrdev_region(devID, WMT_DEV_NUM);
+		gWmtMajor = -1;
+	}
+
+	WMT_ERR_FUNC("fail\n");
+
+	return -1;
+}
+
+static void WMT_exit(void)
+{
+	dev_t dev = MKDEV(gWmtMajor, 0);
+
+	osal_sleepable_lock_deinit(&g_es_lr_lock);
+#ifdef CONFIG_EARLYSUSPEND
+	unregister_early_suspend(&wmt_early_suspend_handler);
+	WMT_INFO_FUNC("unregister_early_suspend finished\n");
+#else
+	fb_unregister_client(&wmt_fb_notifier);
+#endif
+
+	wmt_dev_bgw_desense_deinit();
+
+	wmt_lib_register_thermal_ctrl_cb(NULL);
+
+	wmt_lib_deinit();
+
+#if CFG_WMT_DBG_SUPPORT
+	wmt_dev_dbg_remove();
+#endif
+
+#if CFG_WMT_PROC_FOR_AEE
+	wmt_dev_proc_for_aee_remove();
+#endif
+#if WMT_CREATE_NODE_DYNAMIC
+	if (wmt_dev) {
+		device_destroy(wmt_class, dev);
+		wmt_dev = NULL;
+	}
+	if (wmt_class) {
+		class_destroy(wmt_class);
+		wmt_class = NULL;
+	}
+#endif
+	cdev_del(&gWmtCdev);
+	unregister_chrdev_region(dev, WMT_DEV_NUM);
+	gWmtMajor = -1;
+
+	stp_drv_exit();
+
+	WMT_INFO_FUNC("done\n");
+}
+
+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE
+
+int mtk_wcn_soc_common_drv_init(void)
+{
+	return WMT_init();
+
+}
+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init);
+void mtk_wcn_soc_common_drv_exit(void)
+{
+	return WMT_exit();
+}
+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit);
+
+#else
+module_init(WMT_init);
+module_exit(WMT_exit);
+#endif
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("MediaTek Inc WCN");
+MODULE_DESCRIPTION("MTK WCN combo driver for WMT function");
+
+module_param(gWmtMajor, uint, 0);
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c
new file mode 100644
index 0000000000000..8d5c23732c1c7
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c
@@ -0,0 +1,610 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-EXP]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+
+#include <wmt_exp.h>
+#include <wmt_lib.h>
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+wmt_wlan_probe_cb mtk_wcn_wlan_probe = NULL;
+wmt_wlan_remove_cb mtk_wcn_wlan_remove = NULL;
+wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt = NULL;
+wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr = NULL;
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+OSAL_BIT_OP_VAR gBtWifiGpsState;
+OSAL_BIT_OP_VAR gGpsFmState;
+UINT32 gWifiProbed = 0;
+UINT32 gWmtDbgLvl = WMT_LOG_ERR;
+MTK_WCN_BOOL g_pwr_off_flag = MTK_WCN_BOOL_TRUE;
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId)
+{
+	P_OSAL_OP pOp;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	pSignal = &pOp->signal;
+
+	pOp->op.opId = opId;
+	pOp->op.au4OpData[0] = type;
+	if (WMTDRV_TYPE_WIFI == type)
+		pSignal->timeoutValue = 4000;
+		/*donot block system server/init/netd from longer than 5s, in case of ANR happens*/
+	else
+		pSignal->timeoutValue = (WMT_OPID_FUNC_ON == pOp->op.opId) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME;
+
+	WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]);
+
+	/*do not check return value, we will do this either way */
+	wmt_lib_host_awake_get();
+	/*wake up chip first */
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]);
+		wmt_lib_put_op_to_free_queue(pOp);
+		wmt_lib_host_awake_put();
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+	wmt_lib_host_awake_put();
+
+	if (MTK_WCN_BOOL_FALSE == bRet)
+		WMT_WARN_FUNC("OPID(%d) type(%d) fail\n", pOp->op.opId, pOp->op.au4OpData[0]);
+	else
+		WMT_WARN_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]);
+
+	return bRet;
+}
+
+#if WMT_EXP_HID_API_EXPORT
+MTK_WCN_BOOL _mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type)
+#else
+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type)
+#endif
+{
+	MTK_WCN_BOOL ret;
+
+	if (type == WMTDRV_TYPE_BT)
+		osal_printtimeofday("############ BT OFF ====>");
+
+	ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF);
+
+	if (type == WMTDRV_TYPE_BT)
+		osal_printtimeofday("############ BT OFF <====");
+
+	return ret;
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_func_off);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+MTK_WCN_BOOL _mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type)
+#else
+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type)
+#endif
+{
+	MTK_WCN_BOOL ret;
+
+	if (type == WMTDRV_TYPE_BT)
+		osal_printtimeofday("############ BT ON ====>");
+
+	ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON);
+
+	if (type == WMTDRV_TYPE_BT)
+		osal_printtimeofday(" ############BT ON <====");
+
+	return ret;
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_func_on);
+#endif
+
+VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type)
+{
+	if (on)
+		mtk_wcn_wmt_func_on(type);
+	else
+		mtk_wcn_wmt_func_off(type);
+}
+
+/*
+return value:
+enable/disable thermal sensor function: true(1)/false(0)
+read thermal sensor function:thermal value
+
+*/
+#if WMT_EXP_HID_API_EXPORT
+INT8 _mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType)
+#else
+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType)
+#endif
+{
+	P_OSAL_OP pOp;
+	P_WMT_OP pOpData;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+
+	/*parameter validation check */
+	if (WMTTHERM_MAX < eType || WMTTHERM_ENABLE > eType) {
+		WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType);
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	/*check if chip support thermal control function or not */
+	bRet = wmt_lib_is_therm_ctrl_support();
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		WMT_ERR_FUNC("thermal ctrl function not supported\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	pSignal = &pOp->signal;
+	pOpData = &pOp->op;
+	pOpData->opId = WMT_OPID_THERM_CTRL;
+	/*parameter fill */
+	pOpData->au4OpData[0] = eType;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+
+	WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]);
+
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]);
+		wmt_lib_put_op_to_free_queue(pOp);
+		return -1;
+	}
+
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]);
+		/*0xFF means read error occurs */
+		/*will return to function driver */
+		pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE;
+	} else {
+		WMT_INFO_FUNC("OPID(%d) type(%d) return(%d) ok\n\n",
+			      pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]);
+	}
+	/*return value will be put to lxop->op.au4OpData[1] */
+	WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08x)\n", eType, pOpData->au4OpData[1]);
+	return (INT8) pOpData->au4OpData[1];
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+ENUM_WMTHWVER_TYPE_T _mtk_wcn_wmt_hwver_get(VOID)
+#else
+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID)
+#endif
+{
+	/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */
+	/* TODO: how do we extend for new chip and newer revision? */
+	/* TODO: This way is hard to extend */
+	return wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER);
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+MTK_WCN_BOOL _mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType)
+#else
+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType)
+#endif
+{
+	P_OSAL_OP pOp;
+	P_WMT_OP pOpData;
+	MTK_WCN_BOOL bRet;
+	P_OSAL_SIGNAL pSignal;
+
+	if (WMTDSNS_MAX <= eType) {
+		WMT_ERR_FUNC("invalid desense control command (%d)\n", eType);
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	/*check if chip support thermal control function or not */
+	bRet = wmt_lib_is_dsns_ctrl_support();
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		WMT_ERR_FUNC("thermal ctrl function not supported\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	pSignal = &pOp->signal;
+	pOpData = &pOp->op;
+	pOpData->opId = WMT_OPID_DSNS;
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+	/*parameter fill */
+	if ((WMTDSNS_FM_DISABLE <= eType) && (WMTDSNS_FM_GPS_ENABLE >= eType)) {
+		pOpData->au4OpData[0] = WMTDRV_TYPE_FM;
+		pOpData->au4OpData[1] = eType;
+	}
+
+	WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]);
+
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]);
+		wmt_lib_put_op_to_free_queue(pOp);
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+
+	if (MTK_WCN_BOOL_FALSE == bRet)
+		WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]);
+	else
+		WMT_INFO_FUNC("OPID(%d) type(%d) ok\n\n", pOpData->opId, pOpData->au4OpData[0]);
+
+	return bRet;
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb)
+#else
+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb)
+#endif
+{
+	return (INT32) wmt_lib_msgcb_reg(eType, pCb);
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType)
+#else
+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType)
+#endif
+{
+	return (INT32) wmt_lib_msgcb_unreg(eType);
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb)
+#else
+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb)
+#endif
+{
+	wmt_lib_ps_set_sdio_psop(own_cb);
+	return 0;
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+INT32 _mtk_wcn_stp_wmt_sdio_host_awake(VOID)
+#else
+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID)
+#endif
+{
+	wmt_lib_ps_irq_cb();
+	return 0;
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake);
+#endif
+
+#if WMT_EXP_HID_API_EXPORT
+MTK_WCN_BOOL _mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason)
+#else
+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason)
+#endif
+{
+	P_OSAL_OP pOp = NULL;
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	P_OSAL_SIGNAL pSignal;
+
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_WARN_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	wmt_lib_set_host_assert_info(type, reason, 1);
+
+	pSignal = &pOp->signal;
+
+	pOp->op.opId = WMT_OPID_CMD_TEST;
+
+	pSignal->timeoutValue = MAX_EACH_WMT_CMD;
+	/*this test command should be run with usb cable connected, so no host awake is needed */
+	/* wmt_lib_host_awake_get(); */
+	pOp->op.au4OpData[0] = 0;
+
+	/*wake up chip first */
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed,assert flow abort\n");
+		wmt_lib_put_op_to_free_queue(pOp);
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	bRet = wmt_lib_put_act_op(pOp);
+	ENABLE_PSM_MONITOR();
+
+	/* wmt_lib_host_awake_put(); */
+	WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n",
+		      pOp->op.opId,
+		      pOp->op.au4OpData[0],
+		      pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed");
+
+	return bRet;
+}
+#if !WMT_EXP_HID_API_EXPORT
+EXPORT_SYMBOL(mtk_wcn_wmt_assert);
+#endif
+
+INT8 mtk_wcn_wmt_co_clock_flag_get(void)
+{
+	return wmt_lib_co_clock_get();
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_co_clock_flag_get);
+
+INT32 mtk_wcn_wmt_system_state_reset(void)
+{
+	osal_memset(&gBtWifiGpsState, 0, osal_sizeof(gBtWifiGpsState));
+	osal_memset(&gGpsFmState, 0, osal_sizeof(gGpsFmState));
+
+	return 0;
+}
+
+INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo)
+{
+	INT32 iRet = -1;
+
+	if (!pWmtWlanCbInfo) {
+		WMT_ERR_FUNC("wlan cb info in null!\n");
+		return -1;
+	}
+
+	WMT_INFO_FUNC("wmt wlan cb register\n");
+	mtk_wcn_wlan_probe = pWmtWlanCbInfo->wlan_probe_cb;
+	mtk_wcn_wlan_remove = pWmtWlanCbInfo->wlan_remove_cb;
+	mtk_wcn_wlan_bus_tx_cnt = pWmtWlanCbInfo->wlan_bus_cnt_get_cb;
+	mtk_wcn_wlan_bus_tx_cnt_clr = pWmtWlanCbInfo->wlan_bus_cnt_clr_cb;
+
+	if (gWifiProbed) {
+		WMT_INFO_FUNC("wlan has been done power on,call probe directly\n");
+		iRet = (*mtk_wcn_wlan_probe) ();
+		if (!iRet) {
+			WMT_INFO_FUNC("call wlan probe OK when do wlan register to wmt\n");
+			gWifiProbed = 0;
+		} else {
+			WMT_ERR_FUNC("call wlan probe fail(%d) when do wlan register to wmt\n", iRet);
+			return -2;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_reg);
+
+INT32 mtk_wcn_wmt_wlan_unreg(void)
+{
+	WMT_INFO_FUNC("wmt wlan cb unregister\n");
+	mtk_wcn_wlan_probe = NULL;
+	mtk_wcn_wlan_remove = NULL;
+	mtk_wcn_wlan_bus_tx_cnt = NULL;
+	mtk_wcn_wlan_bus_tx_cnt_clr = NULL;
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_unreg);
+
+MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value)
+{
+	g_pwr_off_flag = value;
+	if (g_pwr_off_flag)
+		WMT_DBG_FUNC("enable connsys power off flag\n");
+	else
+		WMT_INFO_FUNC("disable connsys power off, maybe need trigger coredump!\n");
+	return g_pwr_off_flag;
+}
+EXPORT_SYMBOL(mtk_wcn_set_connsys_power_off_flag);
+
+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+VOID mtk_wcn_wmt_exp_init(void)
+{
+	MTK_WCN_WMT_EXP_CB_INFO wmtExpCb = {
+
+		.wmt_func_on_cb = _mtk_wcn_wmt_func_on,
+		.wmt_func_off_cb = _mtk_wcn_wmt_func_off,
+		.wmt_therm_ctrl_cb = _mtk_wcn_wmt_therm_ctrl,
+		.wmt_hwver_get_cb = _mtk_wcn_wmt_hwver_get,
+		.wmt_dsns_ctrl_cb = _mtk_wcn_wmt_dsns_ctrl,
+		.wmt_msgcb_reg_cb = _mtk_wcn_wmt_msgcb_reg,
+		.wmt_msgcb_unreg_cb = _mtk_wcn_wmt_msgcb_unreg,
+		.wmt_sdio_op_reg_cb = _mtk_wcn_stp_wmt_sdio_op_reg,
+		.wmt_sdio_host_awake_cb = _mtk_wcn_stp_wmt_sdio_host_awake,
+		.wmt_assert_cb = _mtk_wcn_wmt_assert
+	};
+
+	mtk_wcn_wmt_exp_cb_reg(&wmtExpCb);
+}
+
+VOID mtk_wcn_wmt_exp_deinit(void)
+{
+	mtk_wcn_wmt_exp_cb_unreg();
+}
+#ifdef CONFIG_MTK_COMBO_ANT
+/*
+	ctrlId: get ram code status opId or ram code download opId
+	pBuf: pointer to ANT ram code
+	length: total length of ANT ram code
+*/
+ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf,
+						 UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq)
+{
+	ENUM_WMT_ANT_RAM_STATUS eRet = 0;
+	P_OSAL_OP pOp = NULL;
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
+	P_OSAL_SIGNAL pSignal;
+
+	/*1. parameter validation check */
+	/*for WMT_ANT_RAM_GET_STATUS, ignore pBuf and length */
+	/*for WMT_ANT_RAM_DOWNLOAD,
+	   pBuf must not be NULL, kernel space memory pointer
+	   length must be large than 0 */
+
+	if ((WMT_ANT_RAM_GET_STATUS > ctrlId) || (WMT_ANT_RAM_CTRL_MAX <= ctrlId)) {
+		WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId);
+		eRet = WMT_ANT_RAM_PARA_ERR;
+		return eRet;
+	}
+
+	if ((WMT_ANT_RAM_DOWNLOAD == ctrlId) &&
+	    ((NULL == pBuf) ||
+	     (0 >= length) ||
+	     (1000 < length) || (seq >= WMT_ANT_RAM_SEQ_MAX) || (seq < WMT_ANT_RAM_START_PKT))) {
+		eRet = WMT_ANT_RAM_PARA_ERR;
+		WMT_ERR_FUNC
+		    ("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x),seq(%d) .\n",
+		     ctrlId, pBuf, length, seq);
+		return eRet;
+	}
+	/*get WMT opId */
+	pOp = wmt_lib_get_free_op();
+	if (!pOp) {
+		WMT_DBG_FUNC("get_free_lxop fail\n");
+		return MTK_WCN_BOOL_FALSE;
+	}
+
+	pSignal = &pOp->signal;
+	pSignal->timeoutValue =
+	    (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD;
+
+	pOp->op.opId =
+	    (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? WMT_OPID_ANT_RAM_DOWN : WMT_OPID_ANT_RAM_STA_GET;
+	pOp->op.au4OpData[0] = (size_t) pBuf;
+	pOp->op.au4OpData[1] = length;
+	pOp->op.au4OpData[2] = seq;
+
+
+	/*disable PSM monitor */
+	if (DISABLE_PSM_MONITOR()) {
+		WMT_ERR_FUNC("wake up failed\n");
+		wmt_lib_put_op_to_free_queue(pOp);
+		return MTK_WCN_BOOL_FALSE;
+	}
+	/*wakeup wmtd thread */
+	bRet = wmt_lib_put_act_op(pOp);
+
+	/*enable PSM monitor */
+	ENABLE_PSM_MONITOR();
+
+	WMT_DBG_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n",
+		      pOp->op.opId,
+		      bRet,
+		      pOp->op.au4OpData[2], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed");
+
+	/*check return value and return result */
+	if (MTK_WCN_BOOL_FALSE == bRet) {
+		eRet = WMT_ANT_RAM_OP_ERR;
+	} else {
+		eRet = (WMT_ANT_RAM_DOWNLOAD == ctrlId) ?
+		    WMT_ANT_RAM_DOWN_OK :
+		    ((1 == pOp->op.au4OpData[2]) ? WMT_ANT_RAM_EXIST : WMT_ANT_RAM_NOT_EXIST);
+	}
+
+	return eRet;
+
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_ant_ram_ctrl);
+#endif
+
+#endif
+VOID mtk_wcn_wmt_set_wifi_ver(UINT32 Value)
+{
+	wmt_lib_soc_set_wifiver(Value);
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_set_wifi_ver);
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile
new file mode 100644
index 0000000000000..eb37baf87b025
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile
@@ -0,0 +1,27 @@
+ifeq ($(CONFIG_MTK_COMBO), y)
+
+ccflags-y += \
+	-I$(src)/../../linux/include \
+	-I$(src)/../../linux/pri/include \
+	-I$(src)/../../core/include \
+	-I$(src)/../../include \
+	-I$(src)/../include \
+	-I$(src)/../../../common_detect \
+	-I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach \
+	-DMTK_BT_HCI=1
+
+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1
+
+ifeq ($(CONFIG_MTK_TC1_FEATURE), y)
+    ccflags-y += -DCFG_TC1_FEATURE=1
+else
+    ccflags-y += -DCFG_TC1_FEATURE=0
+endif
+
+obj-y += osal.o \
+         bgw_desense.o \
+         wmt_idc.o
+obj-$(CONFIG_MTK_COMBO_BT)		+= stp_chrdev_bt.o
+obj-$(CONFIG_MTK_COMBO_WIFI)	+= wmt_chrdev_wifi.o
+
+endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c
new file mode 100644
index 0000000000000..11e45aa130872
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c
@@ -0,0 +1,153 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <linux/version.h>
+#include <linux/netlink.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/genetlink.h>
+#include "bgw_desense.h"
+
+static struct sock *g_nl_sk;
+/* static struct sockaddr_nl src_addr, des_addr; */
+/* static struct iovec iov; */
+static int pid;
+/* static struct msghdr msg; */
+
+void bgw_destroy_netlink_kernel(void)
+{
+	if (g_nl_sk != NULL) {
+		/* sock_release(g_nl_sk->sk_socket); */
+		netlink_kernel_release(g_nl_sk);
+		MSG("release socket\n");
+		return;
+	}
+	ERR("no socket yet\n");
+}
+
+void send_command_to_daemon(const int command /*struct sk_buff *skb */)
+{
+/*
+	struct iphdr *iph;
+	struct ethhdr *ehdr;
+	*/
+	struct nlmsghdr *nlh;
+	struct sk_buff *nl_skb;
+	int res;
+
+	MSG("here we will send command to native daemon\n");
+/*	if(skb == NULL)
+	{
+		ERR("invalid sk_buff\n");
+		return;
+	}
+*/
+	if (!g_nl_sk) {
+		ERR("invalid socket\n");
+		return;
+	}
+	if (pid == 0) {
+		ERR("invalid native process pid\n");
+		return;
+	}
+	/*alloc data buffer for sending to native */
+	/*malloc data space at least 1500 bytes, which is ethernet data length */
+	nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC);
+	if (nl_skb == NULL) {
+		ERR("malloc skb error\n");
+		return;
+	}
+	MSG("malloc data space done\n");
+	/*
+	   ehdr = eth_hdr(skb);
+	   iph = ip_hdr(skb);
+	 */
+
+/* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */
+	nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0);
+	if (nlh == NULL) {
+		MSG("nlh is NULL\n");
+		kfree_skb(nl_skb);
+		return;
+	}
+	NETLINK_CB(nl_skb).portid = 0;
+
+/* memcpy(NLMSG_DATA(nlh), ACK, 5); */
+	*(char *)NLMSG_DATA(nlh) = command;
+	res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT);
+	if (res == 0) {
+		MSG("send to user space process error\n");
+		return;
+	}
+	ERR("send to user space process done, data length = %d\n", res);
+}
+
+static void nl_data_handler(struct sk_buff *__skb)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	int i;
+	int len;
+	char str[128];
+
+	MSG("we got netlink message\n");
+	len = NLMSG_SPACE(MAX_NL_MSG_LEN);
+	skb = skb_get(__skb);
+	if (skb == NULL)
+		ERR("skb_get return NULL");
+	if (skb->len >= NLMSG_SPACE(0)) {	/*presume there is 5byte payload at leaset */
+		MSG("length is enough\n");
+		nlh = nlmsg_hdr(skb);	/* point to data which include in skb */
+		memcpy(str, NLMSG_DATA(nlh), sizeof(str));
+		for (i = 0; i < 3; i++)
+			MSG("str[%d = %c]", i, str[i]);
+		MSG("str[0] = %d, str[1] = %d, str[2] = %d\n", str[0], str[1], str[2]);
+		if (str[0] == 'B' && str[1] == 'G' && str[2] == 'W') {
+			MSG("got native daemon init command, record it's pid\n");
+			pid = nlh->nlmsg_pid;	/*record the native process PID */
+			MSG("native daemon pid is %d\n", pid);
+		} else {
+			ERR("this is not BGW message, ignore it\n");
+			return;
+		}
+	} else {
+		ERR("not engouth data length\n");
+		return;
+	}
+
+	kfree_skb(skb);
+
+	send_command_to_daemon(ACK);
+}
+
+int bgw_init_socket(void)
+{
+	struct netlink_kernel_cfg cfg;
+
+	memset(&cfg, 0, sizeof(cfg));
+	cfg.input = nl_data_handler;
+
+	g_nl_sk = __netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg);
+
+	if (g_nl_sk == NULL) {
+		ERR("netlink_kernel_create error\n");
+		return -1;
+	}
+	MSG("netlink_kernel_create ok\n");
+	return 0;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c
new file mode 100644
index 0000000000000..959b68de24311
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c
@@ -0,0 +1,1211 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "osal_typedef.h"
+#include "osal.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
+static UINT16 const crc16_table[256] = {
+	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*string operations*/
+_osal_inline_ UINT32 osal_strlen(const char *str)
+{
+	return strlen(str);
+}
+
+_osal_inline_ INT32 osal_strcmp(const char *dst, const char *src)
+{
+	return strcmp(dst, src);
+}
+
+_osal_inline_ INT32 osal_strncmp(const char *dst, const char *src, UINT32 len)
+{
+	return strncmp(dst, src, len);
+}
+
+_osal_inline_ char *osal_strcpy(char *dst, const char *src)
+{
+	return strcpy(dst, src);
+}
+
+_osal_inline_ char *osal_strncpy(char *dst, const char *src, UINT32 len)
+{
+	return strncpy(dst, src, len);
+}
+
+_osal_inline_ char *osal_strcat(char *dst, const char *src)
+{
+	return strcat(dst, src);
+}
+
+_osal_inline_ char *osal_strncat(char *dst, const char *src, UINT32 len)
+{
+	return strncat(dst, src, len);
+}
+
+_osal_inline_ char *osal_strchr(const char *str, UINT8 c)
+{
+	return strchr(str, c);
+}
+
+_osal_inline_ char *osal_strsep(char **str, const char *c)
+{
+	return strsep(str, c);
+}
+
+_osal_inline_ int osal_strtol(const char *str, UINT32 adecimal, long *res)
+{
+	return kstrtol(str, adecimal, res);
+}
+
+_osal_inline_ char *osal_strstr(char *str1, const char *str2)
+{
+	return strstr(str1, str2);
+}
+
+INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...)
+{
+	INT32 iRet = 0;
+	va_list args;
+
+	/*va_start(args, fmt); */
+	va_start(args, fmt);
+	/*iRet = snprintf(buf, len, fmt, args); */
+	iRet = vsnprintf(buf, len, fmt, args);
+	va_end(args);
+
+	return iRet;
+}
+
+INT32 osal_err_print(const char *str, ...)
+{
+	va_list args;
+	char tempString[DBG_LOG_STR_SIZE];
+
+	va_start(args, str);
+	vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args);
+	va_end(args);
+
+	pr_err("%s", tempString);
+
+	return 0;
+}
+
+INT32 osal_dbg_print(const char *str, ...)
+{
+	va_list args;
+	char tempString[DBG_LOG_STR_SIZE];
+
+	va_start(args, str);
+	vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args);
+	va_end(args);
+
+	pr_debug("%s", tempString);
+
+	return 0;
+}
+
+INT32 osal_warn_print(const char *str, ...)
+{
+	va_list args;
+	char tempString[DBG_LOG_STR_SIZE];
+
+	va_start(args, str);
+	vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args);
+	va_end(args);
+
+	pr_warn("%s", tempString);
+
+	return 0;
+}
+
+INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line)
+{
+	if (!expr) {
+		pr_warn("%s (%d)\n", file, line);
+		/*BUG_ON(!expr); */
+#ifdef CFG_COMMON_GPIO_DBG_PIN
+/* package this part */
+		mt_set_gpio_out(GPIO70, GPIO_OUT_ZERO);
+		pr_warn("toggle GPIO70\n");
+		udelay(10);
+		mt_set_gpio_out(GPIO70, GPIO_OUT_ONE);
+#endif
+		return 1;
+	}
+	return 0;
+
+}
+
+INT32 osal_dbg_assert_aee(const char *module, const char *detail_description)
+{
+	osal_err_print("[WMT-ASSERT]" "[E][Module]:%s, [INFO]%s\n", module, detail_description);
+
+#ifdef WMT_PLAT_ALPS
+	/* aee_kernel_warning(module,detail_description); */
+	aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_WCN_ISSUE_INFO, module, detail_description);
+#endif
+	return 0;
+}
+
+INT32 osal_sprintf(char *str, const char *format, ...)
+{
+	INT32 iRet = 0;
+	va_list args;
+
+	va_start(args, format);
+	iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args);
+	va_end(args);
+
+	return iRet;
+}
+
+_osal_inline_ VOID *osal_malloc(UINT32 size)
+{
+	return vmalloc(size);
+}
+
+_osal_inline_ VOID osal_free(const VOID *dst)
+{
+	vfree(dst);
+}
+
+_osal_inline_ VOID *osal_memset(VOID *buf, INT32 i, UINT32 len)
+{
+	return memset(buf, i, len);
+}
+
+_osal_inline_ VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len)
+{
+#ifdef CONFIG_MTK_WCN_ARM64
+	char *tmp;
+	const char *s;
+	size_t i;
+
+	tmp = dst;
+	s = src;
+	for (i = 0; i < len; i++)
+		tmp[i] = s[i];
+
+	return dst;
+
+#else
+	return memcpy(dst, src, len);
+#endif
+}
+
+_osal_inline_ INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len)
+{
+	return memcmp(buf1, buf2, len);
+}
+
+_osal_inline_ UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length)
+{
+	UINT16 crc = 0;
+	UINT32 i = 0;
+
+	/* FIXME: Add STP checksum feature */
+	crc = 0;
+	for (i = 0; i < length; i++, buffer++)
+		crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff];
+
+	return crc;
+}
+
+_osal_inline_ VOID osal_thread_show_stack(P_OSAL_THREAD pThread)
+{
+	return show_stack(pThread->pThread, NULL);
+}
+
+/*
+  *OSAL layer Thread Opeartion related APIs
+  *
+  *
+*/
+_osal_inline_ INT32 osal_thread_create(P_OSAL_THREAD pThread)
+{
+	pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName);
+	if (NULL == pThread->pThread)
+		return -1;
+
+	return 0;
+}
+
+_osal_inline_ INT32 osal_thread_run(P_OSAL_THREAD pThread)
+{
+	if (pThread->pThread) {
+		wake_up_process(pThread->pThread);
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+_osal_inline_ INT32 osal_thread_stop(P_OSAL_THREAD pThread)
+{
+	INT32 iRet;
+
+	if ((pThread) && (pThread->pThread)) {
+		iRet = kthread_stop(pThread->pThread);
+		/* pThread->pThread = NULL; */
+		return iRet;
+	}
+	return -1;
+}
+
+_osal_inline_ INT32 osal_thread_should_stop(P_OSAL_THREAD pThread)
+{
+	if ((pThread) && (pThread->pThread))
+		return kthread_should_stop();
+	else
+		return 1;
+
+}
+
+_osal_inline_ INT32
+osal_thread_wait_for_event(P_OSAL_THREAD pThread, P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker)
+{
+	/*  P_DEV_WMT pDevWmt;*/
+
+	if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) {
+		/* pDevWmt = (P_DEV_WMT)(pThread->pThreadData);*/
+		return wait_event_interruptible(pEvent->waitQueue, (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) || */
+									   osal_thread_should_stop(pThread)
+									   || (*pChecker) (pThread)));
+	}
+	return -1;
+}
+
+_osal_inline_ INT32 osal_thread_destroy(P_OSAL_THREAD pThread)
+{
+	if (pThread && (pThread->pThread)) {
+		kthread_stop(pThread->pThread);
+		pThread->pThread = NULL;
+	}
+	return 0;
+}
+
+/*
+  *OSAL layer Signal Opeartion related APIs
+  *initialization
+  *wait for signal
+  *wait for signal timerout
+  *raise signal
+  *destroy a signal
+  *
+*/
+
+_osal_inline_ INT32 osal_signal_init(P_OSAL_SIGNAL pSignal)
+{
+	if (pSignal) {
+		init_completion(&pSignal->comp);
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+_osal_inline_ INT32 osal_wait_for_signal(P_OSAL_SIGNAL pSignal)
+{
+	if (pSignal) {
+		wait_for_completion_interruptible(&pSignal->comp);
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+_osal_inline_ INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal)
+{
+	/* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */
+	/* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS.
+	 * Avoid using *interruptible" version in order to complete our jobs, such
+	 * as function off gracefully.
+	 */
+	return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue));
+}
+
+_osal_inline_ INT32 osal_raise_signal(P_OSAL_SIGNAL pSignal)
+{
+	/* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */
+	complete(&pSignal->comp);
+	return 0;
+}
+
+_osal_inline_ INT32 osal_signal_deinit(P_OSAL_SIGNAL pSignal)
+{
+	/* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */
+	pSignal->timeoutValue = 0;
+	return 0;
+}
+
+/*
+  *OSAL layer Event Opeartion related APIs
+  *initialization
+  *wait for signal
+  *wait for signal timerout
+  *raise signal
+  *destroy a signal
+  *
+*/
+
+INT32 osal_event_init(P_OSAL_EVENT pEvent)
+{
+	init_waitqueue_head(&pEvent->waitQueue);
+
+	return 0;
+}
+
+INT32 osal_wait_for_event(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa)
+{
+	return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa));
+}
+
+INT32 osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa)
+{
+	return wait_event_interruptible_timeout(pEvent->waitQueue, condition(cond_pa),
+						msecs_to_jiffies(pEvent->timeoutValue));
+}
+
+INT32 osal_trigger_event(P_OSAL_EVENT pEvent)
+{
+	INT32 ret = 0;
+
+	wake_up_interruptible(&pEvent->waitQueue);
+	return ret;
+}
+
+INT32 osal_event_deinit(P_OSAL_EVENT pEvent)
+{
+	return 0;
+}
+
+_osal_inline_ long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset)
+{
+	UINT32 ms = pEvent->timeoutValue;
+
+	if (ms != 0) {
+		return wait_event_interruptible_timeout(pEvent->waitQueue, test_bit(bitOffset, pState),
+							msecs_to_jiffies(ms));
+	} else {
+		return wait_event_interruptible(pEvent->waitQueue, test_bit(bitOffset, pState));
+	}
+
+}
+
+_osal_inline_ long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset)
+{
+	UINT32 ms = pEvent->timeoutValue;
+
+	if (ms != 0) {
+		return wait_event_interruptible_timeout(pEvent->waitQueue, !test_bit(bitOffset, pState),
+							msecs_to_jiffies(ms));
+	} else {
+		return wait_event_interruptible(pEvent->waitQueue, !test_bit(bitOffset, pState));
+	}
+
+}
+
+/*
+  *bit test and set/clear operations APIs
+  *
+  *
+*/
+#if    OS_BIT_OPS_SUPPORT
+#define osal_bit_op_lock(x)
+#define osal_bit_op_unlock(x)
+#else
+
+_osal_inline_ INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock)
+{
+
+	return 0;
+}
+
+_osal_inline_ INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock)
+{
+
+	return 0;
+}
+#endif
+_osal_inline_ INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+	osal_bit_op_lock(&(pData->opLock));
+	clear_bit(bitOffset, &pData->data);
+	osal_bit_op_unlock(&(pData->opLock));
+	return 0;
+}
+
+_osal_inline_ INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+	osal_bit_op_lock(&(pData->opLock));
+	set_bit(bitOffset, &pData->data);
+	osal_bit_op_unlock(&(pData->opLock));
+	return 0;
+}
+
+_osal_inline_ INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+	UINT32 iRet = 0;
+
+	osal_bit_op_lock(&(pData->opLock));
+	iRet = test_bit(bitOffset, &pData->data);
+	osal_bit_op_unlock(&(pData->opLock));
+	return iRet;
+}
+
+_osal_inline_ INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+	UINT32 iRet = 0;
+
+	osal_bit_op_lock(&(pData->opLock));
+	iRet = test_and_clear_bit(bitOffset, &pData->data);
+	osal_bit_op_unlock(&(pData->opLock));
+	return iRet;
+
+}
+
+_osal_inline_ INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+	UINT32 iRet = 0;
+
+	osal_bit_op_lock(&(pData->opLock));
+	iRet = test_and_set_bit(bitOffset, &pData->data);
+	osal_bit_op_unlock(&(pData->opLock));
+	return iRet;
+}
+
+/*
+  *tiemr operations APIs
+  *create
+  *stop
+  * modify
+  *create
+  *delete
+  *
+*/
+
+INT32 osal_timer_create(P_OSAL_TIMER pTimer)
+{
+	struct timer_list *timer = &pTimer->timer;
+
+	/*init_timer(timer);
+	timer->function = pTimer->timeoutHandler;
+	timer->data = (unsigned long)pTimer->timeroutHandlerData;*/
+	timer_setup(timer,pTimer->timeoutHandler,0);
+	return 0;
+}
+
+INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms)
+{
+
+	struct timer_list *timer = &pTimer->timer;
+
+	timer->expires = jiffies + (ms / (1000 / HZ));
+	add_timer(timer);
+	return 0;
+}
+
+INT32 osal_timer_stop(P_OSAL_TIMER pTimer)
+{
+	struct timer_list *timer = &pTimer->timer;
+
+	del_timer(timer);
+	return 0;
+}
+
+INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer)
+{
+	struct timer_list *timer = &pTimer->timer;
+
+	del_timer_sync(timer);
+	return 0;
+}
+
+INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms)
+{
+
+	mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ));
+	return 0;
+}
+
+INT32 _osal_fifo_init(OSAL_FIFO *pFifo, UINT8 *buf, UINT32 size)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = -1;
+
+	if (!pFifo) {
+		pr_err("pFifo must be !NULL\n");
+		return -1;
+	}
+	if (pFifo->pFifoBody) {
+		pr_err("pFifo->pFifoBody must be NULL\n");
+		pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody);
+		return -1;
+	}
+	fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC);
+	if (!buf) {
+		/*fifo's buffer is not ready, we allocate automatically */
+		ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC);
+	} else {
+		if (is_power_of_2(size)) {
+			kfifo_init(fifo, buf, size);
+			ret = 0;
+		} else {
+			kfifo_free(fifo);
+			fifo = NULL;
+			ret = -1;
+		}
+	}
+
+	pFifo->pFifoBody = fifo;
+	return (ret < 0) ? (-1) : (0);
+}
+
+INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo)
+{
+	struct kfifo *fifo = NULL;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo)
+		kfifo_free(fifo);
+
+	return 0;
+}
+
+INT32 _osal_fifo_size(OSAL_FIFO *pFifo)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = 0;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo)
+		ret = kfifo_size(fifo);
+
+	return ret;
+}
+
+/*returns unused bytes in fifo*/
+INT32 _osal_fifo_avail_size(OSAL_FIFO *pFifo)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = 0;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo)
+		ret = kfifo_avail(fifo);
+
+	return ret;
+}
+
+/*returns used bytes in fifo*/
+INT32 _osal_fifo_len(OSAL_FIFO *pFifo)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = 0;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo)
+		ret = kfifo_len(fifo);
+
+	return ret;
+}
+
+INT32 _osal_fifo_is_empty(OSAL_FIFO *pFifo)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = 0;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo)
+		ret = kfifo_is_empty(fifo);
+
+	return ret;
+}
+
+INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = 0;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo)
+		ret = kfifo_is_full(fifo);
+
+	return ret;
+}
+
+INT32 _osal_fifo_data_in(OSAL_FIFO *pFifo, const VOID *buf, UINT32 len)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = 0;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) {
+		ret = kfifo_in(fifo, buf, len);
+	} else {
+		pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n",
+		       __func__, len, _osal_fifo_avail_size(pFifo), buf);
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+INT32 _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, UINT32 len)
+{
+	struct kfifo *fifo = NULL;
+	INT32 ret = 0;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo && buf && (len <= _osal_fifo_len(pFifo))) {
+		ret = kfifo_out(fifo, buf, len);
+	} else {
+		pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n",
+		       __func__, len, _osal_fifo_len(pFifo), buf);
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+INT32 _osal_fifo_reset(OSAL_FIFO *pFifo)
+{
+	struct kfifo *fifo = NULL;
+
+	if (!pFifo || !pFifo->pFifoBody) {
+		pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__);
+		return -1;
+	}
+
+	fifo = (struct kfifo *)pFifo->pFifoBody;
+
+	if (fifo)
+		kfifo_reset(fifo);
+
+	return 0;
+}
+
+INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size)
+{
+	if (!pFifo) {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		return -1;
+	}
+
+	pFifo->FifoInit = _osal_fifo_init;
+	pFifo->FifoDeInit = _osal_fifo_deinit;
+	pFifo->FifoSz = _osal_fifo_size;
+	pFifo->FifoAvailSz = _osal_fifo_avail_size;
+	pFifo->FifoLen = _osal_fifo_len;
+	pFifo->FifoIsEmpty = _osal_fifo_is_empty;
+	pFifo->FifoIsFull = _osal_fifo_is_full;
+	pFifo->FifoDataIn = _osal_fifo_data_in;
+	pFifo->FifoDataOut = _osal_fifo_data_out;
+	pFifo->FifoReset = _osal_fifo_reset;
+
+	if (NULL != pFifo->pFifoBody) {
+		pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__);
+		pFifo->FifoDeInit(pFifo->pFifoBody);
+		pFifo->pFifoBody = NULL;
+	}
+
+	pFifo->FifoInit(pFifo, buffer, size);
+
+	return 0;
+}
+
+VOID osal_fifo_deinit(P_OSAL_FIFO pFifo)
+{
+	if (pFifo)
+		pFifo->FifoDeInit(pFifo);
+	else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		return;
+	}
+	kfree(pFifo->pFifoBody);
+}
+
+INT32 osal_fifo_reset(P_OSAL_FIFO pFifo)
+{
+	INT32 ret = -1;
+
+	if (pFifo) {
+		ret = pFifo->FifoReset(pFifo);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = -1;
+	}
+	return ret;
+}
+
+UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size)
+{
+	UINT32 ret = 0;
+
+	if (pFifo) {
+		ret = pFifo->FifoDataIn(pFifo, buffer, size);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size)
+{
+	UINT32 ret = 0;
+
+	if (pFifo) {
+		ret = pFifo->FifoDataOut(pFifo, buffer, size);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+UINT32 osal_fifo_len(P_OSAL_FIFO pFifo)
+{
+	UINT32 ret = 0;
+
+	if (pFifo) {
+		ret = pFifo->FifoLen(pFifo);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo)
+{
+	UINT32 ret = 0;
+
+	if (pFifo) {
+		ret = pFifo->FifoSz(pFifo);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo)
+{
+	UINT32 ret = 0;
+
+	if (pFifo) {
+		ret = pFifo->FifoAvailSz(pFifo);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo)
+{
+	UINT32 ret = 0;
+
+	if (pFifo) {
+		ret = pFifo->FifoIsEmpty(pFifo);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo)
+{
+	UINT32 ret = 0;
+
+	if (pFifo) {
+		ret = pFifo->FifoIsFull(pFifo);
+	} else {
+		pr_err("%s:pFifo = NULL, error\n", __func__);
+		ret = 0;
+	}
+	return ret;
+}
+
+INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock)
+{
+	if (!pLock)
+		return -1;
+
+	#ifdef CONFIG_PM_WAKELOCKS
+	wakeup_source_init(&pLock->wake_lock, pLock->name);
+	#else
+	wake_lock_init(&pLock->wake_lock, WAKE_LOCK_SUSPEND, pLock->name);
+	#endif
+	return 0;
+}
+
+INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock)
+{
+	if (!pLock)
+		return -1;
+
+	#ifdef CONFIG_PM_WAKELOCKS
+	wakeup_source_trash(&pLock->wake_lock);
+	#else
+	wake_lock_destroy(&pLock->wake_lock);
+	#endif
+	return 0;
+}
+
+INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock)
+{
+	if (!pLock)
+		return -1;
+
+	#ifdef CONFIG_PM_WAKELOCKS
+	__pm_stay_awake(&pLock->wake_lock);
+	#else
+	wake_lock(&pLock->wake_lock);
+	#endif
+
+	return 0;
+}
+
+INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock)
+{
+	if (!pLock)
+		return -1;
+
+	#ifdef CONFIG_PM_WAKELOCKS
+	__pm_relax(&pLock->wake_lock);
+	#else
+	wake_unlock(&pLock->wake_lock);
+	#endif
+
+	return 0;
+
+}
+
+INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock)
+{
+	INT32 count = 0;
+
+	if (!pLock)
+		return -1;
+
+	#ifdef CONFIG_PM_WAKELOCKS
+	count = pLock->wake_lock.active;
+	#else
+	count = wake_lock_active(&pLock->wake_lock);
+	#endif
+	return count;
+}
+
+/*
+  *sleepable lock operations APIs
+  *init
+  *lock
+  *unlock
+  *destroy
+  *
+*/
+
+#if !defined(CONFIG_PROVE_LOCKING)
+INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+	spin_lock_init(&(pUSL->lock));
+	return 0;
+}
+#endif
+
+INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+	spin_lock_irqsave(&(pUSL->lock), pUSL->flag);
+	return 0;
+}
+
+INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+	spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag);
+	return 0;
+}
+
+INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+	return 0;
+}
+
+/*
+  *unsleepable operations APIs
+  *init
+  *lock
+  *unlock
+  *destroy
+
+  *
+*/
+
+#if !defined(CONFIG_PROVE_LOCKING)
+INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+	mutex_init(&pSL->lock);
+	return 0;
+}
+#endif
+
+INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+	return mutex_lock_killable(&pSL->lock);
+}
+
+INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+	mutex_unlock(&pSL->lock);
+	return 0;
+}
+
+INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+	mutex_destroy(&pSL->lock);
+	return 0;
+}
+
+INT32 osal_sleep_ms(UINT32 ms)
+{
+	msleep(ms);
+	return 0;
+}
+
+INT32 osal_udelay(UINT32 us)
+{
+	udelay(us);
+	return 0;
+}
+
+INT32 osal_gettimeofday(PINT32 sec, PINT32 usec)
+{
+	INT32 ret = 0;
+	struct timeval now;
+
+	do_gettimeofday(&now);
+
+	if (sec != NULL)
+		*sec = now.tv_sec;
+	else
+		ret = -1;
+
+	if (usec != NULL)
+		*usec = now.tv_usec;
+	else
+		ret = -1;
+
+	return ret;
+}
+
+INT32 osal_printtimeofday(const PUINT8 prefix)
+{
+	INT32 ret;
+	INT32 sec;
+	INT32 usec;
+
+	ret = osal_gettimeofday(&sec, &usec);
+	ret += osal_dbg_print("%s>sec=%d, usec=%d\n", prefix, sec, usec);
+
+	return ret;
+}
+
+VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, const UINT32 len, const UINT32 limit)
+{
+	INT32 k;
+	UINT32 dump_len;
+
+	pr_warn("start of dump>[%s] len=%d, limit=%d,", title, len, limit);
+
+	dump_len = ((0 != limit) && (len > limit)) ? limit : len;
+#if 0
+	if (limit != 0)
+		len = (len > limit) ? (limit) : (len);
+
+#endif
+
+	for (k = 0; k < dump_len; k++) {
+		if ((k != 0) && (k % 16 == 0))
+			pr_cont("\n");
+		pr_cont("0x%02x ", buf[k]);
+	}
+	pr_warn("<end of dump\n");
+}
+
+UINT32 osal_op_get_id(P_OSAL_OP pOp)
+{
+	return (pOp) ? pOp->op.opId : 0xFFFFFFFF;
+}
+
+MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp)
+{
+	return (pOp && pOp->signal.timeoutValue) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE;
+}
+
+VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result)
+{
+	if (pOp) {
+		pOp->result = result;
+		osal_raise_signal(&pOp->signal);
+	}
+}
+
+VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result)
+{
+	if (pOp)
+		pOp->result = result;
+
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c
new file mode 100644
index 0000000000000..190fa3944d801
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c
@@ -0,0 +1,899 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/sched.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <linux/fcntl.h>
+#include <linux/poll.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#if WMT_CREATE_NODE_DYNAMIC
+#include <linux/device.h>
+#endif
+#include <linux/printk.h>
+
+#include "osal_typedef.h"
+#include "stp_exp.h"
+#include "wmt_exp.h"
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+#ifdef MTK_BT_HCI
+#define MTK_BT_DEBUG 0
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#endif
+
+
+#define BT_DRIVER_NAME "mtk_stp_BT_chrdev"
+#define BT_DEV_MAJOR 192	/* Never used number */
+
+#define PFX                         "[MTK-BT] "
+#define BT_LOG_DBG                  3
+#define BT_LOG_INFO                 2
+#define BT_LOG_WARN                 1
+#define BT_LOG_ERR                  0
+
+#define COMBO_IOC_MAGIC             0xb0
+#define COMBO_IOCTL_FW_ASSERT       _IOWR(COMBO_IOC_MAGIC, 0, int)
+#define COMBO_IOCTL_BT_IC_HW_VER    _IOWR(COMBO_IOC_MAGIC, 1, void*)
+#define COMBO_IOCTL_BT_IC_FW_VER    _IOWR(COMBO_IOC_MAGIC, 2, void*)
+#define COMBO_IOC_BT_HWVER          _IOWR(COMBO_IOC_MAGIC, 3, void*)
+
+static UINT32 gDbgLevel = BT_LOG_INFO;
+
+#define BT_DBG_FUNC(fmt, arg...)	\
+	do { if (gDbgLevel >= BT_LOG_DBG)	\
+		pr_debug(PFX "%s: "  fmt, __func__ , ##arg);	\
+	} while (0)
+#define BT_INFO_FUNC(fmt, arg...)	\
+	do { if (gDbgLevel >= BT_LOG_INFO)	\
+		pr_warn(PFX "%s: "  fmt, __func__ , ##arg);	\
+	} while (0)
+#define BT_WARN_FUNC(fmt, arg...)	\
+	do { if (gDbgLevel >= BT_LOG_WARN)	\
+		pr_err(PFX "%s: "  fmt, __func__ , ##arg);	\
+	} while (0)
+#define BT_ERR_FUNC(fmt, arg...)	\
+	do { if (gDbgLevel >= BT_LOG_ERR)	\
+		pr_err(PFX "%s: "   fmt, __func__ , ##arg);	\
+	} while (0)
+
+#define VERSION "1.0"
+
+#ifdef MTK_BT_HCI
+
+#define   NUM_REASSEMBLY   32
+struct mtk_hci {
+	struct hci_dev *hdev;
+	struct work_struct work;
+	struct sk_buff_head txq;
+        struct sk_buff *reassembly[NUM_REASSEMBLY];
+};
+
+static struct mtk_hci   mtk_hci;
+
+#endif
+
+#if WMT_CREATE_NODE_DYNAMIC
+struct class *stpbt_class = NULL;
+struct device *stpbt_dev = NULL;
+#endif
+
+static INT32 BT_devs = 1;	/* Device count */
+static INT32 BT_major = BT_DEV_MAJOR;	/* Dynamic allocation */
+module_param(BT_major, uint, 0);
+static struct cdev BT_cdev;
+
+#define BT_BUFFER_SIZE 2048
+static UINT8 i_buf[BT_BUFFER_SIZE];	/* Input buffer of read() */
+static UINT8 o_buf[BT_BUFFER_SIZE];	/* Output buffer of write() */
+
+static struct semaphore wr_mtx, rd_mtx;
+/* Wait queue for poll and read */
+static wait_queue_head_t inq;
+static DECLARE_WAIT_QUEUE_HEAD(BT_wq);
+static INT32 flag;
+/* Reset flag for whole chip reset senario */
+static volatile INT32 rstflag;
+
+#ifdef MTK_BT_HCI
+static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
+	int count, __u8 index)
+{
+	int len = 0;
+	int hlen = 0;
+	int offset = 0;
+	int remain = count;
+	struct sk_buff *skb;
+	struct bt_skb_cb *scb;
+	u16 opcode = 0;
+	unsigned char *pdata = data;
+
+        struct mtk_hci *info = NULL;
+	struct hci_event_hdr *ehdr = NULL;
+	struct hci_ev_cmd_complete *ev = NULL;
+	struct hci_rp_read_local_ext_features *ext  = NULL;
+
+        info = hci_get_drvdata(hdev);
+        if ( NULL == info ) {
+            printk(KERN_ERR "mtk_bt_hci: invalid info point\n");
+            return 0;
+        }
+
+	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
+		index >= NUM_REASSEMBLY)
+		return -EILSEQ;
+
+	skb = info->reassembly[index];
+
+	if (!skb) {
+		switch (type) {
+		case HCI_ACLDATA_PKT:
+			len = HCI_MAX_FRAME_SIZE;
+			hlen = HCI_ACL_HDR_SIZE;
+			break;
+		case HCI_EVENT_PKT:
+			len = HCI_MAX_EVENT_SIZE;
+			hlen = HCI_EVENT_HDR_SIZE;
+			break;
+		case HCI_SCODATA_PKT:
+			len = HCI_MAX_SCO_SIZE;
+			hlen = HCI_SCO_HDR_SIZE;
+			break;
+		}
+
+		skb = bt_skb_alloc(len, GFP_ATOMIC);
+		if (!skb)
+			return -ENOMEM;
+
+		scb = (void *) skb->cb;
+		scb->expect = hlen;
+		scb->pkt_type = type;
+
+		info->reassembly[index] = skb;
+	}
+
+	while (count) {
+		scb = (void *) skb->cb;
+		len = min_t(uint, scb->expect, count);
+
+		/*
+		 * Workaround for MT7623+MT6625 BT: the max page in response of cmd READ_LOCAL_EXT_FEATURES
+                 * should be 1, instead of 2, so changing it to 1 here
+		 */
+
+		if (HCI_EVENT_PKT == type) 
+ 		{
+			ehdr = (void *)pdata;
+			offset = sizeof(struct hci_event_hdr);
+			if ( HCI_EV_CMD_COMPLETE == ehdr->evt) 
+			{
+				ev = (struct hci_ev_cmd_complete *)&pdata[offset];
+
+				offset += sizeof(struct hci_ev_cmd_complete);
+
+				opcode = __le16_to_cpu(ev->opcode);
+				if(HCI_OP_READ_LOCAL_EXT_FEATURES == opcode) {
+					ext = (struct hci_rp_read_local_ext_features *) &pdata[offset];
+					if( !ext->status && ext->max_page >= 2) {
+						pr_info("%s: this workaround is applied for mediatek BT\n", __func__);
+						ext->max_page = 1;
+					}						
+				}
+			
+			}
+		}
+
+		memcpy(skb_put(skb, len), data, len);
+
+		count -= len;
+		data += len;
+		scb->expect -= len;
+		remain = count;
+
+		switch (type) {
+		case HCI_EVENT_PKT:
+			if (skb->len == HCI_EVENT_HDR_SIZE) {
+				struct hci_event_hdr *h = hci_event_hdr(skb);
+
+				scb->expect = h->plen;
+
+				if (skb_tailroom(skb) < scb->expect) {
+					kfree_skb(skb);
+					info->reassembly[index] = NULL;
+					return -ENOMEM;
+				}
+			}
+
+			break;
+
+		case HCI_ACLDATA_PKT:
+			if (skb->len  == HCI_ACL_HDR_SIZE) {
+				struct hci_acl_hdr *h = hci_acl_hdr(skb);
+
+				scb->expect = __le16_to_cpu(h->dlen);
+
+				if (skb_tailroom(skb) < scb->expect) {
+					kfree_skb(skb);
+					info->reassembly[index] = NULL;
+					return -ENOMEM;
+				}
+			}
+			break;
+
+		case HCI_SCODATA_PKT:
+			if (skb->len == HCI_SCO_HDR_SIZE) {
+				struct hci_sco_hdr *h = hci_sco_hdr(skb);
+
+				scb->expect = h->dlen;
+
+				if (skb_tailroom(skb) < scb->expect) {
+					kfree_skb(skb);
+					info->reassembly[index] = NULL;
+					return -ENOMEM;
+				}
+			}
+			break;
+		}
+
+		if (scb->expect == 0) {
+			/* Complete frame */
+
+			bt_cb(skb)->pkt_type = type;
+			hci_recv_frame(hdev, skb);
+
+			info->reassembly[index] = NULL;
+			return remain;
+		}
+	}
+
+	return remain;
+}
+
+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
+{
+	int rem = 0;
+
+	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
+		return -EILSEQ;
+
+	while (count) {
+		rem = hci_reassembly(hdev, type, data, count, type - 1);
+		if (rem < 0)
+			return rem;
+
+		data += (count - rem);
+		count = rem;
+	}
+
+	return rem;
+}
+#endif
+
+#ifdef MTK_BT_HCI
+void
+hex_dump(char *prefix, char *p, int len)
+{
+	int i;
+
+	pr_err("%s ", prefix);
+	for (i = 0; i < len; i++)
+		pr_err("%02x ", (*p++ & 0xff));
+	pr_err("\n");
+}
+
+static int
+mtk_bt_hci_open(struct hci_dev *hdev)
+{
+	int err = 0;
+
+#if MTK_BT_DEBUG == 1
+	pr_err("# %s\n", __func__);
+#endif
+
+	err = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT);
+	if (err != MTK_WCN_BOOL_TRUE) {
+		pr_err("%s func on failed with %d\n", __func__, err);
+		return -ENODEV;
+	}
+
+	set_bit(HCI_RUNNING, &hdev->flags);
+
+	mtk_wcn_stp_set_bluez(1);
+
+	return 0;
+}
+
+static int
+mtk_bt_hci_close(struct hci_dev *hdev)
+{
+	int err = 0;
+
+#if MTK_BT_DEBUG == 1
+	pr_err("# %s\n", __func__);
+#endif
+
+	mtk_wcn_stp_set_bluez(0);
+
+	clear_bit(HCI_RUNNING, &hdev->flags);
+
+	err = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT);
+	if (err != MTK_WCN_BOOL_TRUE) {
+		pr_err("%s func off failed with %d\n", __func__, err);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void
+mtk_bt_hci_work(struct work_struct *work)
+{
+	int err;
+	struct sk_buff *skb;
+
+#if MTK_BT_DEBUG == 1
+	pr_err("# %s\n", __func__);
+#endif
+
+	while ((skb = skb_dequeue(&mtk_hci.txq))) {
+		skb_push(skb, 1);
+		skb->data[0] = bt_cb(skb)->pkt_type;
+
+#if MTK_BT_DEBUG == 1
+		hex_dump(">>", skb->data, skb->len);
+#endif
+
+		err = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX);
+		if (err < 0) {
+			pr_err("%s err=%d\n", __func__, err);
+			mtk_hci.hdev->stat.err_tx++;
+			skb_queue_head(&mtk_hci.txq, skb);
+			break;
+		}
+
+		mtk_hci.hdev->stat.byte_tx += skb->len;
+		kfree_skb(skb);
+	}
+}
+
+static int
+mtk_bt_hci_send(struct hci_dev *hdev, struct sk_buff *skb)
+{
+#if MTK_BT_DEBUG == 1
+	pr_err("# %s\n", __func__);
+#endif
+
+	if (mtk_hci.hdev && !test_bit(HCI_RUNNING, &mtk_hci.hdev->flags))
+		return -EBUSY;
+
+	switch (bt_cb(skb)->pkt_type) {
+	case HCI_COMMAND_PKT:
+		mtk_hci.hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		mtk_hci.hdev->stat.acl_tx++;
+		break;
+
+	case HCI_SCODATA_PKT:
+		mtk_hci.hdev->stat.sco_tx++;
+		break;
+
+	default:
+		return -EILSEQ;
+	}
+
+	skb_queue_tail(&mtk_hci.txq, skb);
+	schedule_work(&mtk_hci.work);
+
+	return 0;
+}
+
+static int
+mtk_bt_hci_flush(struct hci_dev *hdev)
+{
+	pr_err("%s: todo\n", __func__);
+
+	return 0;
+}
+
+static void
+mtk_bt_hci_receive(const PUINT8 data, INT32 size)
+{
+	int err;
+
+#if MTK_BT_DEBUG == 1
+	pr_err("# %s\n", __func__);
+	hex_dump("<<", data, size);
+#endif
+
+	err = hci_recv_fragment(mtk_hci.hdev, data[0], (void *)&data[1], size - 1);
+	if (err < 0)
+		pr_err("%s: hci_recv_fragment failed with %d\n", __func__, err);
+
+	if (mtk_hci.hdev)
+		mtk_hci.hdev->stat.byte_rx += size - 1;
+}
+
+static void
+mtk_bt_hci_notify(struct hci_dev *hdev, unsigned int evt)
+{
+	static const char * const notify_str[] = {
+		"null",
+		"HCI_NOTIFY_CONN_ADD",
+		"HCI_NOTIFY_CONN_DEL",
+		"HCI_NOTIFY_VOICE_SETTING"
+	};
+
+	if (evt > HCI_NOTIFY_VOICE_SETTING)
+		pr_info("%s event=0x%x\n", __func__, evt);
+	else
+		pr_info("%s event(%d)=%s\n", __func__, evt, notify_str[evt]);
+}
+#endif
+
+#ifdef MTK_BT_HCI
+
+int mtk_bt_hci_init(void)
+{
+    	INT32 hci_err = 0;
+
+	mtk_hci.hdev = hci_alloc_dev();
+	if (!(mtk_hci.hdev)) {
+		mtk_hci.hdev = NULL;
+		BT_ERR_FUNC("%s hci_alloc_dev failed\n", __func__);
+		return -ENOMEM;
+	}
+	
+	mtk_hci.hdev->bus = HCI_SDIO;
+	mtk_hci.hdev->open = mtk_bt_hci_open;
+	mtk_hci.hdev->close = mtk_bt_hci_close;
+	mtk_hci.hdev->send = mtk_bt_hci_send;
+	mtk_hci.hdev->flush = mtk_bt_hci_flush;
+	mtk_hci.hdev->notify = mtk_bt_hci_notify;
+	SET_HCIDEV_DEV(mtk_hci.hdev, stpbt_dev);
+
+        hci_set_drvdata(mtk_hci.hdev, &mtk_hci);       
+
+	mtk_wcn_stp_register_if_rx(mtk_bt_hci_receive);
+
+	hci_err = hci_register_dev(mtk_hci.hdev);
+	if (hci_err) {
+		BT_ERR_FUNC("%s hci_register_dev failed with %d\n", __func__, hci_err);
+		hci_free_dev(mtk_hci.hdev);
+		mtk_hci.hdev = NULL;
+		return hci_err;
+	}
+
+	skb_queue_head_init(&mtk_hci.txq);
+	INIT_WORK(&mtk_hci.work, mtk_bt_hci_work);
+
+	return 0;
+}
+#endif
+
+
+static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src,
+			   ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz)
+{
+	/*
+	   Handle whole chip reset messages
+	 */
+	ENUM_WMTRSTMSG_TYPE_T rst_msg;
+
+	if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
+		memcpy((PINT8)&rst_msg, (PINT8)buf, sz);
+		BT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src,
+			     dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX);
+		if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT)
+		    && (type == WMTMSG_TYPE_RESET)) {
+			if (rst_msg == WMTRSTMSG_RESET_START) {
+				BT_INFO_FUNC("BT reset start!\n");
+				rstflag = 1;
+				wake_up_interruptible(&inq);
+
+			} else if (rst_msg == WMTRSTMSG_RESET_END) {
+				BT_INFO_FUNC("BT reset end!\n");
+				rstflag = 2;
+				wake_up_interruptible(&inq);
+			}
+		}
+	} else {
+		/* Invalid message format */
+		BT_WARN_FUNC("Invalid message format!\n");
+	}
+}
+
+VOID BT_event_cb(VOID)
+{
+	BT_DBG_FUNC("BT_event_cb()\n");
+
+	flag = 1;
+
+	/*
+	* Finally, wake up any reader blocked in poll or read
+	*/
+	wake_up_interruptible(&inq);
+	wake_up(&BT_wq);
+}
+
+unsigned int BT_poll(struct file *filp, poll_table *wait)
+{
+	UINT32 mask = 0;
+
+/* down(&wr_mtx); */
+	/*
+	 * The buffer is circular; it is considered full
+	 * if "wp" is right behind "rp". "left" is 0 if the
+	 * buffer is empty, and it is "1" if it is completely full.
+	 */
+	if (mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX)) {
+		poll_wait(filp, &inq, wait);
+
+		if (!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) || rstflag)
+			/* BT Rx queue has valid data, or whole chip reset occurs */
+			mask |= POLLIN | POLLRDNORM;	/* Readable */
+	} else {
+		mask |= POLLIN | POLLRDNORM;	/* Readable */
+	}
+
+	/* Do we need condition here? */
+	mask |= POLLOUT | POLLWRNORM;	/* Writable */
+/* up(&wr_mtx); */
+	return mask;
+}
+
+ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+	INT32 retval = 0;
+	INT32 write_size;
+	INT32 written = 0;
+
+	down(&wr_mtx);
+
+	BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos);
+	if (rstflag) {
+		if (rstflag == 1) {	/* Reset start */
+			retval = -88;
+			BT_INFO_FUNC("%s: detect whole chip reset start\n", __func__);
+		} else if (rstflag == 2) {	/* Reset end */
+			retval = -99;
+			BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__);
+		}
+		goto OUT;
+	}
+
+	if (count > 0) {
+		if (count < BT_BUFFER_SIZE) {
+			write_size = count;
+		} else {
+			write_size = BT_BUFFER_SIZE;
+			BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__);
+		}
+
+		if (copy_from_user(&o_buf[0], &buf[0], write_size)) {
+			retval = -EFAULT;
+			goto OUT;
+		}
+
+		written = mtk_wcn_stp_send_data(&o_buf[0], write_size, BT_TASK_INDX);
+		if (0 == written) {
+			retval = -ENOSPC;
+			/* No space is available, native program should not call BT_write with no delay */
+			BT_ERR_FUNC
+			    ("Packet length %zd, sent length %d, retval = %d\n",
+			     count, written, retval);
+		} else {
+			retval = written;
+		}
+
+	} else {
+		retval = -EFAULT;
+		BT_ERR_FUNC("Packet length %zd is not allowed, retval = %d\n", count, retval);
+	}
+
+OUT:
+	up(&wr_mtx);
+	return retval;
+}
+
+ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	static int chip_reset_count;
+	INT32 retval = 0;
+
+	down(&rd_mtx);
+
+	BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos);
+	if (rstflag) {
+		if (rstflag == 1) {	/* Reset start */
+			retval = -88;
+			if ((chip_reset_count%500) == 0)
+				BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count);
+			chip_reset_count++;
+		} else if (rstflag == 2) {	/* Reset end */
+			retval = -99;
+			BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__);
+			chip_reset_count = 0;
+		}
+		goto OUT;
+	}
+
+	if (count > BT_BUFFER_SIZE) {
+		count = BT_BUFFER_SIZE;
+		BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__);
+	}
+
+	retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);
+
+	while (retval == 0) {	/* Got nothing, wait for STP's signal */
+		/*
+		* If nonblocking mode, return directly.
+		* O_NONBLOCK is specified during open()
+		*/
+		if (filp->f_flags & O_NONBLOCK) {
+			BT_DBG_FUNC("Non-blocking BT_read\n");
+			retval = -EAGAIN;
+			goto OUT;
+		}
+
+		BT_DBG_FUNC("%s: wait_event 1\n", __func__);
+		wait_event(BT_wq, flag != 0);
+		BT_DBG_FUNC("%s: wait_event 2\n", __func__);
+		flag = 0;
+		retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);
+		BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval);
+	}
+
+	/* Got something from STP driver */
+	if (copy_to_user(buf, i_buf, retval)) {
+		retval = -EFAULT;
+		goto OUT;
+	}
+
+OUT:
+	up(&rd_mtx);
+	BT_DBG_FUNC("%s: retval = %d\n", __func__, retval);
+	return retval;
+}
+
+/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */
+long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	INT32 retval = 0;
+	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE;
+	ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID;
+
+	BT_DBG_FUNC("%s:  cmd: 0x%x\n", __func__, cmd);
+
+	switch (cmd) {
+	case COMBO_IOC_BT_HWVER:
+		/* Get combo HW version */
+		hw_ver_sym = mtk_wcn_wmt_hwver_get();
+		BT_INFO_FUNC("%s: HW version = %d, sizeof(hw_ver_sym) = %zd\n",
+			     __func__, hw_ver_sym, sizeof(hw_ver_sym));
+		if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym)))
+			retval = -EFAULT;
+		break;
+
+	case COMBO_IOCTL_FW_ASSERT:
+		/* Trigger FW assert for debug */
+		BT_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg);
+		bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg);
+		if (bRet == MTK_WCN_BOOL_TRUE) {
+			BT_INFO_FUNC("Host trigger FW assert succeed\n");
+			retval = 0;
+		} else {
+			BT_ERR_FUNC("Host trigger FW assert Failed\n");
+			retval = (-EBUSY);
+		}
+		break;
+	case COMBO_IOCTL_BT_IC_HW_VER:
+		retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER);
+		break;
+	case COMBO_IOCTL_BT_IC_FW_VER:
+		retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER);
+		break;
+	default:
+		retval = -EFAULT;
+		BT_ERR_FUNC("Unknown cmd (%d)\n", cmd);
+		break;
+	}
+
+	return retval;
+}
+
+long BT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	return BT_unlocked_ioctl(filp, cmd, arg);
+}
+
+static int BT_open(struct inode *inode, struct file *file)
+{
+	BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid);
+
+	/* Turn on BT */
+	if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) {
+		BT_WARN_FUNC("WMT turn on BT fail!\n");
+		return -ENODEV;
+	}
+
+	BT_INFO_FUNC("WMT turn on BT OK!\n");
+	rstflag = 0;
+
+	if (mtk_wcn_stp_is_ready()) {
+
+		mtk_wcn_stp_set_bluez(0);
+
+		BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n");
+		BT_INFO_FUNC("STP is ready!\n");
+
+		BT_DBG_FUNC("Register BT event callback!\n");
+		mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb);
+	} else {
+		BT_ERR_FUNC("STP is not ready\n");
+		mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT);
+		return -ENODEV;
+	}
+
+	BT_DBG_FUNC("Register BT reset callback!\n");
+	mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb);
+
+	/* init_MUTEX(&wr_mtx); */
+	sema_init(&wr_mtx, 1);
+	/* init_MUTEX(&rd_mtx); */
+	sema_init(&rd_mtx, 1);
+	BT_INFO_FUNC("%s: finish\n", __func__);
+
+	return 0;
+}
+
+static int BT_close(struct inode *inode, struct file *file)
+{
+	BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid);
+	rstflag = 0;
+	mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT);
+	mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);
+
+	if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) {
+		BT_ERR_FUNC("WMT turn off BT fail!\n");
+		return -EIO;	/* Mostly, native program will not check this return value. */
+	}
+
+	BT_INFO_FUNC("WMT turn off BT OK!\n");
+
+	return 0;
+}
+
+const struct file_operations BT_fops = {
+	.open = BT_open,
+	.release = BT_close,
+	.read = BT_read,
+	.write = BT_write,
+	/* .ioctl = BT_ioctl, */
+	.unlocked_ioctl = BT_unlocked_ioctl,
+	.compat_ioctl = BT_compat_ioctl,
+	.poll = BT_poll
+};
+
+
+
+static int BT_init(void)
+{
+	dev_t dev = MKDEV(BT_major, 0);
+	INT32 alloc_ret = 0;
+	INT32 cdev_err = 0;
+
+	/* Static allocate char device */
+	alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME);
+	if (alloc_ret) {
+		BT_ERR_FUNC("%s: Failed to register char device\n", __func__);
+		return alloc_ret;
+	}
+
+	cdev_init(&BT_cdev, &BT_fops);
+	BT_cdev.owner = THIS_MODULE;
+
+	cdev_err = cdev_add(&BT_cdev, dev, BT_devs);
+	if (cdev_err)
+		goto error;
+
+#if WMT_CREATE_NODE_DYNAMIC
+	stpbt_class = class_create(THIS_MODULE, "stpbt");
+	if (IS_ERR(stpbt_class))
+		goto error;
+	stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt");
+	if (IS_ERR(stpbt_dev))
+		goto error;
+#endif
+
+	BT_INFO_FUNC("%s driver(major %d) installed\n", BT_DRIVER_NAME, BT_major);
+
+	/* Init wait queue */
+	init_waitqueue_head(&(inq));
+
+#ifdef MTK_BT_HCI
+ 	mtk_bt_hci_init();
+#endif
+
+	return 0;
+
+error:
+#if WMT_CREATE_NODE_DYNAMIC
+	if (!IS_ERR(stpbt_dev))
+		device_destroy(stpbt_class, dev);
+	if (!IS_ERR(stpbt_class)) {
+		class_destroy(stpbt_class);
+		stpbt_class = NULL;
+	}
+#endif
+	if (cdev_err == 0)
+		cdev_del(&BT_cdev);
+
+	if (alloc_ret == 0)
+		unregister_chrdev_region(dev, BT_devs);
+
+	return -1;
+}
+
+static void BT_exit(void)
+{
+	dev_t dev = MKDEV(BT_major, 0);
+
+#if WMT_CREATE_NODE_DYNAMIC
+	if (stpbt_dev) {
+		device_destroy(stpbt_class, dev);
+		stpbt_dev = NULL;
+	}
+	if (stpbt_class) {
+		class_destroy(stpbt_class);
+		stpbt_class = NULL;
+	}
+#endif
+
+	cdev_del(&BT_cdev);
+	unregister_chrdev_region(dev, BT_devs);
+
+	BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME);
+}
+
+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE
+
+int mtk_wcn_stpbt_drv_init(void)
+{
+	return BT_init();
+}
+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_init);
+
+void mtk_wcn_stpbt_drv_exit(void)
+{
+	return BT_exit();
+}
+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_exit);
+
+#else
+
+module_init(BT_init);
+module_exit(BT_exit);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c
new file mode 100644
index 0000000000000..3c7b2969c98a8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c
@@ -0,0 +1,668 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/sched.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <linux/fcntl.h>
+#include <linux/poll.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <net/net_namespace.h>
+#include <linux/string.h>
+
+#include "wmt_exp.h"
+#include "stp_exp.h"
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+#define WIFI_DRIVER_NAME "mtk_wmt_WIFI_chrdev"
+#define WIFI_DEV_MAJOR 155
+
+#define PFX                         "[MTK-WIFI] "
+#define WIFI_LOG_DBG                  3
+#define WIFI_LOG_INFO                 2
+#define WIFI_LOG_WARN                 1
+#define WIFI_LOG_ERR                  0
+
+UINT32 gDbgLevel = WIFI_LOG_DBG;
+
+#define WIFI_DBG_FUNC(fmt, arg...)\
+	do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0)
+#define WIFI_INFO_FUNC(fmt, arg...)\
+	do {if (gDbgLevel >= WIFI_LOG_INFO) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0)
+#define WIFI_WARN_FUNC(fmt, arg...)\
+	do {if (gDbgLevel >= WIFI_LOG_WARN) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0)
+#define WIFI_ERR_FUNC(fmt, arg...)\
+	do {if (gDbgLevel >= WIFI_LOG_ERR) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0)
+#define WIFI_TRC_FUNC(f)\
+	do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "<%s> <%d>\n", __func__, __LINE__); } while (0)
+
+#define VERSION "1.0"
+
+#define WLAN_IFACE_NAME "wlan0"
+#if CFG_TC1_FEATURE
+#define LEGACY_IFACE_NAME "legacy0"
+#endif
+
+enum {
+	WLAN_MODE_HALT,
+	WLAN_MODE_AP,
+	WLAN_MODE_STA_P2P,
+	WLAN_MODE_MAX
+};
+static INT32 wlan_mode = WLAN_MODE_HALT;
+static INT32 powered;
+static INT8 *ifname = WLAN_IFACE_NAME;
+#if CFG_TC1_FEATURE
+volatile INT32 wlan_if_changed = 0;
+EXPORT_SYMBOL(wlan_if_changed);
+#endif
+
+typedef enum _ENUM_RESET_STATUS_T {
+	RESET_FAIL,
+	RESET_SUCCESS
+} ENUM_RESET_STATUS_T;
+
+/*
+ *  enable = 1, mode = 0  => init P2P network
+ *  enable = 1, mode = 1  => init Soft AP network
+ *  enable = 0            => uninit P2P/AP network
+ */
+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T {
+	UINT32 u4Enable;
+	UINT32 u4Mode;
+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T;
+typedef INT32(*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode);
+
+static set_p2p_mode pf_set_p2p_mode;
+VOID register_set_p2p_mode_handler(set_p2p_mode handler)
+{
+	WIFI_INFO_FUNC("(pid %d) register set p2p mode handler %p\n", current->pid, handler);
+	pf_set_p2p_mode = handler;
+}
+EXPORT_SYMBOL(register_set_p2p_mode_handler);
+
+/* For dynamical debug level setting */
+/* copy of debug.h in wlan driver */
+#define DBG_CLASS_ERROR         BIT(0)
+#define DBG_CLASS_WARN          BIT(1)
+#define DBG_CLASS_STATE         BIT(2)
+#define DBG_CLASS_EVENT         BIT(3)
+#define DBG_CLASS_TRACE         BIT(4)
+#define DBG_CLASS_INFO          BIT(5)
+#define DBG_CLASS_LOUD          BIT(6)
+#define DBG_CLASS_TEMP          BIT(7)
+#define DBG_CLASS_MASK          BITS(0, 7)
+
+typedef enum _ENUM_DBG_MODULE_T {
+	DBG_INIT_IDX = 0,	/* For driver initial */
+	DBG_HAL_IDX,		/* For HAL(HW) Layer */
+	DBG_INTR_IDX,		/* For Interrupt */
+	DBG_REQ_IDX,
+	DBG_TX_IDX,
+	DBG_RX_IDX,
+	DBG_RFTEST_IDX,		/* For RF test mode */
+	DBG_EMU_IDX,		/* Developer specific */
+
+	DBG_SW1_IDX,		/* Developer specific */
+	DBG_SW2_IDX,		/* Developer specific */
+	DBG_SW3_IDX,		/* Developer specific */
+	DBG_SW4_IDX,		/* Developer specific */
+
+	DBG_HEM_IDX,		/* HEM */
+	DBG_AIS_IDX,		/* AIS */
+	DBG_RLM_IDX,		/* RLM */
+	DBG_MEM_IDX,		/* RLM */
+	DBG_CNM_IDX,		/* CNM */
+	DBG_RSN_IDX,		/* RSN */
+	DBG_BSS_IDX,		/* BSS */
+	DBG_SCN_IDX,		/* SCN */
+	DBG_SAA_IDX,		/* SAA */
+	DBG_AAA_IDX,		/* AAA */
+	DBG_P2P_IDX,		/* P2P */
+	DBG_QM_IDX,		/* QUE_MGT */
+	DBG_SEC_IDX,		/* SEC */
+	DBG_BOW_IDX,		/* BOW */
+	DBG_WAPI_IDX,		/* WAPI */
+	DBG_ROAMING_IDX,	/* ROAMING */
+
+	DBG_MODULE_NUM		/* Notice the XLOG check */
+} ENUM_DBG_MODULE_T;
+/* end */
+typedef VOID(*set_dbg_level) (UINT8 modules[DBG_MODULE_NUM]);
+
+UINT8 wlan_dbg_level[DBG_MODULE_NUM];
+static set_dbg_level pf_set_dbg_level;
+VOID register_set_dbg_level_handler(set_dbg_level handler)
+{
+	pf_set_dbg_level = handler;
+}
+EXPORT_SYMBOL(register_set_dbg_level_handler);
+
+static INT32 WIFI_devs = 1;
+static INT32 WIFI_major = WIFI_DEV_MAJOR;
+module_param(WIFI_major, uint, 0);
+static struct cdev WIFI_cdev;
+volatile INT32 retflag = 0;
+static struct semaphore wr_mtx;
+
+#define WMT_CHECK_DO_CHIP_RESET() \
+do { \
+	if (g_IsNeedDoChipReset) { \
+		g_IsNeedDoChipReset = 0; \
+		WIFI_ERR_FUNC("Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \
+		mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); \
+	} \
+} while (0)
+
+/*******************************************************************
+ *  WHOLE CHIP RESET PROCEDURE:
+ *
+ *  WMTRSTMSG_RESET_START callback
+ *  -> wlanRemove
+ *  -> WMTRSTMSG_RESET_END callback
+ *
+ *******************************************************************
+*/
+/*-----------------------------------------------------------------*/
+/*
+ *  Receiving RESET_START message
+ */
+/*-----------------------------------------------------------------*/
+INT32 wifi_reset_start(VOID)
+{
+	struct net_device *netdev = NULL;
+	PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode;
+
+	down(&wr_mtx);
+
+	if (powered == 1) {
+		netdev = dev_get_by_name(&init_net, ifname);
+		if (netdev == NULL) {
+			WIFI_ERR_FUNC("Fail to get %s net device\n", ifname);
+		} else {
+			p2pmode.u4Enable = 0;
+			p2pmode.u4Mode = 0;
+
+			if (pf_set_p2p_mode) {
+				if (pf_set_p2p_mode(netdev, p2pmode) != 0)
+					WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
+				else
+					WIFI_INFO_FUNC("Turn off p2p/ap mode");
+			}
+			dev_put(netdev);
+			netdev = NULL;
+		}
+	} else {
+		/* WIFI is off before whole chip reset, do nothing */
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(wifi_reset_start);
+
+/*-----------------------------------------------------------------*/
+/*
+ *  Receiving RESET_END/RESET_END_FAIL message
+ */
+/*-----------------------------------------------------------------*/
+INT32 wifi_reset_end(ENUM_RESET_STATUS_T status)
+{
+	struct net_device *netdev = NULL;
+	PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode;
+	INT32 wait_cnt = 0;
+	INT32 ret = -1;
+
+	if (status == RESET_FAIL) {
+		/* whole chip reset fail, donot recover WIFI */
+		ret = 0;
+		up(&wr_mtx);
+	} else if (status == RESET_SUCCESS) {
+		WIFI_WARN_FUNC("WIFI state recovering...\n");
+
+		if (powered == 1) {
+			/* WIFI is on before whole chip reset, reopen it now */
+			if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
+				WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
+				goto done;
+			} else {
+				WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
+			}
+
+			if (pf_set_p2p_mode == NULL) {
+				WIFI_ERR_FUNC("Set p2p mode handler is NULL\n");
+				goto done;
+			}
+
+			netdev = dev_get_by_name(&init_net, ifname);
+			while (netdev == NULL && wait_cnt < 10) {
+				WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname);
+				msleep(300);
+				wait_cnt++;
+				netdev = dev_get_by_name(&init_net, ifname);
+			}
+			if (wait_cnt >= 10) {
+				WIFI_ERR_FUNC("Get %s net device timeout\n", ifname);
+				goto done;
+			}
+
+			if (wlan_mode == WLAN_MODE_STA_P2P) {
+				p2pmode.u4Enable = 1;
+				p2pmode.u4Mode = 0;
+				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
+					WIFI_ERR_FUNC("Set wlan mode fail\n");
+				} else {
+					WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P);
+					ret = 0;
+				}
+			} else if (wlan_mode == WLAN_MODE_AP) {
+				p2pmode.u4Enable = 1;
+				p2pmode.u4Mode = 1;
+				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
+					WIFI_ERR_FUNC("Set wlan mode fail\n");
+				} else {
+					WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP);
+					ret = 0;
+				}
+			}
+done:
+			if (netdev != NULL)
+				dev_put(netdev);
+		} else {
+			/* WIFI is off before whole chip reset, do nothing */
+			ret = 0;
+		}
+		up(&wr_mtx);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(wifi_reset_end);
+
+static int WIFI_open(struct inode *inode, struct file *file)
+{
+	WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid);
+
+	return 0;
+}
+
+static int WIFI_close(struct inode *inode, struct file *file)
+{
+	WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid);
+	retflag = 0;
+
+	return 0;
+}
+
+ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+	INT32 retval = -EIO;
+	INT8 local[12] = { 0 };
+	struct net_device *netdev = NULL;
+	PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode;
+	INT32 wait_cnt = 0;
+
+	down(&wr_mtx);
+	if (count <= 0) {
+		WIFI_ERR_FUNC("WIFI_write invalid param\n");
+		goto done;
+	}
+
+	if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) {
+		local[11] = 0;
+		WIFI_INFO_FUNC("WIFI_write %s\n", local);
+
+		if (local[0] == '0') {
+			if (powered == 0) {
+				WIFI_INFO_FUNC("WIFI is already power off!\n");
+				retval = count;
+				wlan_mode = WLAN_MODE_HALT;
+				goto done;
+			}
+
+			netdev = dev_get_by_name(&init_net, ifname);
+			if (netdev == NULL) {
+				WIFI_ERR_FUNC("Fail to get %s net device\n", ifname);
+			} else {
+				p2pmode.u4Enable = 0;
+				p2pmode.u4Mode = 0;
+
+				if (pf_set_p2p_mode) {
+					if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
+						WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
+					} else {
+						WIFI_INFO_FUNC("Turn off p2p/ap mode");
+						wlan_mode = WLAN_MODE_HALT;
+					}
+				}
+				dev_put(netdev);
+				netdev = NULL;
+			}
+
+			if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
+				WIFI_ERR_FUNC("WMT turn off WIFI fail!\n");
+				WMT_CHECK_DO_CHIP_RESET();
+			} else {
+				WIFI_INFO_FUNC("WMT turn off WIFI OK!\n");
+				powered = 0;
+				retval = count;
+				wlan_mode = WLAN_MODE_HALT;
+#if CFG_TC1_FEATURE
+				ifname = WLAN_IFACE_NAME;
+				wlan_if_changed = 0;
+#endif
+			}
+		} else if (local[0] == '1') {
+			if (powered == 1) {
+				WIFI_INFO_FUNC("WIFI is already power on!\n");
+				retval = count;
+				goto done;
+			}
+
+			if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
+				WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
+				WMT_CHECK_DO_CHIP_RESET();
+			} else {
+				powered = 1;
+				retval = count;
+				WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
+				wlan_mode = WLAN_MODE_HALT;
+			}
+		} else if (local[0] == 'D') {
+			INT32 k = 0;
+			/*
+			 * 0: no debug
+			 * 1: common debug output
+			 * 2: more detials
+			 * 3: verbose
+			 */
+			switch (local[1]) {
+			case '0':
+				for (k = 0; k < DBG_MODULE_NUM; k++)
+					wlan_dbg_level[k] = 0;
+				if (pf_set_dbg_level)
+					pf_set_dbg_level(wlan_dbg_level);
+				break;
+			case '1':
+				for (k = 0; k < DBG_MODULE_NUM; k++) {
+					wlan_dbg_level[k] = DBG_CLASS_ERROR |
+					    DBG_CLASS_WARN |
+					    DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO;
+				}
+				wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO);
+				wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO);
+				wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO);
+				wlan_dbg_level[DBG_INTR_IDX] = 0;
+				wlan_dbg_level[DBG_MEM_IDX] = 0;
+				if (pf_set_dbg_level)
+					pf_set_dbg_level(wlan_dbg_level);
+				break;
+			case '2':
+				for (k = 0; k < DBG_MODULE_NUM; k++) {
+					wlan_dbg_level[k] = DBG_CLASS_ERROR |
+					    DBG_CLASS_WARN |
+					    DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO;
+				}
+				wlan_dbg_level[DBG_INTR_IDX] = 0;
+				wlan_dbg_level[DBG_MEM_IDX] = 0;
+				if (pf_set_dbg_level)
+					pf_set_dbg_level(wlan_dbg_level);
+				break;
+			case '3':
+				for (k = 0; k < DBG_MODULE_NUM; k++) {
+					wlan_dbg_level[k] = DBG_CLASS_ERROR |
+					    DBG_CLASS_WARN |
+					    DBG_CLASS_STATE |
+					    DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD;
+				}
+				if (pf_set_dbg_level)
+					pf_set_dbg_level(wlan_dbg_level);
+				break;
+			default:
+				break;
+			}
+		} else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') {
+			if (powered == 0) {
+				/* If WIFI is off, turn on WIFI first */
+				if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
+					WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
+					WMT_CHECK_DO_CHIP_RESET();
+					goto done;
+				} else {
+					powered = 1;
+					WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
+					wlan_mode = WLAN_MODE_HALT;
+				}
+			}
+
+			if (pf_set_p2p_mode == NULL) {
+				WIFI_ERR_FUNC("Set p2p mode handler is NULL\n");
+				goto done;
+			}
+
+			netdev = dev_get_by_name(&init_net, ifname);
+			while (netdev == NULL && wait_cnt < 10) {
+				WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname);
+				msleep(300);
+				wait_cnt++;
+				netdev = dev_get_by_name(&init_net, ifname);
+			}
+			if (wait_cnt >= 10) {
+				WIFI_ERR_FUNC("Get %s net device timeout\n", ifname);
+				goto done;
+			}
+
+			if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) ||
+			    (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))) {
+				WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode);
+				retval = count;
+				goto done;
+			}
+
+			if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) ||
+			    (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) {
+				p2pmode.u4Enable = 0;
+				p2pmode.u4Mode = 0;
+				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
+					WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
+					goto done;
+				}
+			}
+
+			if (local[0] == 'S' || local[0] == 'P') {
+#if CFG_TC1_FEATURE
+				/* Restore NIC name to wlan0 */
+				rtnl_lock();
+				if (strcmp(ifname, WLAN_IFACE_NAME) != 0) {
+					if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0) {
+						WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME);
+						rtnl_unlock();
+						goto done;
+					} else {
+						WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname,
+							       WLAN_IFACE_NAME);
+						ifname = WLAN_IFACE_NAME;
+						wlan_if_changed = 0;
+					}
+				}
+				rtnl_unlock();
+#endif
+				p2pmode.u4Enable = 1;
+				p2pmode.u4Mode = 0;
+				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
+					WIFI_ERR_FUNC("Set wlan mode fail\n");
+				} else {
+					WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P);
+					wlan_mode = WLAN_MODE_STA_P2P;
+					retval = count;
+				}
+			} else if (local[0] == 'A') {
+#if CFG_TC1_FEATURE
+				/* Change NIC name to legacy0, since wlan0 is used for AP */
+				rtnl_lock();
+				if (strcmp(ifname, LEGACY_IFACE_NAME) != 0) {
+					if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0) {
+						WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME);
+						rtnl_unlock();
+						goto done;
+					} else {
+						WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname,
+							       LEGACY_IFACE_NAME);
+						ifname = LEGACY_IFACE_NAME;
+						wlan_if_changed = 1;
+					}
+				}
+				rtnl_unlock();
+#endif
+				p2pmode.u4Enable = 1;
+				p2pmode.u4Mode = 1;
+				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
+					WIFI_ERR_FUNC("Set wlan mode fail\n");
+				} else {
+					WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP);
+					wlan_mode = WLAN_MODE_AP;
+					retval = count;
+				}
+			}
+			dev_put(netdev);
+			netdev = NULL;
+		}
+	}
+done:
+	if (netdev != NULL)
+		dev_put(netdev);
+
+	up(&wr_mtx);
+	return retval;
+}
+
+const struct file_operations WIFI_fops = {
+	.open = WIFI_open,
+	.release = WIFI_close,
+	.write = WIFI_write,
+};
+
+#if WMT_CREATE_NODE_DYNAMIC
+struct class *wmtwifi_class = NULL;
+#endif
+
+static int WIFI_init(void)
+{
+	dev_t dev = MKDEV(WIFI_major, 0);
+	INT32 alloc_ret = 0;
+	INT32 cdev_err = 0;
+#if WMT_CREATE_NODE_DYNAMIC
+	struct device *wmtwifi_dev = NULL;
+#endif
+
+	/* static allocate chrdev */
+	alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME);
+	if (alloc_ret) {
+		WIFI_ERR_FUNC("Fail to register chrdev\n");
+		return alloc_ret;
+	}
+
+	cdev_init(&WIFI_cdev, &WIFI_fops);
+	WIFI_cdev.owner = THIS_MODULE;
+
+	cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs);
+	if (cdev_err)
+		goto error;
+
+#if WMT_CREATE_NODE_DYNAMIC	/* mknod replace */
+	wmtwifi_class = class_create(THIS_MODULE, "wmtWifi");
+	if (IS_ERR(wmtwifi_class))
+		goto error;
+	wmtwifi_dev = device_create(wmtwifi_class, NULL, dev, NULL, "wmtWifi");
+	if (wmtwifi_dev == NULL)
+		goto error;
+	if (IS_ERR(wmtwifi_dev))
+		goto error;
+#endif
+
+	sema_init(&wr_mtx, 1);
+
+	WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major);
+	retflag = 0;
+	wlan_mode = WLAN_MODE_HALT;
+	pf_set_p2p_mode = NULL;
+
+	return 0;
+
+error:
+#if WMT_CREATE_NODE_DYNAMIC
+	if (!IS_ERR(wmtwifi_dev))
+		device_destroy(wmtwifi_class, dev);
+	if (!IS_ERR(wmtwifi_class)) {
+		class_destroy(wmtwifi_class);
+		wmtwifi_class = NULL;
+	}
+#endif
+
+	if (cdev_err == 0)
+		cdev_del(&WIFI_cdev);
+
+	if (alloc_ret == 0)
+		unregister_chrdev_region(dev, WIFI_devs);
+
+	return -1;
+}
+
+static void WIFI_exit(void)
+{
+	dev_t dev = MKDEV(WIFI_major, 0);
+
+	retflag = 0;
+
+#if WMT_CREATE_NODE_DYNAMIC
+	device_destroy(wmtwifi_class, dev);
+	class_destroy(wmtwifi_class);
+	wmtwifi_class = NULL;
+#endif
+
+	cdev_del(&WIFI_cdev);
+	unregister_chrdev_region(dev, WIFI_devs);
+
+	WIFI_INFO_FUNC("%s driver removed.\n", WIFI_DRIVER_NAME);
+}
+
+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE
+
+INT32 mtk_wcn_wmt_wifi_init(VOID)
+{
+	return WIFI_init();
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_init);
+
+VOID mtk_wcn_wmt_wifi_exit(VOID)
+{
+	return WIFI_exit();
+}
+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_exit);
+
+#else
+
+module_init(WIFI_init);
+module_exit(WIFI_exit);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c
new file mode 100644
index 0000000000000..641e516f603d4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c
@@ -0,0 +1,307 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "osal_typedef.h"
+#include "wmt_idc.h"
+#include "wmt_lib.h"
+
+#if CFG_WMT_LTE_COEX_HANDLING
+
+MTK_WCN_WMT_IDC_INFO gWmtIdcInfo;
+
+INT32 wmt_idc_init(VOID)
+{
+	INT32 iRet;
+
+	osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo));
+	gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT;
+	gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1;
+	gWmtIdcInfo.iit.sap_id = 0;
+	gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing;
+
+	iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops);
+	if (iRet) {
+		WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet);
+		return -1;
+	}
+	/* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */
+	return 0;
+
+}
+
+INT32 wmt_idc_deinit(VOID)
+{
+	INT32 iRet;
+
+	iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id);
+	if (iRet)
+		WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet);
+
+	osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo));
+
+	return 0;
+}
+
+INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm)
+{
+	MTK_WCN_BOOL bRet;
+
+	if (NULL == ilm) {
+		WMT_ERR_FUNC("NULL pointer\n");
+		return -1;
+	}
+	if (mtk_wcn_stp_is_ready()) {
+		bRet = wmt_lib_handle_idc_msg(ilm);
+		if (MTK_WCN_BOOL_FALSE == bRet) {
+			WMT_ERR_FUNC("wmt handing idc msg fail\n");
+			return -2;
+		}
+	} else {
+		WMT_INFO_FUNC("Received LTE msg,but STP is not ready,drop it!\n");
+	}
+	return 0;
+}
+
+VOID wmt_idc_dump_debug_msg(UINT8 *str, UINT8 *p_buf, UINT32 buf_len)
+{
+	UINT32 idx = 0;
+
+	WMT_DBG_FUNC("%s:, length:%d\n", str, buf_len);
+
+	WMT_DBG_FUNC("ASCII output:\n");
+
+	for (idx = 0; idx < buf_len;) {
+		WMT_DBG_FUNC("%c", p_buf[idx]);
+		idx++;
+		if (0 == idx % 16)
+			WMT_DBG_FUNC("\n");
+	}
+
+	WMT_DBG_FUNC("HEX output:\n");
+
+	for (idx = 0; idx < buf_len;) {
+		WMT_DBG_FUNC("%02x ", p_buf[idx]);
+		idx++;
+		if (0 == idx % 16)
+			WMT_DBG_FUNC("\n");
+	}
+}
+
+INT32 wmt_idc_msg_to_lte_handing(VOID)
+{
+	UINT32 readlen = 0;
+	local_para_struct *p_lps = NULL;
+	UINT8 *p_data = NULL;
+	UINT8 opcode = 0;
+	UINT16 msg_len = 0;
+	UINT32 handle_len = 0;
+#if	CFG_WMT_LTE_ENABLE_MSGID_MAPPING
+	MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE;
+#endif
+	readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX);
+	if (readlen == 0) {
+		osal_sleep_ms(5);
+		readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX);
+	}
+
+	if (readlen > 0) {
+		WMT_DBG_FUNC("read data len from fw(%d)\n", readlen);
+		wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen);
+		p_data = &gWmtIdcInfo.buffer[0];
+
+		while (handle_len < readlen) {
+			p_data += 2;	/*omit direction & opcode 2 bytes */
+			osal_memcpy(&msg_len, p_data, 2);
+			msg_len -= 1;	/*flag byte */
+			WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len);
+
+			p_data += 2;	/*length: 2 bytes */
+
+			/*how to handle flag(msg type) need to Scott comment */
+			/************************************************/
+
+			if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR)
+				/*do not need transfer to LTE */
+			{
+				p_data += 1;	/*flag : 1 byte */
+				/*need to handle these debug message */
+				wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len);
+			} else
+				/*need to transfer to LTE */
+			{
+				p_lps =
+				    (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) +
+								      osal_sizeof(UINT8) * msg_len);
+				if (NULL == p_lps) {
+					WMT_ERR_FUNC("allocate local_para_struct memory fail\n");
+					return -1;
+				}
+
+				p_lps->msg_len = msg_len + osal_sizeof(local_para_struct);
+
+				opcode = *p_data;
+				WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode);
+
+				p_data += 1;	/*flag : 1 byte */
+				osal_memcpy(p_lps->data, p_data, msg_len);
+
+				gWmtIdcInfo.iit.local_para_ptr = p_lps;
+
+#if	CFG_WMT_LTE_ENABLE_MSGID_MAPPING
+				switch (opcode) {
+				case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA:
+					gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND;
+					break;
+				case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN:
+					gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND;
+					break;
+				case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE:
+					gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND;
+					break;
+				case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND:
+					gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND;
+					break;
+				case WMT_IDC_RX_OPCODE_UART_PIN_SEL:
+					gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND;
+					break;
+					/* case WMT_IDC_RX_OPCODE_TDM_REQ: */
+					/* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */
+					/* break; */
+				default:
+					unknown_msgid = MTK_WCN_BOOL_TRUE;
+					WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode);
+					break;
+				}
+				if (MTK_WCN_BOOL_FALSE == unknown_msgid) {
+					/*handling flag value in wmt cmd */
+					mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit);
+				}
+#else
+				if (opcode >= LTE_MSG_ID_OFFSET) {
+					gWmtIdcInfo.iit.msg_id = opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1;
+					/*handling flag value in wmt cmd */
+					mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit);
+					WMT_DBG_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, gWmtIdcInfo.iit.msg_id);
+				} else {
+					WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", opcode);
+				}
+#endif
+				osal_free(p_lps);
+			}
+
+			p_data += msg_len;	/*point to next package header */
+
+			handle_len += (msg_len + 5);
+		}
+
+	} else {
+		WMT_ERR_FUNC("there is no coex data in stp buffer\n");
+	}
+
+	osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE);
+
+	return 0;
+}
+
+UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len)
+{
+	UINT32 readlen = len;
+	local_para_struct *p_lps = NULL;
+	UINT8 *p_data = NULL;
+	UINT8 opcode = 0;
+	UINT16 msg_len = 0;
+	UINT32 handle_len = 0;
+	MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE;
+
+	osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len);
+
+	if (readlen > 0) {
+		WMT_DBG_FUNC("read data len from fw(%d)\n", readlen);
+		p_data = &gWmtIdcInfo.buffer[0];
+
+		while (handle_len < readlen) {
+			p_data += 2;	/*omit direction & opcode 2 bytes */
+			osal_memcpy(&msg_len, p_data, 2);
+			msg_len -= 1;	/*flag byte */
+			WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len);
+
+			p_data += 2;	/*length: 2 bytes */
+
+			/*how to handle flag(msg type) need to Scott comment */
+			/************************************************/
+
+			if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR)
+				/*do not need transfer to LTE */
+			{
+				p_data += 1;	/*flag : 1 byte */
+				/*need to handle these debug message */
+				wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len);
+			} else
+				/*need to transfer to LTE */
+			{
+				p_lps =
+				    (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) +
+								      osal_sizeof(UINT8) * msg_len);
+				if (NULL == p_lps) {
+					WMT_ERR_FUNC("allocate local_para_struct memory fail\n");
+					return -1;
+				}
+
+				p_lps->msg_len = msg_len + osal_sizeof(local_para_struct);
+
+				opcode = *p_data;
+				WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode);
+
+				p_data += 1;	/*flag : 1 byte */
+				osal_memcpy(p_lps->data, p_data, msg_len);
+
+				gWmtIdcInfo.iit.local_para_ptr = p_lps;
+
+				switch (opcode) {
+				case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA:
+					gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND;
+					break;
+				case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN:
+					gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND;
+					break;
+					/* case WMT_IDC_RX_OPCODE_TDM_REQ: */
+					/* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */
+					/* break; */
+				default:
+					unknown_msgid = MTK_WCN_BOOL_TRUE;
+					WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode);
+					break;
+				}
+				if (MTK_WCN_BOOL_FALSE == unknown_msgid) {
+					/*handling flag value in wmt cmd */
+					mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit);
+				}
+				osal_free(p_lps);
+			}
+
+			p_data += msg_len;	/*point to next package header */
+
+			handle_len += (msg_len + 5);
+		}
+
+	} else {
+		WMT_ERR_FUNC("there is no coex data in stp buffer\n");
+	}
+
+	osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE);
+
+	return handle_len;
+}
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile
new file mode 100644
index 0000000000000..c201e8291b8ef
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile
@@ -0,0 +1,25 @@
+# WMT HAL driver for MT7623
+
+ccflags-y += \
+	-I$(src)/include \
+	-I$(src)/../linux/include \
+	-I$(src)/../include \
+	-I$(src)/../../common_detect
+
+  ifeq ($(CONFIG_MTK_CLKMGR),y)
+  	ccflags-y +=	-I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach
+	endif
+  #ifeq ($(CONFIG_MTK_EMI_MPU),y)
+  	ccflags-y +=	-I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach
+  	#endif
+
+subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT
+
+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y)
+	subdir-ccflags-y += -DWMT_IDC_SUPPORT=1
+else
+	subdir-ccflags-y += -DWMT_IDC_SUPPORT=0
+endif
+
+obj-y += mtk_wcn_consys_hw.o
+obj-y += wmt_plat_alps.o
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h
new file mode 100644
index 0000000000000..94d6af9d0b3ea
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h
@@ -0,0 +1,287 @@
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _MTK_WCN_CONSYS_HW_H_
+#define _MTK_WCN_CONSYS_HW_H_
+
+#include <sync_write.h>
+/*#include <mt_reg_base.h>*/
+#include "wmt_plat.h"
+
+/*device tree mode*/
+#ifdef CONFIG_OF
+/* #if 1 */
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/irqreturn.h>
+#include <linux/of_address.h>
+#endif
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+#define CONSYS_BT_WIFI_SHARE_V33        0
+#define CONSYS_PMIC_CTRL_ENABLE         1
+#define CONSYS_PMIC_CTRL_UPMU           1
+#define CONSYS_EMI_MPU_SETTING          0
+#define CONSYS_AHB_CLK_MAGEMENT         1
+#define CONSYS_USE_PLATFORM_WRITE       1
+#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1
+#define CONSYS_CLOCK_BUF_CTRL           0
+#if defined(CONFIG_MTK_LEGACY)
+#define CONFIG_MTK_PMIC_LEGACY          0
+#endif
+#define CONFIG_RESET_CONTROL            1
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*tag start:new platform need to make sure these define */
+#define PLATFORM_SOC_CHIP 0x7623
+/*tag end*/
+
+#ifdef CONFIG_OF
+
+struct CONSYS_BASE_ADDRESS {
+	SIZE_T mcu_base;
+	SIZE_T ap_rgu_base;
+	SIZE_T topckgen_base;
+	SIZE_T spm_base;
+};
+
+/*TOPCKGEN_BASE*/
+#define CONSYS_TOP_CLKCG_CLR_OFFSET	0x00000084
+#define CONSYS_TOP_CLKCG_SET_OFFSET	0x00000054
+#define CONSYS_WD_SYS_RST_OFFSET		0x00000018
+#define CONSYS_AP2CONN_OSC_EN_OFFSET	0x00000800
+#define CONSYS_EMI_MAPPING_OFFSET		0x00000310
+/*AP_RGU_BASE*/
+#define CONSYS_CPU_SW_RST_OFFSET		0x00000018
+/*SPM_BASE*/
+#define CONSYS_PWRON_CONFG_EN_OFFSET	0x00000000
+#define CONSYS_TOP1_PWR_CTRL_OFFSET	0x00000280
+#define CONSYS_PWR_CONN_ACK_OFFSET		0x0000060c
+#define CONSYS_PWR_CONN_ACK_S_OFFSET	0x00000610
+/*CONN_MCU_CONFIG_BASE*/
+#define CONSYS_CHIP_ID_OFFSET			0x00000008
+#define CONSYS_ROM_RAM_DELSEL_OFFSET	0x00000114
+#define CONSYS_MCU_CFG_ACR_OFFSET		0x00000110
+#define CONSYS_CPUPCR_OFFSET			0x00000160
+/*AXI bus*/
+
+#define CONSYS_TOPAXI_PROT_EN_OFFSET    0x1220
+#define CONSYS_TOPAXI_PROT_STA1_OFFSET  0x0228
+#endif
+
+#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile UINT32*)(REG)) |= ((UINT32)(BITVAL)))
+#define CONSYS_CLR_BIT(REG, BITVAL)       ((*(volatile UINT32*)(REG)) &= ~((UINT32)(BITVAL)))
+#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\
+	UINT32 val = (*(volatile UINT32*)(REG)); \
+	val &= ~((UINT32)(BITVAL)); \
+	val |= ((UINT32)(KEY)); \
+	(*(volatile UINT32*)(REG)) = val;\
+}
+#define CONSYS_REG_READ(addr) (*((volatile UINT32*)(addr)))
+#if CONSYS_USE_PLATFORM_WRITE
+#define CONSYS_REG_WRITE(addr, data)  mt_reg_sync_writel(data, addr)
+#else
+#define CONSYS_REG_WRITE(addr, data)  (*((volatile UINT32*)(addr)) = (UINT32)(data))
+#endif
+
+/*tag start: connsys register base address (hard code, no use) */
+#define AP_RGU_BASE			0xF0007000
+#define TOPCKGEN_BASE			0xF0000000
+#define SPM_BASE				0xF0006000
+#define CONN_MCU_CONFIG_BASE	0xF8070000
+/*GIC Interrupt ID*/
+#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 237
+/*tag end*/
+
+/*connsys register offset define(hard code mode)*/
+#if 1
+	/*top clock gating control register */
+#define CONSYS_TOP_CLKCG_CLR_REG		(TOPCKGEN_BASE + 0x00000084)
+#define CONSYS_TOP_CLKCG_SET_REG		(TOPCKGEN_BASE + 0x00000054)
+#define CONSYS_TOP_CLKCG_BIT			(0x1 << 26)
+
+	/*SPM clock gating control register */
+#define CONSYS_PWRON_CONFG_EN_REG		(SPM_BASE + 0x00000000)
+#define CONSYS_PWRON_CONFG_EN_VALUE	(0x0b160001)
+#define CONSYS_PWRON_CONFG_DIS_VALUE	(0x0b160000)
+#endif
+
+#define CONSYS_CPU_SW_RST_REG				(AP_RGU_BASE + 0x00000018)
+#define CONSYS_TOP1_PWR_CTRL_REG			(SPM_BASE + 0x00000280)
+#define CONSYS_PWR_CONN_ACK_REG			(SPM_BASE + 0x0000060c)
+#define CONSYS_PWR_CONN_ACK_S_REG			(SPM_BASE + 0x00000610)
+
+#define CONSYS_WD_SYS_RST_REG				(TOPCKGEN_BASE + 0x00000018)
+#define CONSYS_CHIP_ID_REG					(CONN_MCU_CONFIG_BASE + 0x00000008)
+#define CONSYS_ROM_RAM_DELSEL_REG			(CONN_MCU_CONFIG_BASE + 0x00000114)
+#define CONSYS_MCU_CFG_ACR_REG				(CONN_MCU_CONFIG_BASE + 0x00000110)
+#define CONSYS_AFE_REG						(CONN_TOP_CR_BASE + 0x00002000)
+#define CONSYS_AFE_REG_DIG_RCK_01			(CONSYS_AFE_REG + 0x00000010)
+#define CONSYS_AFE_REG_WBG_PLL_02			(CONSYS_AFE_REG + 0x00000028)
+#define CONSYS_AFE_REG_WBG_WB_TX_01			(CONSYS_AFE_REG + 0x0000003c)
+#define CONSYS_AFE_REG_DIG_RCK_01_VALUE	(0x174b0160)
+#define CONSYS_AFE_REG_WBG_PLL_02_VALUE		(0x844083fe)
+#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE	(0x7fc39a20)
+
+#define CONSYS_TOPAXI_PROT_EN				(TOPCKGEN_BASE + 0x0220)
+#define CONSYS_TOPAXI_PROT_STA1				(TOPCKGEN_BASE + 0x0228)
+#define CONSYS_PROT_MASK				((0x1<<13) | (0x1<<14) | (0x1<<15))	/* bit 13, 14, 15 */
+/*CONSYS_CPU_SW_RST_REG*/
+#define CONSYS_CPU_SW_RST_BIT				(0x1 << 12)
+#define CONSYS_CPU_SW_RST_CTRL_KEY			(0x88 << 24)
+
+/*CONSYS_TOP1_PWR_CTRL_REG*/
+#define CONSYS_SPM_PWR_RST_BIT				(0x1 << 0)
+#define CONSYS_SPM_PWR_ISO_S_BIT			(0x1 << 1)
+#define CONSYS_SPM_PWR_ON_BIT				(0x1 << 2)
+#define CONSYS_SPM_PWR_ON_S_BIT			(0x1 << 3)
+#define CONSYS_CLK_CTRL_BIT				(0x1 << 4)
+#define CONSYS_SRAM_CONN_PD_BIT			(0x1 << 8)
+
+/*CONSYS_PWR_CONN_ACK_REG*/
+#define CONSYS_PWR_ON_ACK_BIT				(0x1 << 1)
+
+/*CONSYS_PWR_CONN_ACK_S_REG*/
+#define CONSYS_PWR_CONN_ACK_S_BIT			(0x1 << 1)
+
+/*CONSYS_WD_SYS_RST_REG*/
+#define CONSYS_WD_SYS_RST_CTRL_KEY			(0x88 << 24)
+#define CONSYS_WD_SYS_RST_BIT				(0x1 << 9)
+
+/*CONSYS_MCU_CFG_ACR_REG*/
+#define CONSYS_MCU_CFG_ACR_MBIST_BIT		(0x1 << 18)
+
+/* EMI part mapping & ctrl*/
+#define KBYTE								(1024*sizeof(char))
+#define CONSYS_EMI_AP_PHY_OFFSET			(0x80000)
+#define CONSYS_EMI_AP_PHY_BASE				(0x80080000)
+#define CONSYS_EMI_FW_PHY_BASE				(0xf0080000)
+#define CONSYS_EMI_MEM_SIZE					(343*KBYTE)	/*coredump space , 343K is enough */
+#define CONSYS_EMI_PAGED_TRACE_OFFSET		(0x400)
+#define CONSYS_EMI_PAGED_DUMP_OFFSET		(0x8400)
+#define CONSYS_EMI_FULL_DUMP_OFFSET			(0x10400)
+
+/*cpupcr*/
+#define CONSYS_CPUPCR_REG					(CONN_MCU_CONFIG_BASE + 0x00000160)
+/*emi mapping*/
+#define CONSYS_EMI_MAPPING					(TOPCKGEN_BASE + 0x1310)
+
+/*control app2cnn_osc_en*/
+#define CONSYS_AP2CONN_OSC_EN_REG			(TOPCKGEN_BASE + 0x00001800)
+#define CONSYS_AP2CONN_OSC_EN_BIT			(0x1 << 16)
+#define CONSYS_AP2CONN_WAKEUP_BIT			(0x1 << 17)
+
+/*paged dump address start*/
+#define CONSYS_PAGED_DUMP_START_ADDR		(0xf0088400)
+#define CONSYS_PAGED_DUMP_SIZE				(32*KBYTE)
+
+/*full dump address start*/
+#define CONSYS_FULL_DUMP_START_ADDR			(0xf0090400)
+#define CONSYS_FULL_DUMP_DLM_LEN			(0x1f000)
+#define CONSYS_FULL_DUMP_SYSB2_START		(CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN)
+#define CONSYS_FULL_DUMP_SYSB2_LEN			(0x6800)
+#define CONSYS_FULL_DUMP_SYSB3_START		(CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN)
+#define CONSYS_FULL_DUMP_SYSB3_LEN			(0x16800)
+
+/*force fw assert pattern*/
+#define EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1   (0x19b30bb1)
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _ENUM_EMI_CTRL_STATE_OFFSET_ {
+	EXP_APMEM_CTRL_STATE = 0x0,
+	EXP_APMEM_CTRL_HOST_SYNC_STATE = 0x4,
+	EXP_APMEM_CTRL_HOST_SYNC_NUM = 0x8,
+	EXP_APMEM_CTRL_CHIP_SYNC_STATE = 0xc,
+	EXP_APMEM_CTRL_CHIP_SYNC_NUM = 0x10,
+	EXP_APMEM_CTRL_CHIP_SYNC_ADDR = 0x14,
+	EXP_APMEM_CTRL_CHIP_SYNC_LEN = 0x18,
+	EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START = 0x1c,
+	EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN = 0x20,
+	EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX = 0x24,
+	EXP_APMEM_CTRL_CHIP_INT_STATUS = 0x28,
+	EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END = 0x2c,
+	EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 = 0x30,
+	EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP = 0x48,
+	EXP_APMEM_CTRL_MAX
+} ENUM_EMI_CTRL_STATE_OFFSET, *P_ENUM_EMI_CTRL_STATE_OFFSET;
+
+#if CONSYS_BT_WIFI_SHARE_V33
+typedef struct _BT_WIFI_V33_STATUS_ {
+	UINT32 counter;
+	UINT32 flags;
+	spinlock_t lock;
+} BT_WIFI_V33_STATUS;
+
+#endif
+
+typedef enum _CONSYS_GPS_CO_CLOCK_TYPE_ {
+	GPS_TCXO_TYPE = 0,
+	GPS_CO_TSX_TYPE = 1,
+	GPS_CO_DCXO_TYPE = 2,
+	GPS_CO_VCTCXO_TYPE = 3,
+	GPS_CO_CLOCK_TYPE_MAX
+} CONSYS_GPS_CO_CLOCK_TYPE, *P_CONSYS_GPS_CO_CLOCK_TYPE;
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+extern struct CONSYS_BASE_ADDRESS conn_reg;
+#if CONSYS_BT_WIFI_SHARE_V33
+extern BT_WIFI_V33_STATUS gBtWifiV33;
+#endif
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+extern INT32 mtk_wcn_consys_hw_init(VOID);
+extern INT32 mtk_wcn_consys_hw_deinit(VOID);
+extern INT32 mtk_wcn_consys_hw_pwr_off(VOID);
+extern INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type);
+extern INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type);
+extern INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable);
+extern INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable);
+extern INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable);
+extern INT32 mtk_wcn_consys_hw_state_show(VOID);
+extern UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset);
+#if CONSYS_ENALBE_SET_JTAG
+extern UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en);
+#endif
+extern UINT32 mtk_wcn_consys_soc_chipid(VOID);
+#if !defined(CONFIG_MTK_GPIO_LEGACY)
+extern struct pinctrl *mtk_wcn_consys_get_pinctrl(VOID);
+#endif
+extern INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 buf);
+#endif /* _MTK_WCN_CMB_HW_H_ */
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c
new file mode 100644
index 0000000000000..53b69a7b3e872
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c
@@ -0,0 +1,738 @@
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG "[WMT-CONSYS-HW]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/memblock.h>
+#include "osal_typedef.h"
+#include "mtk_wcn_consys_hw.h"
+#include <linux/mfd/mt6323/registers.h>
+#include <soc/mediatek/pmic_wrap.h>
+#include <linux/regmap.h>
+#if CONSYS_EMI_MPU_SETTING
+#include <emi_mpu.h>
+#endif
+
+#include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
+#ifdef CONFIG_MTK_HIBERNATION
+#include <mtk_hibernate_dpm.h>
+#endif
+
+#include <linux/of_reserved_mem.h>
+
+#if CONSYS_CLOCK_BUF_CTRL
+#include <mt_clkbuf_ctl.h>
+#endif
+
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static INT32 mtk_wmt_probe(struct platform_device *pdev);
+static INT32 mtk_wmt_remove(struct platform_device *pdev);
+
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+struct CONSYS_BASE_ADDRESS conn_reg;
+static phys_addr_t gConEmiPhyBase;
+static UINT8 __iomem *pEmibaseaddr;
+static struct clk *clk_infra_conn_main;	/*ctrl infra_connmcu_bus clk */
+static struct platform_device *my_pdev;
+static struct reset_control *rstc;
+static struct regulator *reg_VCN18;
+static struct regulator *reg_VCN28;
+static struct regulator *reg_VCN33_BT;
+static struct regulator *reg_VCN33_WIFI;
+static struct pinctrl *consys_pinctrl;
+static struct pinctrl *mt6625_spi_pinctrl;
+static struct pinctrl_state *mt6625_spi_default;
+static struct regmap *pmic_regmap;
+#define DYNAMIC_DUMP_GROUP_NUM 5
+
+static const struct of_device_id apwmt_of_ids[] = {
+	{.compatible = "mediatek,mt7623-consys",}
+};
+MODULE_DEVICE_TABLE(of, apwmt_of_ids);
+
+static struct platform_driver mtk_wmt_dev_drv = {
+	.probe = mtk_wmt_probe,
+	.remove = mtk_wmt_remove,
+	.driver = {
+		   .name = "mt7623consys",
+		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(apwmt_of_ids),
+		   },
+};
+
+static INT32 mtk_wmt_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct device_node *node = NULL;
+
+	pm_runtime_enable(&pdev->dev);
+	my_pdev = pdev;
+	mt6625_spi_pinctrl  = devm_pinctrl_get(&pdev->dev);
+	if (IS_ERR(mt6625_spi_pinctrl)) {
+		ret = PTR_ERR(mt6625_spi_pinctrl);
+		WMT_PLAT_ERR_FUNC("Wmt cannot find pinctrl!\n");
+		goto set_pin_exit;
+	}
+	mt6625_spi_default = pinctrl_lookup_state(mt6625_spi_pinctrl, "consys_pins_default");
+	if (IS_ERR(mt6625_spi_default)) {
+		ret = PTR_ERR(mt6625_spi_default);
+		WMT_PLAT_ERR_FUNC("Wmt Cannot find pinctrl default!\n");
+		goto set_pin_exit;
+	}
+	pinctrl_select_state(mt6625_spi_pinctrl, mt6625_spi_default);
+set_pin_exit:
+
+	node = of_parse_phandle(pdev->dev.of_node, "mediatek,pwrap-regmap", 0);
+	if (node) {
+		pmic_regmap = pwrap_node_to_regmap(node);
+		if (IS_ERR(pmic_regmap))
+			goto set_pmic_wrap_exit;
+	} else {
+		WMT_PLAT_ERR_FUNC("Pwrap node has not register regmap.\n");
+		goto set_pmic_wrap_exit;
+	}
+set_pmic_wrap_exit:
+
+	clk_infra_conn_main = devm_clk_get(&pdev->dev, "consysbus");
+	if (IS_ERR(clk_infra_conn_main)) {
+		WMT_PLAT_ERR_FUNC("sean debug [CCF]cannot get clk_infra_conn_main clock.\n");
+		return PTR_ERR(clk_infra_conn_main);
+	}
+	WMT_PLAT_DBG_FUNC("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main);
+
+	reg_VCN18 = devm_regulator_get(&pdev->dev, "vcn18");
+	if (IS_ERR(reg_VCN18)) {
+		ret = PTR_ERR(reg_VCN18);
+		WMT_PLAT_ERR_FUNC("Regulator_get VCN_1V8 fail, ret=%d\n", ret);
+	}
+	reg_VCN28 = devm_regulator_get(&pdev->dev, "vcn28");
+	if (IS_ERR(reg_VCN28)) {
+		ret = PTR_ERR(reg_VCN28);
+		WMT_PLAT_ERR_FUNC("Regulator_get VCN_2V8 fail, ret=%d\n", ret);
+	}
+	reg_VCN33_BT = devm_regulator_get(&pdev->dev, "vcn33_bt");
+	if (IS_ERR(reg_VCN33_BT)) {
+		ret = PTR_ERR(reg_VCN33_BT);
+		WMT_PLAT_ERR_FUNC("Regulator_get VCN33_BT fail, ret=%d\n", ret);
+	}
+	reg_VCN33_WIFI = devm_regulator_get(&pdev->dev, "vcn33_wifi");
+	if (IS_ERR(reg_VCN33_WIFI)) {
+		ret = PTR_ERR(reg_VCN33_WIFI);
+		WMT_PLAT_ERR_FUNC("Regulator_get VCN33_WIFI fail, ret=%d\n", ret);
+	}
+
+	rstc = devm_reset_control_get(&pdev->dev, "connsys");
+	if (IS_ERR(rstc)) {
+		ret = PTR_ERR(rstc);
+		WMT_PLAT_ERR_FUNC("CanNot get consys reset. ret=%d\n", ret);
+		return PTR_ERR(rstc);
+	}
+
+	consys_pinctrl = devm_pinctrl_get(&pdev->dev);
+	if (IS_ERR(consys_pinctrl)) {
+		ret = PTR_ERR(consys_pinctrl);
+		WMT_PLAT_ERR_FUNC("CanNot find consys pinctrl. ret=%d\n", ret);
+		return PTR_ERR(consys_pinctrl);
+	}
+	return 0;
+}
+
+static INT32 mtk_wmt_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+VOID mtk_wcn_consys_power_on(VOID)
+{
+	INT32 iRet = -1;
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+	iRet = pm_runtime_get_sync(&my_pdev->dev);
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+	if (iRet)
+		WMT_PLAT_ERR_FUNC("pm_runtime_get_sync() fail(%d)\n", iRet);
+	else
+		WMT_PLAT_INFO_FUNC("pm_runtime_get_sync() CONSYS ok\n");
+
+	iRet = device_init_wakeup(&my_pdev->dev, true);
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+	if (iRet)
+		WMT_PLAT_ERR_FUNC("device_init_wakeup(true) fail.\n");
+	else
+		WMT_PLAT_INFO_FUNC("device_init_wakeup(true) CONSYS ok\n");
+}
+
+VOID mtk_wcn_consys_power_off(VOID)
+{
+	INT32 iRet = -1;
+
+	iRet = pm_runtime_put_sync(&my_pdev->dev);
+	if (iRet)
+		WMT_PLAT_ERR_FUNC("pm_runtime_put_sync() fail.\n");
+	else
+		WMT_PLAT_INFO_FUNC("pm_runtime_put_sync() CONSYS ok\n");
+
+	iRet = device_init_wakeup(&my_pdev->dev, false);
+	if (iRet)
+		WMT_PLAT_ERR_FUNC("device_init_wakeup(false) fail.\n");
+	else
+		WMT_PLAT_INFO_FUNC("device_init_wakeup(false) CONSYS ok\n");
+}
+
+INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_type)
+{
+	UINT32 retry = 10;
+	UINT32 consysHwChipId = 0;
+
+	WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),start\n", on);
+	if (on) {
+		WMT_PLAT_DBG_FUNC("++\n");
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+		/*need PMIC driver provide new API protocol */
+		/*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8  */
+		regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY);
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+		/* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */
+		if (reg_VCN18) {
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+			regulator_set_voltage(reg_VCN18, 1800000, 1800000);
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+			if (regulator_enable(reg_VCN18))
+				WMT_PLAT_ERR_FUNC("enable VCN18 fail\n");
+			else
+				WMT_PLAT_DBG_FUNC("enable VCN18 ok\n");
+		}
+		udelay(150);
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+		if (co_clock_type) {
+			/*step0,clk buf ctrl */
+			WMT_PLAT_INFO_FUNC("co clock type(%d),turn on clk buf\n", co_clock_type);
+#if CONSYS_CLOCK_BUF_CTRL
+			clk_buf_ctrl(CLK_BUF_CONN, 1);
+#endif
+			/*if co-clock mode: */
+			/*2.set VCN28 to SW control mode (with PMIC_WRAP API) */
+			/*turn on VCN28 LDO only when FMSYS is activated"  */
+			regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/
+		} else {
+			/*if NOT co-clock: */
+			/*2.1.switch VCN28 to HW control mode (with PMIC_WRAP API) */
+			regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x1 << 14);/*V28*/
+			/*2.2.turn on VCN28 LDO (with PMIC_WRAP API)" */
+			/*fix vcn28 not balance warning */
+			if (reg_VCN28) {
+				regulator_set_voltage(reg_VCN28, 2800000, 2800000);
+				if (regulator_enable(reg_VCN28))
+					WMT_PLAT_ERR_FUNC("enable VCN_2V8 fail!\n");
+				else
+					WMT_PLAT_DBG_FUNC("enable VCN_2V8 ok\n");
+			}
+		}
+
+		/*3.assert CONNSYS CPU SW reset  0x10007018 "[12]=1'b1  [31:24]=8'h88 (key)" */
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+		reset_control_reset(rstc);
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+		mtk_wcn_consys_power_on();
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+		/*11.26M is ready now, delay 10us for mem_pd de-assert */
+		udelay(10);
+		/*enable AP bus clock : connmcu_bus_pd  API: enable_clock() ++?? */
+		clk_prepare_enable(clk_infra_conn_main);
+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);
+		WMT_PLAT_DBG_FUNC("[CCF]enable clk_infra_conn_main\n");
+		/*12.poll CONNSYS CHIP ID until chipid is returned  0x18070008 */
+		while (retry-- > 0) {
+			consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET) - 0xf6d;
+
+			if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) {
+				WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId);
+				break;
+			}
+			if ((consysHwChipId == 0x8163) || (consysHwChipId == 0x8127) || (consysHwChipId == 0x7623)) {
+				WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId);
+				break;
+			}
+
+			WMT_PLAT_ERR_FUNC("Read CONSYS chipId(0x%08x)", consysHwChipId);
+			msleep(20);
+		}
+
+		if ((0 == retry) || (0 == consysHwChipId))
+			WMT_PLAT_ERR_FUNC("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId);
+
+		msleep(40);
+
+	} else {
+
+		clk_disable_unprepare(clk_infra_conn_main);
+		WMT_PLAT_DBG_FUNC("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n");
+		mtk_wcn_consys_power_off();
+
+		if (co_clock_type) {
+			/*VCN28 has been turned off by GPS OR FM */
+#if CONSYS_CLOCK_BUF_CTRL
+			clk_buf_ctrl(CLK_BUF_CONN, 0);
+#endif
+		} else {
+			regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/
+			/*turn off VCN28 LDO (with PMIC_WRAP API)" */
+			if (reg_VCN28) {
+				if (regulator_disable(reg_VCN28))
+					WMT_PLAT_ERR_FUNC("disable VCN_2V8 fail!\n");
+				else
+					WMT_PLAT_DBG_FUNC("disable VCN_2V8 ok\n");
+			}
+		}
+
+		/*AP power off MT6625L VCN_1V8 LDO */
+		regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY);
+		if (reg_VCN18) {
+			if (regulator_disable(reg_VCN18))
+				WMT_PLAT_ERR_FUNC("disable VCN_1V8 fail!\n");
+			else
+				WMT_PLAT_DBG_FUNC("disable VCN_1V8 ok\n");
+		}
+
+	}
+	WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),finish\n", on);
+	return 0;
+}
+
+INT32 mtk_wcn_consys_hw_gpio_ctrl(UINT32 on)
+{
+	INT32 iRet = 0;
+
+	WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), start\n", on);
+
+	if (on) {
+
+		/* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */
+		/* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); */
+		iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT);
+		iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS);
+		WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ registered and disabled\n");
+
+	} else {
+
+		/* set bgf eint/all eint to deinit state, namely input low state */
+		iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS);
+		iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT);
+		WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ unregistered and disabled\n");
+		/* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); */
+	}
+	WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), finish\n", on);
+	return iRet;
+
+}
+
+INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type)
+{
+	INT32 iRet = 0;
+
+	WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, start\n");
+
+	iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type);
+	iRet += mtk_wcn_consys_hw_gpio_ctrl(1);
+
+	WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, finish(%d)\n", iRet);
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_hw_pwr_off(VOID)
+{
+	INT32 iRet = 0;
+
+	WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, start\n");
+
+	iRet += mtk_wcn_consys_hw_reg_ctrl(0, 0);
+	iRet += mtk_wcn_consys_hw_gpio_ctrl(0);
+
+	WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, finish(%d)\n", iRet);
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type)
+{
+	INT32 iRet = 0;
+
+	WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst start, eirq should be disabled before this step\n");
+
+	/*1. do whole hw power off flow */
+	iRet += mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type);
+
+	/*2. do whole hw power on flow */
+	iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type);
+
+	WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst finish, eirq should be enabled after this step\n");
+	return iRet;
+}
+
+#if CONSYS_BT_WIFI_SHARE_V33
+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable)
+{
+	/* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */
+	if (enable) {
+		if (1 == gBtWifiV33.counter) {
+			gBtWifiV33.counter++;
+			WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter);
+		} else if (2 == gBtWifiV33.counter) {
+			WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter);
+		} else {
+#if CONSYS_PMIC_CTRL_ENABLE
+			/*do BT PMIC on,depenency PMIC API ready */
+			/*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */
+			/* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */
+			hwPowerOn(MT6323_POWER_LDO_VCN33, VOL_3300, "wcn_drv");
+			upmu_set_vcn33_on_ctrl_bt(1);
+#endif
+			WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 on\n");
+			gBtWifiV33.counter++;
+		}
+
+	} else {
+		if (1 == gBtWifiV33.counter) {
+			/*do BT PMIC off */
+			/*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */
+#if CONSYS_PMIC_CTRL_ENABLE
+		    upmu_set_vcn33_on_ctrl_bt(0);
+			hwPowerDown(MT6323_POWER_LDO_VCN33, "wcn_drv");
+#endif
+			WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 off\n");
+			gBtWifiV33.counter--;
+		} else if (2 == gBtWifiV33.counter) {
+			gBtWifiV33.counter--;
+			WMT_PLAT_DBG_FUNC("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter);
+		} else {
+			WMT_PLAT_DBG_FUNC("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter);
+		}
+
+	}
+	/* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */
+	return 0;
+}
+
+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable)
+{
+	mtk_wcn_consys_hw_bt_paldo_ctrl(enable);
+	return 0;
+}
+
+#else
+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable)
+{
+
+	if (enable) {
+		/*do BT PMIC on,depenency PMIC API ready */
+		/*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */
+		if (reg_VCN33_BT) {
+			regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000);
+			if (regulator_enable(reg_VCN33_BT))
+				WMT_PLAT_ERR_FUNC("WMT do BT PMIC on fail!\n");
+		}
+		regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x1 << 5);/*BT*/
+		WMT_PLAT_INFO_FUNC("WMT do BT PMIC on\n");
+	} else {
+		/*do BT PMIC off */
+		/*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */
+		regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x0 << 5);/*BT*/
+		if (reg_VCN33_BT)
+			if (regulator_disable(reg_VCN33_BT))
+				WMT_PLAT_ERR_FUNC("WMT do BT PMIC off fail!\n");
+		WMT_PLAT_INFO_FUNC("WMT do BT PMIC off\n");
+	}
+
+	return 0;
+
+}
+
+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable)
+{
+
+	if (enable) {
+		/*do WIFI PMIC on,depenency PMIC API ready */
+		/*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */
+		if (reg_VCN33_WIFI) {
+			regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000);
+			if (regulator_enable(reg_VCN33_WIFI))
+				WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC on fail!\n");
+			else
+				WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on !\n");
+		}
+		regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x1 << 14);/*WIFI*/
+		WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on\n");
+	} else {
+		/*do WIFI PMIC off */
+		/*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */
+		regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x0 << 14);/*WIFI*/
+		if (reg_VCN33_WIFI)
+			if (regulator_disable(reg_VCN33_WIFI))
+				WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC off fail!\n");
+		WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC off\n");
+	}
+
+	return 0;
+}
+
+#endif
+INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable)
+{
+	if (enable) {
+		/*in co-clock mode,need to turn on vcn28 when fm on */
+		if (reg_VCN28) {
+			regulator_set_voltage(reg_VCN28, 2800000, 2800000);
+			if (regulator_enable(reg_VCN28))
+				WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC on fail!\n");
+		}
+		WMT_PLAT_INFO_FUNC("turn on vcn28 for fm/gps usage in co-clock mode\n");
+	} else {
+		/*in co-clock mode,need to turn off vcn28 when fm off */
+		if (reg_VCN28)
+			if (regulator_disable(reg_VCN28))
+				WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC off fail!\n");
+		WMT_PLAT_INFO_FUNC("turn off vcn28 for fm/gps usage in co-clock mode\n");
+	}
+	return 0;
+}
+
+INT32 mtk_wcn_consys_hw_state_show(VOID)
+{
+	return 0;
+}
+
+INT32 mtk_wcn_consys_hw_restore(struct device *device)
+{
+	UINT32 addrPhy = 0;
+
+	if (gConEmiPhyBase) {
+
+#if CONSYS_EMI_MPU_SETTING
+		/*set MPU for EMI share Memory */
+		WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n");
+
+#if 0
+	emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2,
+		gConEmiPhyBase + SZ_1M,
+		5,
+		SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION));
+
+
+#else
+		WMT_PLAT_WARN_FUNC("not define platform config\n");
+#endif
+
+#endif
+		/*consys to ap emi remapping register:10001310, cal remapping address */
+		addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20;
+
+		/*enable consys to ap emi remapping bit12 */
+		addrPhy = addrPhy | 0x1000;
+
+		CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET,
+				 CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy);
+
+		WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n",
+				   CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET));
+
+#if 1
+		pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE);
+#else
+		pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE);
+#endif
+		if (pEmibaseaddr) {
+			WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr);
+			memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE);
+		} else {
+			WMT_PLAT_ERR_FUNC("EMI mapping fail\n");
+		}
+	} else {
+		WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n");
+	}
+
+	return 0;
+}
+
+/*Reserved memory by device tree!*/
+int reserve_memory_consys_fn(struct reserved_mem *rmem)
+{
+	WMT_PLAT_WARN_FUNC(" name: %s, base: 0x%llx, size: 0x%llx\n", rmem->name,
+			   (unsigned long long)rmem->base, (unsigned long long)rmem->size);
+	gConEmiPhyBase = rmem->base;
+	return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(reserve_memory_test, "mediatek,consys-reserve-memory", reserve_memory_consys_fn);
+
+
+INT32 mtk_wcn_consys_hw_init(void)
+{
+
+	INT32 iRet = -1;
+	UINT32 addrPhy = 0;
+	INT32 i = 0;
+	struct device_node *node = NULL;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys");
+	if (node) {
+		/* registers base address */
+		conn_reg.mcu_base = (SIZE_T) of_iomap(node, i);
+		WMT_PLAT_DBG_FUNC("Get mcu register base(0x%zx)\n", conn_reg.mcu_base);
+		i++;
+
+		conn_reg.topckgen_base = (SIZE_T) of_iomap(node, i);
+		WMT_PLAT_DBG_FUNC("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base);
+		i++;
+	} else {
+		WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__);
+		return iRet;
+	}
+	if (gConEmiPhyBase) {
+#if CONSYS_EMI_MPU_SETTING
+		/*set MPU for EMI share Memory */
+		WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n");
+
+#if 0
+	emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2,
+		gConEmiPhyBase + SZ_1M,
+		5,
+		SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION));
+#else
+		WMT_PLAT_WARN_FUNC("not define platform config\n");
+#endif
+
+#endif
+		WMT_PLAT_DBG_FUNC("get consys start phy address(0x%zx)\n", (SIZE_T) gConEmiPhyBase);
+
+		/*consys to ap emi remapping register:10001310, cal remapping address */
+		addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20;
+
+		/*enable consys to ap emi remapping bit12 */
+		addrPhy = addrPhy | 0x1000;
+
+		CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET,
+				 CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy);
+
+		WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump(0x%08x)\n",
+				   CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET));
+
+#if 1
+		pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE);
+#else
+		pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE);
+#endif
+		/* pEmibaseaddr = ioremap_nocache(0x80090400,270*KBYTE); */
+		if (pEmibaseaddr) {
+			WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr);
+			memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE);
+			iRet = 0;
+		} else {
+			WMT_PLAT_ERR_FUNC("EMI mapping fail\n");
+		}
+	} else {
+		WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n");
+	}
+#ifdef CONFIG_MTK_HIBERNATION
+	WMT_PLAT_INFO_FUNC("register connsys restore cb for complying with IPOH function\n");
+	register_swsusp_restore_noirq_func(ID_M_CONNSYS, mtk_wcn_consys_hw_restore, NULL);
+#endif
+	iRet = platform_driver_register(&mtk_wmt_dev_drv);
+	if (iRet)
+		WMT_PLAT_ERR_FUNC("WMT platform driver registered failed(%d)\n", iRet);
+	return iRet;
+}
+
+INT32 mtk_wcn_consys_hw_deinit(void)
+{
+	if (pEmibaseaddr) {
+		iounmap(pEmibaseaddr);
+		pEmibaseaddr = NULL;
+	}
+#ifdef CONFIG_MTK_HIBERNATION
+	unregister_swsusp_restore_noirq_func(ID_M_CONNSYS);
+#endif
+
+	platform_driver_unregister(&mtk_wmt_dev_drv);
+	return 0;
+}
+
+UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset)
+{
+	UINT8 *p_virtual_addr = NULL;
+
+	if (!pEmibaseaddr) {
+		WMT_PLAT_ERR_FUNC("EMI base address is NULL\n");
+		return NULL;
+	}
+	WMT_PLAT_DBG_FUNC("ctrl_state_offset(%08x)\n", ctrl_state_offset);
+	p_virtual_addr = pEmibaseaddr + ctrl_state_offset;
+
+	return p_virtual_addr;
+}
+
+UINT32 mtk_wcn_consys_soc_chipid(void)
+{
+	return PLATFORM_SOC_CHIP;
+}
+
+struct pinctrl *mtk_wcn_consys_get_pinctrl()
+{
+	return consys_pinctrl;
+}
+INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 str_buf)
+{
+	PUINT8 vir_addr = NULL;
+
+	vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP);
+	if (!vir_addr) {
+		WMT_PLAT_ERR_FUNC("get vir address fail\n");
+		return -2;
+	}
+	memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8);
+	WMT_PLAT_INFO_FUNC("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr));
+	return 0;
+}
diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c
new file mode 100644
index 0000000000000..7163dc18a255e
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c
@@ -0,0 +1,1071 @@
+/*! \file
+    \brief  Declaration of library functions
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#ifdef DFT_TAG
+#undef DFT_TAG
+#endif
+#define DFT_TAG         "[WMT-PLAT]"
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/delay.h>
+#include <linux/pinctrl/consumer.h>
+/* ALPS header files */
+/*#include <mtk_rtc.h>*/
+/*#include <mt_irq.h>*/
+#if defined(CONFIG_MTK_GPIO_LEGACY)
+#include <mt_gpio.h>
+#endif
+#include <mtk_wcn_cmb_stub.h>
+
+/* MTK_WCN_COMBO header files */
+#include "osal_typedef.h"
+#include "mtk_wcn_consys_hw.h"
+#include "stp_dbg.h"
+
+#define CFG_WMT_WAKELOCK_SUPPORT 1
+
+#ifdef CONFIG_MTK_MT6306_SUPPORT
+#define MTK_WCN_MT6306_IS_READY 1
+#else
+#define MTK_WCN_MT6306_IS_READY 0
+#endif
+
+#if	MTK_WCN_MT6306_IS_READY
+#include <dcl_sim_gpio.h>
+
+#ifdef	GPIO_GPS_LNA_PIN
+#undef	GPIO_GPS_LNA_PIN
+#endif
+
+#define GPIO_GPS_LNA_PIN GPIO7
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = {
+	.emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE,
+	.emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE,
+	.emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM,
+	.emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE,
+	.emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM,
+	.emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR,
+	.emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN,
+	.emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START,
+	.emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN,
+	.emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX,
+	.emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS,
+	.emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END,
+	.emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1,
+};
+
+CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = {
+	.emi_phy_addr = CONSYS_EMI_FW_PHY_BASE,
+	.paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET,
+	.paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET,
+	.full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET,
+	.p_ecso = &mtk_wcn_emi_state_off,
+};
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static VOID wmt_plat_bgf_eirq_cb(VOID);
+
+static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state);
+static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state);
+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state);
+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state);
+
+static INT32 wmt_plat_dump_pin_conf(VOID);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+UINT32 gCoClockFlag = 0;
+BGF_IRQ_BALANCE gbgfIrqBle;
+UINT32 wmtPlatLogLvl = WMT_PLAT_LOG_DBG;
+#if CONSYS_BT_WIFI_SHARE_V33
+BT_WIFI_V33_STATUS gBtWifiV33;
+#endif
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if CFG_WMT_WAKELOCK_SUPPORT
+static struct mutex gOsSLock;
+#ifdef CONFIG_PM_WAKELOCKS
+static struct wakeup_source wmtWakeLock;
+#else
+static struct wake_lock wmtWakeLock;
+#endif
+#endif
+
+irq_cb wmt_plat_bgf_irq_cb = NULL;
+device_audio_if_cb wmt_plat_audio_if_cb = NULL;
+func_ctrl_cb wmt_plat_func_ctrl_cb = NULL;
+thermal_query_ctrl_cb wmt_plat_thermal_query_ctrl_cb = NULL;
+deep_idle_ctrl_cb wmt_plat_deep_idle_ctrl_cb = NULL;
+
+static const fp_set_pin gfp_set_pin_table[] = {
+	[PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl,
+	[PIN_I2S_GRP] = wmt_plat_i2s_ctrl,
+	[PIN_GPS_SYNC] = wmt_plat_gps_sync_ctrl,
+	[PIN_GPS_LNA] = wmt_plat_gps_lna_ctrl,
+};
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*!
+ * \brief audio control callback function for CMB_STUB on ALPS
+ *
+ * A platform function required for dynamic binding with CMB_STUB on ALPS.
+ *
+ * \param state desired audio interface state to use
+ * \param flag audio interface control options
+ *
+ * \retval 0 operation success
+ * \retval -1 invalid parameters
+ * \retval < 0 error for operation fail
+ */
+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl)
+{
+	INT32 iRet = 0;
+	UINT32 pinShare = 0;
+
+	/* input sanity check */
+	if ((CMB_STUB_AIF_MAX <= state)
+	    || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) {
+		return -1;
+	}
+
+	iRet = 0;
+
+	/* set host side first */
+	switch (state) {
+	case CMB_STUB_AIF_0:
+		/* BT_PCM_OFF & FM line in/out */
+		iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT);
+		break;
+
+	case CMB_STUB_AIF_1:
+		iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT);
+		break;
+
+	case CMB_STUB_AIF_2:
+		iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT);
+		break;
+
+	case CMB_STUB_AIF_3:
+		iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT);
+		break;
+
+	default:
+		/* FIXME: move to cust folder? */
+		WMT_PLAT_ERR_FUNC("invalid state [%d]\n", state);
+		iRet = -1;
+		break;
+	}
+
+	if (CMB_STUB_AIF_CTRL_EN == ctrl) {
+		WMT_PLAT_INFO_FUNC("call chip aif setting\n");
+		/* need to control chip side GPIO */
+		if (NULL != wmt_plat_audio_if_cb) {
+			iRet += (*wmt_plat_audio_if_cb) (state, (pinShare) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE);
+		} else {
+			WMT_PLAT_WARN_FUNC("wmt_plat_audio_if_cb is not registered\n");
+			iRet -= 1;
+		}
+
+	} else {
+		WMT_PLAT_INFO_FUNC("skip chip aif setting\n");
+	}
+
+	return iRet;
+
+}
+
+static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on)
+{
+	if (wmt_plat_func_ctrl_cb)
+		(*wmt_plat_func_ctrl_cb) (on, type);
+}
+
+static long wmt_plat_thermal_ctrl(VOID)
+{
+	long temp = 0;
+
+	if (wmt_plat_thermal_query_ctrl_cb)
+		temp = (*wmt_plat_thermal_query_ctrl_cb) ();
+
+	return temp;
+}
+
+static INT32 wmt_plat_deep_idle_ctrl(UINT32 dpilde_ctrl)
+{
+	INT32 iRet = -1;
+
+	if (wmt_plat_deep_idle_ctrl_cb)
+		iRet = (*wmt_plat_deep_idle_ctrl_cb) (dpilde_ctrl);
+
+	return iRet;
+}
+
+static VOID wmt_plat_bgf_eirq_cb(VOID)
+{
+#if CFG_WMT_PS_SUPPORT
+/* #error "need to disable EINT here" */
+	/* wmt_lib_ps_irq_cb(); */
+	if (NULL != wmt_plat_bgf_irq_cb)
+		(*(wmt_plat_bgf_irq_cb)) ();
+	else
+		WMT_PLAT_WARN_FUNC("WMT-PLAT: wmt_plat_bgf_irq_cb not registered\n");
+#else
+	return;
+#endif
+
+}
+
+irqreturn_t wmt_plat_bgf_irq_isr(INT32 i, VOID *arg)
+{
+#if CFG_WMT_PS_SUPPORT
+	wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS);
+	wmt_plat_bgf_eirq_cb();
+#else
+	WMT_PLAT_INFO_FUNC("skip irq handing because psm is disable");
+#endif
+	return IRQ_HANDLED;
+}
+
+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb)
+{
+	wmt_plat_bgf_irq_cb = bgf_irq_cb;
+}
+EXPORT_SYMBOL(wmt_plat_irq_cb_reg);
+
+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb)
+{
+	wmt_plat_audio_if_cb = aif_ctrl_cb;
+}
+EXPORT_SYMBOL(wmt_plat_aif_cb_reg);
+
+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl)
+{
+	wmt_plat_func_ctrl_cb = subsys_func_ctrl;
+}
+EXPORT_SYMBOL(wmt_plat_func_ctrl_cb_reg);
+
+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl)
+{
+	wmt_plat_thermal_query_ctrl_cb = thermal_query_ctrl;
+}
+EXPORT_SYMBOL(wmt_plat_thermal_ctrl_cb_reg);
+
+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl)
+{
+	wmt_plat_deep_idle_ctrl_cb = deep_idle_ctrl;
+}
+EXPORT_SYMBOL(wmt_plat_deep_idle_ctrl_cb_reg);
+
+UINT32 wmt_plat_soc_co_clock_flag_get(VOID)
+{
+	return gCoClockFlag;
+}
+
+static UINT32 wmt_plat_soc_co_clock_flag_set(UINT32 flag)
+{
+	gCoClockFlag = flag;
+	return 0;
+}
+
+INT32 wmt_plat_init(UINT32 co_clock_type)
+{
+	CMB_STUB_CB stub_cb;
+	INT32 iret;
+	/*init wmt function ctrl wakelock if wake lock is supported by host platform */
+
+	wmt_plat_soc_co_clock_flag_set(co_clock_type);
+
+	stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl;
+	stub_cb.func_ctrl_cb = wmt_plat_func_ctrl;
+	stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl;
+	stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl;
+	stub_cb.size = sizeof(stub_cb);
+
+	/* register to cmb_stub */
+	iret = mtk_wcn_cmb_stub_reg(&stub_cb);
+#ifdef CFG_WMT_WAKELOCK_SUPPORT
+#ifdef CONFIG_PM_WAKELOCKS
+	wakeup_source_init(&wmtWakeLock, "wmtFuncCtrl");
+#else
+	wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl");
+#endif
+	mutex_init(&gOsSLock);
+#endif
+
+#if CONSYS_BT_WIFI_SHARE_V33
+	gBtWifiV33.counter = 0;
+	spin_lock_init(&gBtWifiV33.lock);
+#endif
+
+	iret += mtk_wcn_consys_hw_init();
+
+	spin_lock_init(&gbgfIrqBle.lock);
+	WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret);
+
+	return 0;
+}
+EXPORT_SYMBOL(wmt_plat_init);
+
+INT32 wmt_plat_deinit(VOID)
+{
+	INT32 iret = 0;
+	/* 2. unreg to cmb_stub */
+	iret = mtk_wcn_cmb_stub_unreg();
+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wmt wakelock deinit\n",__FUNCTION__,__LINE__);
+	/*3. wmt wakelock deinit */
+#ifdef CFG_WMT_WAKELOCK_SUPPORT
+#ifdef CONFIG_PM_WAKELOCKS
+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wakeup_source_trash\n",__FUNCTION__,__LINE__);
+	wakeup_source_trash(&wmtWakeLock);
+#else
+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wake lock destroy %d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock);
+//destroy calls wakeup_source_trash with &lock->ws
+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock:%d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock);
+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock->ws: %d\n",__FUNCTION__,__LINE__,(int)&(wmtWakeLock.ws));
+	wake_lock_destroy(&wmtWakeLock);
+#endif
+printk(KERN_ALERT "DEBUG: Passed %s %d now calling mutex_destroy\n",__FUNCTION__,__LINE__);
+	mutex_destroy(&gOsSLock);
+	WMT_PLAT_DBG_FUNC("destroy wmtWakeLock\n");
+#endif
+printk(KERN_ALERT "DEBUG: Passed %s %d now calling consys hw deinit\n",__FUNCTION__,__LINE__);
+
+	iret += mtk_wcn_consys_hw_deinit();
+
+	WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret);
+
+	return 0;
+}
+EXPORT_SYMBOL(wmt_plat_deinit);
+
+static INT32 wmt_plat_dump_pin_conf(VOID)
+{
+	WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration start<=\n");
+#if defined(CONFIG_MTK_GPIO_LEGACY)
+
+#ifdef GPIO_COMBO_BGF_EINT_PIN
+	WMT_PLAT_DBG_FUNC("BGF_EINT(GPIO%d)\n", GPIO_COMBO_BGF_EINT_PIN);
+#else
+	WMT_PLAT_DBG_FUNC("BGF_EINT(not defined)\n");
+#endif
+
+#ifdef CUST_EINT_COMBO_BGF_NUM
+	WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(%d)\n", CUST_EINT_COMBO_BGF_NUM);
+#else
+	WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(not defined)\n");
+#endif
+
+#ifdef GPIO_COMBO_URXD_PIN
+	WMT_PLAT_DBG_FUNC("UART_RX(GPIO%d)\n", GPIO_COMBO_URXD_PIN);
+#else
+	WMT_PLAT_DBG_FUNC("UART_RX(not defined)\n");
+#endif
+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT)
+#ifdef GPIO_COMBO_I2S_CK_PIN
+	WMT_PLAT_DBG_FUNC("I2S_CK(GPIO%d)\n", GPIO_COMBO_I2S_CK_PIN);
+#else
+	WMT_PLAT_DBG_FUNC("I2S_CK(not defined)\n");
+#endif
+#ifdef GPIO_COMBO_I2S_WS_PIN
+	WMT_PLAT_DBG_FUNC("I2S_WS(GPIO%d)\n", GPIO_COMBO_I2S_WS_PIN);
+#else
+	WMT_PLAT_DBG_FUNC("I2S_WS(not defined)\n");
+#endif
+#ifdef GPIO_COMBO_I2S_DAT_PIN
+	WMT_PLAT_DBG_FUNC("I2S_DAT(GPIO%d)\n", GPIO_COMBO_I2S_DAT_PIN);
+#else
+	WMT_PLAT_DBG_FUNC("I2S_DAT(not defined)\n");
+#endif
+#else /* FM_ANALOG_INPUT || FM_ANALOG_OUTPUT */
+	WMT_PLAT_DBG_FUNC("FM digital mode is not set, no need for I2S GPIOs\n");
+#endif
+#ifdef GPIO_GPS_SYNC_PIN
+	WMT_PLAT_DBG_FUNC("GPS_SYNC(GPIO%d)\n", GPIO_GPS_SYNC_PIN);
+#else
+	WMT_PLAT_DBG_FUNC("GPS_SYNC(not defined)\n");
+#endif
+
+#ifdef GPIO_GPS_LNA_PIN
+	WMT_PLAT_INFO_FUNC("GPS_LNA(GPIO%d)\n", GPIO_GPS_LNA_PIN);
+#else
+	WMT_PLAT_INFO_FUNC("GPS_LNA(not defined)\n");
+#endif
+
+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */
+#endif
+	WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n");
+	return 0;
+}
+
+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state)
+{
+	INT32 ret = -1;
+
+	switch (state) {
+	case FUNC_ON:
+		/* TODO:[ChangeFeature][George] always output this or by request throuth /proc or sysfs? */
+		wmt_plat_dump_pin_conf();
+		ret = mtk_wcn_consys_hw_pwr_on(gCoClockFlag);
+		break;
+
+	case FUNC_OFF:
+		ret = mtk_wcn_consys_hw_pwr_off();
+		break;
+
+	case FUNC_RST:
+		ret = mtk_wcn_consys_hw_rst(gCoClockFlag);
+		break;
+	case FUNC_STAT:
+		ret = mtk_wcn_consys_hw_state_show();
+		break;
+	default:
+		WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state);
+		break;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(wmt_plat_pwr_ctrl);
+
+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state)
+{
+#ifdef CONFIG_OF
+	struct device_node *node;
+	unsigned int irq_info[3] = { 0, 0, 0 };
+#endif
+	INT32 iret = -EINVAL;
+	static INT32 bgf_irq_num = -1;
+	static UINT32 bgf_irq_flag;
+	/* TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls */
+
+	if ((PIN_STA_INIT != state)
+	    && (PIN_STA_DEINIT != state)
+	    && (PIN_STA_EINT_EN != state)
+	    && (PIN_STA_EINT_DIS != state)) {
+		WMT_PLAT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id);
+		return -1;
+	}
+
+	switch (id) {
+	case PIN_BGF_EINT:
+
+		if (PIN_STA_INIT == state) {
+#ifdef CONFIG_OF
+			node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys");
+			if (node) {
+				bgf_irq_num = irq_of_parse_and_map(node, 0);
+				/* get the interrupt line behaviour */
+				if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) {
+					WMT_PLAT_ERR_FUNC("get irq flags from DTS fail!!\n");
+					return iret;
+				}
+				bgf_irq_flag = irq_info[2];
+				WMT_PLAT_INFO_FUNC("get irq id(%d) and irq trigger flag(%d) from DT\n", bgf_irq_num,
+						   bgf_irq_flag);
+			} else {
+				WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__);
+				return iret;
+			}
+#else
+			bgf_irq_num = MT_CONN2AP_BTIF_WAKEUP_IRQ_ID;
+			bgf_irq_flag = IRQF_TRIGGER_LOW;
+#endif
+			iret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, bgf_irq_flag, "BTIF_WAKEUP_IRQ", NULL);
+			if (iret) {
+				WMT_PLAT_ERR_FUNC("request_irq fail,irq_no(%d),iret(%d)\n", bgf_irq_num, iret);
+				return iret;
+			}
+			gbgfIrqBle.counter = 1;
+
+		} else if (PIN_STA_EINT_EN == state) {
+
+			spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags);
+			if (gbgfIrqBle.counter) {
+				WMT_PLAT_DBG_FUNC("BGF INT has been enabled,counter(%d)\n", gbgfIrqBle.counter);
+			} else {
+				enable_irq(bgf_irq_num);
+				gbgfIrqBle.counter++;
+			}
+			WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (en)\n");
+			spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags);
+		} else if (PIN_STA_EINT_DIS == state) {
+			spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags);
+			if (!gbgfIrqBle.counter) {
+				WMT_PLAT_INFO_FUNC("BGF INT has been disabled,counter(%d)\n", gbgfIrqBle.counter);
+			} else {
+				disable_irq_nosync(bgf_irq_num);
+				gbgfIrqBle.counter--;
+			}
+			WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (dis)\n");
+			spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags);
+		} else {
+			free_irq(bgf_irq_num, NULL);
+			/* de-init: nothing to do in ALPS, such as un-registration... */
+		}
+		iret = 0;
+		break;
+
+	default:
+		WMT_PLAT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id);
+		iret = -1;
+		break;
+	}
+
+	return iret;
+}
+EXPORT_SYMBOL(wmt_plat_eirq_ctrl);
+
+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state)
+{
+	if ((PIN_ID_MAX > id)
+	    && (PIN_STA_MAX > state)) {
+
+		/* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */
+		if (gfp_set_pin_table[id])
+			return (*(gfp_set_pin_table[id])) (state);	/* .handler */
+		WMT_PLAT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id);
+		return -2;
+	}
+	return -1;
+}
+EXPORT_SYMBOL(wmt_plat_gpio_ctrl);
+
+INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state)
+{
+#if defined(CONFIG_MTK_GPIO_LEGACY)
+#ifdef GPIO_COMBO_BGF_EINT_PIN
+	switch (state) {
+	case PIN_STA_INIT:
+		/*set to gpio input low, pull down enable */
+		mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO);
+		mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN);
+		mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN);
+		mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE);
+		WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd)\n");
+		break;
+
+	case PIN_STA_MUX:
+		mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO);
+		mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE);
+		mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_UP);
+		mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_EINT);
+		WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt mux (eint)\n");
+		break;
+
+	case PIN_STA_IN_L:
+	case PIN_STA_DEINIT:
+		/*set to gpio input low, pull down enable */
+		mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO);
+		mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN);
+		mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN);
+		mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE);
+		WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd)\n");
+		break;
+
+	default:
+		WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state);
+		break;
+	}
+#else
+	WMT_PLAT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n");
+#endif
+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */
+#endif
+	return 0;
+}
+
+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state)
+{
+#if defined(CONFIG_MTK_GPIO_LEGACY)
+
+#ifdef GPIO_GPS_SYNC_PIN
+#ifndef GPIO_GPS_SYNC_PIN_M_GPS_SYNC
+#ifdef GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC
+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC
+#else
+#ifdef GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC
+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC
+#endif
+#endif
+#endif
+	switch (state) {
+	case PIN_STA_INIT:
+	case PIN_STA_DEINIT:
+		mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPIO);
+		mt_set_gpio_dir(GPIO_GPS_SYNC_PIN, GPIO_DIR_OUT);
+		mt_set_gpio_out(GPIO_GPS_SYNC_PIN, GPIO_OUT_ZERO);
+		break;
+
+	case PIN_STA_MUX:
+		mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPS_SYNC);
+		break;
+
+	default:
+		break;
+	}
+#endif
+
+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */
+#endif
+	return 0;
+}
+
+#if MTK_WCN_MT6306_IS_READY
+/* MT6306 GPIO7 is GPIO_GPS_LNA_EN, for K2 common phone pin modification	*/
+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state)
+{
+#ifdef GPIO_GPS_LNA_PIN
+	switch (state) {
+	case PIN_STA_INIT:
+	case PIN_STA_DEINIT:
+		WMT_PLAT_ERR_FUNC("Gps LNA pin ctrl %d!\n", state);
+		mt6306_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT);
+		mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO);
+		break;
+	case PIN_STA_OUT_H:
+		WMT_PLAT_ERR_FUNC("Gps LNA pin output high!\n");
+		mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE);
+		break;
+	case PIN_STA_OUT_L:
+		WMT_PLAT_ERR_FUNC("Gps LNA pin output low!\n");
+		mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO);
+		break;
+	default:
+		WMT_PLAT_WARN_FUNC("%d mode not defined for  gps lna pin !!!\n", state);
+		break;
+	}
+	return 0;
+#else
+	WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n");
+	    return 0;
+#endif
+}
+#else
+
+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state)
+{
+#if !defined(CONFIG_MTK_GPIO_LEGACY)
+	static struct pinctrl_state *gps_lna_init;
+	static struct pinctrl_state *gps_lna_oh;
+	static struct pinctrl_state *gps_lna_ol;
+	static struct pinctrl *consys_pinctrl;
+
+	WMT_PLAT_DBG_FUNC("ENTER++\n");
+	consys_pinctrl = mtk_wcn_consys_get_pinctrl();
+	if (NULL == consys_pinctrl) {
+		WMT_PLAT_ERR_FUNC("get consys pinctrl fail\n");
+		return -1;
+	}
+
+	gps_lna_init = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_init");
+	if (NULL == gps_lna_init) {
+		WMT_PLAT_ERR_FUNC("Cannot find gps lna pin init state!\n");
+		return -2;
+	}
+
+	gps_lna_oh = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_oh");
+	if (NULL == gps_lna_oh) {
+		WMT_PLAT_ERR_FUNC("Cannot find gps lna pin oh state!\n");
+		return -3;
+	}
+
+	gps_lna_ol = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_ol");
+	if (NULL == gps_lna_ol) {
+		WMT_PLAT_ERR_FUNC("Cannot find gps lna pin ol state!\n");
+		return -4;
+	}
+
+	switch (state) {
+	case PIN_STA_INIT:
+	case PIN_STA_DEINIT:
+		pinctrl_select_state(consys_pinctrl, gps_lna_init);
+		WMT_PLAT_INFO_FUNC("set gps lna to init\n");
+		break;
+	case PIN_STA_OUT_H:
+		pinctrl_select_state(consys_pinctrl, gps_lna_oh);
+		WMT_PLAT_INFO_FUNC("set gps lna to oh\n");
+		break;
+	case PIN_STA_OUT_L:
+		pinctrl_select_state(consys_pinctrl, gps_lna_ol);
+		WMT_PLAT_INFO_FUNC("set gps lna to ol\n");
+		break;
+
+	default:
+		WMT_PLAT_WARN_FUNC("%d mode not defined for  gps lna pin !!!\n", state);
+		break;
+	}
+	return 0;
+#else
+#ifdef GPIO_GPS_LNA_PIN
+	switch (state) {
+	case PIN_STA_INIT:
+	case PIN_STA_DEINIT:
+		mt_set_gpio_pull_enable(GPIO_GPS_LNA_PIN, GPIO_PULL_DISABLE);
+		mt_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT);
+		mt_set_gpio_mode(GPIO_GPS_LNA_PIN, GPIO_GPS_LNA_PIN_M_GPIO);
+		mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO);
+		break;
+	case PIN_STA_OUT_H:
+		mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE);
+		break;
+	case PIN_STA_OUT_L:
+		mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO);
+		break;
+
+	default:
+		WMT_PLAT_WARN_FUNC("%d mode not defined for  gps lna pin !!!\n", state);
+		break;
+	}
+	return 0;
+#else
+	WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n");
+	    return 0;
+#endif
+#endif /* !defined(CONFIG_MTK_GPIO_LEGACY) */
+}
+#endif
+
+INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state)
+{
+	/* TODO: [NewFeature][GeorgeKuo]: GPIO_I2Sx is changed according to different project. */
+	/* TODO: provide a translation table in board_custom.h for different ALPS project customization. */
+#if defined(CONFIG_MTK_GPIO_LEGACY)
+
+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT)
+#if defined(GPIO_COMBO_I2S_CK_PIN)
+	switch (state) {
+	case PIN_STA_INIT:
+	case PIN_STA_MUX:
+		mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_I2S0_CK);
+		mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_I2S0_WS);
+		mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_I2S0_DAT);
+		WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n");
+		break;
+	case PIN_STA_IN_L:
+	case PIN_STA_DEINIT:
+		mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_GPIO);
+		mt_set_gpio_dir(GPIO_COMBO_I2S_CK_PIN, GPIO_DIR_OUT);
+		mt_set_gpio_out(GPIO_COMBO_I2S_CK_PIN, GPIO_OUT_ZERO);
+
+		mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_GPIO);
+		mt_set_gpio_dir(GPIO_COMBO_I2S_WS_PIN, GPIO_DIR_OUT);
+		mt_set_gpio_out(GPIO_COMBO_I2S_WS_PIN, GPIO_OUT_ZERO);
+
+		mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_GPIO);
+		mt_set_gpio_dir(GPIO_COMBO_I2S_DAT_PIN, GPIO_DIR_OUT);
+		mt_set_gpio_out(GPIO_COMBO_I2S_DAT_PIN, GPIO_OUT_ZERO);
+		WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n");
+		break;
+	default:
+		WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", state);
+		break;
+	}
+#else
+	WMT_PLAT_ERR_FUNC("[MT6620]Error:FM digital mode set, but no I2S GPIOs defined\n");
+#endif
+#else
+	WMT_PLAT_INFO_FUNC
+	    ("[MT6620]warnning:FM digital mode is not set, no I2S GPIO settings should be modified by combo driver\n");
+#endif
+
+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */
+#endif
+	return 0;
+}
+
+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId)
+{
+#ifdef CFG_WMT_WAKELOCK_SUPPORT
+	static INT32 counter;
+	INT32 status;
+	INT32 ret = 0;
+
+	ret = mutex_lock_killable(&gOsSLock);
+	if (ret) {
+		WMT_PLAT_ERR_FUNC("--->lock gOsSLock failed, ret=%d\n", ret);
+		return ret;
+	}
+
+	if (WL_OP_GET == opId)
+		++counter;
+	else if (WL_OP_PUT == opId)
+		--counter;
+
+	mutex_unlock(&gOsSLock);
+	if (WL_OP_GET == opId && counter == 1) {
+		#ifdef CONFIG_PM_WAKELOCKS
+		__pm_stay_awake(&wmtWakeLock);
+		status = wmtWakeLock.active;
+		#else
+		wake_lock(&wmtWakeLock);
+		status = wake_lock_active(&wmtWakeLock);
+		#endif
+		WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", status, counter);
+
+	} else if (WL_OP_PUT == opId && counter == 0) {
+		#ifdef CONFIG_PM_WAKELOCKS
+		__pm_relax(&wmtWakeLock);
+		status = wmtWakeLock.active;
+		#else
+		wake_unlock(&wmtWakeLock);
+		status = wake_lock_active(&wmtWakeLock);
+		#endif
+		WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", status, counter);
+	} else {
+		#ifdef CONFIG_PM_WAKELOCKS
+		status = wmtWakeLock.active;
+		#else
+		status = wake_lock_active(&wmtWakeLock);
+		#endif
+		WMT_PLAT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", status, counter);
+	}
+	return 0;
+#else
+	WMT_PLAT_WARN_FUNC("WMT-PLAT: host awake function is not supported.\n");
+	return 0;
+
+#endif
+}
+EXPORT_SYMBOL(wmt_plat_wake_lock_ctrl);
+
+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo)
+{
+	INT32 iRet = 0;
+
+	switch (ePt) {
+
+	case BT_PALDO:
+		iRet = mtk_wcn_consys_hw_bt_paldo_ctrl(ePo);
+		break;
+	case WIFI_PALDO:
+		iRet = mtk_wcn_consys_hw_wifi_paldo_ctrl(ePo);
+		break;
+	case FM_PALDO:
+	case GPS_PALDO:
+		iRet = mtk_wcn_consys_hw_vcn28_ctrl(ePo);
+		break;
+	default:
+		WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid type(%d) in palod_ctrl\n", ePt);
+		break;
+	}
+	return iRet;
+}
+EXPORT_SYMBOL(wmt_plat_soc_paldo_ctrl);
+
+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset)
+{
+	return mtk_wcn_consys_emi_virt_addr_get(offset);
+}
+EXPORT_SYMBOL(wmt_plat_get_emi_virt_add);
+
+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID)
+{
+	return &mtk_wcn_emi_addr_info;
+}
+EXPORT_SYMBOL(wmt_plat_get_emi_phy_add);
+
+#if CONSYS_ENALBE_SET_JTAG
+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en)
+{
+	return 0;
+}
+EXPORT_SYMBOL(wmt_plat_jtag_flag_ctrl);
+#endif
+
+#if CFG_WMT_DUMP_INT_STATUS
+VOID wmt_plat_BGF_irq_dump_status(VOID)
+{
+	WMT_PLAT_INFO_FUNC("this function is null in MT8127\n");
+}
+EXPORT_SYMBOL(wmt_plat_BGF_irq_dump_status);
+
+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID)
+{
+	return MTK_WCN_BOOL_FALSE;
+}
+EXPORT_SYMBOL(wmt_plat_dump_BGF_irq_status);
+#endif
+
+UINT32 wmt_plat_read_cpupcr(void)
+{
+	return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET);
+}
+EXPORT_SYMBOL(wmt_plat_read_cpupcr);
+
+UINT32 wmt_plat_read_dmaregs(UINT32 type)
+{
+	return 0;
+#if 0
+	switch (type) {
+	case CONNSYS_CLK_GATE_STATUS:
+		return CONSYS_REG_READ(CONNSYS_CLK_GATE_STATUS_REG);
+	case CONSYS_EMI_STATUS:
+		return CONSYS_REG_READ(CONSYS_EMI_STATUS_REG);
+	case SYSRAM1:
+		return CONSYS_REG_READ(SYSRAM1_REG);
+	case SYSRAM2:
+		return CONSYS_REG_READ(SYSRAM2_REG);
+	case SYSRAM3:
+		return CONSYS_REG_READ(SYSRAM3_REG);
+	default:
+		return 0;
+	}
+#endif
+}
+
+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state)
+{
+	PUINT8 p_virtual_addr = NULL;
+
+	p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_STATE);
+	if (!p_virtual_addr) {
+		WMT_PLAT_ERR_FUNC("get virtual address fail\n");
+		return -1;
+	}
+
+	CONSYS_REG_WRITE(p_virtual_addr, state);
+
+	return 0;
+}
+EXPORT_SYMBOL(wmt_plat_set_host_dump_state);
+
+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type)
+{
+	PUINT8 p_virtual_addr = NULL;
+
+	switch (type) {
+	case STP_FORCE_TRG_ASSERT_EMI:
+
+		WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n");
+		p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1);
+		if (!p_virtual_addr) {
+			WMT_PLAT_ERR_FUNC("get virtual address fail\n");
+			return -1;
+		}
+
+		CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1);
+		WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n");
+		break;
+	case STP_FORCE_TRG_ASSERT_DEBUG_PIN:
+
+		CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET,
+				 CONSYS_REG_READ(conn_reg.topckgen_base +
+						 CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT);
+		WMT_PLAT_INFO_FUNC("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n",
+				   CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET));
+		usleep_range(64, 96);
+		CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET,
+				 CONSYS_REG_READ(conn_reg.topckgen_base +
+						 CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT);
+		WMT_PLAT_INFO_FUNC("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n",
+				   CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET));
+
+		break;
+	default:
+		WMT_PLAT_ERR_FUNC("unknown force trigger assert type\n");
+		break;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(wmt_plat_force_trigger_assert);
+
+INT32 wmt_plat_update_host_sync_num(VOID)
+{
+	PUINT8 p_virtual_addr = NULL;
+	UINT32 sync_num = 0;
+
+	p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_NUM);
+	if (!p_virtual_addr) {
+		WMT_PLAT_ERR_FUNC("get virtual address fail\n");
+		return -1;
+	}
+
+	sync_num = CONSYS_REG_READ(p_virtual_addr);
+	CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1);
+
+	return 0;
+}
+EXPORT_SYMBOL(wmt_plat_update_host_sync_num);
+
+INT32 wmt_plat_get_dump_info(UINT32 offset)
+{
+	PUINT8 p_virtual_addr = NULL;
+
+	p_virtual_addr = wmt_plat_get_emi_virt_add(offset);
+	if (!p_virtual_addr) {
+		WMT_PLAT_ERR_FUNC("get virtual address fail\n");
+		return -1;
+	}
+	WMT_PLAT_INFO_FUNC("connsys_reg_read (0x%x), (0x%p), (0x%x)\n", CONSYS_REG_READ(p_virtual_addr), p_virtual_addr,
+			   offset);
+	return CONSYS_REG_READ(p_virtual_addr);
+}
+EXPORT_SYMBOL(wmt_plat_get_dump_info);
+
+UINT32 wmt_plat_get_soc_chipid(void)
+{
+	UINT32 chipId = mtk_wcn_consys_soc_chipid();
+
+	WMT_PLAT_INFO_FUNC("current SOC chip:0x%x\n", chipId);
+	return chipId;
+}
+EXPORT_SYMBOL(wmt_plat_get_soc_chipid);
+
+#if CFG_WMT_LTE_COEX_HANDLING
+INT32 wmt_plat_get_tdm_antsel_index(VOID)
+{
+	WMT_PLAT_INFO_FUNC("not support LTE in this platform\n");
+	return 0;
+}
+EXPORT_SYMBOL(wmt_plat_get_tdm_antsel_index);
+#endif
+INT32 wmt_plat_set_dbg_mode(UINT32 flag)
+{
+	return -1;
+}
+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf)
+{
+	mtk_wcn_consys_set_dynamic_dump(buf);
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/Makefile b/drivers/misc/mediatek/connectivity/wlan/Makefile
new file mode 100644
index 0000000000000..2961aeb073eaa
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/Makefile
@@ -0,0 +1,8 @@
+ifeq ($(CONFIG_MTK_COMBO_WIFI),y)
+    subdir-ccflags-y += -D MTK_WCN_BUILT_IN_DRIVER
+endif
+
+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),)
+#$(warning include gen2)
+	obj-y   +=  gen2/
+endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile
new file mode 100644
index 0000000000000..b86ab49fce3a0
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile
@@ -0,0 +1,237 @@
+# ---------------------------------------------------
+# Compile Options
+# ---------------------------------------------------
+ccflags-y += -DLINUX -DMT6628
+
+ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=1
+ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1
+ccflags-y += -DCFG_P2P_LEGACY_COEX_REVISE=1
+ccflags-y += -DARP_MONITER_ENABLE=1
+
+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y)
+    ccflags-y += -DCFG_SUPPORT_WAPI=1
+else
+    ccflags-y += -DCFG_SUPPORT_WAPI=0
+endif
+
+ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y)
+    ccflags-y += -DCFG_SUPPORT_MCC=1
+else
+	ccflags-y += -DCFG_SUPPORT_MCC=0
+endif
+
+ifeq ($(CONFIG_HAVE_XLOG_FEATURE), y)
+    ccflags-y += -DCFG_SUPPORT_XLOG=1
+else
+    ccflags-y += -DCFG_SUPPORT_XLOG=0
+endif
+
+ifeq ($(CONFIG_MTK_AEE_FEATURE), y)
+    ccflags-y += -DCFG_SUPPORT_AEE=1
+else
+    ccflags-y += -DCFG_SUPPORT_AEE=0
+endif
+
+#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y)
+#    ccflags-y += -D_HIF_SDIO=1
+#endif
+
+ifeq ($(CONFIG_MTK_PASSPOINT_R1_SUPPORT), y)
+    ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=1
+    ccflags-y += -DCFG_HS20_DEBUG=1
+    ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1
+else
+    ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=0
+    ccflags-y += -DCFG_HS20_DEBUG=0
+    ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0
+endif
+
+MTK_MET_PROFILING_SUPPORT = no
+ifeq ($(MTK_MET_PROFILING_SUPPORT), yes)
+    ccflags-y += -DCFG_SUPPORT_MET_PROFILING=1
+else
+    ccflags-y += -DCFG_SUPPORT_MET_PROFILING=0
+endif
+
+ifeq ($(CONFIG_MTK_TC1_FEATURE), y)
+ifeq ($(CONFIG_MTK_GPT_SCHEME_SUPPORT), y)
+    ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/gpt
+else
+    ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/pmt
+endif
+    ccflags-y += -DCFG_TC1_FEATURE=1
+	ccflags-y += -DCFG_SUPPORT_CFG_FILE=1
+else
+    ccflags-y += -DCFG_TC1_FEATURE=0
+endif
+
+MTK_SRAM_SIZE_OPTION=0
+ifeq ($(CONFIG_ARCH_MT6755), y)
+    MTK_SRAM_SIZE_OPTION=2
+endif
+ifeq ($(CONFIG_ARCH_MT6735), y)
+    MTK_SRAM_SIZE_OPTION=1
+endif
+ifeq ($(CONFIG_ARCH_MT6735M), y)
+    MTK_SRAM_SIZE_OPTION=1
+endif
+ifeq ($(CONFIG_ARCH_MT6753), y)
+    MTK_SRAM_SIZE_OPTION=1
+endif
+ifeq ($(CONFIG_ARCH_MT6580), y)
+    MTK_SRAM_SIZE_OPTION=1
+endif
+ifeq ($(CONFIG_ARCH_MT8163), y)
+    MTK_SRAM_SIZE_OPTION=1
+endif
+ccflags-y += -DCFG_SRAM_SIZE_OPTION=$(MTK_SRAM_SIZE_OPTION)
+
+ifeq ($(strip $(TRUSTONIC_TEE_SUPPORT)),yes)
+ifeq ($(strip $(MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT)),yes)
+    ccflags-y += -DTRUSTONIC_TEE_SUPPORT
+    ccflags-y += -DMTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT
+endif
+endif
+
+ccflags-y += -D_HIF_SDIO=1
+
+ccflags-y += -DDBG=0
+ccflags-y += -I$(src)/os -I$(src)/os/linux/include -I$(src)/os/linux/hif/ahb/include
+ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/
+
+MODULE_NAME := wlan_gen2
+obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o
+#obj-m += $(MODULE_NAME).o if CONFIG_MTK_COMBO_WIFI=m ==> obj-m means ko module, not build in obj-y
+
+# ---------------------------------------------------
+# Directory List
+# ---------------------------------------------------
+COMMON_DIR  := common/
+OS_DIR      := os/linux/
+HIF_DIR	    := os/linux/hif/ahb/
+NIC_DIR     := nic/
+MGMT_DIR    := mgmt/
+DMA_DIR     := ../../../../platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/wifi/
+PLAT_DIR    := os/linux/plat/$(MTK_PLATFORM)/
+HIF_AHB_PDMA := $(HIF_DIR)$(MTK_PLATFORM)/
+#$(call lc,$(MTK_PLATFORM))
+
+
+# ---------------------------------------------------
+# Objects List
+# ---------------------------------------------------
+
+COMMON_OBJS :=	$(COMMON_DIR)dump.o \
+	       		$(COMMON_DIR)wlan_lib.o \
+	       		$(COMMON_DIR)wlan_oid.o \
+	       		$(COMMON_DIR)wlan_bow.o \
+				$(COMMON_DIR)debug.o
+
+NIC_OBJS := $(NIC_DIR)nic.o \
+			$(NIC_DIR)nic_tx.o \
+			$(NIC_DIR)nic_rx.o \
+			$(NIC_DIR)nic_pwr_mgt.o \
+			$(NIC_DIR)cmd_buf.o \
+			$(NIC_DIR)que_mgt.o \
+			$(NIC_DIR)nic_cmd_event.o
+
+OS_OBJS :=	$(OS_DIR)gl_init.o \
+			$(OS_DIR)gl_kal.o  \
+			$(OS_DIR)gl_bow.o \
+			$(OS_DIR)gl_wext.o \
+			$(OS_DIR)gl_wext_priv.o \
+			$(OS_DIR)gl_rst.o \
+			$(OS_DIR)gl_cfg80211.o \
+			$(OS_DIR)gl_vendor.o \
+			$(OS_DIR)platform.o		\
+			$(OS_DIR)gl_proc.o
+
+MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \
+			 $(MGMT_DIR)aaa_fsm.o \
+			 $(MGMT_DIR)assoc.o \
+			 $(MGMT_DIR)auth.o \
+			 $(MGMT_DIR)bss.o \
+			 $(MGMT_DIR)cnm.o \
+			 $(MGMT_DIR)cnm_timer.o \
+			 $(MGMT_DIR)cnm_mem.o \
+			 $(MGMT_DIR)hem_mbox.o \
+			 $(MGMT_DIR)mib.o \
+			 $(MGMT_DIR)privacy.o  \
+			 $(MGMT_DIR)rate.o \
+			 $(MGMT_DIR)rlm.o \
+			 $(MGMT_DIR)rlm_domain.o \
+			 $(MGMT_DIR)rlm_obss.o \
+			 $(MGMT_DIR)rlm_protection.o \
+			 $(MGMT_DIR)rsn.o \
+			 $(MGMT_DIR)saa_fsm.o \
+			 $(MGMT_DIR)scan.o \
+			 $(MGMT_DIR)scan_fsm.o \
+		 	 $(MGMT_DIR)sec_fsm.o \
+             $(MGMT_DIR)swcr.o \
+ 			 $(MGMT_DIR)swcr.o \
+			 $(MGMT_DIR)roaming_fsm.o \
+			 $(MGMT_DIR)hs20.o
+
+# ---------------------------------------------------
+# TDLS Objects List
+# ---------------------------------------------------
+MGMT_OBJS += $(MGMT_DIR)tdls.o \
+			 $(MGMT_DIR)tdls_com.o
+
+# ---------------------------------------------------
+# STATS Objects List
+# ---------------------------------------------------
+MGMT_OBJS += $(MGMT_DIR)stats.o
+
+# ---------------------------------------------------
+# P2P Objects List
+# ---------------------------------------------------
+
+COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o
+
+NIC_OBJS += $(NIC_DIR)p2p_nic.o
+
+OS_OBJS += $(OS_DIR)gl_p2p.o \
+           $(OS_DIR)gl_p2p_cfg80211.o \
+           $(OS_DIR)gl_p2p_init.o \
+           $(OS_DIR)gl_p2p_kal.o
+
+MGMT_OBJS += $(MGMT_DIR)p2p_assoc.o \
+             $(MGMT_DIR)p2p_bss.o \
+             $(MGMT_DIR)p2p_fsm.o \
+             $(MGMT_DIR)p2p_func.o \
+             $(MGMT_DIR)p2p_rlm.o \
+             $(MGMT_DIR)p2p_rlm_obss.o \
+             $(MGMT_DIR)p2p_scan.o \
+             $(MGMT_DIR)p2p_ie.o \
+             $(MGMT_DIR)p2p_state.o
+
+
+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y)
+MGMT_OBJS += $(MGMT_DIR)wapi.o
+endif
+
+ifeq ($(WLAN_PROC), y)
+OS_OBJS += gl_proc.o
+endif
+
+#$(warning $(CONFIG_MACH_MT7623))
+
+ifeq ($(CONFIG_MACH_MT7623), y)
+HIF_AHB_PDMA = $(HIF_DIR)mt8127/
+endif
+HIF_OBJS :=  $(HIF_DIR)arm.o \
+             $(HIF_DIR)ahb.o \
+             $(HIF_AHB_PDMA)ahb_pdma.o
+ifeq ($(CONFIG_ARCH_MT6755), y)
+PLAT_OBJS := $(PLAT_DIR)plat_priv.o
+$(MODULE_NAME)-objs  += $(PLAT_OBJS)
+endif
+$(MODULE_NAME)-objs  += $(COMMON_OBJS)
+$(MODULE_NAME)-objs  += $(NIC_OBJS)
+$(MODULE_NAME)-objs  += $(OS_OBJS)
+$(MODULE_NAME)-objs  += $(HIF_OBJS)
+$(MODULE_NAME)-objs  += $(MGMT_OBJS)
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c
new file mode 100644
index 0000000000000..e31e0b86d231e
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c
@@ -0,0 +1,165 @@
+#include "precomp.h"
+#include "gl_kal.h"
+
+struct COMMAND {
+	UINT_8 ucCID;
+	BOOLEAN fgSetQuery;
+	BOOLEAN fgNeedResp;
+	UINT_8 ucCmdSeqNum;
+};
+
+struct SECURITY_FRAME {
+	UINT_16 u2EthType;
+	UINT_16 u2Reserved;
+};
+
+struct MGMT_FRAME {
+	UINT_16 u2FrameCtl;
+	UINT_16 u2DurationID;
+};
+
+struct TC_RES_RELEASE_ENTRY {
+	UINT_64 u8RelaseTime;
+	UINT_32 u4RelCID;
+	UINT_8	ucTc4RelCnt;
+	UINT_8	ucAvailableTc4;
+};
+
+struct CMD_TRACE_ENTRY {
+	UINT_64 u8TxTime;
+	COMMAND_TYPE eCmdType;
+	union {
+		struct COMMAND rCmd;
+		struct SECURITY_FRAME rSecFrame;
+		struct MGMT_FRAME rMgmtFrame;
+	} u;
+};
+
+#define TC_RELEASE_TRACE_BUF_MAX_NUM 100
+#define TXED_CMD_TRACE_BUF_MAX_NUM 100
+
+static struct TC_RES_RELEASE_ENTRY *gprTcReleaseTraceBuffer;
+static struct CMD_TRACE_ENTRY *gprCmdTraceEntry;
+VOID wlanDebugInit(VOID)
+{
+	/* debug for command/tc4 resource begin */
+	gprTcReleaseTraceBuffer =
+		kalMemAlloc(TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY), PHY_MEM_TYPE);
+	kalMemZero(gprTcReleaseTraceBuffer, TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY));
+	gprCmdTraceEntry = kalMemAlloc(TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY), PHY_MEM_TYPE);
+	kalMemZero(gprCmdTraceEntry, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY));
+	/* debug for command/tc4 resource end */
+}
+
+VOID wlanDebugUninit(VOID)
+{
+	/* debug for command/tc4 resource begin */
+	kalMemFree(gprTcReleaseTraceBuffer, PHY_MEM_TYPE,
+			TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY));
+	kalMemFree(gprCmdTraceEntry, PHY_MEM_TYPE, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY));
+	/* debug for command/tc4 resource end */
+}
+
+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd)
+{
+	static UINT_16 u2CurEntry;
+	struct CMD_TRACE_ENTRY *prCurCmd = &gprCmdTraceEntry[u2CurEntry];
+
+	prCurCmd->u8TxTime = sched_clock();
+	prCurCmd->eCmdType = prCmd->eCmdType;
+	if (prCmd->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
+		P_WLAN_MAC_MGMT_HEADER_T prMgmt = (P_WLAN_MAC_MGMT_HEADER_T)((P_MSDU_INFO_T)prCmd->prPacket)->prPacket;
+
+		prCurCmd->u.rMgmtFrame.u2FrameCtl = prMgmt->u2FrameCtrl;
+		prCurCmd->u.rMgmtFrame.u2DurationID = prMgmt->u2Duration;
+	} else if (prCmd->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
+		PUINT_8 pucPkt = (PUINT_8)((struct sk_buff *)prCmd->prPacket)->data;
+
+		prCurCmd->u.rSecFrame.u2EthType =
+				(pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]);
+	} else {
+		prCurCmd->u.rCmd.ucCID = prCmd->ucCID;
+		prCurCmd->u.rCmd.ucCmdSeqNum = prCmd->ucCmdSeqNum;
+		prCurCmd->u.rCmd.fgNeedResp = prCmd->fgNeedResp;
+		prCurCmd->u.rCmd.fgSetQuery = prCmd->fgSetQuery;
+	}
+	u2CurEntry++;
+	if (u2CurEntry == TC_RELEASE_TRACE_BUF_MAX_NUM)
+		u2CurEntry = 0;
+}
+
+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable)
+{
+	static UINT_16 u2CurEntry;
+	struct TC_RES_RELEASE_ENTRY *prCurBuf = &gprTcReleaseTraceBuffer[u2CurEntry];
+
+	HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &prCurBuf->u4RelCID);
+	prCurBuf->u8RelaseTime = sched_clock();
+	prCurBuf->ucTc4RelCnt = aucTxRlsCnt[TC4_INDEX];
+	prCurBuf->ucAvailableTc4 = ucAvailable;
+	u2CurEntry++;
+	if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM)
+		u2CurEntry = 0;
+}
+
+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen)
+{
+	UINT_16 i = 0;
+	struct CMD_TRACE_ENTRY *prCmd = gprCmdTraceEntry;
+	struct TC_RES_RELEASE_ENTRY *prTcRel = gprTcReleaseTraceBuffer;
+
+	if (pucBuf) {
+		int bufLen = 0;
+
+		for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/2; i++) {
+			bufLen = snprintf(pucBuf, maxLen,
+				"%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n",
+				i*2, prCmd[i*2].u8TxTime, prCmd[i*2].eCmdType, *(PUINT_32)(&prCmd[i*2].u.rCmd.ucCID),
+				i*2+1, prCmd[i*2+1].u8TxTime, prCmd[i*2+1].eCmdType,
+				*(PUINT_32)(&prCmd[i*2+1].u.rCmd.ucCID));
+			if (bufLen <= 0 || (UINT_32)bufLen >= maxLen)
+				break;
+			pucBuf += bufLen;
+			maxLen -= bufLen;
+		}
+		for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/2; i++) {
+			bufLen = snprintf(pucBuf, maxLen,
+				"%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d CID %08x\n",
+				i*2, prTcRel[i*2].u8RelaseTime, prTcRel[i*2].ucTc4RelCnt, prTcRel[i*2].ucAvailableTc4,
+				prTcRel[i*2].u4RelCID,
+				i*2+1, prTcRel[i*2+1].u8RelaseTime, prTcRel[i*2+1].ucTc4RelCnt,
+				prTcRel[i*2+1].ucAvailableTc4, prTcRel[i*2+1].u4RelCID);
+			if (bufLen <= 0 || (UINT_32)bufLen >= maxLen)
+				break;
+			pucBuf += bufLen;
+			maxLen -= bufLen;
+		}
+		return;
+	}
+	for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/4; i++) {
+		LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x; ",
+			i*4, prCmd[i*4].u8TxTime, prCmd[i*4].eCmdType,
+			*(PUINT_32)(&prCmd[i*4].u.rCmd.ucCID),
+			i*4+1, prCmd[i*4+1].u8TxTime, prCmd[i*4+1].eCmdType,
+			*(PUINT_32)(&prCmd[i*4+1].u.rCmd.ucCID));
+		LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n",
+			i*4+2, prCmd[i*4+2].u8TxTime, prCmd[i*4+2].eCmdType,
+			*(PUINT_32)(&prCmd[i*4+2].u.rCmd.ucCID),
+			i*4+3, prCmd[i*4+3].u8TxTime, prCmd[i*4+3].eCmdType,
+			*(PUINT_32)(&prCmd[i*4+3].u.rCmd.ucCID));
+	}
+	for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/4; i++) {
+		LOG_FUNC(
+			"%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x;",
+			i*4, prTcRel[i*4].u8RelaseTime, prTcRel[i*4].ucTc4RelCnt,
+			prTcRel[i*4].ucAvailableTc4, prTcRel[i*4].u4RelCID,
+			i*4+1, prTcRel[i*4+1].u8RelaseTime, prTcRel[i*4+1].ucTc4RelCnt,
+			prTcRel[i*4+1].ucAvailableTc4, prTcRel[i*4+1].u4RelCID);
+		LOG_FUNC(
+			" %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x\n",
+			i*4+2, prTcRel[i*4+2].u8RelaseTime, prTcRel[i*4+2].ucTc4RelCnt,
+			prTcRel[i*4+2].ucAvailableTc4, prTcRel[i*4+2].u4RelCID,
+			i*4+3, prTcRel[i*4+3].u8RelaseTime, prTcRel[i*4+3].ucTc4RelCnt,
+			prTcRel[i*4+3].ucAvailableTc4, prTcRel[i*4+3].u4RelCID);
+	}
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c
new file mode 100644
index 0000000000000..486ba239f16a5
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c
@@ -0,0 +1,345 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/dump.c#1
+*/
+
+/*! \file   "dump.c"
+    \brief  Provide memory dump function for debugging.
+
+    Provide memory dump function for debugging.
+*/
+
+/*
+** Log: dump.c
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Using the new XLOG define for dum Memory.
+ *
+ * 11 03 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Add dumpMemory8 at XLOG support.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 19:58:51 GMT mtk01426
+**  Init develop
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to dump a segment of memory in bytes.
+*
+* \param[in] pucStartAddr   Pointer to the starting address of the memory to be dumped.
+* \param[in] u4Length       Length of the memory to be dumped.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length)
+{
+	ASSERT(pucStartAddr);
+
+	LOG_FUNC("DUMP8 ADDRESS: %p, Length: %u\n", pucStartAddr, u4Length);
+
+	while (u4Length > 0) {
+		if (u4Length >= 16) {
+			LOG_FUNC(
+			"(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x %02x %02x %02x  %02x %02x %02x %02x\n",
+			pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+			pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], pucStartAddr[8],
+			pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], pucStartAddr[12], pucStartAddr[13],
+			pucStartAddr[14], pucStartAddr[15]);
+			u4Length -= 16;
+			pucStartAddr += 16;
+		} else {
+			switch (u4Length) {
+			case 1:
+				LOG_FUNC("(%p) %02x\n", pucStartAddr, pucStartAddr[0]);
+				break;
+			case 2:
+				LOG_FUNC("(%p) %02x %02x\n", pucStartAddr, pucStartAddr[0], pucStartAddr[1]);
+				break;
+			case 3:
+				LOG_FUNC("(%p) %02x %02x %02x\n",
+					pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2]);
+				break;
+			case 4:
+				LOG_FUNC("(%p) %02x %02x %02x %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3]);
+				break;
+			case 5:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4]);
+				break;
+			case 6:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5]);
+				break;
+			case 7:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5], pucStartAddr[6]);
+				break;
+			case 8:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7]);
+				break;
+			case 9:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7],
+					pucStartAddr[8]);
+				break;
+			case 10:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7],
+					pucStartAddr[8], pucStartAddr[9]);
+				break;
+			case 11:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x %02x %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7],
+					pucStartAddr[8], pucStartAddr[9], pucStartAddr[10]);
+				break;
+			case 12:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x %02x %02x %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7],
+					pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11]);
+				break;
+			case 13:
+				LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x %02x %02x %02x  %02x\n",
+					pucStartAddr,
+					pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+					pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7],
+					pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11],
+					pucStartAddr[12]);
+				break;
+			case 14:
+			LOG_FUNC("(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x %02x %02x %02x  %02x %02x\n",
+				pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+				pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7],
+				pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11],
+				pucStartAddr[12], pucStartAddr[13]);
+				break;
+			case 15:
+			LOG_FUNC(
+			"(%p) %02x %02x %02x %02x  %02x %02x %02x %02x - %02x %02x %02x %02x  %02x %02x %02x\n",
+				pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3],
+				pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7],
+				pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11],
+				pucStartAddr[12], pucStartAddr[13], pucStartAddr[14]);
+				break;
+			/*
+			default:
+				break;
+			*/
+			}
+			u4Length = 0;
+		}
+	}
+
+	LOG_FUNC("\n");
+
+}				/* end of dumpMemory8() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to dump a segment of memory in double words.
+*
+* \param[in] pucStartAddr   Pointer to the starting address of the memory to be dumped.
+* \param[in] u4Length       Length of the memory to be dumped.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length)
+{
+	PUINT_8 pucAddr;
+
+	ASSERT(pu4StartAddr);
+
+	LOG_FUNC("DUMP32 ADDRESS: %p, Length: %u\n", pu4StartAddr, u4Length);
+
+	if (IS_NOT_ALIGN_4((ULONG) pu4StartAddr)) {
+		UINT_32 u4ProtrudeLen = sizeof(UINT_32) - ((ULONG) pu4StartAddr % 4);
+
+		u4ProtrudeLen = ((u4Length < u4ProtrudeLen) ? u4Length : u4ProtrudeLen);
+		LOG_FUNC("pu4StartAddr is not at DW boundary.\n");
+		pucAddr = (PUINT_8) &pu4StartAddr[0];
+
+		switch (u4ProtrudeLen) {
+		case 1:
+			LOG_FUNC("(%p) %02x------\n", pu4StartAddr, pucAddr[0]);
+			break;
+		case 2:
+			LOG_FUNC("(%p) %02x%02x----\n", pu4StartAddr, pucAddr[1], pucAddr[0]);
+			break;
+		case 3:
+			LOG_FUNC("(%p) %02x%02x%02x--\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]);
+			break;
+		default:
+			break;
+		}
+
+		u4Length -= u4ProtrudeLen;
+		pu4StartAddr = (PUINT_32) ((ULONG) pu4StartAddr + u4ProtrudeLen);
+	}
+
+	while (u4Length > 0) {
+		if (u4Length >= 16) {
+			LOG_FUNC("(%p) %08x %08x %08x %08x\n",
+				 pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pu4StartAddr[3]);
+			pu4StartAddr += 4;
+			u4Length -= 16;
+		} else {
+			switch (u4Length) {
+			case 1:
+				pucAddr = (PUINT_8) &pu4StartAddr[0];
+				LOG_FUNC("(%p) ------%02x\n", pu4StartAddr, pucAddr[0]);
+				break;
+			case 2:
+				pucAddr = (PUINT_8) &pu4StartAddr[0];
+				LOG_FUNC("(%p) ----%02x%02x\n", pu4StartAddr, pucAddr[1], pucAddr[0]);
+				break;
+			case 3:
+				pucAddr = (PUINT_8) &pu4StartAddr[0];
+				LOG_FUNC("(%p) --%02x%02x%02x\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]);
+				break;
+			case 4:
+				LOG_FUNC("(%p) %08x\n", pu4StartAddr, pu4StartAddr[0]);
+				break;
+			case 5:
+				pucAddr = (PUINT_8) &pu4StartAddr[1];
+				LOG_FUNC("(%p) %08x ------%02x\n", pu4StartAddr, pu4StartAddr[0], pucAddr[0]);
+				break;
+			case 6:
+				pucAddr = (PUINT_8) &pu4StartAddr[1];
+				LOG_FUNC("(%p) %08x ----%02x%02x\n",
+					 pu4StartAddr, pu4StartAddr[0], pucAddr[1], pucAddr[0]);
+				break;
+			case 7:
+				pucAddr = (PUINT_8) &pu4StartAddr[1];
+				LOG_FUNC("(%p) %08x --%02x%02x%02x\n",
+					 pu4StartAddr, pu4StartAddr[0], pucAddr[2], pucAddr[1], pucAddr[0]);
+				break;
+			case 8:
+				LOG_FUNC("(%p) %08x %08x\n", pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1]);
+				break;
+			case 9:
+				pucAddr = (PUINT_8) &pu4StartAddr[2];
+				LOG_FUNC("(%p) %08x %08x ------%02x\n",
+					 pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[0]);
+				break;
+			case 10:
+				pucAddr = (PUINT_8) &pu4StartAddr[2];
+				LOG_FUNC("(%p) %08x %08x ----%02x%02x\n",
+					 pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[1], pucAddr[0]);
+				break;
+			case 11:
+				pucAddr = (PUINT_8) &pu4StartAddr[2];
+				LOG_FUNC("(%p) %08x %08x --%02x%02x%02x\n",
+					 pu4StartAddr,
+					 pu4StartAddr[0], pu4StartAddr[1], pucAddr[2], pucAddr[1], pucAddr[0]);
+				break;
+			case 12:
+				LOG_FUNC("(%p) %08x %08x %08x\n",
+					 pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2]);
+				break;
+			case 13:
+				pucAddr = (PUINT_8) &pu4StartAddr[3];
+				LOG_FUNC("(%p) %08x %08x %08x ------%02x\n",
+					 pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[0]);
+				break;
+			case 14:
+				pucAddr = (PUINT_8) &pu4StartAddr[3];
+				LOG_FUNC("(%p) %08x %08x %08x ----%02x%02x\n",
+					 pu4StartAddr,
+					 pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[1], pucAddr[0]);
+				break;
+			case 15:
+				pucAddr = (PUINT_8) &pu4StartAddr[3];
+				LOG_FUNC("(%p) %08x %08x %08x --%02x%02x%02x\n",
+					 pu4StartAddr,
+					 pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2],
+					 pucAddr[2], pucAddr[1], pucAddr[0]);
+				break;
+			/*
+			default:
+				break;
+			*/
+			}
+			u4Length = 0;
+		}
+	}
+
+}				/* end of dumpMemory32() */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c
new file mode 100644
index 0000000000000..21bd849827e17
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c
@@ -0,0 +1,3442 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_bow.c#1
+*/
+
+/*! \file wlan_bow.c
+    \brief This file contains the 802.11 PAL commands processing routines for
+	   MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: wlan_bow.c
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 16 2012 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support BOW for 5GHz band.
+ *
+ * 01 09 2012 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * [ALPS00110632] [Rose][LCA42][Cross Feature][Bluetooth]The "KE" pops up after the device reboots automatically.(once)
+ *
+ * Fix bow link disconnected event dereference.
+ *
+ * 09 29 2011 cm.chang
+ * NULL
+ * Change the function prototype of rlmDomainGetChnlList()
+ *
+ * 07 06 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Improve BoW connection establishment speed.
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * change parameter name from PeerAddr to BSSID
+ *
+ * 06 21 2011 terry.wu
+ * NULL
+ * Fix BoW KE.
+ *
+ * 06 20 2011 terry.wu
+ * NULL
+ * Add BoW Rate Limitation.
+ *
+ * 06 20 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * 1. specify target's BSSID when requesting channel privilege.
+ * 2. pass BSSID information to firmware domain
+ *
+ * 06 17 2011 terry.wu
+ * NULL
+ * Add BoW 11N support.
+ *
+ * 06 07 2011 cp.wu
+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction
+ * aware more compile options.
+ *
+ * 05 25 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Add BoW Cancel Scan Request and Turn On deactive network function.
+ *
+ * 05 23 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Add some BoW error handling.
+ *
+ * 05 22 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * .
+ *
+ * 05 22 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Only reply probe response to its peer or mached SSID for BoW AP.
+ *
+ * 05 22 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Add BoW SAA retry and disable disconnect event when AAA fail .
+ *
+ * 05 21 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Protect BoW connection establishment.
+ *
+ * 05 17 2011 terry.wu
+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting
+ * Send deauth while disconnecting BoW link.
+ *
+ * 05 17 2011 terry.wu
+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue
+ * Fix wrong StaRec state of BoW .
+ *
+ * 05 06 2011 terry.wu
+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue
+ * Fix BoW Multiple Physical Link connect/disconnect issue.
+ *
+ * 05 03 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix prAssocRspSwRfb casting.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW short range mode.
+ *
+ * 04 12 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add WMM IE for BOW initiator data.
+ *
+ * 04 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes.
+ *
+ * 04 09 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Change Link connection event procedure and change skb length check to 1512 bytes.
+ *
+ * 03 28 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Simplify link disconnected routine, remove link disconnected other routine.
+ *
+ * 03 27 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support multiple physical link.
+ *
+ * 03 27 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add new feature - multiple physical link support.
+ *
+ * 02 22 2011 wh.su
+ * [WCXRP00000486] [MT6620 Wi-Fi][BOW] Fixed the bow send frame but not encrypted issue
+ * fixed the BOW packet sending without encrypted issue.
+ *
+ * 02 21 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix BOW link disconnection bug.
+ *
+ * 02 16 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add bowNotifyAllLinkDisconnected  interface and change channel grant procedure for bow starting.
+ *
+ * 02 11 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update BOW channel granted function.
+ *
+ * 02 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix kernel API change issue.
+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is
+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock);
+ * After ALPS 2.3, kfifo_alloc() is changed to
+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask);
+ *
+ * 02 09 2011 cp.wu
+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3
+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031
+ * with BOW and P2P enabled as default
+ *
+ * 02 08 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in.
+ * Update BOW get MAC status, remove returning event for AIS network type.
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * .
+ *
+ * 01 11 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update BOW Activity Report structure and bug fix.
+ *
+ * 01 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update BOW to support multiple physical link.
+ *
+ * 12 08 2010 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support concurrent networks.
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 11 11 2010 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix BoW timer assert issue.
+ *
+ * 10 18 2010 chinghwa.yu
+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size
+ * Fix for event returnning Band.
+ *
+ * 10 18 2010 chinghwa.yu
+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size
+ * Fix wrong BoW event size.
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced
+ * by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 27 2010 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
+ * Update BCM/BoW design and settings.
+ *
+ * 09 16 2010 chinghwa.yu
+ * NULL
+ * Fix bowResponderScanDone error when prBssDesc is NULL.
+ *
+ * 09 14 2010 chinghwa.yu
+ * NULL
+ * Add bowRunEventAAAComplete.
+ *
+ * 09 14 2010 cp.wu
+ * NULL
+ * indicate correct AIS network information for PAL.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Initialize nicActivateNetwork(prAdapter as soon as bow is starting..
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Update BOW for the 1st time.
+ *
+ * 08 23 2010 cp.wu
+ * NULL
+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
+ *
+ * 07 30 2010 cp.wu
+ * NULL
+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
+ *
+ * 07 15 2010 cp.wu
+ *
+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add API in que_mgt to retrieve sta-rec index for security frames.
+ *
+ * 06 24 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 05 13 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add NULL OID implementation for WOL-related OIDs.
+ *
+ * 05 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * 1) all BT physical handles shares the same RSSI/Link Quality.
+ * 2) simplify BT command composing
+ *
+ * 04 28 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change prefix for data structure used to communicate with 802.11 PAL
+ * to avoid ambiguous naming with firmware interface
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add multiple physical link support
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * information buffer for query oid/ioctl is now buffered in prCmdInfo
+ * instead of glue-layer variable to improve multiple oid/ioctl capability
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  * 2) command sequence number is now increased atomically
+ *  * 3) private data could be hold and taken use for other purpose
+**
+*/
+
+/******************************************************************************
+*                         C O M P I L E R   F L A G S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+*******************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_ENABLE_BT_OVER_WIFI
+
+/******************************************************************************
+*                              C O N S T A N T S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                             D A T A   T Y P E S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                            P U B L I C   D A T A
+*******************************************************************************
+*/
+
+static UINT_32 g_u4LinkCount;
+static UINT_32 g_u4Beaconing;
+static BOW_TABLE_T arBowTable[CFG_BOW_PHYSICAL_LINK_NUM];
+
+/******************************************************************************
+*                           P R I V A T E   D A T A
+*******************************************************************************
+*/
+
+const BOW_CMD_T arBowCmdTable[] = {
+	{BOW_CMD_ID_GET_MAC_STATUS, bowCmdGetMacStatus},
+	{BOW_CMD_ID_SETUP_CONNECTION, bowCmdSetupConnection},
+	{BOW_CMD_ID_DESTROY_CONNECTION, bowCmdDestroyConnection},
+	{BOW_CMD_ID_SET_PTK, bowCmdSetPTK},
+	{BOW_CMD_ID_READ_RSSI, bowCmdReadRSSI},
+	{BOW_CMD_ID_READ_LINK_QUALITY, bowCmdReadLinkQuality},
+	{BOW_CMD_ID_SHORT_RANGE_MODE, bowCmdShortRangeMode},
+	{BOW_CMD_ID_GET_CHANNEL_LIST, bowCmdGetChannelList},
+};
+
+/******************************************************************************
+*                                 M A C R O S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                              F U N C T I O N S
+*******************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief command packet generation utility
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] ucCID              Command ID
+* \param[in] fgSetQuery         Set or Query
+* \param[in] fgNeedResp         Need for response
+* \param[in] pfCmdDoneHandler   Function pointer when command is done
+* \param[in] u4SetQueryInfoLen  The length of the set/query buffer
+* \param[in] pucInfoBuffer      Pointer to set/query buffer
+*
+*
+* \retval WLAN_STATUS_PENDING
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter,
+			  IN UINT_8 ucCID,
+			  IN BOOLEAN fgSetQuery,
+			  IN BOOLEAN fgNeedResp,
+			  IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler,
+			  IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler,
+			  IN UINT_32 u4SetQueryInfoLen, IN PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_8 ucCmdSeqNum;
+
+	ASSERT(prAdapter);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	ASSERT(prGlueInfo);
+
+	DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID);
+
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen));
+
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+	DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum);
+
+	/* Setup common CMD Info Packet */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = NETWORK_TYPE_BOW_INDEX;
+	prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen);
+	prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler;
+	prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler;
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = ucCID;
+	prCmdInfo->fgSetQuery = fgSetQuery;
+	prCmdInfo->fgNeedResp = fgNeedResp;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen;
+	prCmdInfo->pvInformationBuffer = NULL;
+	prCmdInfo->u4InformationBufferLength = 0;
+	prCmdInfo->u4PrivateData = (UINT_32) ucSeqNumber;
+
+	/* Setup WIFI_CMD_T (no payload) */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL)
+		kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen);
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+	return WLAN_STATUS_PENDING;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to dispatch command coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	WLAN_STATUS retval = WLAN_STATUS_FAILURE;
+	UINT_16 i;
+
+	ASSERT(prAdapter);
+
+	for (i = 0; i < sizeof(arBowCmdTable) / sizeof(BOW_CMD_T); i++) {
+		if ((arBowCmdTable[i].uCmdID == prCmd->rHeader.ucCommandId) && arBowCmdTable[i].pfCmdHandle) {
+			retval = arBowCmdTable[i].pfCmdHandle(prAdapter, prCmd);
+			break;
+		}
+	}
+
+	return retval;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_GET_MAC_STATUS
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	P_AMPC_EVENT prEvent;
+	P_BOW_MAC_STATUS prMacStatus;
+	UINT_8 idx = 0;
+	UINT_8 ucPrimaryChannel;
+	ENUM_BAND_T eBand;
+	ENUM_CHNL_EXT_T eBssSCO;
+	UINT_8 ucNumOfChannel = 0;	/* MAX_BOW_NUMBER_OF_CHANNEL; */
+
+	RF_CHANNEL_INFO_T aucChannelList[MAX_BOW_NUMBER_OF_CHANNEL];
+
+	ASSERT(prAdapter);
+
+	/* 3 <1> If LinkCount != 0 -> OK (optional) */
+
+	eBand = BAND_2G4;
+	eBssSCO = CHNL_EXT_SCN;
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return WLAN_STATUS_FAILURE;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_MAC_STATUS;
+	prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_MAC_STATUS);
+
+	/* fill event body */
+	prMacStatus = (P_BOW_MAC_STATUS) (prEvent->aucPayload);
+	kalMemZero(prMacStatus, sizeof(BOW_MAC_STATUS));
+
+	/* 3 <2> Call CNM to decide if BOW available. */
+	if (cnmBowIsPermitted(prAdapter))
+		prMacStatus->ucAvailability = TRUE;
+	else
+		prMacStatus->ucAvailability = FALSE;
+
+	memcpy(prMacStatus->aucMacAddr, prAdapter->rWifiVar.aucDeviceAddress, PARAM_MAC_ADDR_LEN);
+
+	if (cnmPreferredChannel(prAdapter, &eBand, &ucPrimaryChannel, &eBssSCO)) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, TRACE, "bowCmdGetMacStatus, Get preferred channel.\n");
+#endif
+
+		prMacStatus->ucNumOfChannel = 1;
+		prMacStatus->arChannelList[0].ucChannelBand = eBand;
+		prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel;
+	} else {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, TRACE,
+		       "bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel);
+#endif
+
+		rlmDomainGetChnlList(prAdapter, BAND_2G4, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_2G4,
+				     &ucNumOfChannel, aucChannelList);
+
+		if (ucNumOfChannel > 0) {
+			for (idx = 0; idx < ucNumOfChannel; idx++) {
+				prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand;
+				prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum;
+			}
+
+			prMacStatus->ucNumOfChannel = ucNumOfChannel;
+		}
+
+		rlmDomainGetChnlList(prAdapter, BAND_5G, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_5G,
+				     &ucNumOfChannel, aucChannelList);
+
+		if (ucNumOfChannel > 0) {
+			for (idx = 0; idx < ucNumOfChannel; idx++) {
+				prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelBand =
+				    aucChannelList[idx].eBand;
+				prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelNum =
+				    aucChannelList[idx].ucChannelNum;
+			}
+
+			prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel;
+
+		}
+	}
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, TRACE,
+		"ucNumOfChannel,eBand,aucChannelList,%x,%x,%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n",
+		ucNumOfChannel, aucChannelList[0].eBand, aucChannelList[0].ucChannelNum, aucChannelList[1].ucChannelNum,
+		aucChannelList[2].ucChannelNum, aucChannelList[3].ucChannelNum, aucChannelList[4].ucChannelNum,
+		aucChannelList[5].ucChannelNum, aucChannelList[6].ucChannelNum, aucChannelList[7].ucChannelNum,
+		aucChannelList[8].ucChannelNum, aucChannelList[9].ucChannelNum, aucChannelList[10].ucChannelNum,
+		aucChannelList[11].ucChannelNum, aucChannelList[12].ucChannelNum, aucChannelList[13].ucChannelNum,
+		aucChannelList[14].ucChannelNum, aucChannelList[15].ucChannelNum, aucChannelList[16].ucChannelNum,
+		aucChannelList[17].ucChannelNum));
+
+	DBGLOG(BOW, TRACE,
+	       "prMacStatus->ucNumOfChannel, eBand, %x, %x.\n",
+		prMacStatus->ucNumOfChannel, prMacStatus->arChannelList[0].ucChannelBand);
+	DBGLOG(BOW, TRACE,
+	       "prMacStatus->arChannelList, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n",
+		prMacStatus->arChannelList[0].ucChannelNum, prMacStatus->arChannelList[1].ucChannelNum,
+		prMacStatus->arChannelList[2].ucChannelNum, prMacStatus->arChannelList[3].ucChannelNum,
+		prMacStatus->arChannelList[4].ucChannelNum, prMacStatus->arChannelList[5].ucChannelNum,
+		prMacStatus->arChannelList[6].ucChannelNum, prMacStatus->arChannelList[7].ucChannelNum,
+		prMacStatus->arChannelList[8].ucChannelNum, prMacStatus->arChannelList[9].ucChannelNum,
+		prMacStatus->arChannelList[10].ucChannelNum, prMacStatus->arChannelList[11].ucChannelNum,
+		prMacStatus->arChannelList[12].ucChannelNum, prMacStatus->arChannelList[13].ucChannelNum,
+		prMacStatus->arChannelList[14].ucChannelNum, prMacStatus->arChannelList[15].ucChannelNum,
+		prMacStatus->arChannelList[16].ucChannelNum, prMacStatus->arChannelList[17].ucChannelNum));
+
+	DBGLOG(BOW, TRACE, "prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel);
+	DBGLOG(BOW, TRACE,
+	       "prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand);
+	DBGLOG(BOW, TRACE,
+	       "prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum);
+	DBGLOG(BOW, TRACE, "prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability);
+	DBGLOG(BOW, TRACE, "prMacStatus->aucMacAddr, %x:%x:%x:%x:%x:%x.\n",
+			    prMacStatus->aucMacAddr[0],
+			    prMacStatus->aucMacAddr[1],
+			    prMacStatus->aucMacAddr[2],
+			    prMacStatus->aucMacAddr[3], prMacStatus->aucMacAddr[4], prMacStatus->aucMacAddr[5]));
+#endif
+
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS)));
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_SETUP_CONNECTION
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	P_BOW_SETUP_CONNECTION prBowSetupConnection;
+	CMD_BT_OVER_WIFI rCmdBtOverWifi;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	BOW_TABLE_T rBowTable;
+
+	UINT_8 ucBowTableIdx = 0;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prBowSetupConnection = (P_BOW_SETUP_CONNECTION) &(prCmd->aucPayload[0]);
+
+	/* parameter size check */
+	if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SETUP_CONNECTION)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+	/* 3 <1> If ucLinkCount >= 4 -> Fail. */
+	if (g_u4LinkCount >= CFG_BOW_PHYSICAL_LINK_NUM) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+	/* 3 <2> Call CNM, check if BOW is available. */
+	if (!cnmBowIsPermitted(prAdapter)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+	/* 3 <3> Lookup BOW Table, if Peer MAC address exist and valid -> Fail. */
+	if (bowCheckBowTableIfVaild(prAdapter, prBowSetupConnection->aucPeerAddress)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+
+	if (EQUAL_MAC_ADDR(prBowSetupConnection->aucPeerAddress, prAdapter->rWifiVar.aucDeviceAddress)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+	/* fill CMD_BT_OVER_WIFI */
+	rCmdBtOverWifi.ucAction = BOW_SETUP_CMD;
+	rCmdBtOverWifi.ucChannelNum = prBowSetupConnection->ucChannelNum;
+	COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowSetupConnection->aucPeerAddress);
+	rCmdBtOverWifi.u2BeaconInterval = prBowSetupConnection->u2BeaconInterval;
+	rCmdBtOverWifi.ucTimeoutDiscovery = prBowSetupConnection->ucTimeoutDiscovery;
+	rCmdBtOverWifi.ucTimeoutInactivity = prBowSetupConnection->ucTimeoutInactivity;
+	rCmdBtOverWifi.ucRole = prBowSetupConnection->ucRole;
+	rCmdBtOverWifi.PAL_Capabilities = prBowSetupConnection->ucPAL_Capabilities;
+	rCmdBtOverWifi.cMaxTxPower = prBowSetupConnection->cMaxTxPower;
+
+	if (prBowSetupConnection->ucChannelNum > 14)
+		rCmdBtOverWifi.ucChannelBand = BAND_5G;
+	else
+		rCmdBtOverWifi.ucChannelBand = BAND_2G4;
+
+	COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowSetupConnection->aucPeerAddress);
+
+#if CFG_BOW_PHYSICAL_LINK_NUM > 1
+	/*Channel check for supporting multiple physical link */
+	if (g_u4LinkCount > 0) {
+		if (prBowSetupConnection->ucChannelNum != prBowFsmInfo->ucPrimaryChannel) {
+			wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+			return WLAN_STATUS_NOT_ACCEPTED;
+		}
+	}
+#endif
+
+	prBowFsmInfo->ucPrimaryChannel = prBowSetupConnection->ucChannelNum;
+	prBowFsmInfo->eBand = rCmdBtOverWifi.ucChannelBand;
+	prBowFsmInfo->u2BeaconInterval = prBowSetupConnection->u2BeaconInterval;
+	prBowFsmInfo->ucRole = prBowSetupConnection->ucRole;
+
+	if (prBowSetupConnection->ucPAL_Capabilities > 0)
+		prBowFsmInfo->fgSupportQoS = TRUE;
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowCmdSetupConnection.\n");
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum);
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi Peer address - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0],
+			    rCmdBtOverWifi.rPeerAddr[1],
+			    rCmdBtOverWifi.rPeerAddr[2],
+			    rCmdBtOverWifi.rPeerAddr[3], rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]);
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval);
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery);
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity);
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole);
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities);
+	DBGLOG(BOW, EVENT, "rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower);
+#endif
+
+	/* 3 <4> Get a free BOW entry, mark as Valid, fill in Peer MAC address, LinkCount += 1, state == Starting. */
+	if (!bowGetBowTableFreeEntry(prAdapter, &ucBowTableIdx)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+
+	prBowFsmInfo->prTargetBssDesc = NULL;
+
+	kalMemZero(&rBowTable, sizeof(BOW_TABLE_T));
+
+	COPY_MAC_ADDR(rBowTable.aucPeerAddress, prBowSetupConnection->aucPeerAddress);
+	/* owTable.eState = BOW_DEVICE_STATE_ACQUIRING_CHANNEL; */
+	rBowTable.fgIsValid = TRUE;
+	rBowTable.ucAcquireID = prBowFsmInfo->ucSeqNumOfChReq;
+	/* rBowTable.ucRole = prBowSetupConnection->ucRole; */
+	/* rBowTable.ucChannelNum = prBowSetupConnection->ucChannelNum; */
+	bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable);
+
+	kalSetBowRole(prAdapter->prGlueInfo, rCmdBtOverWifi.ucRole, prBowSetupConnection->aucPeerAddress);
+
+	GLUE_INC_REF_CNT(g_u4LinkCount);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount);
+#endif
+
+	if (g_u4LinkCount == 1) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowStarting, cnmTimerInitTimer.\n");
+		DBGLOG(BOW, EVENT, "prBowFsmInfo->u2BeaconInterval, %d.\n", prBowFsmInfo->u2BeaconInterval);
+#endif
+		cnmTimerInitTimer(prAdapter,
+				  &prBowFsmInfo->rStartingBeaconTimer,
+				  (PFN_MGMT_TIMEOUT_FUNC) bowSendBeacon, (ULONG) NULL);
+
+		cnmTimerInitTimer(prAdapter,
+				  &prBowFsmInfo->rChGrantedTimer,
+				  (PFN_MGMT_TIMEOUT_FUNC) bowChGrantedTimeout, (ULONG) NULL);
+
+		/* Reset Global Variable */
+		g_u4Beaconing = 0;
+
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowCmdSetupConnection, g_u4LinkCount, %x.\n", g_u4LinkCount);
+		DBGLOG(BOW, EVENT, "kalInitBowDevice, bow0\n");
+#endif
+#if CFG_BOW_SEPARATE_DATA_PATH
+		kalInitBowDevice(prAdapter->prGlueInfo, BOWDEVNAME);
+#endif
+
+		/*Active BoW Network */
+		SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX);
+
+	}
+
+	if (rCmdBtOverWifi.ucRole == BOW_INITIATOR) {
+		bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress,
+				    BOW_DEVICE_STATE_ACQUIRING_CHANNEL);
+		bowRequestCh(prAdapter);
+	} else {
+		bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, BOW_DEVICE_STATE_SCANNING);
+		bowResponderScan(prAdapter);
+	}
+
+	wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_DESTROY_CONNECTION
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	P_BOW_DESTROY_CONNECTION prBowDestroyConnection;
+	CMD_BT_OVER_WIFI rCmdBtOverWifi;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+#if CFG_BOW_TEST
+	UINT_8 ucIdx;
+#endif
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	/* 3 <1> If LinkCount == 0 ->Fail (Optional) */
+	if (g_u4LinkCount == 0) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+	/* parameter size check */
+	if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_DESTROY_CONNECTION)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+	/* 3 <2> Lookup BOW table, check if is not exist (Valid and Peer MAC address) -> Fail */
+	prBowDestroyConnection = (P_BOW_DESTROY_CONNECTION) &(prCmd->aucPayload[0]);
+
+	if (!bowCheckBowTableIfVaild(prAdapter, prBowDestroyConnection->aucPeerAddress)) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowCmdDestroyConnection, bowCheckIfVaild, not accepted.\n");
+#endif
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT,
+	       "bowCmdDestroyConnection, destroy Peer address - %x:%x:%x:%x:%x:%x.\n",
+		prBowDestroyConnection->aucPeerAddress[0], prBowDestroyConnection->aucPeerAddress[1],
+		prBowDestroyConnection->aucPeerAddress[2], prBowDestroyConnection->aucPeerAddress[3],
+		prBowDestroyConnection->aucPeerAddress[4], prBowDestroyConnection->aucPeerAddress[5]));
+#endif
+
+	/* fill CMD_BT_OVER_WIFI */
+	rCmdBtOverWifi.ucAction = 2;
+	COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowDestroyConnection->aucPeerAddress);
+	COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowDestroyConnection->aucPeerAddress);
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT,
+	       "bowCmdDestroyConnection, rCmdBtOverWifi.rPeerAddr - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0],
+		rCmdBtOverWifi.rPeerAddr[1], rCmdBtOverWifi.rPeerAddr[2], rCmdBtOverWifi.rPeerAddr[3],
+		rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]);
+#endif
+
+#if CFG_BOW_TEST
+	for (ucIdx = 0; ucIdx < 11; ucIdx++) {
+		DBGLOG(BOW, EVENT,
+		       "BoW receiving PAL packet delta time vs packet number -- %d ms vs %x.\n", ucIdx,
+			g_arBowRevPalPacketTime[ucIdx]);
+	}
+#endif
+
+	wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS);
+
+	return wlanoidSendSetQueryBowCmd(prAdapter,
+					 CMD_ID_CMD_BT_OVER_WIFI,
+					 TRUE,
+					 FALSE,
+					 wlanbowCmdEventLinkDisconnected,
+					 wlanbowCmdTimeoutHandler,
+					 sizeof(CMD_BT_OVER_WIFI),
+					 (PUINT_8)&rCmdBtOverWifi, prCmd->rHeader.ucSeqNumber);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_SET_PTK
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	P_BOW_SET_PTK prBowSetPTK;
+	CMD_802_11_KEY rCmdKey;
+
+	ASSERT(prAdapter);
+
+	/* parameter size check */
+	if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SET_PTK))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prBowSetPTK = (P_BOW_SET_PTK) &(prCmd->aucPayload[0]);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "prBowSetPTK->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+			    prBowSetPTK->aucPeerAddress[0],
+			    prBowSetPTK->aucPeerAddress[1],
+			    prBowSetPTK->aucPeerAddress[2],
+			    prBowSetPTK->aucPeerAddress[3],
+			    prBowSetPTK->aucPeerAddress[4], prBowSetPTK->aucPeerAddress[5]));
+
+	DBGLOG(BOW, EVENT,
+	       "rCmdKey.ucIsAuthenticator, %x.\n", kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress));
+#endif
+
+	if (!bowCheckBowTableIfVaild(prAdapter, prBowSetPTK->aucPeerAddress)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+
+	if (bowGetBowTableState(prAdapter, prBowSetPTK->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE);
+
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+	/* fill CMD_802_11_KEY */
+	rCmdKey.ucAddRemove = 1;	/* add */
+	rCmdKey.ucTxKey = 1;
+	rCmdKey.ucKeyType = 1;
+	rCmdKey.ucIsAuthenticator = kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress);
+	COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prBowSetPTK->aucPeerAddress);
+	rCmdKey.ucNetType = NETWORK_TYPE_BOW_INDEX;	/* BT Over Wi-Fi */
+	rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP;	/* AES */
+	rCmdKey.ucKeyId = 0;
+	rCmdKey.ucKeyLen = 16;	/* AES = 128bit */
+	kalMemCopy(rCmdKey.aucKeyMaterial, prBowSetPTK->aucTemporalKey, 16);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "prBowSetPTK->aucTemporalKey, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n",
+			    prBowSetPTK->aucTemporalKey[0],
+			    prBowSetPTK->aucTemporalKey[1],
+			    prBowSetPTK->aucTemporalKey[2],
+			    prBowSetPTK->aucTemporalKey[3],
+			    prBowSetPTK->aucTemporalKey[4],
+			    prBowSetPTK->aucTemporalKey[5],
+			    prBowSetPTK->aucTemporalKey[6],
+			    prBowSetPTK->aucTemporalKey[7],
+			    prBowSetPTK->aucTemporalKey[8],
+			    prBowSetPTK->aucTemporalKey[9],
+			    prBowSetPTK->aucTemporalKey[10],
+			    prBowSetPTK->aucTemporalKey[11],
+			    prBowSetPTK->aucTemporalKey[12],
+			    prBowSetPTK->aucTemporalKey[13],
+			    prBowSetPTK->aucTemporalKey[14], prBowSetPTK->aucTemporalKey[15]));
+
+	DBGLOG(BOW, EVENT, "rCmdKey.aucKeyMaterial, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n",
+			    rCmdKey.aucKeyMaterial[0],
+			    rCmdKey.aucKeyMaterial[1],
+			    rCmdKey.aucKeyMaterial[2],
+			    rCmdKey.aucKeyMaterial[3],
+			    rCmdKey.aucKeyMaterial[4],
+			    rCmdKey.aucKeyMaterial[5],
+			    rCmdKey.aucKeyMaterial[6],
+			    rCmdKey.aucKeyMaterial[7],
+			    rCmdKey.aucKeyMaterial[8],
+			    rCmdKey.aucKeyMaterial[9],
+			    rCmdKey.aucKeyMaterial[10],
+			    rCmdKey.aucKeyMaterial[11],
+			    rCmdKey.aucKeyMaterial[12],
+			    rCmdKey.aucKeyMaterial[13], rCmdKey.aucKeyMaterial[14], rCmdKey.aucKeyMaterial[15]));
+#endif
+
+	return wlanoidSendSetQueryBowCmd(prAdapter,
+					 CMD_ID_ADD_REMOVE_KEY,
+					 TRUE,
+					 FALSE,
+					 wlanbowCmdEventSetCommon,
+					 wlanbowCmdTimeoutHandler,
+					 sizeof(CMD_802_11_KEY), (PUINT_8)&rCmdKey, prCmd->rHeader.ucSeqNumber);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_READ_RSSI
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	P_BOW_READ_RSSI prBowReadRSSI;
+
+	ASSERT(prAdapter);
+
+	/* parameter size check */
+	if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_READ_RSSI))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prBowReadRSSI = (P_BOW_READ_RSSI) &(prCmd->aucPayload[0]);
+
+	return wlanoidSendSetQueryBowCmd(prAdapter,
+					 CMD_ID_GET_LINK_QUALITY,
+					 FALSE,
+					 TRUE,
+					 wlanbowCmdEventReadRssi,
+					 wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_READ_LINK_QUALITY
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	P_BOW_READ_LINK_QUALITY prBowReadLinkQuality;
+
+	ASSERT(prAdapter);
+
+	/* parameter size check */
+	if (prCmd->rHeader.u2PayloadLength != sizeof(P_BOW_READ_LINK_QUALITY))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prBowReadLinkQuality = (P_BOW_READ_LINK_QUALITY) &(prCmd->aucPayload[0]);
+
+	return wlanoidSendSetQueryBowCmd(prAdapter,
+					 CMD_ID_GET_LINK_QUALITY,
+					 FALSE,
+					 TRUE,
+					 wlanbowCmdEventReadLinkQuality,
+					 wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_SHORT_RANGE_MODE
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	P_BOW_SHORT_RANGE_MODE prBowShortRangeMode;
+	CMD_TX_PWR_T rTxPwrParam;
+
+	ASSERT(prAdapter);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowCmdShortRangeMode.\n");
+#endif
+
+	prBowShortRangeMode = (P_BOW_SHORT_RANGE_MODE) &(prCmd->aucPayload[0]);
+
+	/* parameter size check */
+	if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SHORT_RANGE_MODE)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	if (!bowCheckBowTableIfVaild(prAdapter, prBowShortRangeMode->aucPeerAddress)) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+
+	if (bowGetBowTableState(prAdapter, prBowShortRangeMode->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) {
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE);
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "prBowShortRangeMode->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+			    prBowShortRangeMode->aucPeerAddress[0],
+			    prBowShortRangeMode->aucPeerAddress[1],
+			    prBowShortRangeMode->aucPeerAddress[2],
+			    prBowShortRangeMode->aucPeerAddress[3],
+			    prBowShortRangeMode->aucPeerAddress[4], prBowShortRangeMode->aucPeerAddress[5]));
+#endif
+
+	rTxPwrParam.cTxPwr2G4Cck = (prBowShortRangeMode->cTxPower << 1);
+
+	rTxPwrParam.cTxPwr2G4OFDM_BPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4OFDM_QPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4OFDM_16QAM = (prBowShortRangeMode->cTxPower << 1);
+
+	rTxPwrParam.cTxPwr2G4OFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4OFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1);
+
+	rTxPwrParam.cTxPwr2G4HT20_BPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT20_QPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT20_16QAM = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT20_MCS5 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT20_MCS6 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT20_MCS7 = (prBowShortRangeMode->cTxPower << 1);
+
+	rTxPwrParam.cTxPwr2G4HT40_BPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT40_QPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT40_16QAM = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT40_MCS5 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT40_MCS6 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr2G4HT40_MCS7 = (prBowShortRangeMode->cTxPower << 1);
+
+	rTxPwrParam.cTxPwr5GOFDM_BPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GOFDM_QPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GOFDM_16QAM = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GOFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GOFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1);
+
+	rTxPwrParam.cTxPwr5GHT20_BPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT20_QPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT20_16QAM = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT20_MCS5 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT20_MCS6 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT20_MCS7 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT40_BPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT40_QPSK = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT40_16QAM = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT40_MCS5 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT40_MCS6 = (prBowShortRangeMode->cTxPower << 1);
+	rTxPwrParam.cTxPwr5GHT40_MCS7 = (prBowShortRangeMode->cTxPower << 1);
+
+	if (nicUpdateTxPower(prAdapter, &rTxPwrParam) == WLAN_STATUS_SUCCESS) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowCmdShortRangeMode, %x.\n", WLAN_STATUS_SUCCESS);
+#endif
+		wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS);
+		return WLAN_STATUS_SUCCESS;
+	}
+	wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE);
+	return WLAN_STATUS_FAILURE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is command handler for BOW_CMD_ID_GET_CHANNEL_LIST
+*        coming from 802.11 PAL
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+* \param[in] prCmd      Pointer to the buffer that holds the command
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd)
+{
+	ASSERT(prAdapter);
+
+	/* not supported yet */
+	return WLAN_STATUS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is generic command done handler
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+* \param[in] pucEventBuf    Pointer to the set buffer OR event buffer
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf)
+{
+	P_AMPC_EVENT prEvent;
+	P_BOW_COMMAND_STATUS prBowCmdStatus;
+
+	ASSERT(prAdapter);
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS;
+	prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS);
+
+	/* fill event body */
+	prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload);
+	kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS));
+
+	prBowCmdStatus->ucStatus = ucEventBuf;
+
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is generic command done handler
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+* \param[in] pucEventBuf    Pointer to the set buffer OR event buffer
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_AMPC_EVENT prEvent;
+	P_BOW_COMMAND_STATUS prBowCmdStatus;
+
+	ASSERT(prAdapter);
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS;
+	prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS);
+
+	/* fill event body */
+	prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload);
+	kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS));
+
+	prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS;
+
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+* \param[in] pucEventBuf    Pointer to the set buffer OR event buffer
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_AMPC_EVENT prEvent;
+	P_BOW_LINK_CONNECTED prBowLinkConnected;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED;
+	prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED);
+
+	/* fill event body */
+	prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prEvent->aucPayload);
+	kalMemZero(prBowLinkConnected, sizeof(BOW_LINK_CONNECTED));
+	prBowLinkConnected->rChannel.ucChannelNum = prBssInfo->ucPrimaryChannel;
+	prBowLinkConnected->rChannel.ucChannelBand = prBssInfo->eBand;
+	COPY_MAC_ADDR(prBowLinkConnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId);
+	DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber);
+	DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength);
+	DBGLOG(BOW, EVENT,
+	       "prBowLinkConnected->rChannel.ucChannelNum, 0x%x\n", prBowLinkConnected->rChannel.ucChannelNum);
+	DBGLOG(BOW, EVENT,
+	       "prBowLinkConnected->rChannel.ucChannelBand, 0x%x\n", prBowLinkConnected->rChannel.ucChannelBand);
+	DBGLOG(BOW, EVENT,
+	       "wlanbowCmdEventLinkConnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+		prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2],
+		prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]);
+	DBGLOG(BOW, EVENT,
+	       "wlanbowCmdEventLinkConnected, prBowLinkConnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+		prBowLinkConnected->aucPeerAddress[0], prBowLinkConnected->aucPeerAddress[1],
+		prBowLinkConnected->aucPeerAddress[2], prBowLinkConnected->aucPeerAddress[3],
+		prBowLinkConnected->aucPeerAddress[4], prBowLinkConnected->aucPeerAddress[5]));
+	DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkConnected, g_u4LinkCount, %x.\n", g_u4LinkCount);
+#endif
+
+	/*Indicate Event to PAL */
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)));
+
+	/*Release channel if granted */
+	if (prBowFsmInfo->fgIsChannelGranted) {
+		cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer);
+		/* bowReleaseCh(prAdapter); */
+		/*Requested, not granted yet */
+	} else if (prBowFsmInfo->fgIsChannelRequested) {
+		prBowFsmInfo->fgIsChannelRequested = FALSE;
+	}
+
+	/* set to connected status */
+	bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTED);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+* \param[in] pucEventBuf    Pointer to the set buffer OR event buffer
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_AMPC_EVENT prEvent;
+	P_BOW_LINK_DISCONNECTED prBowLinkDisconnected;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	BOW_TABLE_T rBowTable;
+	UINT_8 ucBowTableIdx;
+	ENUM_BOW_DEVICE_STATE eFsmState;
+	BOOLEAN fgSendDeauth = FALSE;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress);
+
+	if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) {
+		/*do nothing */
+		return;
+	}
+	/*Cancel scan */
+	else if (eFsmState == BOW_DEVICE_STATE_SCANNING && !(prBowFsmInfo->fgIsChannelRequested)) {
+		bowResponderCancelScan(prAdapter, FALSE);
+		bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_DISCONNECTING);
+		return;
+	}
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED;
+	if ((prCmdInfo->u4PrivateData))
+		prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData;
+	else
+		prEvent->rHeader.ucSeqNumber = 0;
+
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED);
+
+	/* fill event body */
+	prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prEvent->aucPayload);
+	kalMemZero(prBowLinkDisconnected, sizeof(BOW_LINK_DISCONNECTED));
+	prBowLinkDisconnected->ucReason = 0x0;
+	COPY_MAC_ADDR(prBowLinkDisconnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId);
+	DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber);
+	DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength);
+
+	DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+			    prBowFsmInfo->aucPeerAddress[0],
+			    prBowFsmInfo->aucPeerAddress[1],
+			    prBowFsmInfo->aucPeerAddress[2],
+			    prBowFsmInfo->aucPeerAddress[3],
+			    prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]));
+
+	DBGLOG(BOW, EVENT,
+	       "wlanbowCmdEventLinkDisconnected, prBowLinkDisconnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+		prBowLinkDisconnected->aucPeerAddress[0], prBowLinkDisconnected->aucPeerAddress[1],
+		prBowLinkDisconnected->aucPeerAddress[2], prBowLinkDisconnected->aucPeerAddress[3],
+		prBowLinkDisconnected->aucPeerAddress[4], prBowLinkDisconnected->aucPeerAddress[5]));
+
+	DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, g_u4LinkCount, %x.\n", g_u4LinkCount);
+#endif
+
+	/*Indicate BoW event to PAL */
+#if 0
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)));
+#endif
+
+	/* set to disconnected status */
+	prBowFsmInfo->prTargetStaRec =
+	    cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_BOW_INDEX, prBowLinkDisconnected->aucPeerAddress);
+	if (!(prBowFsmInfo->prTargetStaRec)) {
+		kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)));
+		ASSERT(FALSE);
+		return;
+	}
+
+	/*Release channel if granted */
+	if (prBowFsmInfo->fgIsChannelGranted) {
+		cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer);
+		bowReleaseCh(prAdapter);
+		/*Requested, not granted yet */
+	} else if (prBowFsmInfo->fgIsChannelRequested) {
+		prBowFsmInfo->fgIsChannelRequested = FALSE;
+		/* bowReleaseCh(prAdapter); */
+	}
+#if 1
+	/*Send Deauth to connected peer */
+	if (eFsmState == BOW_DEVICE_STATE_CONNECTED && (prBowFsmInfo->prTargetStaRec->ucStaState == STA_STATE_3)) {
+		fgSendDeauth = TRUE;
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT,
+		       "wlanbowCmdEventLinkDisconnected, bowGetBowTableState, %x.\n",
+			bowGetBowTableState(prAdapter, prBowLinkDisconnected->aucPeerAddress));
+#endif
+		authSendDeauthFrame(prAdapter,
+				    prBowFsmInfo->prTargetStaRec,
+				    (P_SW_RFB_T) NULL,
+				    REASON_CODE_DEAUTH_LEAVING_BSS, (PFN_TX_DONE_HANDLER) bowDisconnectLink);
+	}
+#endif
+
+#if 0
+	/* 3 <3>Stop this link; flush Tx;
+	 * send deAuthentication -> abort. SAA, AAA. need to check BOW table state == Connected.
+	 */
+	if (prAdapter->prGlueInfo->i4TxPendingFrameNum > 0)
+		kalFlushPendingTxPackets(prAdapter->prGlueInfo);
+
+	/* flush pending security frames */
+	if (prAdapter->prGlueInfo->i4TxPendingSecurityFrameNum > 0)
+		kalClearSecurityFrames(prAdapter->prGlueInfo);
+#endif
+
+	/*Update BoW table */
+	bowGetBowTableEntryByPeerAddress(prAdapter, prBowLinkDisconnected->aucPeerAddress, &ucBowTableIdx);
+	rBowTable.fgIsValid = FALSE;
+	rBowTable.eState = BOW_DEVICE_STATE_DISCONNECTED;
+	kalMemZero(rBowTable.aucPeerAddress, sizeof(rBowTable.aucPeerAddress));
+	bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable);
+
+	/*Indicate BoW event to PAL */
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)));
+
+	/*Decrease link count */
+	GLUE_DEC_REF_CNT(g_u4LinkCount);
+
+	/*If no need to send deauth, DO disconnect now */
+	/*If need to send deauth, DO disconnect at deauth Tx done */
+	if (!fgSendDeauth)
+		bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+* \param[in] pucEventBuf    Pointer to the set buffer OR event buffer
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_AMPC_EVENT prEvent;
+	P_BOW_COMMAND_STATUS prBowCmdStatus;
+	P_WIFI_CMD_T prWifiCmd;
+	P_CMD_BT_OVER_WIFI prCmdBtOverWifi;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	/* restore original command for rPeerAddr */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prCmdBtOverWifi = (P_CMD_BT_OVER_WIFI) (prWifiCmd->aucBuffer);
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS;
+	prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS);
+
+	/* fill event body */
+	prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload);
+	kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS));
+	prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS;
+
+	/*Indicate BoW event to PAL */
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)));
+
+	/* set to starting status */
+	kalSetBowState(prAdapter->prGlueInfo, BOW_DEVICE_STATE_STARTING, prCmdBtOverWifi->rPeerAddr);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is the command done handler for BOW_CMD_ID_READ_LINK_QUALITY
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+* \param[in] pucEventBuf    Pointer to the set buffer OR event buffer
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_LINK_QUALITY prLinkQuality;
+	P_AMPC_EVENT prEvent;
+	P_BOW_LINK_QUALITY prBowLinkQuality;
+
+	ASSERT(prAdapter);
+
+	prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf;
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_QUALITY;
+	prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_QUALITY);
+
+	/* fill event body */
+	prBowLinkQuality = (P_BOW_LINK_QUALITY) (prEvent->aucPayload);
+	kalMemZero(prBowLinkQuality, sizeof(BOW_LINK_QUALITY));
+	prBowLinkQuality->ucLinkQuality = (UINT_8) prLinkQuality->cLinkQuality;
+
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is the command done handler for BOW_CMD_ID_READ_RSSI
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+* \param[in] pucEventBuf    Pointer to the set buffer OR event buffer
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_LINK_QUALITY prLinkQuality;
+	P_AMPC_EVENT prEvent;
+	P_BOW_RSSI prBowRssi;
+
+	ASSERT(prAdapter);
+
+	prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf;
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_RSSI;
+	prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_RSSI);
+
+	/* fill event body */
+	prBowRssi = (P_BOW_RSSI) (prEvent->aucPayload);
+	kalMemZero(prBowRssi, sizeof(BOW_RSSI));
+	prBowRssi->cRssi = (INT_8) prLinkQuality->cRssi;
+
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)));
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is the default command timeout handler
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] prCmdInfo      Pointer to the buffer that holds the command info
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	P_AMPC_EVENT prEvent;
+	P_BOW_COMMAND_STATUS prBowCmdStatus;
+
+	ASSERT(prAdapter);
+
+	/* fill event header */
+	prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE);
+	if (!prEvent) {
+		ASSERT(FALSE);
+		return;
+	}
+	prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS;
+	prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData;
+	prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS);
+
+	/* fill event body */
+	prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload);
+	kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS));
+
+	prBowCmdStatus->ucStatus = BOWCMD_STATUS_TIMEOUT;	/* timeout */
+
+	kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent);
+
+	kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)));
+
+}
+
+VOID bowStopping(IN P_ADAPTER_T prAdapter)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_BSS_INFO_T prBowBssInfo;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowStoping.\n");
+	DBGLOG(BOW, EVENT, "bowStoping, SSID %s.\n", prBowBssInfo->aucSSID);
+	DBGLOG(BOW, EVENT, "bowStoping, prBowBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n",
+			    prBowBssInfo->aucBSSID[0],
+			    prBowBssInfo->aucBSSID[1],
+			    prBowBssInfo->aucBSSID[2],
+			    prBowBssInfo->aucBSSID[3], prBowBssInfo->aucBSSID[4], prBowBssInfo->aucBSSID[5]));
+	DBGLOG(BOW, EVENT, "bowStoping, prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n",
+			    prBowBssInfo->aucOwnMacAddr[0],
+			    prBowBssInfo->aucOwnMacAddr[1],
+			    prBowBssInfo->aucOwnMacAddr[2],
+			    prBowBssInfo->aucOwnMacAddr[3],
+			    prBowBssInfo->aucOwnMacAddr[4], prBowBssInfo->aucOwnMacAddr[5]));
+	DBGLOG(BOW, EVENT, "bowStoping, prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n",
+			    prAdapter->rWifiVar.aucDeviceAddress[0],
+			    prAdapter->rWifiVar.aucDeviceAddress[1],
+			    prAdapter->rWifiVar.aucDeviceAddress[2],
+			    prAdapter->rWifiVar.aucDeviceAddress[3],
+			    prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5]));
+	DBGLOG(BOW, EVENT, "bowStopping, g_u4LinkCount, %x.\n", g_u4LinkCount);
+	DBGLOG(BOW, EVENT, "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0],
+			    prBowFsmInfo->aucPeerAddress[1],
+			    prBowFsmInfo->aucPeerAddress[2],
+			    prBowFsmInfo->aucPeerAddress[3],
+			    prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]));
+	kalPrint("BoW Stoping,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing);
+#endif
+
+	if (g_u4LinkCount == 0) {
+		/*Stop beaconing */
+		GLUE_DEC_REF_CNT(g_u4Beaconing);
+
+		/*Deactive BoW network */
+		/* prBowBssInfo->fgIsNetActive = FALSE; */
+		/* prBowBssInfo->fgIsBeaconActivated = FALSE; */
+		nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+		nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		/*temp solution for FW hal_pwr_mgt.c#3037 ASSERT */
+		nicDeactivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX);
+
+	}
+
+}
+
+VOID bowStarting(IN P_ADAPTER_T prAdapter)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	if (g_u4LinkCount == 1) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "BoW Starting.\n");
+		DBGLOG(BOW, EVENT, "BoW channel granted.\n");
+#endif
+
+#if 0
+		/*Active BoW Network */
+		SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX);
+#endif
+
+		/* 3 <1> Update BSS_INFO_T per Network Basis */
+		/* 4 <1.1> Setup Operation Mode */
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+		prBssInfo->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
+		prBssInfo->eCurrentOPMode = OP_MODE_BOW;
+
+		/* 4 <1.2> Setup SSID */
+		COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress);
+		COPY_MAC_ADDR(prBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress);
+		prBssInfo->ucSSIDLen = BOW_SSID_LEN;
+		bowAssignSsid(prBssInfo->aucSSID, prBssInfo->aucOwnMacAddr);
+
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "SSID %s.\n", prBssInfo->aucSSID);
+		DBGLOG(BOW, EVENT, "prBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n",
+				    prBssInfo->aucBSSID[0],
+				    prBssInfo->aucBSSID[1],
+				    prBssInfo->aucBSSID[2],
+				    prBssInfo->aucBSSID[3], prBssInfo->aucBSSID[4], prBssInfo->aucBSSID[5]));
+		DBGLOG(BOW, EVENT, "prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n",
+				    prBssInfo->aucOwnMacAddr[0],
+				    prBssInfo->aucOwnMacAddr[1],
+				    prBssInfo->aucOwnMacAddr[2],
+				    prBssInfo->aucOwnMacAddr[3],
+				    prBssInfo->aucOwnMacAddr[4], prBssInfo->aucOwnMacAddr[5]));
+		DBGLOG(BOW, EVENT, "prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n",
+				    prAdapter->rWifiVar.aucDeviceAddress[0],
+				    prAdapter->rWifiVar.aucDeviceAddress[1],
+				    prAdapter->rWifiVar.aucDeviceAddress[2],
+				    prAdapter->rWifiVar.aucDeviceAddress[3],
+				    prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5]));
+#endif
+
+		/* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */
+		prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+		prBssInfo->u2AssocId = 0;
+
+		/* 4 <1.4> Setup Channel, Band and Phy Attributes */
+		prBssInfo->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel;
+		if (prBowFsmInfo->eBand == BAND_2G4)
+			prBssInfo->eBand = BAND_2G4;
+		else
+			prBssInfo->eBand = BAND_5G;
+
+#if CFG_BOW_SUPPORT_11N
+		/* Depend on eBand */
+		prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN;
+		/* Depend on eCurrentOPMode and ucPhyTypeSet */
+		prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG;
+
+		prBssInfo->ucNonHTBasicPhyType = (UINT_8)
+		    rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
+		prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;
+
+		prBssInfo->u2OperationalRateSet =
+		    rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;
+
+		rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet,
+					    prBssInfo->u2BSSBasicRateSet,
+					    prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen);
+
+#else
+		if (prBssInfo->eBand == BAND_2G4) {
+			/* Depend on eBand */
+			prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG;
+			/* Depend on eCurrentOPMode and ucPhyTypeSet */
+			prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG;
+
+			/* RATE_SET_ERP; */
+			prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP;
+			prBssInfo->u2OperationalRateSet = RATE_SET_ERP;
+			prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX;
+		} else {
+			/* Depend on eBand */
+			/* prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; */
+			/* Depend on eCurrentOPMode and ucPhyTypeSet */
+			/* prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; */
+			/* Depend on eBand */
+			prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A;
+			/* Depend on eCurrentOPMode and ucPhyTypeSet */
+			prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A;
+
+			/* RATE_SET_ERP; */
+			/* prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; */
+			/* prBssInfo->u2OperationalRateSet = RATE_SET_ERP; */
+
+			/* RATE_SET_ERP; */
+			prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM;
+			prBssInfo->u2OperationalRateSet = RATE_SET_OFDM;
+			prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX;
+		}
+
+#endif
+		prBssInfo->fgErpProtectMode = FALSE;
+
+		/* 4 <1.5> Setup MIB for current BSS */
+		prBssInfo->u2BeaconInterval = prBowFsmInfo->u2BeaconInterval;
+		prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT;
+		prBssInfo->u2ATIMWindow = 0;
+		prBssInfo->ucBeaconTimeoutCount = 0;
+		if (prBowFsmInfo->fgSupportQoS) {
+			prAdapter->rWifiVar.fgSupportQoS = TRUE;
+			prBssInfo->fgIsQBSS = TRUE;
+		}
+		/* 3 <2> Update BSS_INFO_T common part */
+#if CFG_SUPPORT_AAA
+		bssInitForAP(prAdapter, prBssInfo, TRUE);
+		nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_BOW_INDEX);
+#endif /* CFG_SUPPORT_AAA */
+		prBssInfo->fgIsNetActive = TRUE;
+		prBssInfo->fgIsBeaconActivated = TRUE;
+
+		/* 3 <3> Set MAC HW */
+
+		/* 4 <2> Initiate BSS_INFO_T - common part */
+		BOW_BSS_INFO_INIT(prAdapter, NETWORK_TYPE_BOW_INDEX);
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT,
+		       "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0],
+			prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2],
+			prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4],
+			prBowFsmInfo->aucPeerAddress[5]));
+#endif
+
+		/* 4 <3.1> use command packets to inform firmware */
+		rlmBssInitForAPandIbss(prAdapter, prBssInfo);
+		nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX);
+
+		/* 4 <3.2> Update AdHoc PM parameter */
+		nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_BOW_INDEX);
+
+		/* 4 <3.1> Reset HW TSF Update Mode and Beacon Mode */
+
+		/* 4 <3.2> Setup BSSID */
+		/* TODO: rxmSetRxFilterBSSID0 */
+/* rxmSetRxFilterBSSID0(prBssInfo->ucHwBssidId, prBssInfo->aucBSSID); */
+
+		/* 4 <3.3> Setup RX Filter to accept Probe Request */
+		/* TODO: f get/set RX filter. */
+
+#if 0
+		{
+			UINT_32 u4RxFilter;
+
+			if (halMacRxGetRxFilters(&u4RxFilter) == HAL_STATUS_SUCCESS) {
+
+				u4RxFilter &= ~BIT(RXFILTER_DROP_PROBE_REQ);
+
+				halMacRxSetRxFilters(u4RxFilter);
+			}
+		}
+#endif
+	}
+
+	/*Update BoW Table */
+	bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_STARTING);
+
+#if CFG_BOW_TEST
+	kalPrint("BoW Starting,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing);
+	DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount);
+#endif
+
+	/*Start beaconing */
+	if (g_u4Beaconing < 1) {
+		GLUE_INC_REF_CNT(g_u4Beaconing);
+		bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0);
+		cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval);
+	}
+#if 0
+	/*Responder: Start to scan Initiator */
+	if (prBowFsmInfo->ucRole == BOW_RESPONDER) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowStarting responder, start scan result searching.\n");
+#endif
+		cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer);
+		bowReleaseCh(prAdapter);
+		bowResponderScan(prAdapter);
+	}
+	/*Initiator: Request channel, wait for responder */
+	else {
+		/* Todo:: Nothing*/
+		/* bowRequestCh(prAdapter); */
+	}
+#endif
+
+}
+
+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 puOwnMacAddr)
+{
+	UINT_8 i;
+	UINT_8 aucSSID[] = BOW_WILDCARD_SSID;
+
+	kalMemCopy(pucSsid, aucSSID, BOW_WILDCARD_SSID_LEN);
+
+	for (i = 0; i < 6; i++) {
+		pucSsid[(3 * i) + 3] = 0x2D;
+		if ((*(puOwnMacAddr + i) >> 4) < 0xA)
+			*(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x30;
+		else
+			*(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x57;
+
+		if ((*(puOwnMacAddr + i) & 0x0F) < 0xA)
+			pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x30;
+		else
+			pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x57;
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Probe Request Frame and then return
+*        result to BSS to indicate if need to send the corresponding Probe Response
+*        Frame if the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu4ControlFlags   Control flags for replying the Probe Response
+*
+* @retval TRUE      Reply the Probe Response
+* @retval FALSE     Don't reply the Probe Response
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags)
+{
+	P_WLAN_MAC_MGMT_HEADER_T prMgtHdr;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_BSS_INFO_T prBssInfo;
+	P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
+	PUINT_8 pucIE;
+	UINT_16 u2IELength;
+	UINT_16 u2Offset = 0;
+	BOOLEAN fgReplyProbeResp = FALSE;
+
+	ASSERT(prSwRfb);
+	ASSERT(pu4ControlFlags);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+#if 0				/* CFG_BOW_TEST */
+	DBGLOG(BOW, EVENT, "bowValidateProbeReq.\n");
+#endif
+
+	/* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */
+	prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader;
+
+	u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen;
+	pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen);
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		if (ELEM_ID_SSID == IE_ID(pucIE)) {
+			if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID))
+				prIeSsid = (P_IE_SSID_T) pucIE;
+			break;
+		}
+	}			/* end of IE_FOR_EACH */
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		if (ELEM_ID_SSID == IE_ID(pucIE)) {
+			if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID))
+				prIeSsid = (P_IE_SSID_T) pucIE;
+			break;
+		}
+	}			/* end of IE_FOR_EACH */
+
+	/* 4 <2> Check network conditions */
+	/*If BoW AP is beaconing */
+	if (prBssInfo->eCurrentOPMode == OP_MODE_BOW && g_u4Beaconing > 0) {
+
+		/*Check the probe requset sender is our peer */
+		if (bowCheckBowTableIfVaild(prAdapter, prMgtHdr->aucSrcAddr))
+			fgReplyProbeResp = TRUE;
+		/*Check the probe request target SSID is our SSID */
+		else if ((prIeSsid) &&
+			 EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength))
+			fgReplyProbeResp = TRUE;
+		else
+			fgReplyProbeResp = FALSE;
+	}
+
+	return fgReplyProbeResp;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "Media Disconnect" to HOST
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, IN ULONG ulParam)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	if ((g_u4Beaconing != 0) && (g_u4LinkCount > 0) && (g_u4LinkCount < CFG_BOW_PHYSICAL_LINK_NUM)) {
+		/* Send beacon */
+		bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0);
+		cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval);
+	}
+#if CFG_BOW_TEST
+	else
+		kalPrint("BoW Send Beacon,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "Media Disconnect" to HOST
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowResponderScan(IN P_ADAPTER_T prAdapter)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_MSG_SCN_SCAN_REQ prScanReqMsg;
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowResponderScan.\n");
+	kalPrint("BOW SCAN [REQ:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq + 1);
+#endif
+
+	prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ));
+
+	if (!prScanReqMsg) {
+		ASSERT(0);	/* Can't trigger SCAN FSM */
+		return;
+	}
+
+	/*Fill scan message */
+	prScanReqMsg->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_REQ;
+	prScanReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfScanReq;
+	prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_BOW_INDEX;
+	prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN;
+	prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
+	prScanReqMsg->ucSSIDLength = BOW_SSID_LEN;
+	bowAssignSsid(prScanReqMsg->aucSSID, prBowFsmInfo->aucPeerAddress);
+	prScanReqMsg->ucChannelListNum = 1;
+
+	if (prBowFsmInfo->eBand == BAND_2G4) {
+		prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED;
+		prScanReqMsg->arChnlInfoList[0].eBand = BAND_2G4;
+	} else {
+		prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G;
+		prScanReqMsg->arChnlInfoList[0].eBand = BAND_5G;
+	}
+
+	prScanReqMsg->arChnlInfoList[0].ucChannelNum = prBowFsmInfo->ucPrimaryChannel;
+	prScanReqMsg->u2IELen = 0;
+
+	/*Send scan message */
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF);
+
+	/*Change state to SCANNING */
+	bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_SCANNING);
+
+	/* prBowFsmInfo->fgTryScan = FALSE; */ /* Will enable background sleep for infrastructure */
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_SCN_SCAN_DONE prScanDoneMsg;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_BSS_DESC_T prBssDesc;
+	UINT_8 ucSeqNumOfCompMsg;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	ENUM_BOW_DEVICE_STATE eFsmState;
+	ENUM_SCAN_STATUS eScanStatus;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr;
+	eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress);
+
+	ASSERT(prScanDoneMsg->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX);
+
+	ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum;
+	eScanStatus = prScanDoneMsg->eScanStatus;
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowResponderScanDone.\n");
+	kalPrint("BOW SCAN [DONE:%d]\n", ucSeqNumOfCompMsg);
+#endif
+
+	if (eScanStatus == SCAN_STATUS_CANCELLED) {
+#if CFG_BOW_TEST
+		kalPrint("BOW SCAN [CANCELLED:%d]\n", ucSeqNumOfCompMsg);
+#endif
+		if (eFsmState == BOW_DEVICE_STATE_DISCONNECTING) {
+			wlanoidSendSetQueryBowCmd(prAdapter,
+						  CMD_ID_CMD_BT_OVER_WIFI,
+						  TRUE,
+						  FALSE,
+						  wlanbowCmdEventLinkDisconnected,
+						  wlanbowCmdTimeoutHandler, 0, NULL, 0);
+		}
+		return;
+	} else if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) {
+		/* bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); */
+		return;
+	} else if (ucSeqNumOfCompMsg != prBowFsmInfo->ucSeqNumOfScanReq) {
+		DBGLOG(BOW, EVENT, "Sequence no. of BOW Responder scan done is not matched.\n");
+		return;
+	}
+	prConnSettings->fgIsScanReqIssued = FALSE;
+	prBssDesc = scanSearchBssDescByBssid(prAdapter, prBowFsmInfo->aucPeerAddress);
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "End scan result searching.\n");
+#endif
+
+	/* Initiator is FOUND */
+	if (prBssDesc != NULL) {
+		/* (prBssDesc->aucBSSID != NULL)) */
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "Search Bow Peer address - %x:%x:%x:%x:%x:%x.\n", prBssDesc->aucBSSID[0],
+				    prBssDesc->aucBSSID[1],
+				    prBssDesc->aucBSSID[2],
+				    prBssDesc->aucBSSID[3], prBssDesc->aucBSSID[4], prBssDesc->aucBSSID[5]);
+		DBGLOG(BOW, EVENT, "Starting to join initiator.\n");
+#endif
+		/*Set target BssDesc */
+		prBowFsmInfo->prTargetBssDesc = prBssDesc;
+		/*Request channel to do JOIN */
+		bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress,
+				    BOW_DEVICE_STATE_ACQUIRING_CHANNEL);
+		bowRequestCh(prAdapter);
+	}
+	/*Initiator is NOT FOUND */
+	else {
+		/*Scan again, until PAL timeout */
+		bowResponderScan(prAdapter);
+#if 0
+		wlanoidSendSetQueryBowCmd(prAdapter,
+					  CMD_ID_CMD_BT_OVER_WIFI,
+					  TRUE,
+					  FALSE,
+					  wlanbowCmdEventLinkDisconnected,
+					  wlanbowCmdTimeoutHandler, 0, NULL, 0);
+#endif
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Function for cancelling scan request. There is another option to extend channel privilige
+*           for another purpose.
+*
+* @param fgIsChannelExtention - Keep the channel previlege, but can cancel scan timer.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention)
+{
+
+	P_MSG_SCN_SCAN_CANCEL prScanCancel = (P_MSG_SCN_SCAN_CANCEL) NULL;
+	P_BOW_FSM_INFO_T prBowFsmInfo = (P_BOW_FSM_INFO_T) NULL;
+
+	DEBUGFUNC("bowResponderCancelScan()");
+
+	do {
+		ASSERT(prAdapter);
+
+		prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+		if (TRUE) {
+#if CFG_BOW_TEST
+			kalPrint("BOW SCAN [CANCEL:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq);
+#endif
+			/* There is a channel privilege on hand. */
+
+			DBGLOG(P2P, TRACE, "BOW Cancel Scan\n");
+
+			prScanCancel =
+			    (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL));
+			if (!prScanCancel) {
+				/* Buffer not enough, can not cancel scan request. */
+				DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n");
+				ASSERT(FALSE);
+				break;
+			}
+
+			prScanCancel->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_CANCEL;
+			prScanCancel->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
+			prScanCancel->ucSeqNum = prBowFsmInfo->ucSeqNumOfScanReq;
+#if CFG_ENABLE_WIFI_DIRECT
+			prScanCancel->fgIsChannelExt = fgIsChannelExtention;
+#endif
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancel, MSG_SEND_METHOD_BUF);
+
+		}
+
+	} while (FALSE);
+
+}				/* bowResponderCancelScan */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Initialization of JOIN STATE
+*
+* @param[in] prBssDesc  The pointer of BSS_DESC_T which is the BSS we will try to join with.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_BSS_INFO_T prBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_STA_RECORD_T prStaRec;
+	P_MSG_JOIN_REQ_T prJoinReqMsg;
+
+	ASSERT(prBssDesc);
+	ASSERT(prAdapter);
+
+	DBGLOG(BOW, EVENT, "Starting bowResponderJoin.\n");
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	/* 4 <1> We are going to connect to this BSS. */
+	prBssDesc->fgIsConnecting = TRUE;
+	bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTING);
+
+	/* 4 <2> Setup corresponding STA_RECORD_T */
+	/*Support First JOIN and retry */
+	prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_BOW_AP, NETWORK_TYPE_BOW_INDEX, prBssDesc);
+	if (!prStaRec)
+		return;
+
+	prBowFsmInfo->prTargetStaRec = prStaRec;
+
+	/* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */
+	prStaRec->fgIsReAssoc = FALSE;
+	prBowFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM;
+	prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT;
+
+	/* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */
+	if (prBowFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) {
+
+		DBGLOG(BOW, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n");
+		prBowFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM;
+
+		prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM;
+	} else {
+		ASSERT(0);
+	}
+
+	/* 4 <4.1> sync. to firmware domain */
+	cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+	/* 4 <5> Overwrite Connection Setting for eConnectionPolicy */
+	if (prBssDesc->ucSSIDLen) {
+		COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prBssDesc->aucSSID);
+		DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prConnSettings->aucSSID);
+#endif
+	}
+	/* 4 <6> Send a Msg to trigger SAA to start JOIN process. */
+	prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T));
+	if (!prJoinReqMsg) {
+
+		ASSERT(0);	/* Can't trigger SAA FSM */
+		return;
+	}
+
+	prJoinReqMsg->rMsgHdr.eMsgId = MID_BOW_SAA_FSM_START;
+	prJoinReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfReqMsg;
+	prJoinReqMsg->prStaRec = prStaRec;
+
+	prBssInfo->prStaRecOfAP = prStaRec;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "prStaRec->eStaType, %x.\n", prStaRec->eStaType);
+	DBGLOG(BOW, INFO, "BoW trigger SAA [%pM]\n", prStaRec->aucMacAddr);
+#endif
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Join Complete Event from SAA FSM for BOW FSM
+*
+* @param[in] prMsgHdr   Message of Join Complete of SAA FSM.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_JOIN_COMP_T prJoinCompMsg;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_STA_RECORD_T prStaRec;
+	P_SW_RFB_T prAssocRspSwRfb;
+	P_BSS_INFO_T prBssInfo;
+	P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL;
+	UINT_16 u2IELength;
+	PUINT_8 pucIE;
+	P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr;
+	prStaRec = prJoinCompMsg->prStaRec;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete.\n");
+	DBGLOG(BOW, EVENT, "bowfsmRunEventJoinComplete ptr check\n");
+	DBGLOG(BOW, EVENT, "prMsgHdr %x\n", prMsgHdr);
+	DBGLOG(BOW, EVENT, "prAdapter %x\n", prAdapter);
+	DBGLOG(BOW, EVENT, "prBowFsmInfo %x\n", prBowFsmInfo);
+	DBGLOG(BOW, EVENT, "prStaRec %x\n", prStaRec);
+#endif
+
+	ASSERT(prStaRec);
+	ASSERT(prBowFsmInfo);
+
+	/* Check SEQ NUM */
+	if (prJoinCompMsg->ucSeqNum == prBowFsmInfo->ucSeqNumOfReqMsg) {
+		COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr);
+
+		/* 4 <1> JOIN was successful */
+		if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) {
+			prAssocRspSwRfb = prJoinCompMsg->prSwRfb;
+			prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader;
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+			u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) -
+						(OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) -
+						 WLAN_MAC_MGMT_HEADER_LEN));
+			pucIE = prAssocRspFrame->aucInfoElem;
+
+			prStaRec->eStaType = STA_TYPE_BOW_AP;
+			prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet;
+			prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet;
+#if CFG_BOW_RATE_LIMITATION
+			/* 4 <1.2>Update Rate Set */
+			/*Limit Rate Set to 24M,  48M, 54M */
+			prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M);
+			/*If peer cannot support the above rate set, fix on the available highest rate */
+			if (prStaRec->u2DesiredNonHTRateSet == 0) {
+				UINT_8 ucHighestRateIndex;
+
+				if (rateGetHighestRateIndexFromRateSet
+				    (prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) {
+					prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex);
+				}
+			}
+#endif
+
+			/* 4 <1.1> Change FW's Media State immediately. */
+			bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+
+			mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
+
+			/* 4 <1.2> Update HT information and set channel */
+			/* Record HT related parameters in rStaRec and rBssInfo
+			 * Note: it shall be called before nicUpdateBss()
+			 */
+#if CFG_BOW_SUPPORT_11N
+			rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
+#endif
+
+			/* 4 <1.3> Update BSS_INFO_T */
+			nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX);
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "Finish bowUpdateBssInfoForJOIN.\n");
+#endif
+			/* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */
+			cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "bowFsmRunEventJoinComplete, qmActivateStaRec.\n");
+#endif
+
+			/* 4 <1.7> Set the Next State of BOW  FSM */
+			wlanoidSendSetQueryBowCmd(prAdapter,
+						  CMD_ID_CMD_BT_OVER_WIFI,
+						  TRUE,
+						  FALSE,
+						  wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0);
+		}
+		/* 4 <2> JOIN was not successful */
+		else {
+			/*Retry */
+			bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc);
+#if 0
+			wlanoidSendSetQueryBowCmd(prAdapter,
+						  CMD_ID_CMD_BT_OVER_WIFI,
+						  TRUE,
+						  FALSE,
+						  wlanbowCmdEventLinkDisconnected,
+						  wlanbowCmdTimeoutHandler, 0, NULL, 0);
+#endif
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete -- Join failed.\n");
+			DBGLOG(BOW, INFO, "BoW trigger SAA REJOIN\n");
+#endif
+		}
+	}
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate the Media State to HOST
+*
+* @param[in] eConnectionState   Current Media State
+* @param[in] fgDelayIndication  Set TRUE for postponing the Disconnect Indication.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter,
+				IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN BOOLEAN fgDelayIndication)
+{
+	EVENT_CONNECTION_STATUS rEventConnStatus;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_INFO_T prBssInfo;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	/* NOTE(Kevin): Move following line to bowChangeMediaState() macro per CM's request. */
+	/* prBowBssInfo->eConnectionState = eConnectionState; */
+
+	/* For indicating the Disconnect Event only if current media state is
+	 * disconnected and we didn't do indication yet.
+	 */
+	if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
+		if (prBssInfo->eConnectionStateIndicated == eConnectionState)
+			return;
+	}
+
+	if (!fgDelayIndication) {
+		/* 4 <0> Cancel Delay Timer */
+		cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rIndicationOfDisconnectTimer);
+
+		/* 4 <1> Fill EVENT_CONNECTION_STATUS */
+		rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState;
+
+		if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+			rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED;
+
+			if (prBssInfo->eCurrentOPMode == OP_MODE_BOW) {
+				rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA;
+				rEventConnStatus.u2AID = prBssInfo->u2AssocId;
+				rEventConnStatus.u2ATIMWindow = 0;
+			} else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
+				rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS;
+				rEventConnStatus.u2AID = 0;
+				rEventConnStatus.u2ATIMWindow = prBssInfo->u2ATIMWindow;
+			} else {
+				ASSERT(0);
+			}
+
+			COPY_SSID(rEventConnStatus.aucSsid,
+				  rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+
+			COPY_MAC_ADDR(rEventConnStatus.aucBssid, prBssInfo->aucBSSID);
+
+			rEventConnStatus.u2BeaconPeriod = prBssInfo->u2BeaconInterval;
+			rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prBssInfo->ucPrimaryChannel);
+
+			switch (prBssInfo->ucNonHTBasicPhyType) {
+			case PHY_TYPE_HR_DSSS_INDEX:
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS;
+				break;
+
+			case PHY_TYPE_ERP_INDEX:
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24;
+				break;
+
+			case PHY_TYPE_OFDM_INDEX:
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5;
+				break;
+
+			default:
+				ASSERT(0);
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS;
+				break;
+			}
+		} else {
+#if CFG_PRIVACY_MIGRATION
+			/* Clear the pmkid cache while media disconnect */
+			secClearPmkid(prAdapter);
+#endif
+
+			rEventConnStatus.ucReasonOfDisconnect = prBssInfo->ucReasonOfDisconnect;
+
+		}
+
+		/* 4 <2> Indication */
+		nicMediaStateChange(prAdapter, NETWORK_TYPE_BOW_INDEX, &rEventConnStatus);
+		prBssInfo->eConnectionStateIndicated = eConnectionState;
+	} else {
+		/* NOTE: Only delay the Indication of Disconnect Event */
+		ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED);
+
+		DBGLOG(BOW, INFO, "Postpone the indication of Disconnect for %d seconds\n",
+				   prConnSettings->ucDelayTimeOfDisconnectEvent);
+
+		cnmTimerStartTimer(prAdapter,
+				   &prBowFsmInfo->rIndicationOfDisconnectTimer,
+				   SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent));
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate the Event of Tx Fail of AAA Module.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowRunEventAAATxFail , bssRemoveStaRecFromClientList.\n");
+	DBGLOG(BOW, INFO, "BoW AAA TxFail, target state %d\n", prStaRec->ucStaState + 1);
+#endif
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+	bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate the Event of Successful Completion of AAA Module.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+
+	ASSERT(prStaRec);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowRunEventAAAComplete, cnmStaRecChangeState, STA_STATE_3.\n");
+	DBGLOG(BOW, INFO, "BoW AAA complete [%pM]\n", prStaRec->aucMacAddr);
+#endif
+
+	/*Update BssInfo to connected */
+	bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+	nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX);
+
+	/*Update StaRec to State3 */
+	cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+
+	/*Connected */
+	wlanoidSendSetQueryBowCmd(prAdapter,
+				  CMD_ID_CMD_BT_OVER_WIFI,
+				  TRUE, FALSE, wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle RxDeauth
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+
+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb)
+{
+	P_BSS_INFO_T prBowBssInfo;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	ENUM_BOW_DEVICE_STATE eFsmState;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+	if (!IS_STA_IN_BOW(prStaRec))
+		return WLAN_STATUS_NOT_ACCEPTED;
+
+	eFsmState = bowGetBowTableState(prAdapter, prStaRec->aucMacAddr);
+
+	if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) {
+		/*do nothing */
+		return WLAN_STATUS_NOT_ACCEPTED;
+	}
+
+	if (prStaRec->ucStaState > STA_STATE_1) {
+
+		if (STA_STATE_3 == prStaRec->ucStaState) {
+			/* P_MSG_AIS_ABORT_T prAisAbortMsg; */
+
+			/* NOTE(Kevin): Change state immediately to avoid starvation of
+			 * MSG buffer because of too many deauth frames before changing
+			 * the STA state.
+			 */
+			cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+		}
+
+		COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr);
+
+		wlanoidSendSetQueryBowCmd(prAdapter,
+					  CMD_ID_CMD_BT_OVER_WIFI,
+					  TRUE,
+					  FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0);
+
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	return WLAN_STATUS_NOT_ACCEPTED;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function handle BoW Link disconnect.
+*
+* \param[in] pMsduInfo            Pointer to the Msdu Info
+* \param[in] rStatus              The Tx done status
+*
+* \return -
+*
+* \note after receive deauth frame, callback function call this
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	/*Free target StaRec */
+	if (prMsduInfo)
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	else
+		prStaRec = prBowFsmInfo->prTargetStaRec;
+
+	if (prStaRec)
+		/* cnmStaRecFree(prAdapter, prStaRec, TRUE); */
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+	kalPrint("bowDisconnectLink\n");
+	/*No one connected */
+	if (g_u4LinkCount == 0 && g_u4Beaconing != 0) {
+		cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer);
+		bowStopping(prAdapter);
+		kalPrint("bowStopping\n");
+		/*Restore TxPower from Short range mode */
+#if CFG_SUPPORT_NVRAM && 0
+		wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo));
+#endif
+		/*Uninit BoW Interface */
+#if CFG_BOW_SEPARATE_DATA_PATH
+		kalUninitBowDevice(prAdapter->prGlueInfo);
+#endif
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Assoc Req Frame and then return
+*        the status code to AAA to indicate if need to perform following actions
+*        when the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu2StatusCode     The Status Code of Validation Result
+*
+* @retval TRUE      Reply the Assoc Resp
+* @retval FALSE     Don't reply the Assoc Resp
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode)
+{
+	BOOLEAN fgReplyAssocResp = FALSE;
+	P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL;
+	OS_SYSTIME rCurrentTime;
+	static OS_SYSTIME rLastRejectAssocTime;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
+	*pu2StatusCode = STATUS_CODE_REQ_DECLINED;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowValidateAssocReq, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+			    prBowFsmInfo->aucPeerAddress[0],
+			    prBowFsmInfo->aucPeerAddress[1],
+			    prBowFsmInfo->aucPeerAddress[2],
+			    prBowFsmInfo->aucPeerAddress[3],
+			    prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]));
+	DBGLOG(BOW, EVENT, "bowValidateAssocReq, prAssocReqFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n",
+			    prAssocReqFrame->aucSrcAddr[0],
+			    prAssocReqFrame->aucSrcAddr[1],
+			    prAssocReqFrame->aucSrcAddr[2],
+			    prAssocReqFrame->aucSrcAddr[3],
+			    prAssocReqFrame->aucSrcAddr[4], prAssocReqFrame->aucSrcAddr[5]));
+#endif
+
+	/*Assoc Accept */
+	while (EQUAL_MAC_ADDR(prAssocReqFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowValidateAssocReq, return wlanbowCmdEventLinkConnected.\n");
+#endif
+		/*Update StaRec */
+		prStaRec = cnmGetStaRecByAddress(prAdapter,
+						 (UINT_8) NETWORK_TYPE_BOW_INDEX, prAssocReqFrame->aucSrcAddr);
+		if (!prStaRec)
+			break;
+		prStaRec->eStaType = STA_TYPE_BOW_CLIENT;
+		prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet;
+		prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet;
+
+#if CFG_BOW_RATE_LIMITATION
+		/*Limit Rate Set to 24M,  48M, 54M */
+		prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M);
+		/*If peer cannot support the above rate set, fix on the available highest rate */
+		if (prStaRec->u2DesiredNonHTRateSet == 0) {
+			UINT_8 ucHighestRateIndex;
+
+			if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex))
+				prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex);
+			else {
+				/*If no available rate is found, DECLINE the association */
+				*pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED;
+				break;
+			}
+		}
+#endif
+		prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
+
+		/*Undpate BssInfo to FW */
+		bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+		nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX);
+
+		/*reply successful */
+		*pu2StatusCode = STATUS_CODE_SUCCESSFUL;
+		fgReplyAssocResp = TRUE;
+		break;
+	}
+
+	/*Reject Assoc */
+	if (*pu2StatusCode != STATUS_CODE_SUCCESSFUL) {
+		/*Reply Assoc with reject every 5s */
+		rCurrentTime = kalGetTimeTick();
+		if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAssocTime, MSEC_TO_SYSTIME(5000)) ||
+		    rLastRejectAssocTime == 0) {
+			fgReplyAssocResp = TRUE;
+			rLastRejectAssocTime = rCurrentTime;
+		}
+	}
+
+	return fgReplyAssocResp;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Auth Frame and then return
+*        the status code to AAA to indicate if need to perform following actions
+*        when the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[in] pprStaRec          Pointer to pointer of STA_RECORD_T structure.
+* @param[out] pu2StatusCode     The Status Code of Validation Result
+*
+* @retval TRUE      Reply the Auth
+* @retval FALSE     Don't reply the Auth
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+bowValidateAuth(IN P_ADAPTER_T prAdapter,
+		IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode)
+{
+	BOOLEAN fgReplyAuth = FALSE;
+	P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL;
+	OS_SYSTIME rCurrentTime;
+	static OS_SYSTIME rLastRejectAuthTime;
+
+	/* TODO(Kevin): Call BoW functions to check ..
+	   1. Check we are BoW now.
+	   2. Check we can accept connection from thsi peer
+	   3. Check Black List here.
+	 */
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowValidateAuth, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+			    prBowFsmInfo->aucPeerAddress[0],
+			    prBowFsmInfo->aucPeerAddress[1],
+			    prBowFsmInfo->aucPeerAddress[2],
+			    prBowFsmInfo->aucPeerAddress[3],
+			    prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]));
+	DBGLOG(BOW, EVENT, "bowValidateAuth, prAuthFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n",
+			    prAuthFrame->aucSrcAddr[0],
+			    prAuthFrame->aucSrcAddr[1],
+			    prAuthFrame->aucSrcAddr[2],
+			    prAuthFrame->aucSrcAddr[3], prAuthFrame->aucSrcAddr[4], prAuthFrame->aucSrcAddr[5]));
+#endif
+
+	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX, prAuthFrame->aucSrcAddr);
+	if (!prStaRec) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecAlloc.\n");
+#endif
+		prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX);
+
+		/* TODO(Kevin): Error handling of allocation of STA_RECORD_T for
+		 * exhausted case and do removal of unused STA_RECORD_T.
+		 */
+		if (!prStaRec)
+			return fgReplyAuth;
+		COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr);
+		prSwRfb->ucStaRecIdx = prStaRec->ucIndex;
+		prBowBssInfo->prStaRecOfAP = prStaRec;
+
+		/* NOTE(Kevin): Better to change state here, not at TX Done */
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecChangeState.\n");
+#endif
+	} else {
+		prSwRfb->ucStaRecIdx = prStaRec->ucIndex;
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucIndex, %x.\n", prStaRec->ucIndex);
+#endif
+		bssRemoveStaRecFromClientList(prAdapter, prBowBssInfo, prStaRec);
+	}
+
+	if (EQUAL_MAC_ADDR(prAuthFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) {
+
+		prStaRec->eStaType = STA_TYPE_BOW_CLIENT;
+		prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->eStaType, %x.\n", prStaRec->eStaType);
+		DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucNetTypeIndex, %x.\n", prStaRec->ucNetTypeIndex);
+#endif
+		/* Update Station Record - Status/Reason Code */
+		prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
+		prStaRec->ucJoinFailureCount = 0;
+		*pprStaRec = prStaRec;
+		*pu2StatusCode = STATUS_CODE_SUCCESSFUL;
+		fgReplyAuth = TRUE;
+	} else {
+		cnmStaRecFree(prAdapter, prStaRec, FALSE);
+		*pu2StatusCode = STATUS_CODE_REQ_DECLINED;
+
+		/*Reply auth with reject every 5s */
+		rCurrentTime = kalGetTimeTick();
+		if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAuthTime, MSEC_TO_SYSTIME(5000)) ||
+		    rLastRejectAuthTime == 0) {
+			fgReplyAuth = TRUE;
+			rLastRejectAuthTime = rCurrentTime;
+		}
+	}
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "bowValidateAuth,  fgReplyAuth, %x.\n", fgReplyAuth);
+#endif
+	return fgReplyAuth;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is invoked when CNM granted channel privilege
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_BSS_INFO_T prBowBssInfo;
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_MSG_CH_GRANT_T prMsgChGrant;
+	UINT_8 ucTokenID;
+	UINT_32 u4GrantInterval;
+	ENUM_BOW_DEVICE_STATE eFsmState;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+	prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr;
+	ucTokenID = prMsgChGrant->ucTokenID;
+	u4GrantInterval = prMsgChGrant->u4GrantInterval;
+
+	/* 1. free message */
+	cnmMemFree(prAdapter, prMsgHdr);
+	prBowFsmInfo->fgIsChannelGranted = TRUE;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "Entering bowRunEventChGrant.\n");
+#endif
+
+	eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress);
+
+	/*Release channel */
+	if ((!prBowFsmInfo->fgIsChannelRequested) ||
+	    (prBowFsmInfo->ucSeqNumOfChReq != ucTokenID) ||
+	    (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) || (eFsmState == BOW_DEVICE_STATE_DISCONNECTING)) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, INFO, "BoW Channel [GIVE UP:%d]\n", ucTokenID);
+		DBGLOG(BOW, INFO, "[Requested:%d][ucSeqNumOfChReq:%d][eFsmState:%d]\n",
+		       prBowFsmInfo->fgIsChannelRequested, prBowFsmInfo->ucSeqNumOfChReq, eFsmState);
+#endif
+		bowReleaseCh(prAdapter);
+		return;
+	}
+
+	/* 2. channel privilege has been approved */
+	prBowFsmInfo->u4ChGrantedInterval = u4GrantInterval;
+
+#if 0
+	cnmTimerStartTimer(prAdapter,
+			   &prBowFsmInfo->rChGrantedTimer,
+			   prBowFsmInfo->u4ChGrantedInterval - BOW_JOIN_CH_GRANT_THRESHOLD);
+#else
+	cnmTimerStartTimer(prAdapter,
+			   &prBowFsmInfo->rChGrantedTimer, BOW_JOIN_CH_REQUEST_INTERVAL - BOW_JOIN_CH_GRANT_THRESHOLD);
+#endif
+
+	/* 3.2 set local variable to indicate join timer is ticking */
+	prBowFsmInfo->fgIsInfraChannelFinished = FALSE;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, INFO, "BoW Channel [GRANTED:%d].\n", ucTokenID);
+#endif
+
+	if (eFsmState == BOW_DEVICE_STATE_ACQUIRING_CHANNEL) {
+		bowStarting(prAdapter);
+		bowReleaseCh(prAdapter);
+		if (prBowFsmInfo->ucRole == BOW_RESPONDER)
+			bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc);
+	} else {
+		/*update bssinfo */
+		nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX);
+		bowReleaseCh(prAdapter);
+	}
+
+}				/* end of aisFsmRunEventChGrant() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is to inform CNM for channel privilege requesting
+*           has been released
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowRequestCh(IN P_ADAPTER_T prAdapter)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_MSG_CH_REQ_T prMsgChReq;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	if (prBowFsmInfo->fgIsChannelGranted == FALSE) {
+
+#if CFG_BOW_TEST
+		DBGLOG(BOW, INFO, "BoW channel [REQUEST:%d], %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq + 1,
+		       prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand);
+#endif
+		prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T));
+
+		if (!prMsgChReq) {
+			ASSERT(0);	/* Can't indicate CNM for channel acquiring */
+			return;
+		}
+
+		prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ;
+		prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
+		prMsgChReq->ucTokenID = ++prBowFsmInfo->ucSeqNumOfChReq;
+		prMsgChReq->eReqType = CH_REQ_TYPE_JOIN;
+#if 0
+		prMsgChReq->u4MaxInterval = BOW_JOIN_CH_REQUEST_INTERVAL;
+#else
+		prMsgChReq->u4MaxInterval = 1;
+#endif
+		/* prBowFsmInfo->prTargetBssDesc->ucChannelNum; */
+		prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel;
+		/* prBowFsmInfo->prTargetBssDesc->eSco; */
+		prMsgChReq->eRfSco = CHNL_EXT_SCN;
+		/* prBowFsmInfo->prTargetBssDesc->eBand; */
+		prMsgChReq->eRfBand = prBowFsmInfo->eBand;
+		COPY_MAC_ADDR(prMsgChReq->aucBSSID, prBowFsmInfo->aucPeerAddress);
+
+		prBowFsmInfo->fgIsChannelRequested = TRUE;
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is to inform BOW that channel privilege is granted
+*           has been released
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	P_MSG_CH_ABORT_T prMsgChAbort;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+	if (prBowFsmInfo->fgIsChannelGranted != FALSE || prBowFsmInfo->fgIsChannelRequested != FALSE) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, INFO, "BoW channel [RELEASE:%d] %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq,
+		       prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand);
+#endif
+
+		prBowFsmInfo->fgIsChannelRequested = FALSE;
+		prBowFsmInfo->fgIsChannelGranted = FALSE;
+
+		/* 1. return channel privilege to CNM immediately */
+		prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T));
+		if (!prMsgChAbort) {
+			ASSERT(0);	/* Can't release Channel to CNM */
+			return;
+		}
+
+		prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT;
+		prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
+		prMsgChAbort->ucTokenID = prBowFsmInfo->ucSeqNumOfChReq;
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF);
+	}
+
+}				/* end of aisFsmReleaseCh() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "Media Disconnect" to HOST
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam)
+{
+	P_BOW_FSM_INFO_T prBowFsmInfo;
+	ENUM_BOW_DEVICE_STATE eFsmState;
+
+	ASSERT(prAdapter);
+
+	prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, INFO, "BoW Channel [TIMEOUT]\n");
+#endif
+#if 1
+	/* bowReleaseCh(prAdapter); */
+	eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress);
+
+	/*If connecting is not completed, request CH again */
+	if ((eFsmState == BOW_DEVICE_STATE_CONNECTING) || (eFsmState == BOW_DEVICE_STATE_STARTING))
+		bowRequestCh(prAdapter);
+#endif
+}
+
+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 ucBowTableIdx = 0;
+	CMD_INFO_T rCmdInfo;
+
+	ASSERT(prAdapter);
+
+	kalMemZero(&rCmdInfo, sizeof(CMD_INFO_T));
+
+	while (ucBowTableIdx < CFG_BOW_PHYSICAL_LINK_NUM) {
+		if (arBowTable[ucBowTableIdx].fgIsValid) {
+			COPY_MAC_ADDR(prAdapter->rWifiVar.rBowFsmInfo.aucPeerAddress,
+				      arBowTable[ucBowTableIdx].aucPeerAddress);
+
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT,
+			       "bowNotifyAllLinkDisconnected, arBowTable[%x].aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+				ucBowTableIdx, arBowTable[ucBowTableIdx].aucPeerAddress[0],
+				arBowTable[ucBowTableIdx].aucPeerAddress[1],
+				arBowTable[ucBowTableIdx].aucPeerAddress[2],
+				arBowTable[ucBowTableIdx].aucPeerAddress[3],
+				arBowTable[ucBowTableIdx].aucPeerAddress[4],
+				arBowTable[ucBowTableIdx].aucPeerAddress[5]));
+			DBGLOG(BOW, EVENT,
+			       "bowNotifyAllLinkDisconnected, arBowTable[%x].fgIsValid, %x.\n", ucBowTableIdx,
+				arBowTable[ucBowTableIdx].fgIsValid);
+#endif
+#if 1
+			wlanoidSendSetQueryBowCmd(prAdapter,
+						  CMD_ID_CMD_BT_OVER_WIFI,
+						  TRUE,
+						  FALSE,
+						  wlanbowCmdEventLinkDisconnected,
+						  wlanbowCmdTimeoutHandler, 0, NULL, 0);
+#else
+			wlanbowCmdEventLinkDisconnected(prAdapter, &rCmdInfo, NULL);
+#endif
+		}
+
+		ucBowTableIdx += 1;
+	}
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer
+*
+* \param[in]
+*           prGlueInfo
+*           rPeerAddr
+* \return
+*           ENUM_BOW_DEVICE_STATE
+*/
+/*----------------------------------------------------------------------------*/
+
+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6])
+{
+	UINT_8 idx;
+
+	KAL_SPIN_LOCK_DECLARATION();
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) {
+		if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) {
+
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx,
+					    aucPeerAddress[0],
+					    aucPeerAddress[1],
+					    aucPeerAddress[2],
+					    aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]));
+
+			DBGLOG(BOW, EVENT,
+			       "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx,
+				arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1],
+				arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3],
+				arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5]));
+
+			DBGLOG(BOW, EVENT,
+			       "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx,
+				arBowTable[idx].fgIsValid);
+
+#endif
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+			return TRUE;
+		}
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+	return FALSE;
+}
+
+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable)
+{
+	KAL_SPIN_LOCK_DECLARATION();
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	if (arBowTable[ucBowTableIdx].fgIsValid) {
+
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT,
+		       "bowGetBowTableContent, arBowTable[idx].fgIsValid, %x, %x.\n", ucBowTableIdx,
+			arBowTable[ucBowTableIdx].fgIsValid);
+		DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[ucBowTableIdx].eState);
+#endif
+		prBowTable = &(arBowTable[ucBowTableIdx]);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+		return TRUE;
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	return FALSE;
+}
+
+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable)
+{
+	KAL_SPIN_LOCK_DECLARATION();
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	COPY_MAC_ADDR(arBowTable[ucBowTableIdx].aucPeerAddress, prBowTable->aucPeerAddress);
+	arBowTable[ucBowTableIdx].eState = prBowTable->eState;
+	arBowTable[ucBowTableIdx].fgIsValid = prBowTable->fgIsValid;
+	arBowTable[ucBowTableIdx].ucAcquireID = prBowTable->ucAcquireID;
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	kalSetBowState(prAdapter->prGlueInfo, prBowTable->eState, prBowTable->aucPeerAddress);
+	/* kalSetBowRole(prAdapter->prGlueInfo, prBowTable->ucRole, prBowTable->aucPeerAddress); */
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, INFO, "SET State [%d]\n", arBowTable[ucBowTableIdx].eState);
+	DBGLOG(BOW, EVENT,
+	       "kalCheckBowifVaild, arBowTable[ucBowTableIdx].fgIsValid, %x, %x.\n", ucBowTableIdx,
+		arBowTable[ucBowTableIdx].fgIsValid);
+#endif
+
+	return TRUE;
+
+}
+
+BOOLEAN
+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx)
+{
+	UINT_8 idx;
+
+	KAL_SPIN_LOCK_DECLARATION();
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) {
+		if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) {
+
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx,
+					    aucPeerAddress[0],
+					    aucPeerAddress[1],
+					    aucPeerAddress[2],
+					    aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]));
+			DBGLOG(BOW, EVENT,
+			       "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx,
+				arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1],
+				arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3],
+				arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5]));
+			DBGLOG(BOW, EVENT,
+			       "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx,
+				arBowTable[idx].fgIsValid);
+#endif
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+			*pucBowTableIdx = idx;
+
+			return TRUE;
+		}
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	return FALSE;
+}
+
+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx)
+{
+	UINT_8 idx;
+
+	KAL_SPIN_LOCK_DECLARATION();
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) {
+		if (!arBowTable[idx].fgIsValid) {
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT,
+			       "bowGetBowTableFreeEntry, arBowTable[idx].fgIsValid, %x, %x.\n", idx,
+				arBowTable[idx].fgIsValid);
+#endif
+			*pucBowTableIdx = idx;
+			arBowTable[idx].fgIsValid = TRUE;
+
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+			return TRUE;
+		}
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	return FALSE;
+}
+
+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6])
+{
+	UINT_8 idx;
+
+	KAL_SPIN_LOCK_DECLARATION();
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) {
+		if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) {
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "bowGetState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx,
+					    aucPeerAddress[0],
+					    aucPeerAddress[1],
+					    aucPeerAddress[2],
+					    aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]));
+			DBGLOG(BOW, EVENT, "bowGetState, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx,
+					    arBowTable[idx].aucPeerAddress[0],
+					    arBowTable[idx].aucPeerAddress[1],
+					    arBowTable[idx].aucPeerAddress[2],
+					    arBowTable[idx].aucPeerAddress[3],
+					    arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5]));
+			DBGLOG(BOW, EVENT,
+			       "bowGetState, arBowTable[idx].fgIsValid, %x, %x.\n", idx, arBowTable[idx].fgIsValid);
+			DBGLOG(BOW, EVENT,
+			       "bowGetState, arBowTable[idx].eState;, %x, %x.\n", idx, arBowTable[idx].eState);
+			DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[idx].eState);
+#endif
+
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+			return arBowTable[idx].eState;
+		}
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+	return BOW_DEVICE_STATE_DISCONNECTED;
+}
+
+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState)
+{
+	UINT_8 ucBowTableIdx;
+
+	if (bowGetBowTableEntryByPeerAddress(prAdapter, aucPeerAddress, &ucBowTableIdx)) {
+		KAL_SPIN_LOCK_DECLARATION();
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+		arBowTable[ucBowTableIdx].eState = eState;
+#if CFG_BOW_TEST
+		DBGLOG(BOW, INFO, "SET State [%d]\n", eState);
+#endif
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE);
+
+		kalSetBowState(prAdapter->prGlueInfo, eState, aucPeerAddress);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c
new file mode 100644
index 0000000000000..1c59f861047e6
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c
@@ -0,0 +1,6240 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_lib.c#2
+*/
+/*! \file   wlan_lib.c
+    \brief  Internal driver stack will export the required procedures here for GLUE Layer.
+
+    This file contains all routines which are exported from MediaTek 802.11 Wireless
+    LAN driver stack to GLUE Layer.
+*/
+
+/*
+** Log: wlan_lib.c
+**
+** 08 15 2012 eason.tsai
+** [ALPS00338170] [Need Patch] [Volunteer Patch] modify build warning
+** fix build waring for codechange
+ *
+ * 07 13 2012 cp.wu
+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for termination
+ * after SDIO error has happened
+ * [driver domain] add force reset by host-to-device interrupt mechanism
+ *
+ * 06 11 2012 cp.wu
+ * [WCXRP00001252] [MT6620 Wi-Fi][Driver] Add debug message while encountering firmware response timeout
+ * output message while timeout event occurs
+ *
+ * 06 11 2012 eason.tsai
+ * NULL
+ * change from binay to hex code
+ *
+ * 06 08 2012 eason.tsai
+ * NULL
+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool
+ *
+ * 05 11 2012 cp.wu
+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience
+ * show MAC address & source while initiliazation
+ *
+ * 03 29 2012 eason.tsai
+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define
+ * add conditional define.
+ *
+ * 03 04 2012 eason.tsai
+ * NULL
+ * modify the cal fail report code.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 16 2012 cp.wu
+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band
+ * configuration with corresponding network configuration correct scan result removing policy.
+ *
+ * 01 16 2012 cp.wu
+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with
+ * corresponding network configuration add wlanSetPreferBandByNetwork() for glue layer to invoke
+ * for setting preferred band configuration corresponding to network type.
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 11 28 2011 cp.wu
+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment
+ * when returining to ROM code
+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware
+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not
+ *
+ * 11 14 2011 cm.chang
+ * [WCXRP00001104] [All Wi-Fi][FW] Show init process by HW mail-box register
+ * Show FW initial ID when timeout to wait for ready bit
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 10 18 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * when powering off, always clear pending interrupts, then wait for RDY to be de-asserted
+ *
+ * 10 14 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * shorten the packet length for firmware download if no more than 2048 bytes.
+ *
+ * 10 03 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * add firmware download path in divided scatters.
+ *
+ * 10 03 2011 cp.wu
+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * add firmware downloading aggregated path.
+ *
+ * 09 30 2011 cm.chang
+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band
+ * .
+ *
+ * 09 20 2011 cp.wu
+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized
+ * 1. always show error message for SDIO bus errors.
+ * 2. reset bus error flag when re-initialization
+ *
+ * 08 26 2011 cm.chang
+ * [WCXRP00000952] [MT5931 Wi-Fi][FW] Handshake with BWCS before DPD/TX power calibration
+ * Fix compiling error for WinXP MT5931 driver
+ *
+ * 08 25 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS Sync ready for WinXP.
+ *
+ * 08 25 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add DFS switch.
+ *
+ * 08 24 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Update RDD test mode cases.
+ *
+ * 08 19 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * escape from normal path if any error is occurred.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * reuse firmware download logic of MT6620 for MT6628.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms.
+ *
+ * 08 02 2011 yuche.tsai
+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a
+ * disconnecting device issue.
+ * Fix GO send deauth frame issue.
+ *
+ * 07 22 2011 jeffrey.chang
+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time
+ * modify driver to set OSC stable time after f/w download
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 06 24 2011 cp.wu
+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content
+ * if there is no valid address in chip, generate a new one from driver domain instead of firmware domain
+ * due to sufficient randomness
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content
+ * check with firmware for valid MAC address.
+ *
+ * 06 20 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * disable whole-chip resetting mechanism due to the need of further ECO to work as expected.
+ *
+ * 05 31 2011 cp.wu
+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
+ * changed to use non-zero checking for valid bit in NVRAM content
+ *
+ * 05 27 2011 cp.wu
+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
+ *
+ * 05 18 2011 cp.wu
+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain
+ * pass PHY_PARAM in NVRAM from driver to firmware.
+ *
+ * 05 11 2011 cp.wu
+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
+ * correct assertion.
+ *
+ * 05 11 2011 cp.wu
+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke.
+ *
+ * 05 11 2011 cm.chang
+ * [WCXRP00000717] [MT5931 Wi-Fi][Driver] Handle wrong NVRAM content about AP bandwidth setting
+ * .
+ *
+ * 05 05 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * change delay from 100ms to 120ms upon DE's suggestion.
+ *
+ * 05 05 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * add delay after whole-chip resetting for MT5931 E1 ASIC.
+ *
+ * 04 22 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space
+ * process for RESET_START and RESET_END events skip power-off handshaking when RESET indication is received.
+ *
+ * 04 22 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * .
+ *
+ * 04 18 2011 cp.wu
+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
+ * 1) add API for glue layer to query ACPI state
+ * 2) Windows glue should not access to hardware after switched into D3 state
+ *
+ * 04 15 2011 cp.wu
+ * [WCXRP00000654] [MT6620 Wi-Fi][Driver] Add loop termination criterion for wlanAdapterStop().
+ * add loop termination criteria for wlanAdapterStop().
+ *
+ * 04 12 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix the sta index in processing security frame
+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
+ * Add debug message.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing
+ * frame dropping cases for TC4 path
+ * 1. add nicTxGetResource() API for QM to make decisions.
+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case.
+ *
+ * 04 06 2011 cp.wu
+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure
+ * happend inside wlanAdapterStart invoke nicReleaseAdapterMemory() as failure handling in case
+ * wlanAdapterStart() failed unexpectedly
+ *
+ * 03 29 2011 wh.su
+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error
+ * fixed the kclocwork error.
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically
+ * continuous memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 10 2011 cp.wu
+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
+ * deprecate configuration used by MT6620 E2
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 02 25 2011 cp.wu
+ * [WCXRP00000496] [MT5931][Driver] Apply host-triggered chip reset before initializing firmware download procedures
+ * apply host-triggered chip reset mechanism before initializing firmware download procedures.
+ *
+ * 02 17 2011 eddie.chen
+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel
+ * 1) Change GetFrameAction decision when BSS is absent.
+ * 2) Check channel and resource in processing ProbeRequest
+ *
+ * 02 16 2011 cm.chang
+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism
+ * .
+ *
+ * 02 01 2011 george.huang
+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers
+ * init variable for CTIA.
+ *
+ * 01 27 2011 george.huang
+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability
+ * Support current measure mode, assigned by registry (XP only).
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 01 10 2011 cp.wu
+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer when the
+ * corresponding BSS is disconnected due to beacon timeout remove from scanning result when the BSS
+ * is disconnected due to beacon timeout.
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to
+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous
+ * and physically-continuous type to ease slab system pressure
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
+ * while being unloaded, clear all pending interrupt then set LP-own to firmware
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay
+ * to avoid blocking to system scheduling change to use msleep() and shorten waiting interval
+ * to reduce blocking to other task while Wi-Fi driver is being loaded
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * report EEPROM used flag via NIC_CAPABILITY
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools
+ *
+ * 12 22 2010 eddie.chen
+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry
+ * Remove controling auto rate from initial setting. The initial setting is defined by FW code.
+ *
+ * 12 15 2010 cp.wu
+ * NULL
+ * sync. with ALPS code by enabling interrupt just before leaving wlanAdapterStart()
+ *
+ * 12 08 2010 yuche.tsai
+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in
+ * Change Param name for invitation connection.
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 11 03 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * 1) use 8 buffers for MT5931 which is equipped with less memory
+ * 2) modify MT5931 debug level to TRACE when download is successful
+ *
+ * 11 02 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * for MT5931, adapter initialization is done *after* firmware is downloaded.
+ *
+ * 11 02 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * correct MT5931 firmware download procedure:
+ * MT5931 will download firmware first then acquire LP-OWN
+ *
+ * 11 02 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * 1) update MT5931 firmware encryption tool. (using 64-bytes unit)
+ * 2) update MT5931 firmware download procedure
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version
+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying
+ * current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 11 01 2010 yarco.yang
+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
+ * Add code to run WlanIST in SDIO callback.
+ *
+ * 10 27 2010 george.huang
+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function
+ * for SQA test by using E1 EVB
+ * Support registry option for disable beacon lost detection.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version
+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 26 2010 eddie.chen
+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB
+ * Add auto rate parameter in registry.
+ *
+ * 10 25 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add option for enable/disable TX PWR gain adjustment (default: off)
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion
+ * 2. shorten polling count for shorter response time
+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version
+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 10 15 2010 cp.wu
+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A
+ * bugfix: always reset pointer to IEbuf to zero when keeping scanning result for the connected AP
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * adding fixed rate support for distance test. (from registry setting)
+ *
+ * 10 07 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * add firmware download for MT5931.
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * code reorganization to improve isolation between GLUE and CORE layers.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced
+ * by ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 29 2010 wh.su
+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * eliminate unused variables which lead gcc to argue
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature
+ * Modify online scan as a run-time adjustable option (for Windows, in registry)
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
+ * use firmware reported mac address right after wlanAdapterStart() as permanent address
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with
+ * AIS associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 13 2010 cp.wu
+ * NULL
+ * acquire & release power control in oid handing wrapper.
+ *
+ * 09 09 2010 cp.wu
+ * NULL
+ * move IE to buffer head when the IE pointer is not pointed at head.
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * HIFSYS Clock Source Workaround
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart()
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * Add AT GO test configure mode under WinXP.
+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 24 2010 cp.wu
+ * NULL
+ * 1) initialize variable for enabling short premable/short time slot.
+ * 2) add compile option for disabling online scan
+ *
+ * 08 13 2010 cp.wu
+ * NULL
+ * correction issue: desired phy type not initialized as ABGN mode.
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
+ *
+ * 08 10 2010 cm.chang
+ * NULL
+ * Support EEPROM read/write in RF test mode
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * Centralize mgmt/system service procedures into independent calls.
+ *
+ * 07 30 2010 cp.wu
+ * NULL
+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc*
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo
+ * 2) change nicMediaStateChange() API prototype
+ *
+ * 07 21 2010 cp.wu
+ *
+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term
+ * 2) only clear scanning result when scan is permitted to do
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 13 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Reduce unnecessary type casting
+ *
+ * 07 13 2010 cp.wu
+ *
+ * use multiple queues to keep 1x/MMPDU/CMD's strict order even when there is incoming 1x frames.
+ *
+ * 07 13 2010 cp.wu
+ *
+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent
+ * network operation
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) ignore RSN checking when RSN is not turned on.
+ * 2) set STA-REC deactivation callback as NULL
+ * 3) add variable initialization API based on PHY configuration
+ *
+ * 07 02 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) for event packet, no need to fill RFB.
+ * 2) when wlanAdapterStart() failed, no need to initialize state machines
+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support sync command of STA_REC
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan uninitialization procedure
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add API in que_mgt to retrieve sta-rec index for security frames.
+ *
+ * 06 24 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
+ *
+ * 06 23 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Merge g_arStaRec[] into adapter->arStaRec[]
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * initialize mbox & ais_fsm in wlanAdapterStart()
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change MAC address updating logic.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * simplify timer usage.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * cnm_timer has been migrated.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 28 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * disable interrupt then send power control command packet.
+ *
+ * 05 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) when stopping adapter, wait til RDY bit has been cleaerd.
+ * 2) set TASK_OFFLOAD as driver-core OIDs
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) do not take timeout mechanism for power mode oids
+ * 2) retrieve network type from connection status
+ * 3) after disassciation, set radio state to off
+ * 4) TCP option over IPv6 is supported
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add CFG_STARTUP_DEBUG for debugging starting up issue.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * roll-back to rev.60.
+ *
+ * 04 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove redundant firmware image unloading
+ * 2) use compile-time macros to separate logic related to accquiring own
+ *
+ * 04 16 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * treat BUS access failure as kind of card removal.
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * always set fw-own before driver is unloaded.
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  * 2) command sequence number is now increased atomically
+ *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * finish non-glue layer access to glue variables
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ * are done in adapter layer.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * ePowerCtrl is not necessary as a glue variable.
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add timeout check in the kalOidComplete
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) for some OID, never do timeout expiration
+ * 2) add 2 kal API for later integration
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) eliminate unused definitions
+ * 2) ready bit will be polled for limited iteration
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * kalOidComplete is not necessary in linux
+ *
+ * 04 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change to use pass-in prRegInfo instead of accessing prGlueInfo directly
+ *
+ * 04 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change to use WIFI_TCM_ALWAYS_ON as firmware image
+ *
+ * 04 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * .
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 30 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * adding none-glue code portability
+ *
+ * 03 30 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * adding non-glue code portability
+ *
+ * 03 29 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve non-glue code portability
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * firmware download load address & start address are now configured from config.h
+ * due to the different configurations on FPGA and ASIC
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * only send CMD_NIC_POWER_CTRL in wlanAdapterStop() when card is not removed and is not in D3 state
+ *
+ * 03 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
+ *
+* 03 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add two option for ACK and ENCRYPTION for firmware download
+ *
+ * 03 11 2010 cp.wu
+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING
+ *
+ * 03 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
+ * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * when starting adapter, read local adminsitrated address from registry and send to firmware via CMD_BASIC_CONFIG.
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock
+ * 2) ensure wlanReleasePendingOid will clear all command queues
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add mutex to avoid multiple access to qmTxQueue simultaneously.
+ *
+ * 03 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add command/event definitions for initial states
+ *
+ * 02 24 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Added code for QM_TEST_MODE
+ *
+ * 02 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct function name ..
+ *
+ * 02 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * separate wlanProcesQueuePacket() into 2 APIs upon request
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add new API: wlanProcessQueuedPackets()
+ *
+ * 02 11 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct wlanAdapterStart
+ *
+ * 02 11 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. add logic for firmware download
+ * 2. firmware image filename and start/load address are now retrieved from registry
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement host-side firmware download logic
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
+ * 2) firmware image length is now retrieved via NdisFileOpen
+ * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
+ * 4) nicRxWaitResponse() revised
+ * 5) another set of TQ counter default value is added for fw-download state
+ * 6) Wi-Fi load address is now retrieved from registry too
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ * 2. follow MSDN defined behavior when associates to another AP
+ * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 02 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * prepare for implementing fw download logic
+ *
+ * 02 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * wlanoidSetFrequency is now implemented by RF test command.
+ *
+ * 02 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * QueryRssi is no longer w/o hardware access, it is now implemented by command/event handling loop
+ *
+ * 02 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. clear prPendingCmdInfo properly
+ * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes.
+ *
+ * 01 28 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * allow MCR read/write OIDs in RF test mode
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) implement timeout mechanism when OID is pending for longer than 1 second
+ * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ * 2. block TX/ordinary OID when RF test mode is engaged
+ * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ * 4. correct some HAL implementation
+ *
+ * 01 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer
+**  \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-12-10 16:54:36 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-12-09 20:04:59 GMT mtk02752
+**  only report as connected when CFG_HIF_EMULATION_TEST is set to 1
+**  \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-12-08 17:39:41 GMT mtk02752
+**  wlanoidRftestQueryAutoTest could be executed without touching hardware
+**  \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-12-03 16:10:26 GMT mtk01461
+**  Add debug message
+**  \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-02 22:05:33 GMT mtk02752
+**  kalOidComplete() will decrease i4OidPendingCount
+**  \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-01 23:02:36 GMT mtk02752
+**  remove unnecessary spinlock
+**  \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-01 22:50:38 GMT mtk02752
+**  use TC4 for command, maintein i4OidPendingCount
+**  \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-27 12:45:34 GMT mtk02752
+**  prCmdInfo should be freed when invoking wlanReleasePendingOid() to clear pending oid
+**  \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-24 19:55:51 GMT mtk02752
+**  wlanSendPacket & wlanRetransmitOfPendingFrames is only used in old data path
+**  \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-23 17:59:55 GMT mtk02752
+**  clear prPendingOID inside wlanSendCommand() when the OID didn't need to be replied.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-23 14:45:29 GMT mtk02752
+**  add another version of wlanSendCommand() for command-sending only without blocking for response
+**  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-17 22:40:44 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 10:14:56 GMT mtk01084
+**  modify place to invoke wlanIst
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-10-30 18:17:07 GMT mtk01084
+**  fix compiler warning
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-10-29 19:46:15 GMT mtk01084
+**  invoke interrupt process routine
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-10-13 21:58:24 GMT mtk01084
+**  modify for new HW architecture
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-09-09 17:26:01 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-05-20 12:21:27 GMT mtk01461
+**  Add SeqNum check when process Event Packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-05-19 10:38:44 GMT mtk01461
+**  Add wlanReleasePendingOid() for mpReset() if there is a pending OID and no available TX resource to send it.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-04-29 15:41:34 GMT mtk01461
+**  Add handle of EVENT of CMD Result in wlanSendCommand()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-04-22 09:11:23 GMT mtk01461
+**  Fix wlanSendCommand() for Driver Domain CR
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-04-21 09:33:56 GMT mtk01461
+**  Update wlanSendCommand() for Driver Domain Response and handle Event Packet,
+**  wlanQuery/SetInformation() for enqueue CMD_INFO_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-17 20:00:08 GMT mtk01461
+**  Update wlanImageSectionDownload for optimized CMD process
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-14 20:50:51 GMT mtk01426
+**  Fixed compile error
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-13 16:38:40 GMT mtk01084
+**  add wifi start function
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-13 14:26:44 GMT mtk01084
+**  modify a parameter about FW download length
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-10 21:53:42 GMT mtk01461
+**  Update wlanSendCommand()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-08 16:51:04 GMT mtk01084
+**  Update for the image download part
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-01 10:32:47 GMT mtk01461
+**  Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-03-23 21:44:13 GMT mtk01461
+**  Refine TC assignment for WmmAssoc flag
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 16:51:57 GMT mtk01084
+**  modify the input argument of caller to RECLAIM_POWER_CONTROL_TO_PM()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:27:13 GMT mtk01461
+**  Add reference code of FW Image Download
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:37 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:08 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 16:28:45 GMT mtk01426
+**  Init develop
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+#include "mgmt/ais_fsm.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* 6.1.1.2 Interpretation of priority parameter in MAC service primitives */
+/* Static convert the Priority Parameter/TID(User Priority/TS Identifier) to Traffic Class */
+const UINT_8 aucPriorityParam2TC[] = {
+	TC1_INDEX,
+	TC0_INDEX,
+	TC0_INDEX,
+	TC1_INDEX,
+	TC2_INDEX,
+	TC2_INDEX,
+	TC3_INDEX,
+	TC3_INDEX
+};
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _CODE_MAPPING_T {
+	UINT_32 u4RegisterValue;
+	INT_32 i4TxpowerOffset;
+} CODE_MAPPING_T, *P_CODE_MAPPING_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+BOOLEAN fgIsBusAccessFailed = FALSE;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define SIGNED_EXTEND(n, _sValue) \
+	(((_sValue) & BIT((n)-1)) ? ((_sValue) | BITS(n, 31)) : \
+	((_sValue) & ~BITS(n, 31)))
+
+/* TODO: Check */
+/* OID set handlers without the need to access HW register */
+PFN_OID_HANDLER_FUNC apfnOidSetHandlerWOHwAccess[] = {
+	wlanoidSetChannel,
+	wlanoidSetBeaconInterval,
+	wlanoidSetAtimWindow,
+	wlanoidSetFrequency,
+};
+
+/* TODO: Check */
+/* OID query handlers without the need to access HW register */
+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerWOHwAccess[] = {
+	wlanoidQueryBssid,
+	wlanoidQuerySsid,
+	wlanoidQueryInfrastructureMode,
+	wlanoidQueryAuthMode,
+	wlanoidQueryEncryptionStatus,
+	wlanoidQueryPmkid,
+	wlanoidQueryNetworkTypeInUse,
+	wlanoidQueryBssidList,
+	wlanoidQueryAcpiDevicePowerState,
+	wlanoidQuerySupportedRates,
+	wlanoidQueryDesiredRates,
+	wlanoidQuery802dot11PowerSaveProfile,
+	wlanoidQueryBeaconInterval,
+	wlanoidQueryAtimWindow,
+	wlanoidQueryFrequency,
+};
+
+/* OID set handlers allowed in RF test mode */
+PFN_OID_HANDLER_FUNC apfnOidSetHandlerAllowedInRFTest[] = {
+	wlanoidRftestSetTestMode,
+	wlanoidRftestSetAbortTestMode,
+	wlanoidRftestSetAutoTest,
+	wlanoidSetMcrWrite,
+	wlanoidSetEepromWrite
+};
+
+/* OID query handlers allowed in RF test mode */
+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerAllowedInRFTest[] = {
+	wlanoidRftestQueryAutoTest,
+	wlanoidQueryMcrRead,
+	wlanoidQueryEepromRead
+}
+
+;
+
+PFN_OID_HANDLER_FUNC apfnOidWOTimeoutCheck[] = {
+	wlanoidRftestSetTestMode,
+	wlanoidRftestSetAbortTestMode,
+	wlanoidSetAcpiDevicePowerState,
+};
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#if 0				/* no use */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is a private routine, which is used to check if HW access is needed
+*        for the OID query/ set handlers.
+*
+* \param[IN] pfnOidHandler Pointer to the OID handler.
+* \param[IN] fgSetInfo     It is a Set information handler.
+*
+* \retval TRUE This function needs HW access
+* \retval FALSE This function does not need HW access
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo)
+{
+	PFN_OID_HANDLER_FUNC *apfnOidHandlerWOHwAccess;
+	UINT_32 i;
+	UINT_32 u4NumOfElem;
+
+	if (fgSetInfo) {
+		apfnOidHandlerWOHwAccess = apfnOidSetHandlerWOHwAccess;
+		u4NumOfElem = sizeof(apfnOidSetHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC);
+	} else {
+		apfnOidHandlerWOHwAccess = apfnOidQueryHandlerWOHwAccess;
+		u4NumOfElem = sizeof(apfnOidQueryHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC);
+	}
+
+	for (i = 0; i < u4NumOfElem; i++) {
+		if (apfnOidHandlerWOHwAccess[i] == pfnOidHandler)
+			return FALSE;
+	}
+
+	return TRUE;
+}				/* wlanIsHandlerNeedHwAccess */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set flag for later handling card
+*        ejected event.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+*
+* \return (none)
+*
+* \note When surprised removal happens, Glue layer should invoke this
+*       function to notify WPDD not to do any hw access.
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter)
+{
+	DEBUGFUNC("wlanCardEjected");
+	/* INITLOG(("\n")); */
+
+	ASSERT(prAdapter);
+
+	/* mark that the card is being ejected, NDIS will shut us down soon */
+	nicTxRelease(prAdapter);
+
+}				/* wlanCardEjected */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Create adapter object
+*
+* \param prAdapter This routine is call to allocate the driver software objects.
+*                  If fails, return NULL.
+* \retval NULL If it fails, NULL is returned.
+* \retval NOT NULL If the adapter was initialized successfully.
+*/
+/*----------------------------------------------------------------------------*/
+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo)
+{
+	P_ADAPTER_T prAdpater = (P_ADAPTER_T) NULL;
+
+	DEBUGFUNC("wlanAdapterCreate");
+
+	do {
+		prAdpater = (P_ADAPTER_T) kalMemAlloc(sizeof(ADAPTER_T), VIR_MEM_TYPE);
+
+		if (!prAdpater) {
+			DBGLOG(INIT, ERROR, "Allocate ADAPTER memory ==> FAILED\n");
+			break;
+		}
+
+		kalMemZero(prAdpater, sizeof(ADAPTER_T));
+		prAdpater->prGlueInfo = prGlueInfo;
+
+	} while (FALSE);
+
+	return prAdpater;
+}				/* wlanAdapterCreate */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Destroy adapter object
+*
+* \param prAdapter This routine is call to destroy the driver software objects.
+*                  If fails, return NULL.
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter)
+{
+
+	if (!prAdapter)
+		return;
+
+	kalMemFree(prAdapter, VIR_MEM_TYPE, sizeof(ADAPTER_T));
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Initialize the adapter. The sequence is
+*        1. Disable interrupt
+*        2. Read adapter configuration from EEPROM and registry, verify chip ID.
+*        3. Create NIC Tx/Rx resource.
+*        4. Initialize the chip
+*        5. Initialize the protocol
+*        6. Enable Interrupt
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+*
+* \retval WLAN_STATUS_SUCCESS: Success
+* \retval WLAN_STATUS_FAILURE: Failed
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanAdapterStart(IN P_ADAPTER_T prAdapter,
+		 IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength)
+{
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+	UINT_32 i, u4Value = 0;
+	UINT_32 u4WHISR = 0;
+	UINT_8 aucTxCount[8];
+#if CFG_ENABLE_FW_DOWNLOAD
+	UINT_32 u4FwLoadAddr, u4ImgSecSize;
+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
+	UINT_32 j;
+	P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead;
+	BOOLEAN fgValidHead;
+	const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries);
+#endif
+#endif
+	enum Adapter_Start_Fail_Reason {
+		ALLOC_ADAPTER_MEM_FAIL,
+		DRIVER_OWN_FAIL,
+		INIT_ADAPTER_FAIL,
+		RAM_CODE_DOWNLOAD_FAIL,
+		WAIT_FIRMWARE_READY_FAIL,
+		FAIL_REASON_MAX
+	} eFailReason;
+	ASSERT(prAdapter);
+
+	DEBUGFUNC("wlanAdapterStart");
+
+	eFailReason = FAIL_REASON_MAX;
+	/* 4 <0> Reset variables in ADAPTER_T */
+	prAdapter->fgIsFwOwn = TRUE;
+	prAdapter->fgIsEnterD3ReqIssued = FALSE;
+
+	QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue));
+
+	/* Initialize rWlanInfo */
+	kalMemSet(&(prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T));
+
+	/* 4 <0.1> reset fgIsBusAccessFailed */
+	fgIsBusAccessFailed = FALSE;
+	prAdapter->ulSuspendFlag = 0;
+
+	do {
+		u4Status = nicAllocateAdapterMemory(prAdapter);
+		if (u4Status != WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, ERROR, "nicAllocateAdapterMemory Error!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+			eFailReason = ALLOC_ADAPTER_MEM_FAIL;
+			break;
+		}
+
+		prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED;
+
+		DBGLOG(INIT, TRACE, "wlanAdapterStart(): Acquiring LP-OWN %d\n", fgIsResetting);
+		ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
+
+#if !CFG_ENABLE_FULL_PM
+		nicpmSetDriverOwn(prAdapter);
+#endif
+
+		if (prAdapter->fgIsFwOwn == TRUE) {
+			DBGLOG(INIT, ERROR, "nicpmSetDriverOwn() failed!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+			eFailReason = DRIVER_OWN_FAIL;
+			break;
+		}
+		/* 4 <1> Initialize the Adapter */
+		u4Status = nicInitializeAdapter(prAdapter);
+		if (u4Status != WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, ERROR, "nicInitializeAdapter failed!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+			eFailReason = INIT_ADAPTER_FAIL;
+			break;
+		}
+
+		/* init wake lock before interrupt enable and tx thread */
+		KAL_WAKE_LOCK_INIT(prAdapter, &prAdapter->rTxThreadWakeLock, "WLAN TX THREAD");
+
+		/* 4 <2> Initialize System Service (MGMT Memory pool and STA_REC) */
+		nicInitSystemService(prAdapter);
+
+		/* 4 <3> Initialize Tx */
+		nicTxInitialize(prAdapter);
+		wlanDefTxPowerCfg(prAdapter);
+
+		/* 4 <4> Initialize Rx */
+		nicRxInitialize(prAdapter);
+
+#if CFG_ENABLE_FW_DOWNLOAD
+		if (pvFwImageMapFile == NULL) {
+			DBGLOG(INIT, ERROR, "No Firmware found!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+			eFailReason = RAM_CODE_DOWNLOAD_FAIL;
+			break;
+		}
+
+		/* 1. disable interrupt, download is done by polling mode only */
+		nicDisableInterrupt(prAdapter);
+
+		/* 2. Initialize Tx Resource to fw download state */
+		nicTxInitResetResource(prAdapter);
+
+		/* 3. FW download here */
+		u4FwLoadAddr = prRegInfo->u4LoadAddress;
+
+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
+		/* 3a. parse file header for decision of divided firmware download or not */
+		prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile;
+
+		if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE &&
+		    prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset,
+						 u4FwImageFileLength - u4CRCOffset)) {
+			fgValidHead = TRUE;
+		} else {
+			fgValidHead = FALSE;
+		}
+
+		/* 3b. engage divided firmware downloading */
+		if (fgValidHead == TRUE) {
+			DBGLOG(INIT, TRACE, "wlanAdapterStart(): fgValidHead == TRUE\n");
+
+			for (i = 0; i < prFwHead->u4NumOfEntries; i++) {
+
+#if CFG_START_ADDRESS_IS_1ST_SECTION_ADDR
+				if (i == 0) {
+					prRegInfo->u4StartAddress = prFwHead->arSection[i].u4DestAddr;
+					DBGLOG(INIT, TRACE,
+					       "wlanAdapterStart(): FW start address 0x%08x\n",
+						prRegInfo->u4StartAddress);
+				}
+#endif
+
+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
+				if (wlanImageSectionDownloadAggregated(prAdapter,
+								       prFwHead->arSection[i].u4DestAddr,
+								       prFwHead->arSection[i].u4Length,
+								       (PUINT_8) pvFwImageMapFile +
+								       prFwHead->arSection[i].u4Offset) !=
+				    WLAN_STATUS_SUCCESS) {
+					DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n");
+					u4Status = WLAN_STATUS_FAILURE;
+				}
+#else
+				for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) {
+					if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length)
+						u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
+					else
+						u4ImgSecSize = prFwHead->arSection[i].u4Length - j;
+
+					if (wlanImageSectionDownload(prAdapter,
+								     prFwHead->arSection[i].u4DestAddr + j,
+								     u4ImgSecSize,
+								     (PUINT_8) pvFwImageMapFile +
+								     prFwHead->arSection[i].u4Offset + j) !=
+					    WLAN_STATUS_SUCCESS) {
+						DBGLOG(INIT, ERROR,
+						       "Firmware scatter download failed %d!\n", (int)i);
+						u4Status = WLAN_STATUS_FAILURE;
+						break;
+					}
+				}
+#endif
+
+				/* escape from loop if any pending error occurs */
+				if (u4Status == WLAN_STATUS_FAILURE)
+					break;
+			}
+		} else
+#endif
+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
+		if (wlanImageSectionDownloadAggregated(prAdapter,
+							       u4FwLoadAddr,
+							       u4FwImageFileLength,
+							       (PUINT_8) pvFwImageMapFile) !=
+			    WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+		}
+#else
+			for (i = 0; i < u4FwImageFileLength; i += CMD_PKT_SIZE_FOR_IMAGE) {
+				if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImageFileLength)
+					u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
+				else
+					u4ImgSecSize = u4FwImageFileLength - i;
+
+				if (wlanImageSectionDownload(prAdapter,
+							     u4FwLoadAddr + i,
+							     u4ImgSecSize,
+							     (PUINT_8) pvFwImageMapFile + i) !=
+				    WLAN_STATUS_SUCCESS) {
+					DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n");
+					u4Status = WLAN_STATUS_FAILURE;
+					break;
+				}
+			}
+#endif
+
+		if (u4Status != WLAN_STATUS_SUCCESS) {
+			eFailReason = RAM_CODE_DOWNLOAD_FAIL;
+			break;
+		}
+#if !CFG_ENABLE_FW_DOWNLOAD_ACK
+		/* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */
+		if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, ERROR, "Firmware download failed!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+			break;
+		}
+#endif
+
+		/* 4. send Wi-Fi Start command */
+		DBGLOG(INIT, INFO, "<wifi> send Wi-Fi Start command\n");
+#if CFG_OVERRIDE_FW_START_ADDRESS
+		wlanConfigWifiFunc(prAdapter, TRUE, prRegInfo->u4StartAddress);
+#else
+		wlanConfigWifiFunc(prAdapter, FALSE, 0);
+#endif
+#endif
+
+		DBGLOG(INIT, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n");
+		/* 4 <5> check Wi-Fi FW asserts ready bit */
+		i = 0;
+		while (1) {
+			HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
+
+			if (u4Value & WCIR_WLAN_READY) {
+				DBGLOG(INIT, TRACE, "Ready bit asserted\n");
+				break;
+			} else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+				u4Status = WLAN_STATUS_FAILURE;
+				eFailReason = WAIT_FIRMWARE_READY_FAIL;
+				break;
+			} else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
+				UINT_32 u4MailBox0;
+
+				nicGetMailbox(prAdapter, 0, &u4MailBox0);
+				DBGLOG(INIT, ERROR, "Waiting for Ready bit: Timeout, ID=%u\n",
+						     (u4MailBox0 & 0x0000FFFF));
+				u4Status = WLAN_STATUS_FAILURE;
+				eFailReason = WAIT_FIRMWARE_READY_FAIL;
+				break;
+			}
+			i++;
+			kalMsleep(10);
+		}
+
+		if (u4Status == WLAN_STATUS_SUCCESS) {
+			/* 1. reset interrupt status */
+			HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR);
+			if (HAL_IS_TX_DONE_INTR(u4WHISR))
+				HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount);
+
+			/* 2. reset TX Resource for normal operation */
+			nicTxResetResource(prAdapter);
+
+			/* 3. query for permanent address by polling */
+			wlanQueryPermanentAddress(prAdapter);
+
+#if (CFG_SUPPORT_NIC_CAPABILITY == 1)
+			/* 4. query for NIC capability */
+			wlanQueryNicCapability(prAdapter);
+#endif
+			/* 4.1 query for compiler flags */
+			wlanQueryCompileFlags(prAdapter);
+
+			/* 5. Override network address */
+			wlanUpdateNetworkAddress(prAdapter);
+
+			/* 6. indicate disconnection as default status */
+			kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+		}
+
+		RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
+
+		if (u4Status != WLAN_STATUS_SUCCESS) {
+			eFailReason = WAIT_FIRMWARE_READY_FAIL;
+			break;
+		}
+
+		/* OID timeout timer initialize */
+		cnmTimerInitTimer(prAdapter,
+				  &prAdapter->rOidTimeoutTimer,
+				  (PFN_MGMT_TIMEOUT_FUNC) wlanReleasePendingOid, (ULONG) NULL);
+
+		/* Return Indicated Rfb list timer */
+		cnmTimerInitTimer(prAdapter,
+				  &prAdapter->rReturnIndicatedRfbListTimer,
+				  (PFN_MGMT_TIMEOUT_FUNC) wlanReturnIndicatedPacketsTimeOut, (ULONG) NULL);
+
+		/* Power state initialization */
+		prAdapter->fgWiFiInSleepyState = FALSE;
+		prAdapter->rAcpiState = ACPI_STATE_D0;
+
+		/* Online scan option */
+		if (prRegInfo->fgDisOnlineScan == 0)
+			prAdapter->fgEnOnlineScan = TRUE;
+		else
+			prAdapter->fgEnOnlineScan = FALSE;
+
+		/* Beacon lost detection option */
+		if (prRegInfo->fgDisBcnLostDetection != 0)
+			prAdapter->fgDisBcnLostDetection = TRUE;
+
+		/* Load compile time constant */
+		prAdapter->rWlanInfo.u2BeaconPeriod = CFG_INIT_ADHOC_BEACON_INTERVAL;
+		prAdapter->rWlanInfo.u2AtimWindow = CFG_INIT_ADHOC_ATIM_WINDOW;
+
+#if 1				/* set PM parameters */
+		prAdapter->fgEnArpFilter = prRegInfo->fgEnArpFilter;
+		prAdapter->u4PsCurrentMeasureEn = prRegInfo->u4PsCurrentMeasureEn;
+
+		prAdapter->u4UapsdAcBmp = prRegInfo->u4UapsdAcBmp;
+
+		prAdapter->u4MaxSpLen = prRegInfo->u4MaxSpLen;
+
+		DBGLOG(INIT, TRACE, "[1] fgEnArpFilter:0x%x, u4UapsdAcBmp:0x%x, u4MaxSpLen:0x%x",
+				     prAdapter->fgEnArpFilter, prAdapter->u4UapsdAcBmp, prAdapter->u4MaxSpLen);
+
+		prAdapter->fgEnCtiaPowerMode = FALSE;
+
+#if CFG_SUPPORT_DBG_POWERMODE
+		prAdapter->fgEnDbgPowerMode = FALSE;
+#endif
+
+#endif
+
+		/* MGMT Initialization */
+		nicInitMGMT(prAdapter, prRegInfo);
+
+		/* Enable WZC Disassociation */
+		prAdapter->rWifiVar.fgSupportWZCDisassociation = TRUE;
+
+		/* Apply Rate Setting */
+		if ((ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate) < FIXED_RATE_NUM)
+			prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate);
+		else
+			prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE;
+
+		if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) {
+			/* Enable Auto (Long/Short) Preamble */
+			prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO;
+		} else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS &&
+			    prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS)
+			   || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS &&
+			       prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) {
+			/* Force Short Preamble */
+			prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT;
+		} else {
+			/* Force Long Preamble */
+			prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG;
+		}
+
+		/* Disable Hidden SSID Join */
+		prAdapter->rWifiVar.fgEnableJoinToHiddenSSID = FALSE;
+
+		/* Enable Short Slot Time */
+		prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable = TRUE;
+
+		/* configure available PHY type set */
+		nicSetAvailablePhyTypeSet(prAdapter);
+
+#if 1				/* set PM parameters */
+		{
+#if  CFG_SUPPORT_PWR_MGT
+			prAdapter->u4PowerMode = prRegInfo->u4PowerMode;
+			prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucNetTypeIndex =
+			    NETWORK_TYPE_P2P_INDEX;
+			prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile = ENUM_PSP_FAST_SWITCH;
+#else
+			prAdapter->u4PowerMode = ENUM_PSP_CONTINUOUS_ACTIVE;
+#endif
+
+			nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX,	/* FIXIT */
+						  prAdapter->u4PowerMode, FALSE);
+		}
+
+#endif
+
+#if CFG_SUPPORT_NVRAM
+		/* load manufacture data */
+		wlanLoadManufactureData(prAdapter, prRegInfo);
+#endif
+
+#ifdef CONFIG_MTK_TC1_FEATURE	/* 1 //keep alive packet time change from default 30secs to 20secs. //TC01// */
+		{
+			CMD_SW_DBG_CTRL_T rCmdSwCtrl;
+
+			rCmdSwCtrl.u4Id = 0x90100000;
+			rCmdSwCtrl.u4Data = 30;
+			DBGLOG(INIT, TRACE, "wlanAdapterStart Keepaliveapcket 0x%x, %d\n",
+				rCmdSwCtrl.u4Id, rCmdSwCtrl.u4Data);
+			wlanSendSetQueryCmd(prAdapter,
+					    CMD_ID_SW_DBG_CTRL,
+					    TRUE,
+					    FALSE,
+					    FALSE,
+					    NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8) (&rCmdSwCtrl), NULL, 0);
+		}
+#endif
+
+#if 0
+		/* Update Auto rate parameters in FW */
+		nicRlmArUpdateParms(prAdapter,
+				    prRegInfo->u4ArSysParam0,
+				    prRegInfo->u4ArSysParam1, prRegInfo->u4ArSysParam2, prRegInfo->u4ArSysParam3);
+#endif
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+		/* clock gating workaround */
+		prAdapter->fgIsClockGatingEnabled = FALSE;
+#endif
+
+	} while (FALSE);
+
+	if (u4Status == WLAN_STATUS_SUCCESS) {
+		/* restore to hardware default */
+		HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter);
+		HAL_SET_MAILBOX_READ_CLEAR(prAdapter, FALSE);
+
+		/* Enable interrupt */
+		nicEnableInterrupt(prAdapter);
+
+	} else {
+		/* release allocated memory */
+		switch (eFailReason) {
+		case WAIT_FIRMWARE_READY_FAIL:
+			DBGLOG(INIT, ERROR, "Wait firmware ready fail, FailReason: %d\n",
+					eFailReason);
+			g_IsNeedDoChipReset = 1;
+			kalSendAeeWarning("[Wait firmware ready fail!]", __func__);
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
+			nicRxUninitialize(prAdapter);
+			nicTxRelease(prAdapter);
+			/* System Service Uninitialization */
+			nicUninitSystemService(prAdapter);
+			nicReleaseAdapterMemory(prAdapter);
+			break;
+		case RAM_CODE_DOWNLOAD_FAIL:
+			DBGLOG(INIT, ERROR, "Ram code download fail, FailReason: %d\n",
+					eFailReason);
+			g_IsNeedDoChipReset = 1;
+			kalSendAeeWarning("[Ram code download fail!]", __func__);
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
+			nicRxUninitialize(prAdapter);
+			nicTxRelease(prAdapter);
+			/* System Service Uninitialization */
+			nicUninitSystemService(prAdapter);
+			nicReleaseAdapterMemory(prAdapter);
+			break;
+		case INIT_ADAPTER_FAIL:
+			nicReleaseAdapterMemory(prAdapter);
+			break;
+		case DRIVER_OWN_FAIL:
+			nicReleaseAdapterMemory(prAdapter);
+			break;
+		case ALLOC_ADAPTER_MEM_FAIL:
+			break;
+		default:
+			break;
+		}
+	}
+
+	return u4Status;
+}				/* wlanAdapterStart */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Uninitialize the adapter
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+*
+* \retval WLAN_STATUS_SUCCESS: Success
+* \retval WLAN_STATUS_FAILURE: Failed
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i, u4Value = 0;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	if (prAdapter->fgIsClockGatingEnabled == TRUE)
+		nicDisableClockGating(prAdapter);
+#endif
+
+	/* MGMT - unitialization */
+	nicUninitMGMT(prAdapter);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D0 &&
+#if (CFG_CHIP_RESET_SUPPORT == 1)
+	    kalIsResetting() == FALSE &&
+#endif
+	    kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) {
+
+		/* 0. Disable interrupt, this can be done without Driver own */
+		nicDisableInterrupt(prAdapter);
+
+		ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
+
+		/* 1. Set CMD to FW to tell WIFI to stop (enter power off state) */
+		/* the command must be issue to firmware even in wlanRemove() */
+		if (prAdapter->fgIsFwOwn == FALSE && wlanSendNicPowerCtrlCmd(prAdapter, 1) == WLAN_STATUS_SUCCESS) {
+			/* 2. Clear pending interrupt */
+			i = 0;
+			while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
+				i++;
+			};
+
+			/* 3. Wait til RDY bit has been cleaerd */
+			i = 0;
+			while (1) {
+				HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
+
+				if ((u4Value & WCIR_WLAN_READY) == 0)
+					break;
+				else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
+					 || fgIsBusAccessFailed == TRUE || i >= CFG_RESPONSE_POLLING_TIMEOUT) {
+					g_IsNeedDoChipReset = 1;
+					kalSendAeeWarning("[Read WCIR_WLAN_READY fail!]", __func__);
+					break;
+				}
+				i++;
+				kalMsleep(10);
+			}
+		}
+
+		/* 4. Set Onwership to F/W */
+		nicpmSetFWOwn(prAdapter, FALSE);
+
+#if CFG_FORCE_RESET_UNDER_BUS_ERROR
+		if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == TRUE) {
+			/* force acquire firmware own */
+			kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
+
+			/* delay for 10ms */
+			kalMdelay(10);
+
+			/* force firmware reset via software interrupt */
+			kalDevRegWrite(prAdapter->prGlueInfo, MCR_WSICR, WSICR_H2D_SW_INT_SET);
+
+			/* force release firmware own */
+			kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
+		}
+#endif
+
+		RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
+	}
+
+	nicRxUninitialize(prAdapter);
+
+	nicTxRelease(prAdapter);
+
+	/* System Service Uninitialization */
+	nicUninitSystemService(prAdapter);
+
+	nicReleaseAdapterMemory(prAdapter);
+
+#if defined(_HIF_SPI)
+	/* Note: restore the SPI Mode Select from 32 bit to default */
+	nicRestoreSpiDefMode(prAdapter);
+#endif
+
+	return u4Status;
+}				/* wlanAdapterStop */
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called by ISR (interrupt).
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+*
+* \retval TRUE: NIC's interrupt
+* \retval FALSE: Not NIC's interrupt
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl)
+{
+	ASSERT(prAdapter);
+
+	if (fgGlobalIntrCtrl) {
+		nicDisableInterrupt(prAdapter);
+
+		/* wlanIST(prAdapter); */
+	}
+
+	return TRUE;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called by IST (task_let).
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanIST(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	/* wake up CONNSYS */
+	ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
+
+	/* handle interrupts */
+	nicProcessIST(prAdapter);
+
+	/* re-enable HIF interrupts */
+	nicEnableInterrupt(prAdapter);
+
+	/* CONNSYS can decide to sleep */
+	RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will check command queue to find out if any could be dequeued
+*        and/or send to HIF to MT6620
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+* \param prCmdQue       Pointer of Command Queue (in Glue Layer)
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue)
+{
+	WLAN_STATUS rStatus;
+	QUE_T rTempCmdQue, rMergeCmdQue, rStandInCmdQue;
+	P_QUE_T prTempCmdQue, prMergeCmdQue, prStandInCmdQue;
+	P_QUE_ENTRY_T prQueueEntry;
+	P_CMD_INFO_T prCmdInfo;
+	P_MSDU_INFO_T prMsduInfo;
+	ENUM_FRAME_ACTION_T eFrameAction = FRAME_ACTION_DROP_PKT;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	/* sanity check */
+	ASSERT(prAdapter);
+	ASSERT(prCmdQue);
+
+	/* init */
+	prTempCmdQue = &rTempCmdQue;
+	prMergeCmdQue = &rMergeCmdQue;
+	prStandInCmdQue = &rStandInCmdQue;
+
+	QUEUE_INITIALIZE(prTempCmdQue);
+	QUEUE_INITIALIZE(prMergeCmdQue);
+	QUEUE_INITIALIZE(prStandInCmdQue);
+
+	/* 4 <1> Move whole list of CMD_INFO to the temp queue */
+	/* copy all commands to prTempCmdQue and empty prCmdQue */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE);
+	QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE);
+
+	/* 4 <2> Dequeue from head and check it is able to be sent */
+	/* remove the first one */
+	QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+
+	while (prQueueEntry) {
+		prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+		/* check how to handle the command: drop, queue, or tx */
+		switch (prCmdInfo->eCmdType) {
+		case COMMAND_TYPE_GENERAL_IOCTL:
+		case COMMAND_TYPE_NETWORK_IOCTL:
+			/* command packet will be always sent */
+			eFrameAction = FRAME_ACTION_TX_PKT;
+			break;
+
+		case COMMAND_TYPE_SECURITY_FRAME:
+			/* inquire with QM */
+			eFrameAction = qmGetFrameAction(prAdapter,
+							prCmdInfo->eNetworkType,
+							prCmdInfo->ucStaRecIndex, NULL, FRAME_TYPE_802_1X);
+			break;
+
+		case COMMAND_TYPE_MANAGEMENT_FRAME:
+			/* inquire with QM */
+			prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket);
+
+			eFrameAction = qmGetFrameAction(prAdapter,
+							prMsduInfo->ucNetworkType,
+							prMsduInfo->ucStaRecIndex, prMsduInfo, FRAME_TYPE_MMPDU);
+			break;
+
+		default:
+			ASSERT(0);
+			break;
+		}
+
+		/* 4 <3> handling upon dequeue result */
+		if (eFrameAction == FRAME_ACTION_DROP_PKT) {
+			if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME)
+				DBGLOG(TX, WARN, "Drop Security frame seqNo=%d\n",
+					prCmdInfo->ucCmdSeqNum);
+			wlanReleaseCommand(prAdapter, prCmdInfo);
+		} else if (eFrameAction == FRAME_ACTION_QUEUE_PKT) {
+			if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME)
+				DBGLOG(TX, INFO, "Queue Security frame seqNo=%d\n",
+					prCmdInfo->ucCmdSeqNum);
+			QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry);
+		} else if (eFrameAction == FRAME_ACTION_TX_PKT) {
+			/* 4 <4> Send the command */
+			rStatus = wlanSendCommand(prAdapter, prCmdInfo);
+
+			if (rStatus == WLAN_STATUS_RESOURCES) {
+				/* no more TC4 resource for further transmission */
+				QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry);
+				DBGLOG(TX, EVENT, "No TC4 resource to send cmd, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n",
+					prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum,
+					prCmdInfo->eCmdType, prCmdInfo->fgIsOid);
+				break;
+			} else if (rStatus == WLAN_STATUS_PENDING) {
+				/* command packet which needs further handling upon response */
+				/* i.e. we need to wait for FW's response */
+				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+				QUEUE_INSERT_TAIL(&(prAdapter->rPendingCmdQueue), prQueueEntry);
+				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+			} else {
+				/* send success or fail */
+				P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+				if (rStatus == WLAN_STATUS_SUCCESS) {
+					/* send success */
+					if (prCmdInfo->pfCmdDoneHandler) {
+						prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo,
+									    prCmdInfo->pucInfoBuffer);
+					}
+				} else {
+					/* send fail */
+					if (prCmdInfo->fgIsOid) {
+						kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery,
+							       prCmdInfo->u4SetInfoLen, rStatus);
+					}
+					DBGLOG(TX, WARN, "Send CMD, status=%u, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n",
+							rStatus, prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum,
+							prCmdInfo->eCmdType, prCmdInfo->fgIsOid);
+				}
+
+				/* free the command memory */
+				cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+			}
+		} else {
+
+			/* impossible, wrong eFrameAction */
+			ASSERT(0);
+		}
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+
+	/* 4 <3> Merge back to original queue */
+	/* 4 <3.1> Merge prMergeCmdQue & prTempCmdQue */
+	QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prTempCmdQue);
+
+	/* 4 <3.2> Move prCmdQue to prStandInQue, due to prCmdQue might differ due to incoming 802.1X frames */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE);
+
+	/* ??? here, prCmdQue shall be empty, why QUEUE_MOVE_ALL ??? */
+	QUEUE_MOVE_ALL(prStandInCmdQue, prCmdQue);
+
+	/* 4 <3.3> concatenate prStandInQue to prMergeCmdQue */
+	QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prStandInCmdQue);
+
+	/* 4 <3.4> then move prMergeCmdQue to prCmdQue */
+	QUEUE_MOVE_ALL(prCmdQue, prMergeCmdQue);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanProcessCommandQueue() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will take CMD_INFO_T which carry some information of
+*        incoming OID and notify the NIC_TX to send CMD.
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+* \param prCmdInfo      Pointer of P_CMD_INFO_T
+*
+* \retval WLAN_STATUS_SUCCESS   : CMD was written to HIF and be freed(CMD Done) immediately.
+* \retval WLAN_STATUS_RESOURCE  : No resource for current command, need to wait for previous
+*                                 frame finishing their transmission.
+* \retval WLAN_STATUS_FAILURE   : Get failure while access HIF or been rejected.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	P_TX_CTRL_T prTxCtrl;
+	UINT_8 ucTC;		/* "Traffic Class" SW(Driver) resource classification */
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	BOOLEAN pfgIsSecOrMgmt = FALSE;
+
+	/* sanity check */
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	/* init */
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	/* DbgPrint("wlanSendCommand()\n"); */
+	/*  */
+	/*  */
+#if DBG && 0
+	LOG_FUNC("wlanSendCommand()\n");
+	LOG_FUNC("CmdType %u NetworkType %u StaRecIndex %u Oid %u CID 0x%x SetQuery %u NeedResp %u CmdSeqNum %u\n",
+		 prCmdInfo->eCmdType,
+		 prCmdInfo->eNetworkType,
+		 prCmdInfo->ucStaRecIndex,
+		 prCmdInfo->fgIsOid,
+		 prCmdInfo->ucCID, prCmdInfo->fgSetQuery, prCmdInfo->fgNeedResp, prCmdInfo->ucCmdSeqNum);
+#endif
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	if (prAdapter->fgIsClockGatingEnabled == TRUE)
+		nicDisableClockGating(prAdapter);
+#endif
+
+	do {
+		/* <0> card removal check */
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+			rStatus = WLAN_STATUS_FAILURE;
+			break;
+		}
+		/* <1> Normal case of sending CMD Packet */
+		if (!prCmdInfo->fgDriverDomainMCR) {
+			/* <1.1> Assign Traffic Class(TC) = TC4. */
+			ucTC = TC4_INDEX;
+
+			if ((prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) ||
+				(prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME))
+				pfgIsSecOrMgmt = TRUE;
+
+			/* <1.2> Check if pending packet or resource was exhausted */
+			rStatus = nicTxAcquireResource(prAdapter, ucTC, pfgIsSecOrMgmt);
+			if (rStatus == WLAN_STATUS_RESOURCES) {
+				DbgPrint("NO Resource:%d\n", ucTC);
+				break;
+			}
+			/* <1.3> Forward CMD_INFO_T to NIC Layer */
+			rStatus = nicTxCmd(prAdapter, prCmdInfo, ucTC);
+
+			/* <1.4> Set Pending in response to Query Command/Need Response */
+			if (rStatus == WLAN_STATUS_SUCCESS) {
+				if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp))
+					rStatus = WLAN_STATUS_PENDING;
+			}
+		}
+		/* <2> "Special case" for access Driver Domain MCR */
+		else {
+
+			P_CMD_ACCESS_REG prCmdAccessReg;
+
+			prCmdAccessReg = (P_CMD_ACCESS_REG) (prCmdInfo->pucInfoBuffer + CMD_HDR_SIZE);
+
+			if (prCmdInfo->fgSetQuery) {
+				/* address is in DWORD unit */
+				HAL_MCR_WR(prAdapter, (prCmdAccessReg->u4Address & BITS(2, 31)),
+					   prCmdAccessReg->u4Data);
+			} else {
+				P_CMD_ACCESS_REG prEventAccessReg;
+				UINT_32 u4Address;
+
+				u4Address = prCmdAccessReg->u4Address;
+				prEventAccessReg = (P_CMD_ACCESS_REG) prCmdInfo->pucInfoBuffer;
+				prEventAccessReg->u4Address = u4Address;
+				/* address is in DWORD unit */
+				HAL_MCR_RD(prAdapter, prEventAccessReg->u4Address & BITS(2, 31),
+					   &prEventAccessReg->u4Data);
+			}
+		}
+
+	} while (FALSE);
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	if (prAdapter->fgIsClockGatingEnabled == FALSE)
+		nicEnableClockGating(prAdapter);
+#endif
+
+	return rStatus;
+}				/* end of wlanSendCommand() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief This function will release thd CMD_INFO upon its attribution
+ *
+ * \param prAdapter  Pointer of Adapter Data Structure
+ * \param prCmdInfo  Pointer of CMD_INFO_T
+ *
+ * \return (none)
+ */
+/*----------------------------------------------------------------------------*/
+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	P_TX_CTRL_T prTxCtrl;
+	P_MSDU_INFO_T prMsduInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	switch (prCmdInfo->eCmdType) {
+	case COMMAND_TYPE_GENERAL_IOCTL:
+	case COMMAND_TYPE_NETWORK_IOCTL:
+		if (prCmdInfo->fgIsOid) {
+			/* for OID command, we need to do complete() to wake up kalIoctl() */
+			kalOidComplete(prAdapter->prGlueInfo,
+				       prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_FAILURE);
+		}
+		break;
+
+	case COMMAND_TYPE_SECURITY_FRAME:
+		/* free packets in kalSecurityFrameSendComplete() */
+		kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE);
+		break;
+
+	case COMMAND_TYPE_MANAGEMENT_FRAME:
+		prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket;
+
+		/* invoke callbacks */
+		if (prMsduInfo->pfTxDoneHandler != NULL)
+			prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);
+
+		GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
+		cnmMgtPktFree(prAdapter, prMsduInfo);
+		break;
+
+	default:
+		/* impossible, shall not be here */
+		ASSERT(0);
+		break;
+	}
+
+	/* free command buffer and return the command header to command pool */
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+}				/* end of wlanReleaseCommand() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will search the CMD Queue to look for the pending OID and
+*        compelete it immediately when system request a reset.
+*
+* \param prAdapter  ointer of Adapter Data Structure
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("wlanReleasePendingOid");
+
+	ASSERT(prAdapter);
+
+	DBGLOG(OID, ERROR, "OID Timeout! Releasing pending OIDs ..\n");
+
+	do {
+		/* 1: Handle OID commands in pending queue */
+		/* Clear Pending OID in prAdapter->rPendingCmdQueue */
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+
+		/* move all pending commands to prTempCmdQue and empty prCmdQue */
+		prCmdQue = &prAdapter->rPendingCmdQueue;
+		QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+		/* get first pending command */
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+
+		while (prQueueEntry) {
+			prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+			if (prCmdInfo->fgIsOid) {
+				if (prCmdInfo->pfCmdTimeoutHandler) {
+					prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo);
+				} else {
+					/* send complete() to wake up kalIoctl() */
+					kalOidComplete(prAdapter->prGlueInfo,
+						       prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE);
+				}
+
+				/* free command memory */
+				cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+			} else {
+				/* nothing to do so re-queue it to prCmdQue */
+				QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+			}
+
+			QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+		}
+
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+
+		/* 2: Clear pending OID staying in command queue */
+		kalOidCmdClearance(prAdapter->prGlueInfo);
+
+		/* 3: Do complete(), do we need this? because we have completed in kalOidComplete */
+		kalOidClearance(prAdapter->prGlueInfo);
+
+	} while (FALSE);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will search the CMD Queue to look for the pending CMD/OID for specific
+*        NETWORK TYPE and compelete it immediately when system request a reset.
+*
+* \param prAdapter  ointer of Adapter Data Structure
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	/* only free commands from the network interface, AIS, P2P, or BOW */
+
+	do {
+		/* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+
+		prCmdQue = &prAdapter->rPendingCmdQueue;
+		QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+		while (prQueueEntry) {
+			prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+			DBGLOG(P2P, TRACE, "Pending CMD for Network Type:%d\n", prCmdInfo->eNetworkType);
+
+			if (prCmdInfo->eNetworkType == eNetworkType) {
+				if (prCmdInfo->pfCmdTimeoutHandler) {
+					prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo);
+				} else
+					kalOidComplete(prAdapter->prGlueInfo,
+						       prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE);
+
+				cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+			} else {
+				QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+			}
+
+			QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+		}
+
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+
+	} while (FALSE);
+
+}				/* wlanReleasePendingCMDbyNetwork */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Return the packet buffer and reallocate one to the RFB
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+* \param pvPacket       Pointer of returned packet
+*
+* \retval WLAN_STATUS_SUCCESS: Success
+* \retval WLAN_STATUS_FAILURE: Failed
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_SW_RFB_T prSwRfb = NULL;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("wlanReturnPacket");
+
+	ASSERT(prAdapter);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	/* free the packet */
+	if (pvPacket) {
+		kalPacketFree(prAdapter->prGlueInfo, pvPacket);
+		RX_ADD_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT, 1);
+#if CFG_NATIVE_802_11
+		if (GLUE_TEST_FLAG(prAdapter->prGlueInfo, GLUE_FLAG_HALT)) {
+			/*Todo:: nothing*/
+			/*Todo:: nothing*/
+		}
+#endif
+	}
+
+	/* free the packet control block */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+	QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+	if (!prSwRfb) {
+		ASSERT(0);
+		return;
+	}
+
+	if (nicRxSetupRFB(prAdapter, prSwRfb)) {
+		ASSERT(0);
+		/* return; // Don't return here or it would lost SwRfb --kc */
+		if (!timerPendingTimer(&prAdapter->rReturnIndicatedRfbListTimer)) {
+			DBGLOG(RX, WARN,
+			       "wlanReturnPacket, Start ReturnIndicatedRfbList Timer (%ds)\n",
+				RX_RETURN_INDICATED_RFB_TIMEOUT_SEC);
+			cnmTimerStartTimer(prAdapter, &prAdapter->rReturnIndicatedRfbListTimer,
+					   SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC));
+		}
+	}
+	nicRxReturnRFB(prAdapter, prSwRfb);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Return the indicated packet buffer and reallocate one to the RFB
+*
+* \param prAdapter      Pointer of Adapter Data Structure
+* \param pvPacket       Pointer of returned packet
+*
+* \retval WLAN_STATUS_SUCCESS: Success
+* \retval WLAN_STATUS_FAILURE: Failed
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_SW_RFB_T prSwRfb = NULL;
+
+	KAL_SPIN_LOCK_DECLARATION();
+	WLAN_STATUS status = WLAN_STATUS_SUCCESS;
+	P_QUE_T prQueList;
+
+	DEBUGFUNC("wlanReturnIndicatedPacketsTimeOut");
+	DBGLOG(RX, WARN, "wlanReturnIndicatedPacketsTimeOut");
+
+	ASSERT(prAdapter);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	prQueList = &prRxCtrl->rIndicatedRfbList;
+	DBGLOG(RX, WARN, "IndicatedRfbList num = %u\n", (unsigned int)prQueList->u4NumElem);
+
+	while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rIndicatedRfbList)) {
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+		if (nicRxSetupRFB(prAdapter, prSwRfb)) {
+			status = WLAN_STATUS_RESOURCES;
+			ASSERT(0);
+		}
+		nicRxReturnRFB(prAdapter, prSwRfb);
+		if (status == WLAN_STATUS_RESOURCES)
+			break;
+	}
+	if (status == WLAN_STATUS_RESOURCES) {
+		DBGLOG(RX, WARN, "Start ReturnIndicatedRfbList Timer (%ds)\n", RX_RETURN_INDICATED_RFB_TIMEOUT_SEC);
+		/* restart timer */
+		cnmTimerStartTimer(prAdapter,
+				   &prAdapter->rReturnIndicatedRfbListTimer,
+				   SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC));
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is a required function that returns information about
+*        the capabilities and status of the driver and/or its network adapter.
+*
+* \param[IN] prAdapter        Pointer to the Adapter structure.
+* \param[IN] pfnOidQryHandler Function pointer for the OID query handler.
+* \param[IN] pvInfoBuf        Points to a buffer for return the query information.
+* \param[IN] u4QueryBufferLen Specifies the number of bytes at pvInfoBuf.
+* \param[OUT] pu4QueryInfoLen  Points to the number of bytes it written or is needed.
+*
+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers.
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanQueryInformation(IN P_ADAPTER_T prAdapter,
+		     IN PFN_OID_HANDLER_FUNC pfnOidQryHandler,
+		     IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen)
+{
+	WLAN_STATUS status = WLAN_STATUS_FAILURE;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QryInfoLen);
+
+	/* ignore any OID request after connected, under PS current measurement mode */
+	/* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for
+	 * blocking OIDs during current measurement
+	 */
+	if (prAdapter->u4PsCurrentMeasureEn &&
+	    (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED))
+		return WLAN_STATUS_SUCCESS;
+#if 1
+	/* most OID handler will just queue a command packet */
+	status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen);
+#else
+	if (wlanIsHandlerNeedHwAccess(pfnOidQryHandler, FALSE)) {
+		ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
+
+		/* Reset sleepy state */
+		if (prAdapter->fgWiFiInSleepyState == TRUE)
+			prAdapter->fgWiFiInSleepyState = FALSE;
+
+		status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen);
+
+		RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
+	} else
+		status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen);
+#endif
+
+	return status;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is a required function that allows bound protocol drivers,
+*        or NDIS, to request changes in the state information that the miniport
+*        maintains for particular object identifiers, such as changes in multicast
+*        addresses.
+*
+* \param[IN] prAdapter     Pointer to the Glue info structure.
+* \param[IN] pfnOidSetHandler     Points to the OID set handlers.
+* \param[IN] pvInfoBuf     Points to a buffer containing the OID-specific data for the set.
+* \param[IN] u4InfoBufLen  Specifies the number of bytes at prSetBuffer.
+* \param[OUT] pu4SetInfoLen Points to the number of bytes it read or is needed.
+*
+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers.
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanSetInformation(IN P_ADAPTER_T prAdapter,
+		   IN PFN_OID_HANDLER_FUNC pfnOidSetHandler,
+		   IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS status = WLAN_STATUS_FAILURE;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	/* ignore any OID request after connected, under PS current measurement mode */
+	/* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking
+	 * OIDs during current measurement
+	 */
+	if (prAdapter->u4PsCurrentMeasureEn &&
+	    (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED))
+		return WLAN_STATUS_SUCCESS;
+#if 1
+	/* most OID handler will just queue a command packet
+	 * for power state transition OIDs, handler will acquire power control by itself
+	 */
+	status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen);
+#else
+	if (wlanIsHandlerNeedHwAccess(pfnOidSetHandler, TRUE)) {
+		ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
+
+		/* Reset sleepy state */
+		if (prAdapter->fgWiFiInSleepyState == TRUE)
+			prAdapter->fgWiFiInSleepyState = FALSE;
+
+		status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen);
+
+		RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
+	} else {
+		status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen);
+	}
+#endif
+
+	return status;
+}
+
+#if CFG_SUPPORT_WAPI
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is a used to query driver's config wapi mode or not
+*
+* \param[IN] prAdapter     Pointer to the Glue info structure.
+*
+* \retval TRUE for use wapi mode
+*
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	return prAdapter->rWifiVar.rConnSettings.fgWapiMode;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to set RX filter to Promiscuous Mode.
+*
+* \param[IN] prAdapter        Pointer to the Adapter structure.
+* \param[IN] fgEnablePromiscuousMode Enable/ disable RX Promiscuous Mode.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode)
+{
+	ASSERT(prAdapter);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to set RX filter to allow to receive
+*        broadcast address packets.
+*
+* \param[IN] prAdapter        Pointer to the Adapter structure.
+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast)
+{
+	ASSERT(prAdapter);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to send out CMD_NIC_POWER_CTRL command packet
+*
+* \param[IN] prAdapter        Pointer to the Adapter structure.
+* \param[IN] ucPowerMode      refer to CMD/EVENT document
+*
+* \return WLAN_STATUS_SUCCESS
+* \return WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode)
+{
+	WLAN_STATUS status = WLAN_STATUS_SUCCESS;
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_8 ucTC, ucCmdSeqNum;
+
+	ASSERT(prAdapter);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	/* 1. Prepare CMD */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL)));
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+
+	/* 2.1 increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+	DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum);
+
+	/* 2.2 Setup common CMD Info Packet */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL));
+	prCmdInfo->pfCmdDoneHandler = NULL;
+	prCmdInfo->pfCmdTimeoutHandler = NULL;
+	prCmdInfo->fgIsOid = TRUE;
+	prCmdInfo->ucCID = CMD_ID_NIC_POWER_CTRL;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = sizeof(CMD_NIC_POWER_CTRL);
+
+	/* 2.3 Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	kalMemZero(prWifiCmd->aucBuffer, sizeof(CMD_NIC_POWER_CTRL));
+	((P_CMD_NIC_POWER_CTRL) (prWifiCmd->aucBuffer))->ucPowerMode = ucPowerMode;
+
+	/* 3. Issue CMD for entering specific power mode */
+	ucTC = TC4_INDEX;
+
+	while (1) {
+		/* 3.0 Removal check */
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+			status = WLAN_STATUS_FAILURE;
+			break;
+		}
+		/* 3.1 Acquire TX Resource */
+		if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) {
+
+			/* wait and poll tx resource */
+			if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) {
+				DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n");
+				status = WLAN_STATUS_FAILURE;
+				break;
+			}
+			continue;
+		}
+		/* 3.2 Send CMD Info Packet */
+		if (nicTxCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, ERROR, "Fail to transmit CMD_NIC_POWER_CTRL command\n");
+			status = WLAN_STATUS_FAILURE;
+		}
+
+		break;
+	};
+
+	/* 4. Free CMD Info Packet. */
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	/* 5. Add flag */
+	if (ucPowerMode == 1)
+		prAdapter->fgIsEnterD3ReqIssued = TRUE;
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to check if it is RF test mode and
+*        the OID is allowed to be called or not
+*
+* \param[IN] prAdapter        Pointer to the Adapter structure.
+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo)
+{
+	PFN_OID_HANDLER_FUNC *apfnOidHandlerAllowedInRFTest;
+	UINT_32 i;
+	UINT_32 u4NumOfElem;
+
+	if (fgSetInfo) {
+		apfnOidHandlerAllowedInRFTest = apfnOidSetHandlerAllowedInRFTest;
+		u4NumOfElem = sizeof(apfnOidSetHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC);
+	} else {
+		apfnOidHandlerAllowedInRFTest = apfnOidQueryHandlerAllowedInRFTest;
+		u4NumOfElem = sizeof(apfnOidQueryHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC);
+	}
+
+	for (i = 0; i < u4NumOfElem; i++) {
+		if (apfnOidHandlerAllowedInRFTest[i] == pfnOidHandler)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+#if CFG_ENABLE_FW_DOWNLOAD
+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to download FW image in an aggregated way
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter,
+				   IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf)
+{
+#if defined(MT6620) || defined(MT6628)
+	P_CMD_INFO_T prCmdInfo;
+	P_INIT_HIF_TX_HEADER_T prInitHifTxHeader;
+	P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf;
+	UINT_8 ucTC, ucCmdSeqNum;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+	PUINT_8 pucOutputBuf = (PUINT_8) NULL;	/* Pointer to Transmit Data Structure Frame */
+	UINT_32 u4PktCnt, u4Offset, u4Length;
+	UINT_32 u4TotalLength;
+
+	ASSERT(prAdapter);
+	ASSERT(pucImgSecBuf);
+
+	pucOutputBuf = prAdapter->rTxCtrl.pucTxCoalescingBufPtr;
+
+	DEBUGFUNC("wlanImageSectionDownloadAggregated");
+
+	if (u4ImgSecSize == 0)
+		return WLAN_STATUS_SUCCESS;
+	/* 1. Allocate CMD Info Packet and Pre-fill Headers */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter,
+					  sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) +
+					  CMD_PKT_SIZE_FOR_IMAGE);
+
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+
+	prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + CMD_PKT_SIZE_FOR_IMAGE;
+
+	/* 2. Use TC0's resource to download image. (only TC0 is allowed) */
+	ucTC = TC0_INDEX;
+
+	/* 3. Setup common CMD Info Packet */
+	prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer);
+	prInitHifTxHeader->ucEtherTypeOffset = 0;
+	prInitHifTxHeader->ucCSflags = 0;
+	prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF;
+
+	/* 4. Setup CMD_DOWNLOAD_BUF */
+	prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer);
+	prInitCmdDownloadBuf->u4DataMode = 0
+#if CFG_ENABLE_FW_ENCRYPTION
+	    | DOWNLOAD_BUF_ENCRYPTION_MODE
+#endif
+	    ;
+
+	/* 5.0 reset loop control variable */
+	u4TotalLength = 0;
+	u4Offset = u4PktCnt = 0;
+
+	/* 5.1 main loop for maximize transmission count per access */
+	while (u4Offset < u4ImgSecSize) {
+		if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_SUCCESS) {
+			/* 5.1.1 calculate u4Length */
+			if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < u4ImgSecSize)
+				u4Length = CMD_PKT_SIZE_FOR_IMAGE;
+			else
+				u4Length = u4ImgSecSize - u4Offset;
+
+			/* 5.1.1 increase command sequence number */
+			ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+			prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum;
+
+			/* 5.1.2 update HIF TX hardware header */
+			prInitHifTxHeader->u2TxByteCount =
+			    ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4Length);
+
+			/* 5.1.3 fill command header */
+			prInitCmdDownloadBuf->u4Address = u4DestAddr + u4Offset;
+			prInitCmdDownloadBuf->u4Length = u4Length;
+			prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf + u4Offset, u4Length);
+
+			/* 5.1.4.1 copy header to coalescing buffer */
+			kalMemCopy(pucOutputBuf + u4TotalLength,
+				   (PVOID) prCmdInfo->pucInfoBuffer,
+				   sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF));
+
+			/* 5.1.4.2 copy payload to coalescing buffer */
+			kalMemCopy(pucOutputBuf + u4TotalLength + sizeof(INIT_HIF_TX_HEADER_T) +
+				   sizeof(INIT_CMD_DOWNLOAD_BUF), pucImgSecBuf + u4Offset, u4Length);
+
+			/* 5.1.4.3 update length and other variables */
+			u4TotalLength +=
+			    ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4Length);
+			u4Offset += u4Length;
+			u4PktCnt++;
+
+			if (u4Offset < u4ImgSecSize)
+				continue;
+		} else if (u4PktCnt == 0) {
+			/* no resource, so get some back */
+			if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) {
+				u4Status = WLAN_STATUS_FAILURE;
+				DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n");
+				break;
+			}
+		}
+
+		if (u4PktCnt != 0) {
+			/* start transmission */
+			HAL_WRITE_TX_PORT(prAdapter,
+					  0,
+					  u4TotalLength, (PUINT_8) pucOutputBuf, prAdapter->u4CoalescingBufCachedSize);
+
+			/* reset varaibles */
+			u4PktCnt = 0;
+			u4TotalLength = 0;
+		}
+	}
+
+	/* 8. Free CMD Info Packet. */
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	return u4Status;
+
+#else
+#error "Only MT6620/MT6628/MT6582 supports firmware download in an aggregated way"
+
+	return WLAN_STATUS_FAILURE;
+
+#endif
+}
+
+#endif
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to download FW image.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter,
+			 IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf)
+{
+	P_CMD_INFO_T prCmdInfo;
+	P_INIT_HIF_TX_HEADER_T prInitHifTxHeader;
+	P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf;
+	UINT_8 ucTC, ucCmdSeqNum;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+	ASSERT(pucImgSecBuf);
+	ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE);
+
+	DEBUGFUNC("wlanImageSectionDownload");
+
+	if (u4ImgSecSize == 0)
+		return WLAN_STATUS_SUCCESS;
+	/* 1. Allocate CMD Info Packet and its Buffer. */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter,
+					  sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4ImgSecSize);
+
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+
+	prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4ImgSecSize;
+
+	/* 2. Use TC0's resource to download image. (only TC0 is allowed) */
+	ucTC = TC0_INDEX;
+
+	/* 3. increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* 4. Setup common CMD Info Packet */
+	prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer);
+	prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF;
+	prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum;
+
+	/* 5. Setup CMD_DOWNLOAD_BUF */
+	prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer);
+	prInitCmdDownloadBuf->u4Address = u4DestAddr;
+	prInitCmdDownloadBuf->u4Length = u4ImgSecSize;
+	prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf, u4ImgSecSize);
+
+	prInitCmdDownloadBuf->u4DataMode = 0
+#if CFG_ENABLE_FW_DOWNLOAD_ACK
+	    | DOWNLOAD_BUF_ACK_OPTION	/* ACK needed */
+#endif
+#if CFG_ENABLE_FW_ENCRYPTION
+	    | DOWNLOAD_BUF_ENCRYPTION_MODE
+#endif
+	    ;
+
+	kalMemCopy(prInitCmdDownloadBuf->aucBuffer, pucImgSecBuf, u4ImgSecSize);
+
+	/* 6. Send FW_Download command */
+	while (1) {
+		/* 6.1 Acquire TX Resource */
+		if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) {
+			if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) {
+				u4Status = WLAN_STATUS_FAILURE;
+				DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n");
+				break;
+			}
+			continue;
+		}
+		/* 6.2 Send CMD Info Packet */
+		if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) {
+			u4Status = WLAN_STATUS_FAILURE;
+			DBGLOG(INIT, ERROR, "Fail to transmit image download command\n");
+		}
+
+		break;
+	};
+
+#if CFG_ENABLE_FW_DOWNLOAD_ACK
+	/* 7. Wait for INIT_EVENT_ID_CMD_RESULT */
+	u4Status = wlanImageSectionDownloadStatus(prAdapter, ucCmdSeqNum);
+#endif
+
+	/* 8. Free CMD Info Packet. */
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	return u4Status;
+}
+
+#if !CFG_ENABLE_FW_DOWNLOAD_ACK
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to confirm previously firmware download is done without error
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter)
+{
+	P_CMD_INFO_T prCmdInfo;
+	P_INIT_HIF_TX_HEADER_T prInitHifTxHeader;
+	UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR)];
+	UINT_32 u4RxPktLength;
+	P_INIT_HIF_RX_HEADER_T prInitHifRxHeader;
+	P_INIT_EVENT_PENDING_ERROR prEventPendingError;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+	UINT_8 ucTC, ucCmdSeqNum;
+
+	ASSERT(prAdapter);
+
+	DEBUGFUNC("wlanImageQueryStatus");
+
+	/* 1. Allocate CMD Info Packet and it Buffer. */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T));
+
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+
+	kalMemZero(prCmdInfo, sizeof(INIT_HIF_TX_HEADER_T));
+	prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T);
+
+	/* 2. Use TC0's resource to download image. (only TC0 is allowed) */
+	ucTC = TC0_INDEX;
+
+	/* 3. increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* 4. Setup common CMD Info Packet */
+	prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer);
+	prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_QUERY_PENDING_ERROR;
+	prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum;
+
+	/* 5. Send command */
+	while (1) {
+		/* 5.1 Acquire TX Resource */
+		if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) {
+			if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) {
+				u4Status = WLAN_STATUS_FAILURE;
+				DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n");
+				break;
+			}
+			continue;
+		}
+		/* 5.2 Send CMD Info Packet */
+		if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) {
+			u4Status = WLAN_STATUS_FAILURE;
+			DBGLOG(INIT, ERROR, "Fail to transmit image download command\n");
+		}
+
+		break;
+	};
+
+	/* 6. Wait for INIT_EVENT_ID_PENDING_ERROR */
+	do {
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+			u4Status = WLAN_STATUS_FAILURE;
+		} else if (nicRxWaitResponse(prAdapter,
+					     0,
+					     aucBuffer,
+					     sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR),
+					     &u4RxPktLength) != WLAN_STATUS_SUCCESS) {
+			u4Status = WLAN_STATUS_FAILURE;
+		} else {
+			prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer;
+
+			/* EID / SeqNum check */
+			if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_PENDING_ERROR) {
+				u4Status = WLAN_STATUS_FAILURE;
+			} else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) {
+				u4Status = WLAN_STATUS_FAILURE;
+			} else {
+				prEventPendingError =
+				    (P_INIT_EVENT_PENDING_ERROR) (prInitHifRxHeader->rInitWifiEvent.aucBuffer);
+				if (prEventPendingError->ucStatus != 0) {	/* 0 for download success */
+					u4Status = WLAN_STATUS_FAILURE;
+				} else {
+					u4Status = WLAN_STATUS_SUCCESS;
+				}
+			}
+		}
+	} while (FALSE);
+
+	/* 7. Free CMD Info Packet. */
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	return u4Status;
+}
+
+#else
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to confirm the status of
+*        previously downloaded firmware scatter
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*        ucCmdSeqNum    Sequence number of previous firmware scatter
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum)
+{
+	UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT)];
+	P_INIT_HIF_RX_HEADER_T prInitHifRxHeader;
+	P_INIT_EVENT_CMD_RESULT prEventCmdResult;
+	UINT_32 u4RxPktLength;
+	WLAN_STATUS u4Status;
+
+	ASSERT(prAdapter);
+
+	do {
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+			DBGLOG(INIT, ERROR, "kalIsCardRemoved or fgIsBusAccessFailed\n");
+			u4Status = WLAN_STATUS_FAILURE;
+		} else if (nicRxWaitResponse(prAdapter,
+					0,
+					aucBuffer,
+					sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT),/* 4B + 4B */
+					&u4RxPktLength) != WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, ERROR, "nicRxWaitResponse fail\n");
+			u4Status = WLAN_STATUS_FAILURE;
+		} else {
+			prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer;
+
+			/* EID / SeqNum check */
+			if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT) {
+				DBGLOG(INIT, ERROR, "rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT\n");
+				u4Status = WLAN_STATUS_FAILURE;
+				g_IsNeedDoChipReset = 1;
+				kalSendAeeWarning("[Check EID error!]", __func__);
+			} else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) {
+				DBGLOG(INIT, ERROR, "rInitWifiEvent.ucSeqNum != ucCmdSeqNum\n");
+				u4Status = WLAN_STATUS_FAILURE;
+				g_IsNeedDoChipReset = 1;
+				kalSendAeeWarning("[Check SeqNum error!]", __func__);
+			} else {
+				prEventCmdResult =
+				    (P_INIT_EVENT_CMD_RESULT) (prInitHifRxHeader->rInitWifiEvent.aucBuffer);
+				if (prEventCmdResult->ucStatus != 0) {	/* 0 for download success */
+					/*
+					   0: success
+					   1: rejected by invalid param
+					   2: rejected by incorrect CRC
+					   3: rejected by decryption failure
+					   4: unknown CMD
+					 */
+					DBGLOG(INIT, ERROR, "Read Response status error = %d\n",
+							     prEventCmdResult->ucStatus);
+					u4Status = WLAN_STATUS_FAILURE;
+				} else {
+					u4Status = WLAN_STATUS_SUCCESS;
+				}
+			}
+		}
+	} while (FALSE);
+
+	return u4Status;
+}
+
+#endif
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to start FW normal operation.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress)
+{
+	P_CMD_INFO_T prCmdInfo;
+	P_INIT_HIF_TX_HEADER_T prInitHifTxHeader;
+	P_INIT_CMD_WIFI_START prInitCmdWifiStart;
+	UINT_8 ucTC, ucCmdSeqNum;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+
+	DEBUGFUNC("wlanConfigWifiFunc");
+
+	/* 1. Allocate CMD Info Packet and its Buffer. */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START));
+
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+
+	kalMemZero(prCmdInfo->pucInfoBuffer, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START));
+	prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START);
+
+	/* 2. Always use TC0 */
+	ucTC = TC0_INDEX;
+
+	/* 3. increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* 4. Setup common CMD Info Packet */
+	prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer);
+	prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_WIFI_START;
+	prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum;
+
+	prInitCmdWifiStart = (P_INIT_CMD_WIFI_START) (prInitHifTxHeader->rInitWifiCmd.aucBuffer);
+	prInitCmdWifiStart->u4Override = (fgEnable == TRUE ? 1 : 0);
+	prInitCmdWifiStart->u4Address = u4StartAddress;
+
+	/* 5. Seend WIFI start command */
+	while (1) {
+		/* 5.1 Acquire TX Resource */
+		if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) {
+
+			/* wait and poll tx resource */
+			if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) {
+				u4Status = WLAN_STATUS_FAILURE;
+				DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n");
+				break;
+			}
+
+			continue;
+		}
+		/* 5.2 Send CMD Info Packet */
+		if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) {
+			u4Status = WLAN_STATUS_FAILURE;
+			DBGLOG(INIT, ERROR, "Fail to transmit WIFI start command\n");
+		}
+
+		break;
+	};
+
+	/* 6. Free CMD Info Packet. */
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	return u4Status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to generate CRC32 checksum
+*
+* @param buf Pointer to the data.
+* @param len data length
+*
+* @return crc32 value
+*/
+/*----------------------------------------------------------------------------*/
+static const UINT_32 crc32_ccitt_table[256] = {
+		0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+		0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+		0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+		0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+		0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+		0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+		0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+		0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+		0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+		0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+		0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+		0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+		0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+		0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+		0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+		0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+		0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+		0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+		0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+		0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+		0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+		0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+		0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+		0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+		0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+		0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+		0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+		0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+		0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+		0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+		0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+		0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+		0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+		0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+		0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+		0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+		0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+		0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+		0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+		0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+		0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+		0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+		0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+		0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+		0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+		0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+		0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+		0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+		0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+		0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+		0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+		0x2d02ef8d
+	};
+
+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len)
+{
+	UINT_32 i, crc32 = 0xFFFFFFFF;
+
+	for (i = 0; i < len; i++)
+		crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8);
+
+	return ~crc32;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to process queued RX packets
+*
+* @param prAdapter          Pointer to the Adapter structure.
+*        prSwRfbListHead    Pointer to head of RX packets link list
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead)
+{
+	P_SW_RFB_T prSwRfb, prNextSwRfb;
+	P_TX_CTRL_T prTxCtrl;
+	P_RX_CTRL_T prRxCtrl;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfbListHead);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	prRxCtrl = &prAdapter->rRxCtrl;
+
+	prSwRfb = prSwRfbListHead;
+
+	do {
+		/* save next first */
+		prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb);
+
+		switch (prSwRfb->eDst) {
+		case RX_PKT_DESTINATION_HOST:
+			/* to host */
+			nicRxProcessPktWithoutReorder(prAdapter, prSwRfb);
+			break;
+
+		case RX_PKT_DESTINATION_FORWARD:
+			/* need ot forward */
+			nicRxProcessForwardPkt(prAdapter, prSwRfb);
+			break;
+
+		case RX_PKT_DESTINATION_HOST_WITH_FORWARD:
+			/* to host and forward */
+			nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb);
+			break;
+
+		case RX_PKT_DESTINATION_NULL:
+			/* free it */
+			nicRxReturnRFB(prAdapter, prSwRfb);
+			break;
+
+		default:
+			break;
+		}
+
+#if CFG_HIF_RX_STARVATION_WARNING
+		prRxCtrl->u4DequeuedCnt++;
+#endif
+
+		/* check next queued packet */
+		prSwRfb = prNextSwRfb;
+	} while (prSwRfb);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to purge queued TX packets
+*        by indicating failure to OS and returned to free list
+*
+* @param prAdapter          Pointer to the Adapter structure.
+*        prMsduInfoListHead Pointer to head of TX packets link list
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
+{
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfoListHead);
+
+	nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead);
+	nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to check if the OID handler needs timeout
+*
+* @param prAdapter          Pointer to the Adapter structure.
+*        pfnOidHandler      Pointer to the OID handler
+*
+* @return TRUE
+*         FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler)
+{
+	PFN_OID_HANDLER_FUNC *apfnOidHandlerWOTimeoutCheck;
+	UINT_32 i;
+	UINT_32 u4NumOfElem;
+
+	apfnOidHandlerWOTimeoutCheck = apfnOidWOTimeoutCheck;
+	u4NumOfElem = sizeof(apfnOidWOTimeoutCheck) / sizeof(PFN_OID_HANDLER_FUNC);
+
+	/* skip some OID timeout checks ? */
+	for (i = 0; i < u4NumOfElem; i++) {
+		if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler)
+			return FALSE;
+	}
+
+	/* set timer if need timeout check */
+	/* cnmTimerStartTimer(prAdapter, */
+	/* &(prAdapter->rOidTimeoutTimer), */
+	/* 1000); */
+	cnmTimerStartTimer(prAdapter, &(prAdapter->rOidTimeoutTimer), 2000);
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to clear any pending OID timeout check
+*
+* @param prAdapter          Pointer to the Adapter structure.
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	cnmTimerStopTimer(prAdapter, &(prAdapter->rOidTimeoutTimer));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to update network address in firmware domain
+*
+* @param prAdapter          Pointer to the Adapter structure.
+*
+* @return WLAN_STATUS_FAILURE   The request could not be processed
+*         WLAN_STATUS_PENDING   The request has been queued for later processing
+*         WLAN_STATUS_SUCCESS   The request has been processed
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter)
+{
+	const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR;
+	PARAM_MAC_ADDRESS rMacAddr = {0};
+	UINT_8 ucCmdSeqNum;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	P_CMD_BASIC_CONFIG prCmdBasicConfig;
+	UINT_32 u4SysTime;
+
+	DEBUGFUNC("wlanUpdateNetworkAddress");
+
+	ASSERT(prAdapter);
+
+	if (kalRetrieveNetworkAddress(prAdapter->prGlueInfo, &rMacAddr) == FALSE || IS_BMCAST_MAC_ADDR(rMacAddr)
+	    || EQUAL_MAC_ADDR(aucZeroMacAddr, rMacAddr)) {
+		/* eFUSE has a valid address, don't do anything */
+		if (prAdapter->fgIsEmbbededMacAddrValid == TRUE) {
+#if CFG_SHOW_MACADDR_SOURCE
+			DBGLOG(INIT, INFO, "Using embedded MAC address");
+#endif
+			return WLAN_STATUS_SUCCESS;
+		}
+#if CFG_SHOW_MACADDR_SOURCE
+		DBGLOG(INIT, TRACE, "Using dynamically generated MAC address");
+#endif
+		/* dynamic generate */
+		u4SysTime = kalGetTimeTick();
+
+		rMacAddr[0] = 0x00;
+		rMacAddr[1] = 0x08;
+		rMacAddr[2] = 0x22;
+
+		kalMemCopy(&rMacAddr[3], &u4SysTime, 3);
+	} else {
+#if CFG_SHOW_MACADDR_SOURCE
+		DBGLOG(INIT, INFO, "Using host-supplied MAC address");
+#endif
+	}
+
+	/* allocate command memory */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG));
+
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_BUILD_CONNECTION cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG);
+	prCmdInfo->pfCmdDoneHandler = NULL;
+	prCmdInfo->pfCmdTimeoutHandler = NULL;
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG);
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	/* configure CMD_BASIC_CONFIG */
+	prCmdBasicConfig = (P_CMD_BASIC_CONFIG) (prWifiCmd->aucBuffer);
+	kalMemCopy(&(prCmdBasicConfig->rMyMacAddr), &rMacAddr, PARAM_MAC_ADDR_LEN);
+	prCmdBasicConfig->ucNative80211 = 0;
+	prCmdBasicConfig->rCsumOffload.u2RxChecksum = 0;
+	prCmdBasicConfig->rCsumOffload.u2TxChecksum = 0;
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP)
+		prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(2);
+
+	if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP)
+		prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(1);
+
+	if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP)
+		prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(0);
+
+	if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP)
+		prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(2);
+
+	if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP)
+		prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(1);
+
+	if (prAdapter->u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6))
+		prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(0);
+#endif
+
+	/* send the command to FW */
+	if (wlanSendCommand(prAdapter, prCmdInfo) == WLAN_STATUS_RESOURCES) {
+
+		/* backup the command to wait response */
+		prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryAddress;
+		kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+		return WLAN_STATUS_PENDING;
+	}
+	/* send ok without response */
+	nicCmdEventQueryAddress(prAdapter, prCmdInfo, (PUINT_8) prCmdBasicConfig);
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	return WLAN_STATUS_SUCCESS;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to check if the device is in RF test mode
+*
+* @param pfnOidHandler      Pointer to the OID handler
+*
+* @return TRUE
+*         FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	return prAdapter->fgTestMode;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to identify 802.1x and Bluetooth-over-Wi-Fi
+*        security frames, and queued into command queue for strict ordering
+*        due to 802.1x frames before add-key OIDs are not to be encrypted
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param prPacket       Pointer of native packet
+*
+* @return TRUE
+*         FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket)
+{
+	UINT_8 ucPriorityParam;
+	UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN];
+	BOOLEAN fgIs1x = FALSE;
+	BOOLEAN fgIsPAL = FALSE;
+	UINT_32 u4PacketLen;
+	ULONG u4SysTime;
+	UINT_8 ucNetworkType;
+	P_CMD_INFO_T prCmdInfo;
+	UINT_8 ucCmdSeqNo = 0;
+
+	/* 1x data packets */
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(prPacket);
+
+	/* retrieve some information for packet classification */
+	if (kalQoSFrameClassifierAndPacketInfo(prAdapter->prGlueInfo,
+						prPacket,
+						&ucPriorityParam,
+						&u4PacketLen,
+						aucEthDestAddr,
+						&fgIs1x,
+						&fgIsPAL,
+						&ucNetworkType,
+						&ucCmdSeqNo) == TRUE) {
+		/* almost TRUE except frame length < 14B */
+
+		if (fgIs1x == FALSE)
+			return FALSE;
+
+		/* get a free command entry */
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+		QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+
+		if (prCmdInfo) {
+			P_STA_RECORD_T prStaRec;
+
+			/* fill arrival time */
+			u4SysTime = (OS_SYSTIME) kalGetTimeTick();
+			GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime);
+
+			kalMemZero(prCmdInfo, sizeof(CMD_INFO_T));
+
+			prCmdInfo->eCmdType = COMMAND_TYPE_SECURITY_FRAME;
+			prCmdInfo->u2InfoBufLen = (UINT_16) u4PacketLen;
+			prCmdInfo->pucInfoBuffer = NULL;
+			prCmdInfo->prPacket = prPacket;
+			prCmdInfo->ucCmdSeqNum = ucCmdSeqNo;
+#if 0
+			prCmdInfo->ucStaRecIndex = qmGetStaRecIdx(prAdapter,
+								  aucEthDestAddr,
+								  (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType);
+#endif
+			prStaRec = cnmGetStaRecByAddress(prAdapter,
+							 (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType,
+							 aucEthDestAddr);
+			if (prStaRec)
+				prCmdInfo->ucStaRecIndex = prStaRec->ucIndex;
+			else
+				prCmdInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND;
+
+			prCmdInfo->eNetworkType = (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType;
+			prCmdInfo->pfCmdDoneHandler = wlanSecurityFrameTxDone;
+			prCmdInfo->pfCmdTimeoutHandler = wlanSecurityFrameTxTimeout;
+			prCmdInfo->fgIsOid = FALSE;
+			prCmdInfo->fgSetQuery = TRUE;
+			prCmdInfo->fgNeedResp = FALSE;
+
+			/*
+			   queue the 1x packet and we will send the packet to CONNSYS by
+			   using command queue
+			 */
+			kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+			/* TRUE: means we have already handled it in the function */
+			return TRUE;
+		}
+
+		/* no memory, why assert ? can skip the packet ? */
+		ASSERT(0);
+		return FALSE;
+	}
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi
+*        security frames has been sent to firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param prCmdInfo      Pointer of CMD_INFO_T
+* @param pucEventBuf    meaningless, only for API compatibility
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	if (prCmdInfo->eNetworkType == NETWORK_TYPE_AIS_INDEX &&
+	    prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure) {
+
+		/* AIS counter measure so change RSN FSM to SEND_DEAUTH state */
+		P_STA_RECORD_T prSta = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex);
+
+		if (prSta) {
+			kalMsleep(10);
+			secFsmEventEapolTxDone(prAdapter, prSta, TX_RESULT_SUCCESS);
+		}
+	}
+
+	/* free the packet */
+	kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_SUCCESS);
+	DBGLOG(TX, INFO, "Security frame tx done, SeqNum: %d\n", prCmdInfo->ucCmdSeqNum);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi
+*        security frames has failed sending to firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param prCmdInfo      Pointer of CMD_INFO_T
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	/* free the packet */
+	kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called before AIS is starting a new scan
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter)
+{
+	BOOLEAN fgKeepCurrOne = FALSE;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	/* clear scanning result except current one */
+	/* copy current one to prAdapter->rWlanInfo.arScanResult[0] */
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+		for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
+
+			if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress,
+					   prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) {
+				fgKeepCurrOne = TRUE;
+
+				if (i != 0) {
+					/* copy structure */
+					kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[0]),
+						   &(prAdapter->rWlanInfo.arScanResult[i]),
+						   OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
+				}
+
+				if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) {
+					if (prAdapter->rWlanInfo.apucScanResultIEs[i] !=
+					    &(prAdapter->rWlanInfo.aucScanIEBuf[0])) {
+						/* move IEs to head */
+						kalMemCopy(prAdapter->rWlanInfo.aucScanIEBuf,
+							   prAdapter->rWlanInfo.apucScanResultIEs[i],
+							   prAdapter->rWlanInfo.arScanResult[i].u4IELength);
+					}
+					/* modify IE pointer */
+					prAdapter->rWlanInfo.apucScanResultIEs[0] =
+					    &(prAdapter->rWlanInfo.aucScanIEBuf[0]);
+				} else {
+					prAdapter->rWlanInfo.apucScanResultIEs[0] = NULL;
+				}
+
+				break;
+			}
+		}
+	}
+
+	if (fgKeepCurrOne == TRUE) {
+		prAdapter->rWlanInfo.u4ScanResultNum = 1;
+		prAdapter->rWlanInfo.u4ScanIEBufferUsage = ALIGN_4(prAdapter->rWlanInfo.arScanResult[0].u4IELength);
+	} else {
+		prAdapter->rWlanInfo.u4ScanResultNum = 0;
+		prAdapter->rWlanInfo.u4ScanIEBufferUsage = 0;
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when AIS received a beacon timeout event
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param arBSSID        MAC address of the specified BSS
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID)
+{
+	UINT_32 i, j, u4IELength = 0, u4IEMoveLength;
+	PUINT_8 pucIEPtr;
+
+	ASSERT(prAdapter);
+
+	/* clear the scanning result for arBSSID */
+	i = 0;
+	while (1) {
+		if (i >= prAdapter->rWlanInfo.u4ScanResultNum)
+			break;
+
+		if (EQUAL_MAC_ADDR(arBSSID, prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) {
+
+			/* backup current IE length */
+			u4IELength = ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4IELength);
+			pucIEPtr = prAdapter->rWlanInfo.apucScanResultIEs[i];
+
+			/* removed from middle */
+			for (j = i + 1; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) {
+				kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[j - 1]),
+					   &(prAdapter->rWlanInfo.arScanResult[j]),
+					   OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
+
+				prAdapter->rWlanInfo.apucScanResultIEs[j - 1] =
+				    prAdapter->rWlanInfo.apucScanResultIEs[j];
+			}
+
+			prAdapter->rWlanInfo.u4ScanResultNum--;
+
+			/* remove IE buffer if needed := move rest of IE buffer */
+			if (u4IELength > 0) {
+				u4IEMoveLength = prAdapter->rWlanInfo.u4ScanIEBufferUsage -
+				    (((ULONG) pucIEPtr) + (ULONG) u4IELength -
+				     ((ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0]))));
+
+				kalMemCopy(pucIEPtr, pucIEPtr + u4IELength, u4IEMoveLength);
+
+				prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4IELength;
+
+				/* correction of pointers to IE buffer */
+				for (j = 0; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) {
+					if (prAdapter->rWlanInfo.apucScanResultIEs[j] > pucIEPtr) {
+						prAdapter->rWlanInfo.apucScanResultIEs[j] =
+						    (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[j]) -
+							       u4IELength);
+					}
+				}
+			}
+		}
+
+		i++;
+	}
+
+}
+
+#if CFG_TEST_WIFI_DIRECT_GO
+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter)
+{
+#if 0
+	P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL;
+
+	prMsgFuncSwitch =
+	    (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T));
+	if (!prMsgFuncSwitch) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
+	prMsgFuncSwitch->fgIsFuncOn = TRUE;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF);
+#endif
+
+}
+
+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter)
+{
+
+	P_MSG_P2P_CONNECTION_REQUEST_T prMsgConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL;
+	UINT_8 aucTargetDeviceID[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+	prMsgConnReq =
+	    (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_REQUEST_T));
+	if (!prMsgConnReq) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	prMsgConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ;
+
+    /*=====Param Modified for test=====*/
+	COPY_MAC_ADDR(prMsgConnReq->aucDeviceID, aucTargetDeviceID);
+	prMsgConnReq->fgIsTobeGO = TRUE;
+	prMsgConnReq->fgIsPersistentGroup = FALSE;
+
+    /*=====Param Modified for test=====*/
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgConnReq, MSG_SEND_METHOD_BUF);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to retrieve permanent address from firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 ucCmdSeqNum;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_32 u4RxPktLength;
+	UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG)];
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	P_WIFI_EVENT_T prEvent;
+	P_EVENT_BASIC_CONFIG prEventBasicConfig;
+
+	ASSERT(prAdapter);
+
+	DEBUGFUNC("wlanQueryPermanentAddress");
+
+	/* 1. Allocate CMD Info Packet and its Buffer */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG));
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_BUILD_CONNECTION cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG);
+	prCmdInfo->pfCmdDoneHandler = NULL;
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG;
+	prCmdInfo->fgSetQuery = FALSE;
+	prCmdInfo->fgNeedResp = TRUE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG);
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	/* send the command */
+	wlanSendCommand(prAdapter, prCmdInfo);
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	/* wait for response */
+	if (nicRxWaitResponse(prAdapter,
+				1,
+				aucBuffer,
+				sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG),	/* 8B + 12B */
+				&u4RxPktLength) != WLAN_STATUS_SUCCESS)
+		return WLAN_STATUS_FAILURE;
+	/* header checking .. */
+	prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer;
+	if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT)
+		return WLAN_STATUS_FAILURE;
+
+	prEvent = (P_WIFI_EVENT_T) aucBuffer;
+	if (prEvent->ucEID != EVENT_ID_BASIC_CONFIG)
+		return WLAN_STATUS_FAILURE;
+
+	prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (prEvent->aucBuffer);
+
+	COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, &(prEventBasicConfig->rMyMacAddr));
+	COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, &(prEventBasicConfig->rMyMacAddr));
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to retrieve NIC capability from firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 ucCmdSeqNum;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_32 u4RxPktLength;
+	UINT_32 u4FwIDVersion = 0;
+	UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY)];
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	P_WIFI_EVENT_T prEvent;
+	P_EVENT_NIC_CAPABILITY prEventNicCapability;
+
+	ASSERT(prAdapter);
+
+	DEBUGFUNC("wlanQueryNicCapability");
+
+	/* 1. Allocate CMD Info Packet and its Buffer */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY));
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_BUILD_CONNECTION cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY);
+	prCmdInfo->pfCmdDoneHandler = NULL;
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY;
+	prCmdInfo->fgSetQuery = FALSE;
+	prCmdInfo->fgNeedResp = TRUE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = 0;
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	/* send the command */
+	wlanSendCommand(prAdapter, prCmdInfo);
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	/* wait for FW response */
+	if (nicRxWaitResponse(prAdapter,
+			      1,
+			      aucBuffer,
+			      sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY),
+			      &u4RxPktLength) != WLAN_STATUS_SUCCESS)
+		return WLAN_STATUS_FAILURE;
+	/* header checking .. */
+	prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer;
+	if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT)
+		return WLAN_STATUS_FAILURE;
+
+	prEvent = (P_WIFI_EVENT_T) aucBuffer;
+	if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY)
+		return WLAN_STATUS_FAILURE;
+
+	prEventNicCapability = (P_EVENT_NIC_CAPABILITY) (prEvent->aucBuffer);
+
+	prAdapter->rVerInfo.u2FwProductID = prEventNicCapability->u2ProductID;
+	prAdapter->rVerInfo.u2FwOwnVersion = prEventNicCapability->u2FwVersion;
+	prAdapter->rVerInfo.u2FwPeerVersion = prEventNicCapability->u2DriverVersion;
+	prAdapter->fgIsHw5GBandDisabled = (BOOLEAN) prEventNicCapability->ucHw5GBandDisabled;
+	prAdapter->fgIsEepromUsed = (BOOLEAN) prEventNicCapability->ucEepromUsed;
+	prAdapter->fgIsEfuseValid = (BOOLEAN) prEventNicCapability->ucEfuseValid;
+	prAdapter->fgIsEmbbededMacAddrValid = (BOOLEAN) prEventNicCapability->ucMacAddrValid;
+
+	u4FwIDVersion = (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion);
+	mtk_wcn_wmt_set_wifi_ver(u4FwIDVersion);
+#if (CFG_SUPPORT_TDLS == 1)
+	if (prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_TDLS))
+		prAdapter->fgTdlsIsSup = TRUE;
+	DBGLOG(TDLS, TRACE, "<wifi> support flag: 0x%x\n", prEventNicCapability->ucFeatureSet);
+#else
+	prAdapter->fgTdlsIsSup = 0;
+#endif /* CFG_SUPPORT_TDLS */
+
+	if (!(prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_5G_SUPPORT)))
+		prAdapter->fgEnable5GBand = FALSE;	/* firmware does not support */
+
+#if CFG_ENABLE_CAL_LOG
+	DBGLOG(INIT, LOUD, " RF CAL FAIL  = (%d),BB CAL FAIL  = (%d)\n",
+			    prEventNicCapability->ucRfCalFail, prEventNicCapability->ucBbCalFail);
+#endif
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to retrieve NIC capability from firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 ucCmdSeqNum;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+
+	ASSERT(prAdapter);
+
+	DEBUGFUNC("wlanQueryDebugCode");
+
+	/* 1. Allocate CMD Info Packet and its Buffer */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE);
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_BUILD_CONNECTION cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE;
+	prCmdInfo->pfCmdDoneHandler = NULL;
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = CMD_ID_GET_DEBUG_CODE;
+	prCmdInfo->fgSetQuery = FALSE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = 0;
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	/* send the command */
+	wlanSendCommand(prAdapter, prCmdInfo);
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to retrieve compiler flag from firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryCompileFlag(IN P_ADAPTER_T prAdapter, IN UINT_32 u4QueryID, OUT PUINT_32 pu4CompilerFlag)
+{
+	UINT_8 ucCmdSeqNum;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_32 u4RxPktLength;
+	UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T)];
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	P_WIFI_EVENT_T prEvent;
+	P_CMD_SW_DBG_CTRL_T prCmdNicCompileFlag, prEventNicCompileFlag;
+
+	ASSERT(prAdapter);
+
+	DEBUGFUNC(__func__);
+
+	/* 1. Allocate CMD Info Packet and its Buffer */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T));
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_BUILD_CONNECTION cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T);
+	prCmdInfo->pfCmdDoneHandler = NULL;
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = CMD_ID_SW_DBG_CTRL;
+	prCmdInfo->fgSetQuery = FALSE;
+	prCmdInfo->fgNeedResp = TRUE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = 0;
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	/* Fill up SW CR */
+	prCmdNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prWifiCmd->aucBuffer);
+
+	prCmdNicCompileFlag->u4Id = u4QueryID;
+
+	wlanSendCommand(prAdapter, prCmdInfo);
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	if (nicRxWaitResponse(prAdapter,
+			      1,
+			      aucBuffer,
+			      sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T),
+			      &u4RxPktLength) != WLAN_STATUS_SUCCESS)
+		return WLAN_STATUS_FAILURE;
+	/* header checking .. */
+	prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer;
+	if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT)
+		return WLAN_STATUS_FAILURE;
+
+	prEvent = (P_WIFI_EVENT_T) aucBuffer;
+	if (prEvent->ucEID != EVENT_ID_SW_DBG_CTRL)
+		return WLAN_STATUS_FAILURE;
+
+	prEventNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prEvent->aucBuffer);
+
+	*pu4CompilerFlag = prEventNicCompileFlag->u4Data;
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter)
+{
+	wlanQueryCompileFlag(prAdapter, 0xA0240000, &prAdapter->u4FwCompileFlag0);
+	wlanQueryCompileFlag(prAdapter, 0xA0240001, &prAdapter->u4FwCompileFlag1);
+
+	DBGLOG(INIT, TRACE,
+	       "Compile Flags: 0x%08x 0x%08x\n", prAdapter->u4FwCompileFlag0, prAdapter->u4FwCompileFlag1);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#if defined(MT6628)
+static INT_32 wlanChangeCodeWord(INT_32 au4Input)
+{
+
+	UINT_16 i;
+#if TXPWR_USE_PDSLOPE
+	CODE_MAPPING_T arCodeTable[] = {
+		{0X100, -40},
+		{0X104, -35},
+		{0X128, -30},
+		{0X14C, -25},
+		{0X170, -20},
+		{0X194, -15},
+		{0X1B8, -10},
+		{0X1DC, -5},
+		{0, 0},
+		{0X24, 5},
+		{0X48, 10},
+		{0X6C, 15},
+		{0X90, 20},
+		{0XB4, 25},
+		{0XD8, 30},
+		{0XFC, 35},
+		{0XFF, 40},
+
+	};
+#else
+	CODE_MAPPING_T arCodeTable[] = {
+		{0X100, 0x80},
+		{0X104, 0x80},
+		{0X128, 0x80},
+		{0X14C, 0x80},
+		{0X170, 0x80},
+		{0X194, 0x94},
+		{0X1B8, 0XB8},
+		{0X1DC, 0xDC},
+		{0, 0},
+		{0X24, 0x24},
+		{0X48, 0x48},
+		{0X6C, 0x6c},
+		{0X90, 0x7F},
+		{0XB4, 0x7F},
+		{0XD8, 0x7F},
+		{0XFC, 0x7F},
+		{0XFF, 0x7F},
+
+	};
+#endif
+
+	for (i = 0; i < sizeof(arCodeTable) / sizeof(CODE_MAPPING_T); i++) {
+
+		if (arCodeTable[i].u4RegisterValue == au4Input)
+			return arCodeTable[i].i4TxpowerOffset;
+	}
+
+	return 0;
+}
+#endif
+
+#if TXPWR_USE_PDSLOPE
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo)
+{
+	UINT_8 ucCmdSeqNum;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_32 u4RxPktLength;
+	UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG)];
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	P_WIFI_EVENT_T prEvent;
+	P_CMD_ACCESS_REG prCmdMcrQuery;
+
+	ASSERT(prAdapter);
+
+	/* 1. Allocate CMD Info Packet and its Buffer */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG));
+
+	if (!prCmdInfo) {
+		DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_BUILD_CONNECTION cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG));
+	prCmdInfo->pfCmdDoneHandler = NULL;
+	prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = CMD_ID_ACCESS_REG;
+	prCmdInfo->fgSetQuery = FALSE;
+	prCmdInfo->fgNeedResp = TRUE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = sizeof(CMD_ACCESS_REG);
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+	kalMemCopy(prWifiCmd->aucBuffer, prMcrRdInfo, sizeof(CMD_ACCESS_REG));
+
+	wlanSendCommand(prAdapter, prCmdInfo);
+	cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+
+	if (nicRxWaitResponse(prAdapter,
+			      1,
+			      aucBuffer,
+			      sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG), &u4RxPktLength) != WLAN_STATUS_SUCCESS)
+		return WLAN_STATUS_FAILURE;
+	/* header checking .. */
+	prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer;
+	if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT)
+		return WLAN_STATUS_FAILURE;
+
+	prEvent = (P_WIFI_EVENT_T) aucBuffer;
+
+	if (prEvent->ucEID != EVENT_ID_ACCESS_REG)
+		return WLAN_STATUS_FAILURE;
+
+	prCmdMcrQuery = (P_CMD_ACCESS_REG) (prEvent->aucBuffer);
+	prMcrRdInfo->u4McrOffset = prCmdMcrQuery->u4Address;
+	prMcrRdInfo->u4McrData = prCmdMcrQuery->u4Data;
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+static INT_32 wlanIntRound(INT_32 au4Input)
+{
+
+	if (au4Input >= 0) {
+		if ((au4Input % 10) == 5) {
+			au4Input = au4Input + 5;
+			return au4Input;
+		}
+	}
+
+	if (au4Input < 0) {
+		if ((au4Input % 10) == -5) {
+			au4Input = au4Input - 5;
+			return au4Input;
+		}
+	}
+
+	return au4Input;
+}
+
+static INT_32 wlanCal6628EfuseForm(IN P_ADAPTER_T prAdapter, INT_32 au4Input)
+{
+
+	PARAM_MCR_RW_STRUCT_T rMcrRdInfo;
+	INT_32 au4PdSlope, au4TxPwrOffset, au4TxPwrOffset_Round;
+	INT_8 auTxPwrOffset_Round;
+
+	rMcrRdInfo.u4McrOffset = 0x60205c68;
+	rMcrRdInfo.u4McrData = 0;
+	au4TxPwrOffset = au4Input;
+	wlanQueryPdMcr(prAdapter, &rMcrRdInfo);
+
+	au4PdSlope = (rMcrRdInfo.u4McrData) & BITS(0, 6);
+	au4TxPwrOffset_Round = wlanIntRound((au4TxPwrOffset * au4PdSlope)) / 10;
+
+	au4TxPwrOffset_Round = -au4TxPwrOffset_Round;
+
+	if (au4TxPwrOffset_Round < -128)
+		au4TxPwrOffset_Round = 128;
+	else if (au4TxPwrOffset_Round < 0)
+		au4TxPwrOffset_Round += 256;
+	else if (au4TxPwrOffset_Round > 127)
+		au4TxPwrOffset_Round = 127;
+
+	auTxPwrOffset_Round = (UINT8) au4TxPwrOffset_Round;
+
+	return au4TxPwrOffset_Round;
+}
+
+#endif
+
+#if defined(MT6628)
+static VOID wlanChangeNvram6620to6628(PUINT_8 pucEFUSE)
+{
+
+#define EFUSE_CH_OFFSET1_L_MASK_6620         BITS(0, 8)
+#define EFUSE_CH_OFFSET1_L_SHIFT_6620        0
+#define EFUSE_CH_OFFSET1_M_MASK_6620         BITS(9, 17)
+#define EFUSE_CH_OFFSET1_M_SHIFT_6620        9
+#define EFUSE_CH_OFFSET1_H_MASK_6620         BITS(18, 26)
+#define EFUSE_CH_OFFSET1_H_SHIFT_6620        18
+#define EFUSE_CH_OFFSET1_VLD_MASK_6620       BIT(27)
+#define EFUSE_CH_OFFSET1_VLD_SHIFT_6620      27
+
+#define EFUSE_CH_OFFSET1_L_MASK_5931         BITS(0, 7)
+#define EFUSE_CH_OFFSET1_L_SHIFT_5931        0
+#define EFUSE_CH_OFFSET1_M_MASK_5931         BITS(8, 15)
+#define EFUSE_CH_OFFSET1_M_SHIFT_5931        8
+#define EFUSE_CH_OFFSET1_H_MASK_5931         BITS(16, 23)
+#define EFUSE_CH_OFFSET1_H_SHIFT_5931        16
+#define EFUSE_CH_OFFSET1_VLD_MASK_5931       BIT(24)
+#define EFUSE_CH_OFFSET1_VLD_SHIFT_5931      24
+#define EFUSE_ALL_CH_OFFSET1_MASK_5931       BITS(25, 27)
+#define EFUSE_ALL_CH_OFFSET1_SHIFT_5931      25
+
+	INT_32 au4ChOffset;
+	INT_16 au2ChOffsetL, au2ChOffsetM, au2ChOffsetH;
+
+	au4ChOffset = *(UINT_32 *) (pucEFUSE + 72);
+
+	if ((au4ChOffset & EFUSE_CH_OFFSET1_VLD_MASK_6620) && ((*(UINT_32 *) (pucEFUSE + 28)) == 0)) {
+
+		au2ChOffsetL = ((au4ChOffset & EFUSE_CH_OFFSET1_L_MASK_6620) >> EFUSE_CH_OFFSET1_L_SHIFT_6620);
+
+		au2ChOffsetM = ((au4ChOffset & EFUSE_CH_OFFSET1_M_MASK_6620) >> EFUSE_CH_OFFSET1_M_SHIFT_6620);
+
+		au2ChOffsetH = ((au4ChOffset & EFUSE_CH_OFFSET1_H_MASK_6620) >> EFUSE_CH_OFFSET1_H_SHIFT_6620);
+
+		au2ChOffsetL = wlanChangeCodeWord(au2ChOffsetL);
+		au2ChOffsetM = wlanChangeCodeWord(au2ChOffsetM);
+		au2ChOffsetH = wlanChangeCodeWord(au2ChOffsetH);
+
+		au4ChOffset = 0;
+		au4ChOffset |= *(UINT_32 *) (pucEFUSE + 72)
+		    >> (EFUSE_CH_OFFSET1_VLD_SHIFT_6620 -
+			EFUSE_CH_OFFSET1_VLD_SHIFT_5931) & EFUSE_CH_OFFSET1_VLD_MASK_5931;
+
+		au4ChOffset |=
+		    ((((UINT_32) au2ChOffsetL) << EFUSE_CH_OFFSET1_L_SHIFT_5931) & EFUSE_CH_OFFSET1_L_MASK_5931);
+		au4ChOffset |=
+		    ((((UINT_32) au2ChOffsetM) << EFUSE_CH_OFFSET1_M_SHIFT_5931) & EFUSE_CH_OFFSET1_M_MASK_5931);
+		au4ChOffset |=
+		    ((((UINT_32) au2ChOffsetH) << EFUSE_CH_OFFSET1_H_SHIFT_5931) & EFUSE_CH_OFFSET1_H_MASK_5931);
+
+		*((INT_32 *) ((pucEFUSE + 28))) = au4ChOffset;
+
+	}
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to load manufacture data from NVRAM
+* if available and valid
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param prRegInfo      Pointer of REG_INFO_T
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo)
+{
+#if CFG_SUPPORT_RDD_TEST_MODE
+	CMD_RDD_CH_T rRddParam;
+#endif
+
+	ASSERT(prAdapter);
+
+	/* 1. Version Check */
+	kalGetConfigurationVersion(prAdapter->prGlueInfo,
+				   &(prAdapter->rVerInfo.u2Part1CfgOwnVersion),
+				   &(prAdapter->rVerInfo.u2Part1CfgPeerVersion),
+				   &(prAdapter->rVerInfo.u2Part2CfgOwnVersion),
+				   &(prAdapter->rVerInfo.u2Part2CfgPeerVersion));
+
+#if (CFG_SW_NVRAM_VERSION_CHECK == 1)
+	if (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion
+	    || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion
+	    || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION
+	    || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION) {
+		return WLAN_STATUS_FAILURE;
+	}
+#endif
+
+	/* MT6620 E1/E2 would be ignored directly */
+	if (prAdapter->rVerInfo.u2Part1CfgOwnVersion == 0x0001) {
+		prRegInfo->ucTxPwrValid = 1;
+	} else {
+		/* 2. Load TX power gain parameters if valid */
+		if (prRegInfo->ucTxPwrValid != 0) {
+			/* send to F/W */
+			nicUpdateTxPower(prAdapter, (P_CMD_TX_PWR_T) (&(prRegInfo->rTxPwr)));
+		}
+	}
+
+        /* Workaround for supporting 5G */
+        prRegInfo->ucEnable5GBand = 1;
+        prRegInfo->ucSupport5GBand = 1;
+
+	/* 3. Check if needs to support 5GHz */
+	/* if(prRegInfo->ucEnable5GBand) { // Frank workaround */
+	if (1) {
+		/* check if it is disabled by hardware */
+		if (prAdapter->fgIsHw5GBandDisabled || prRegInfo->ucSupport5GBand == 0)
+			prAdapter->fgEnable5GBand = FALSE;
+		else
+			prAdapter->fgEnable5GBand = TRUE;
+	} else
+		prAdapter->fgEnable5GBand = FALSE;
+        /* Workaround for supporting 5G */
+        prAdapter->fgEnable5GBand = TRUE;
+/*
+	DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d)\n",
+	       prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled);
+*/
+	/* 4. Send EFUSE data */
+#if  defined(MT6628)
+	wlanChangeNvram6620to6628(prRegInfo->aucEFUSE);
+#endif
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SET_PHY_PARAM,
+			    TRUE,
+			    FALSE,
+			    FALSE, NULL, NULL, sizeof(CMD_PHY_PARAM_T), (PUINT_8) (prRegInfo->aucEFUSE), NULL, 0);
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+	rRddParam.ucRddTestMode = (UINT_8) prRegInfo->u4RddTestMode;
+	rRddParam.ucRddShutCh = (UINT_8) prRegInfo->u4RddShutFreq;
+	rRddParam.ucRddStartCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStartFreq);
+	rRddParam.ucRddStopCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStopFreq);
+	rRddParam.ucRddDfs = (UINT_8) prRegInfo->u4RddDfs;
+	prAdapter->ucRddStatus = 0;
+	nicUpdateRddTestMode(prAdapter, (P_CMD_RDD_CH_T) (&rRddParam));
+#endif
+
+	/* 5. Get 16-bits Country Code and Bandwidth */
+	prAdapter->rWifiVar.rConnSettings.u2CountryCode =
+	    (((UINT_16) prRegInfo->au2CountryCode[0]) << 8) | (((UINT_16) prRegInfo->au2CountryCode[1]) & BITS(0, 7));
+
+	DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d) CountryCode(0x%x 0x%x)\n",
+		prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled,
+		prRegInfo->au2CountryCode[0], prRegInfo->au2CountryCode[1]);
+
+#if 0  /* Bandwidth control will be controlled by GUI. 20110930
+	* So ignore the setting from registry/NVRAM
+	*/
+	prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode =
+	    prRegInfo->uc2G4BwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M;
+	prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode =
+	    prRegInfo->uc5GBwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M;
+#endif
+
+	/* 6. Set domain and channel information to chip */
+	rlmDomainSendCmd(prAdapter, FALSE);
+	/* Update supported channel list in channel table */
+	wlanUpdateChannelTable(prAdapter->prGlueInfo);
+
+	/* 7. Set band edge tx power if available */
+	if (prRegInfo->fg2G4BandEdgePwrUsed) {
+		CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit;
+
+		rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK = prRegInfo->cBandEdgeMaxPwrCCK;
+		rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 = prRegInfo->cBandEdgeMaxPwrOFDM20;
+		rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 = prRegInfo->cBandEdgeMaxPwrOFDM40;
+
+		DBGLOG(INIT, TRACE, "NVRAM 2G Bandedge CCK(%d) HT20(%d)HT40(%d)\n",
+		       rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK,
+		       rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40);
+
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_EDGE_TXPWR_LIMIT,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL,
+				    NULL, sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0);
+	}
+	/* 8. set 5G band edge tx power if available (add for 6625) */
+	if (prAdapter->fgEnable5GBand) {
+#define NVRAM_5G_TX_BANDEDGE_VALID_OFFSET  10
+#define NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET 11
+#define NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET 12
+
+		if (prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_VALID_OFFSET]) {
+			CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit;
+
+			rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20
+			    = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET];
+			rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40
+			    = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET];
+
+			DBGLOG(INIT, TRACE, "NVRAM 5G Bandedge HT20(%d)HT40(%d)\n",
+			       rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40);
+
+			wlanSendSetQueryCmd(prAdapter,
+					    CMD_ID_SET_5G_EDGE_TXPWR_LIMIT,
+					    TRUE,
+					    FALSE,
+					    FALSE,
+					    NULL,
+					    NULL,
+					    sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0);
+		}
+	}
+	/* 9. set RSSI compensation */
+	/* DBGLOG(INIT, INFO, ("[frank] RSSI valid(%d) 2G(%d) 5G(%d)",
+		prRegInfo->fgRssiCompensationValidbit,
+		prRegInfo->uc2GRssiCompensation,
+		prRegInfo->uc5GRssiCompensation)); */
+	if (prRegInfo->fgRssiCompensationValidbit) {
+		CMD_RSSI_COMPENSATE_T rCmdRssiCompensate;
+
+		rCmdRssiCompensate.uc2GRssiCompensation = prRegInfo->uc2GRssiCompensation;
+		rCmdRssiCompensate.uc5GRssiCompensation = prRegInfo->uc5GRssiCompensation;
+
+		DBGLOG(INIT, LOUD, "NVRAM RSSI Comp. 2G(%d)5G(%d)\n",
+		       rCmdRssiCompensate.uc2GRssiCompensation, rCmdRssiCompensate.uc5GRssiCompensation);
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_RSSI_COMPENSATE,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL, NULL, sizeof(CMD_RSSI_COMPENSATE_T), (PUINT_8)&rCmdRssiCompensate, NULL, 0);
+	}
+	/* 10. notify FW Band Support 5G */
+	if (prAdapter->fgEnable5GBand) {
+		CMD_BAND_SUPPORT_T rCmdBandSupport;
+
+		rCmdBandSupport.uc5GBandSupport = TRUE;
+		DBGLOG(INIT, TRACE, "NVRAM 5G BandSupport\n");
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_BAND_SUPPORT,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL, NULL, sizeof(CMD_BAND_SUPPORT_T), (PUINT_8)&rCmdBandSupport, NULL, 0);
+
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to check
+*        Media Stream Mode is set to non-default value or not,
+*        and clear to default value if above criteria is met
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return TRUE
+*           The media stream mode was non-default value and has been reset
+*         FALSE
+*           The media stream mode is default value
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	if (prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode != 0) {
+		prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0;
+
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to check if any pending timer has expired
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	/* check timer status */
+	cnmTimerDoTimeOutCheck(prAdapter);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to check if any pending mailbox message
+*        to be handled
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) {	/* MBOX_ID_TOTAL_NUM = 1 */
+		mboxRcvAllMsg(prAdapter, (ENUM_MBOX_ID_T) i);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to enqueue a single TX packet into CORE
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*        prNativePacket Pointer of Native Packet
+*
+* @return WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_RESOURCES
+*         WLAN_STATUS_INVALID_PACKET
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket)
+{
+	P_TX_CTRL_T prTxCtrl;
+	P_MSDU_INFO_T prMsduInfo;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	/* get a free packet header */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+	QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+
+	if (prMsduInfo == NULL)
+		return WLAN_STATUS_RESOURCES;
+
+	prMsduInfo->eSrc = TX_PACKET_OS;
+
+	if (nicTxFillMsduInfo(prAdapter, prMsduInfo, prNativePacket) == FALSE) {
+		/* packet is not extractable */
+
+		/* fill fails */
+		kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_INVALID_PACKET);
+
+		nicTxReturnMsduInfo(prAdapter, prMsduInfo);
+
+		return WLAN_STATUS_INVALID_PACKET;
+	}
+	/* enqueue to QM */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to flush pending TX packets in CORE
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	return nicTxFlush(prAdapter);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief this function sends pending MSDU_INFO_T to MT6620
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param pfgHwAccess    Pointer for tracking LP-OWN status
+*
+* @retval WLAN_STATUS_SUCCESS   Reset is done successfully.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess)
+{
+	P_TX_CTRL_T prTxCtrl;
+	P_MSDU_INFO_T prMsduInfo;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	ASSERT(pfgHwAccess);
+
+	/* <1> dequeue packets by txDequeuTxPackets() */
+	/* Note: prMsduInfo is a packet list queue */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+	prMsduInfo = qmDequeueTxPackets(prAdapter, &prTxCtrl->rTc);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+
+	if (prMsduInfo != NULL) {
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) {
+			/* <2> Acquire LP-OWN if necessary */
+			if (*pfgHwAccess == FALSE) {
+				*pfgHwAccess = TRUE;
+
+				wlanAcquirePowerControl(prAdapter);
+			}
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+			if (prAdapter->fgIsClockGatingEnabled == TRUE)
+				nicDisableClockGating(prAdapter);
+#endif
+			/* <3> send packet"s" to HIF */
+			nicTxMsduInfoList(prAdapter, prMsduInfo);
+
+			/* <4> update TC by txAdjustTcQuotas() */
+			nicTxAdjustTcq(prAdapter);
+		} else
+			wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); /* free the packet */
+	}
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	if (prAdapter->fgIsClockGatingEnabled == FALSE)
+		nicEnableClockGating(prAdapter);
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to acquire power control from firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	/* do driver own */
+	ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
+
+	/* Reset sleepy state *//* no use */
+	if (prAdapter->fgWiFiInSleepyState == TRUE)
+		prAdapter->fgWiFiInSleepyState = FALSE;
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to release power control to firmware
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	/* do FW own */
+	RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to report currently pending TX frames count
+*        (command packets are not included)
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return number of pending TX frames
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter)
+{
+	P_TX_CTRL_T prTxCtrl;
+	UINT_32 u4Num;
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	/* number in prTxQueue + number in RX forward */
+	u4Num = kalGetTxPendingFrameCount(prAdapter->prGlueInfo) + (UINT_32) (prTxCtrl->i4PendingFwdFrameCount);
+
+	return u4Num;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to report current ACPI state
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return ACPI_STATE_D0 Normal Operation Mode
+*         ACPI_STATE_D3 Suspend Mode
+*/
+/*----------------------------------------------------------------------------*/
+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	return prAdapter->rAcpiState;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to update current ACPI state only
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param ePowerState    ACPI_STATE_D0 Normal Operation Mode
+*                       ACPI_STATE_D3 Suspend Mode
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState)
+{
+	ASSERT(prAdapter);
+	ASSERT(ePowerState <= ACPI_STATE_D3);
+
+	prAdapter->rAcpiState = ePowerState;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to query ECO version from HIFSYS CR
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return zero      Unable to retrieve ECO version information
+*         non-zero  ECO version (1-based)
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	if (nicVerifyChipID(prAdapter) == TRUE)
+		return prAdapter->ucRevID + 1;
+	else
+		return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to setting the default Tx Power configuration
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return zero      Unable to retrieve ECO version information
+*         non-zero  ECO version (1-based)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 i;
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+	P_SET_TXPWR_CTRL_T prTxpwr;
+
+	ASSERT(prGlueInfo);
+
+	prTxpwr = &prGlueInfo->rTxPwr;
+
+	prTxpwr->c2GLegacyStaPwrOffset = 0;
+	prTxpwr->c2GHotspotPwrOffset = 0;
+	prTxpwr->c2GP2pPwrOffset = 0;
+	prTxpwr->c2GBowPwrOffset = 0;
+	prTxpwr->c5GLegacyStaPwrOffset = 0;
+	prTxpwr->c5GHotspotPwrOffset = 0;
+	prTxpwr->c5GP2pPwrOffset = 0;
+	prTxpwr->c5GBowPwrOffset = 0;
+	prTxpwr->ucConcurrencePolicy = 0;
+	for (i = 0; i < 3; i++)
+		prTxpwr->acReserved1[i] = 0;
+
+	for (i = 0; i < 14; i++)
+		prTxpwr->acTxPwrLimit2G[i] = 63;
+
+	for (i = 0; i < 4; i++)
+		prTxpwr->acTxPwrLimit5G[i] = 63;
+
+	for (i = 0; i < 2; i++)
+		prTxpwr->acReserved2[i] = 0;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to
+*        set preferred band configuration corresponding to network type
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param eBand          Given band
+* @param eNetTypeIndex  Given Network Type
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	ASSERT(prAdapter);
+	ASSERT(eBand <= BAND_NUM);
+	ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
+
+	/* 1. set prefer band according to network type */
+	prAdapter->aePreferBand[eNetTypeIndex] = eBand;
+
+	/* 2. remove buffered BSS descriptors correspondingly */
+	if (eBand == BAND_2G4)
+		scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_5G, eNetTypeIndex);
+	else if (eBand == BAND_5G)
+		scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_2G4, eNetTypeIndex);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to
+*        get channel information corresponding to specified network type
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param eNetTypeIndex  Given Network Type
+*
+* @return channel number
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+	return prBssInfo->ucPrimaryChannel;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to
+*        get BSS descriptor information corresponding to specified network type
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+* @param eNetTypeIndex  Given Network Type
+*
+* @return pointer to BSS_DESC_T
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	ASSERT(prAdapter);
+	ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
+
+	switch (eNetTypeIndex) {
+	case NETWORK_TYPE_AIS_INDEX:
+		return prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc;
+
+	case NETWORK_TYPE_P2P_INDEX:
+		return NULL;
+
+	case NETWORK_TYPE_BOW_INDEX:
+		return prAdapter->rWifiVar.rBowFsmInfo.prTargetBssDesc;
+
+	default:
+		return NULL;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to
+*        check unconfigured system properties and generate related message on
+*        scan list to notify users
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter)
+{
+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1)
+	const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR;
+	const UINT_8 aucBCAddr[] = BC_MAC_ADDR;
+	BOOLEAN fgIsConfExist = TRUE;
+	BOOLEAN fgGenErrMsg = FALSE;
+	P_REG_INFO_T prRegInfo = NULL;
+	P_WLAN_BEACON_FRAME_T prBeacon = NULL;
+	P_IE_SSID_T prSsid = NULL;
+	UINT_32 u4ErrCode = 0;
+	UINT_8 aucErrMsg[32];
+	PARAM_SSID_T rSsid;
+	PARAM_802_11_CONFIG_T rConfiguration;
+	PARAM_RATES_EX rSupportedRates;
+#endif
+
+	DEBUGFUNC("wlanCheckSystemConfiguration");
+
+	ASSERT(prAdapter);
+
+#if (CFG_NVRAM_EXISTENCE_CHECK == 1)
+	if (kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) {
+		fgIsConfExist = FALSE;
+		fgGenErrMsg = TRUE;
+	}
+#endif
+
+#if (CFG_SW_NVRAM_VERSION_CHECK == 1)
+	prRegInfo = kalGetConfiguration(prAdapter->prGlueInfo);
+
+	if (fgIsConfExist == TRUE && (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion
+					|| CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion
+					|| prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION
+					|| prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */
+					|| CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion
+					|| prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+					|| prAdapter->fgIsPowerLimitTableValid == FALSE
+#endif
+					|| (prAdapter->fgIsEmbbededMacAddrValid == FALSE &&
+					  (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr)
+					   || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr)))
+					|| prRegInfo->ucTxPwrValid == 0))
+		fgGenErrMsg = TRUE;
+#endif
+
+	if (fgGenErrMsg == TRUE) {
+		prBeacon = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T));
+		if (!prBeacon) {
+			ASSERT(FALSE);
+			return WLAN_STATUS_FAILURE;
+		}
+
+		/* initialization */
+		kalMemZero(prBeacon, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T));
+
+		/* prBeacon initialization */
+		prBeacon->u2FrameCtrl = MAC_FRAME_BEACON;
+		COPY_MAC_ADDR(prBeacon->aucDestAddr, aucBCAddr);
+		COPY_MAC_ADDR(prBeacon->aucSrcAddr, aucZeroMacAddr);
+		COPY_MAC_ADDR(prBeacon->aucBSSID, aucZeroMacAddr);
+		prBeacon->u2BeaconInterval = 100;
+		prBeacon->u2CapInfo = CAP_INFO_ESS;
+
+		/* prSSID initialization */
+		prSsid = (P_IE_SSID_T) (&prBeacon->aucInfoElem[0]);
+		prSsid->ucId = ELEM_ID_SSID;
+
+		/* rConfiguration initialization */
+		rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T);
+		rConfiguration.u4BeaconPeriod = 100;
+		rConfiguration.u4ATIMWindow = 1;
+		rConfiguration.u4DSConfig = 2412;
+		rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
+
+		/* rSupportedRates initialization */
+		kalMemZero(rSupportedRates, sizeof(PARAM_RATES_EX));
+	}
+#if (CFG_NVRAM_EXISTENCE_CHECK == 1)
+#define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01"
+	if ((kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) && (prBeacon) && (prSsid)) {
+		COPY_SSID(prSsid->aucSSID, prSsid->ucLength, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG));
+
+		kalIndicateBssInfo(prAdapter->prGlueInfo,
+				   (PUINT_8) prBeacon,
+				   OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T,
+											   aucSSID) + prSsid->ucLength,
+				   1, 0);
+		COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG));
+		nicAddScanResult(prAdapter,
+				 prBeacon->aucBSSID,
+				 &rSsid,
+				 0,
+				 0,
+				 PARAM_NETWORK_TYPE_FH,
+				 &rConfiguration,
+				 NET_TYPE_INFRA,
+				 rSupportedRates,
+				 OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T,
+											 aucSSID) + prSsid->ucLength -
+				 WLAN_MAC_MGMT_HEADER_LEN, (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN));
+	}
+#endif
+
+#if (CFG_SW_NVRAM_VERSION_CHECK == 1)
+#define VER_ERR_MSG     "NVRAM WARNING: Err = 0x%02X"
+	if ((fgIsConfExist == TRUE) && (prBeacon) && (prSsid)) {
+		if ((CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion
+			|| CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion
+			|| prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION
+			|| prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION	/* NVRAM */
+			|| CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion
+			|| prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION))
+			u4ErrCode |= NVRAM_ERROR_VERSION_MISMATCH;
+
+		if (prRegInfo->ucTxPwrValid == 0)
+			u4ErrCode |= NVRAM_ERROR_INVALID_TXPWR;
+
+		if (prAdapter->fgIsEmbbededMacAddrValid == FALSE && (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr)
+								     || EQUAL_MAC_ADDR(aucZeroMacAddr,
+										       prRegInfo->aucMacAddr)))
+			u4ErrCode |= NVRAM_ERROR_INVALID_MAC_ADDR;
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+		if (prAdapter->fgIsPowerLimitTableValid == FALSE)
+			u4ErrCode |= NVRAM_POWER_LIMIT_TABLE_INVALID;
+#endif
+		if (u4ErrCode != 0) {
+			sprintf(aucErrMsg, VER_ERR_MSG, (unsigned int)u4ErrCode);
+			COPY_SSID(prSsid->aucSSID, prSsid->ucLength, aucErrMsg, strlen(aucErrMsg));
+
+			kalIndicateBssInfo(prAdapter->prGlueInfo,
+					   (PUINT_8) prBeacon,
+					   OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T,
+												   aucSSID) +
+					   prSsid->ucLength, 1, 0);
+
+			COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG));
+			nicAddScanResult(prAdapter,
+					 prBeacon->aucBSSID,
+					 &rSsid,
+					 0,
+					 0,
+					 PARAM_NETWORK_TYPE_FH,
+					 &rConfiguration,
+					 NET_TYPE_INFRA,
+					 rSupportedRates,
+					 OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T,
+												 aucSSID) +
+					 prSsid->ucLength - WLAN_MAC_MGMT_HEADER_LEN,
+					 (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN));
+		}
+	}
+#endif
+
+	if (fgGenErrMsg == TRUE)
+		cnmMemFree(prAdapter, prBeacon);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+WLAN_STATUS
+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rResult = WLAN_STATUS_FAILURE;
+	P_STA_RECORD_T prStaRec, prTempStaRec;
+	P_PARAM_GET_STA_STATISTICS prQueryStaStatistics;
+	UINT_8 ucStaRecIdx;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+	CMD_GET_STA_STATISTICS_T rQueryCmdStaStatistics;
+	UINT_8 ucIdx;
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+
+	do {
+		ASSERT(pvQueryBuffer);
+
+		/* 4 1. Sanity test */
+		if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL))
+			break;
+
+		if ((u4QueryBufferLen) && (pvQueryBuffer == NULL))
+			break;
+
+		if (u4QueryBufferLen < sizeof(PARAM_GET_STA_STA_STATISTICS)) {
+			*pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS);
+			rResult = WLAN_STATUS_BUFFER_TOO_SHORT;
+			break;
+		}
+
+		prQueryStaStatistics = (P_PARAM_GET_STA_STATISTICS) pvQueryBuffer;
+		*pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS);
+
+		/* 4 5. Get driver global QM counter */
+		for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) {
+			prQueryStaStatistics->au4TcAverageQueLen[ucIdx] = prQM->au4AverageQueLen[ucIdx];
+			prQueryStaStatistics->au4TcCurrentQueLen[ucIdx] = prQM->au4CurrentTcResource[ucIdx];
+		}
+
+		/* 4 2. Get StaRec by MAC address */
+		prStaRec = NULL;
+
+		for (ucStaRecIdx = 0; ucStaRecIdx < CFG_NUM_OF_STA_RECORD; ucStaRecIdx++) {
+			prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]);
+			if (prTempStaRec->fgIsValid && prTempStaRec->fgIsInUse) {
+				if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prQueryStaStatistics->aucMacAddr)) {
+					prStaRec = prTempStaRec;
+					break;
+				}
+			}
+		}
+
+		if (!prStaRec) {
+			rResult = WLAN_STATUS_INVALID_DATA;
+			break;
+		}
+
+		prQueryStaStatistics->u4Flag |= BIT(0);
+
+#if CFG_ENABLE_PER_STA_STATISTICS
+		/* 4 3. Get driver statistics */
+		DBGLOG(TX, INFO, "skbToDriver %lld, skbFreed: %lld\n",
+			prAdapter->prGlueInfo->u8SkbToDriver,
+			prAdapter->prGlueInfo->u8SkbFreed);
+		prAdapter->prGlueInfo->u8SkbFreed = 0;
+		prAdapter->prGlueInfo->u8SkbToDriver = 0;
+
+		prQueryStaStatistics->u4TxTotalCount = prStaRec->u4TotalTxPktsNumber;
+		prQueryStaStatistics->u4TxExceedThresholdCount = prStaRec->u4ThresholdCounter;
+		prQueryStaStatistics->u4TxMaxTime = prStaRec->u4MaxTxPktsTime;
+		prQueryStaStatistics->u4TxMaxHifTime = prStaRec->u4MaxTxPktsHifTime;
+		if (prStaRec->u4TotalTxPktsNumber) {
+			prQueryStaStatistics->u4TxAverageProcessTime =
+			    (prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber);
+			prQueryStaStatistics->u4TxAverageHifTime =
+			    (prStaRec->u4TotalTxPktsHifTime / prStaRec->u4TotalTxPktsNumber);
+		} else
+			prQueryStaStatistics->u4TxAverageProcessTime = 0;
+
+		for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) {
+			prQueryStaStatistics->au4TcResourceEmptyCount[ucIdx] =
+			    prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx];
+			/* Reset */
+			prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx] = 0;
+			prQueryStaStatistics->au4TcResourceBackCount[ucIdx] =
+				prQM->au4QmTcResourceBackCounter[ucIdx];
+			prQM->au4QmTcResourceBackCounter[ucIdx] = 0;
+
+			prQueryStaStatistics->au4DequeueNoTcResource[ucIdx] =
+				prQM->au4DequeueNoTcResourceCounter[ucIdx];
+			prQM->au4DequeueNoTcResourceCounter[ucIdx] = 0;
+			prQueryStaStatistics->au4TcResourceUsedCount[ucIdx] =
+				prQM->au4ResourceUsedCounter[ucIdx];
+			prQM->au4ResourceUsedCounter[ucIdx] = 0;
+			prQueryStaStatistics->au4TcResourceWantedCount[ucIdx] =
+				prQM->au4ResourceWantedCounter[ucIdx];
+			prQM->au4ResourceWantedCounter[ucIdx] = 0;
+		}
+
+		prQueryStaStatistics->u4EnqueueCounter = prQM->u4EnqeueuCounter;
+		prQueryStaStatistics->u4DequeueCounter = prQM->u4DequeueCounter;
+		prQueryStaStatistics->u4EnqueueStaCounter = prStaRec->u4EnqeueuCounter;
+		prQueryStaStatistics->u4DequeueStaCounter = prStaRec->u4DeqeueuCounter;
+
+		prQueryStaStatistics->IsrCnt = prGlueInfo->IsrCnt - prGlueInfo->IsrPreCnt;
+		prQueryStaStatistics->IsrPassCnt = prGlueInfo->IsrPassCnt - prGlueInfo->IsrPrePassCnt;
+		prQueryStaStatistics->TaskIsrCnt = prGlueInfo->TaskIsrCnt - prGlueInfo->TaskPreIsrCnt;
+
+		prQueryStaStatistics->IsrAbnormalCnt = prGlueInfo->IsrAbnormalCnt;
+		prQueryStaStatistics->IsrSoftWareCnt = prGlueInfo->IsrSoftWareCnt;
+		prQueryStaStatistics->IsrRxCnt = prGlueInfo->IsrRxCnt;
+		prQueryStaStatistics->IsrTxCnt = prGlueInfo->IsrTxCnt;
+
+		/* 4 4.1 Reset statistics */
+		prStaRec->u4ThresholdCounter = 0;
+		prStaRec->u4TotalTxPktsNumber = 0;
+		prStaRec->u4TotalTxPktsTime = 0;
+		prStaRec->u4MaxTxPktsTime = 0;
+		prStaRec->u4MaxTxPktsHifTime = 0;
+
+		prStaRec->u4EnqeueuCounter = 0;
+		prStaRec->u4DeqeueuCounter = 0;
+
+		prQM->u4EnqeueuCounter = 0;
+		prQM->u4DequeueCounter = 0;
+
+		prGlueInfo->IsrPreCnt = prGlueInfo->IsrCnt;
+		prGlueInfo->IsrPrePassCnt = prGlueInfo->IsrPassCnt;
+		prGlueInfo->TaskPreIsrCnt = prGlueInfo->TaskIsrCnt;
+		prGlueInfo->IsrAbnormalCnt = 0;
+		prGlueInfo->IsrSoftWareCnt = 0;
+		prGlueInfo->IsrRxCnt = 0;
+		prGlueInfo->IsrTxCnt = 0;
+#endif
+
+		for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++)
+			prQueryStaStatistics->au4TcQueLen[ucIdx] = prStaRec->arTxQueue[ucIdx].u4NumElem;
+
+		rResult = WLAN_STATUS_SUCCESS;
+
+		/* 4 6. Ensure FW supports get station link status */
+		if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) {
+
+			rQueryCmdStaStatistics.ucIndex = prStaRec->ucIndex;
+			COPY_MAC_ADDR(rQueryCmdStaStatistics.aucMacAddr, prQueryStaStatistics->aucMacAddr);
+			rQueryCmdStaStatistics.ucReadClear = TRUE;
+
+			rResult = wlanSendSetQueryCmd(prAdapter,
+						      CMD_ID_GET_STA_STATISTICS,
+						      FALSE,
+						      TRUE,
+						      TRUE,
+						      nicCmdEventQueryStaStatistics,
+						      nicOidCmdTimeoutCommon,
+						      sizeof(CMD_GET_STA_STATISTICS_T),
+						      (PUINT_8)&rQueryCmdStaStatistics,
+						      pvQueryBuffer, u4QueryBufferLen);
+
+			prQueryStaStatistics->u4Flag |= BIT(1);
+		} else {
+			rResult = WLAN_STATUS_NOT_SUPPORTED;
+		}
+
+	} while (FALSE);
+
+	return rResult;
+}				/* wlanoidQueryP2pVersion */
+
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+
+/* 4   Auto Channel Selection */
+WLAN_STATUS
+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rResult = WLAN_STATUS_FAILURE;
+	/* P_PARAM_GET_CHN_LOAD prQueryChnLoad; */
+	P_PARAM_GET_LTE_MODE prLteMode;
+	CMD_GET_LTE_SAFE_CHN_T rQuery_LTE_SAFE_CHN;
+
+	DBGLOG(P2P, INFO, "[Auto Channel]wlanoidQueryACSChannelList\n");
+	do {
+		ASSERT(pvQueryBuffer);
+
+		/* 4 1. Sanity test */
+		if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL))
+			break;
+
+		if ((u4QueryBufferLen) && (pvQueryBuffer == NULL))
+			break;
+
+		prLteMode = (P_PARAM_GET_LTE_MODE) pvQueryBuffer;
+
+		/* 4 3. Ensure FW supports get station link status */
+#if 0
+		if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) {
+			CMD_ACCESS_REG rCmdAccessReg;
+
+			rCmdAccessReg.u4Address = 0xFFFFFFFF;
+			rCmdAccessReg.u4Data = ELEM_RM_TYPE_ACS_CHN;
+
+			rResult = wlanSendSetQueryCmd(prAdapter,
+							CMD_ID_ACCESS_REG,
+							TRUE,
+							TRUE,
+							TRUE,
+							/* The handler to receive firmware notification */
+							nicCmdEventQueryChannelLoad,
+							nicOidCmdTimeoutCommon,
+							sizeof(CMD_ACCESS_REG),
+							(PUINT_8)&rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen);
+
+			prQueryChnLoad->u4Flag |= BIT(1);
+		} else {
+			rResult = WLAN_STATUS_NOT_SUPPORTED;
+		}
+#endif
+		/* 4 4.Avoid LTE Channels */
+		prLteMode->u4Flags &= BIT(0);
+		/*if(prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) */  {
+
+			rResult = wlanSendSetQueryCmd(prAdapter,
+							CMD_ID_GET_LTE_CHN,
+							FALSE,
+							TRUE,
+							/* Query ID */
+							TRUE,
+							/* The handler to receive firmware notification */
+							nicCmdEventQueryLTESafeChn,
+							nicOidCmdTimeoutCommon,
+							sizeof(CMD_GET_LTE_SAFE_CHN_T),
+							(PUINT_8)&rQuery_LTE_SAFE_CHN,
+							pvQueryBuffer, u4QueryBufferLen);
+
+			DBGLOG(P2P, INFO, "[Auto Channel] Get LTE Channels\n");
+			prLteMode->u4Flags |= BIT(1);
+		}
+
+		/* 4 5. Calc the value */
+
+		DBGLOG(P2P, INFO, "[Auto Channel] Candidated Channels\n");
+	} while (FALSE);
+
+	return rResult;
+}				/* wlanoidQueryP2pVersion */
+#endif
+#if CFG_SUPPORT_CFG_FILE
+
+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey)
+{
+
+	P_WLAN_CFG_ENTRY_T prWlanCfgEntry;
+	P_WLAN_CFG_T prWlanCfg;
+	UINT_32 i;
+
+	prWlanCfg = prAdapter->prWlanCfg;
+
+	ASSERT(prWlanCfg);
+	ASSERT(pucKey);
+
+	prWlanCfgEntry = NULL;
+
+	for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) {
+		prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i];
+		if (prWlanCfgEntry->aucKey[0] != '\0') {
+			DBGLOG(INIT, LOUD, "compare key %s saved key %s\n", pucKey, prWlanCfgEntry->aucKey);
+			if (kalStrniCmp(pucKey, prWlanCfgEntry->aucKey, WLAN_CFG_KEY_LEN_MAX - 1) == 0)
+				return prWlanCfgEntry;
+		}
+	}
+
+	DBGLOG(INIT, LOUD, "wifi config there is no entry \'%s\'\n", pucKey);
+	return NULL;
+
+}
+
+WLAN_STATUS wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags)
+{
+
+	P_WLAN_CFG_ENTRY_T prWlanCfgEntry;
+	P_WLAN_CFG_T prWlanCfg;
+
+	prWlanCfg = prAdapter->prWlanCfg;
+
+	ASSERT(prWlanCfg);
+	ASSERT(pucValue);
+
+	/* Find the exist */
+	prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey);
+
+	if (prWlanCfgEntry) {
+		kalStrnCpy(pucValue, prWlanCfgEntry->aucValue, WLAN_CFG_VALUE_LEN_MAX - 1);
+		return WLAN_STATUS_SUCCESS;
+	}
+	if (pucValueDef)
+		kalStrnCpy(pucValue, pucValueDef, WLAN_CFG_VALUE_LEN_MAX - 1);
+	return WLAN_STATUS_FAILURE;
+
+}
+
+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef)
+{
+	P_WLAN_CFG_ENTRY_T prWlanCfgEntry;
+	P_WLAN_CFG_T prWlanCfg;
+	UINT_32 u4Value;
+	INT_32 u4Ret;
+
+	prWlanCfg = prAdapter->prWlanCfg;
+
+	ASSERT(prWlanCfg);
+
+	u4Value = u4ValueDef;
+	/* Find the exist */
+	prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey);
+
+	if (prWlanCfgEntry) {
+		u4Ret = kalkStrtou32(prWlanCfgEntry->aucValue, 0, &u4Value);
+		if (u4Ret)
+			DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue u4Ret=%u\n", u4Ret);
+		/* u4Value = kalStrtoul(prWlanCfgEntry->aucValue, NULL, 0); */
+	}
+
+	return u4Value;
+}
+
+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef)
+{
+	P_WLAN_CFG_ENTRY_T prWlanCfgEntry;
+	P_WLAN_CFG_T prWlanCfg;
+	INT_32 i4Value;
+	INT_32 i4Ret;
+
+	prWlanCfg = prAdapter->prWlanCfg;
+
+	ASSERT(prWlanCfg);
+
+	i4Value = i4ValueDef;
+	/* Find the exist */
+	prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey);
+
+	if (prWlanCfgEntry) {
+		i4Ret = kalkStrtos32(prWlanCfgEntry->aucValue, 0, &i4Value);
+		/* i4Ret = kalStrtol(prWlanCfgEntry->aucValue, NULL, 0); */
+		if (i4Ret)
+			DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue i4Ret=%u\n\r", i4Ret);
+	}
+
+	return i4Value;
+}
+
+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags)
+{
+
+	P_WLAN_CFG_ENTRY_T prWlanCfgEntry;
+	P_WLAN_CFG_T prWlanCfg;
+	UINT_32 u4EntryIndex;
+	UINT_32 i;
+	UINT_8 ucExist;
+
+	prWlanCfg = prAdapter->prWlanCfg;
+	ASSERT(prWlanCfg);
+	ASSERT(pucKey);
+
+	/* Find the exist */
+	ucExist = 0;
+	prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey);
+
+	if (!prWlanCfgEntry) {
+		/* Find the empty */
+		for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) {
+			prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i];
+			if (prWlanCfgEntry->aucKey[0] == '\0')
+				break;
+		}
+
+		u4EntryIndex = i;
+		if (u4EntryIndex < WLAN_CFG_ENTRY_NUM_MAX) {
+			prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[u4EntryIndex];
+			kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T));
+		} else {
+			prWlanCfgEntry = NULL;
+			DBGLOG(INIT, ERROR, "wifi config there is no empty entry\n");
+		}
+	} /* !prWlanCfgEntry */
+	else
+		ucExist = 1;
+
+	if (prWlanCfgEntry) {
+		if (ucExist == 0) {
+			kalStrnCpy(prWlanCfgEntry->aucKey, pucKey, WLAN_CFG_KEY_LEN_MAX - 1);
+			prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0';
+		}
+
+		if (pucValue && pucValue[0] != '\0') {
+			kalStrnCpy(prWlanCfgEntry->aucValue, pucValue, WLAN_CFG_VALUE_LEN_MAX - 1);
+			prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = '\0';
+
+			if (ucExist) {
+				if (prWlanCfgEntry->pfSetCb)
+					prWlanCfgEntry->pfSetCb(prAdapter,
+								prWlanCfgEntry->aucKey,
+								prWlanCfgEntry->aucValue, prWlanCfgEntry->pPrivate, 0);
+			}
+		} else {
+			/* Call the pfSetCb if value is empty ? */
+			/* remove the entry if value is empty */
+			kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T));
+		}
+
+	}
+	/* prWlanCfgEntry */
+	if (prWlanCfgEntry) {
+		DBGLOG(INIT, LOUD, "Set wifi config exist %u \'%s\' \'%s\'\n",
+				    ucExist, prWlanCfgEntry->aucKey, prWlanCfgEntry->aucValue);
+		return WLAN_STATUS_SUCCESS;
+	}
+	if (pucKey)
+		DBGLOG(INIT, ERROR, "Set wifi config error key \'%s\'\n", pucKey);
+	if (pucValue)
+		DBGLOG(INIT, ERROR, "Set wifi config error value \'%s\'\n", pucValue);
+	return WLAN_STATUS_FAILURE;
+
+}
+
+WLAN_STATUS
+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags)
+{
+
+	P_WLAN_CFG_ENTRY_T prWlanCfgEntry;
+	P_WLAN_CFG_T prWlanCfg;
+
+	prWlanCfg = prAdapter->prWlanCfg;
+	ASSERT(prWlanCfg);
+
+	/* Find the exist */
+	prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey);
+
+	if (prWlanCfgEntry) {
+		prWlanCfgEntry->pfSetCb = pfSetCb;
+		prWlanCfgEntry->pPrivate = pPrivate;
+	}
+
+	if (prWlanCfgEntry)
+		return WLAN_STATUS_SUCCESS;
+	else
+		return WLAN_STATUS_FAILURE;
+
+}
+
+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value)
+{
+
+	P_WLAN_CFG_T prWlanCfg;
+	UINT_8 aucBuf[WLAN_CFG_VALUE_LEN_MAX];
+
+	prWlanCfg = prAdapter->prWlanCfg;
+
+	ASSERT(prWlanCfg);
+
+	kalMemZero(aucBuf, sizeof(aucBuf));
+
+	kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", (unsigned int)u4Value);
+
+	return wlanCfgSet(prAdapter, pucKey, aucBuf, 0);
+}
+
+enum {
+	STATE_EOF = 0,
+	STATE_TEXT = 1,
+	STATE_NEWLINE = 2
+};
+
+struct WLAN_CFG_PARSE_STATE_S {
+	CHAR *ptr;
+	CHAR *text;
+	INT_32 nexttoken;
+	UINT_32 maxSize;
+};
+
+INT_32 wlanCfgFindNextToken(struct WLAN_CFG_PARSE_STATE_S *state)
+{
+	CHAR *x = state->ptr;
+	CHAR *s;
+
+	if (state->nexttoken) {
+		INT_32 t = state->nexttoken;
+
+		state->nexttoken = 0;
+		return t;
+	}
+
+	for (;;) {
+		switch (*x) {
+		case 0:
+			state->ptr = x;
+			return STATE_EOF;
+		case '\n':
+			x++;
+			state->ptr = x;
+			return STATE_NEWLINE;
+		case ' ':
+		case '\t':
+		case '\r':
+			x++;
+			continue;
+		case '#':
+			while (*x && (*x != '\n'))
+				x++;
+			if (*x == '\n') {
+				state->ptr = x + 1;
+				return STATE_NEWLINE;
+			}
+			state->ptr = x;
+			return STATE_EOF;
+		default:
+			goto text;
+		}
+	}
+
+textdone:
+	state->ptr = x;
+	*s = 0;
+	return STATE_TEXT;
+text:
+	state->text = s = x;
+textresume:
+	for (;;) {
+		switch (*x) {
+		case 0:
+			goto textdone;
+		case ' ':
+		case '\t':
+		case '\r':
+			x++;
+			goto textdone;
+		case '\n':
+			state->nexttoken = STATE_NEWLINE;
+			x++;
+			goto textdone;
+		case '"':
+			x++;
+			for (;;) {
+				switch (*x) {
+				case 0:
+					/* unterminated quoted thing */
+					state->ptr = x;
+					return STATE_EOF;
+				case '"':
+					x++;
+					goto textresume;
+				default:
+					*s++ = *x++;
+				}
+			}
+			break;
+		case '\\':
+			x++;
+			switch (*x) {
+			case 0:
+				goto textdone;
+			case 'n':
+				*s++ = '\n';
+				break;
+			case 'r':
+				*s++ = '\r';
+				break;
+			case 't':
+				*s++ = '\t';
+				break;
+			case '\\':
+				*s++ = '\\';
+				break;
+			case '\r':
+				/* \ <cr> <lf> -> line continuation */
+				if (x[1] != '\n') {
+					x++;
+					continue;
+				}
+			case '\n':
+				/* \ <lf> -> line continuation */
+				x++;
+				/* eat any extra whitespace */
+				while ((*x == ' ') || (*x == '\t'))
+					x++;
+				continue;
+			default:
+				/* unknown escape -- just copy */
+				*s++ = *x++;
+			}
+			continue;
+		default:
+			*s++ = *x++;
+		}
+	}
+	return STATE_EOF;
+}
+
+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[])
+{
+	struct WLAN_CFG_PARSE_STATE_S state;
+	CHAR **args;
+	INT_32 nargs;
+
+	if (cmdLine == NULL || argc == NULL || argv == NULL) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+	args = argv;
+	nargs = 0;
+	state.ptr = cmdLine;
+	state.nexttoken = 0;
+	state.maxSize = 0;
+
+	if (kalStrnLen(cmdLine, 512) >= 512) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	for (;;) {
+		switch (wlanCfgFindNextToken(&state)) {
+		case STATE_EOF:
+			goto exit;
+		case STATE_NEWLINE:
+			goto exit;
+		case STATE_TEXT:
+			if (nargs < WLAN_CFG_ARGV_MAX)
+				args[nargs++] = state.text;
+			break;
+		}
+	}
+
+exit:
+	*argc = nargs;
+	return WLAN_STATUS_SUCCESS;
+}
+
+WLAN_STATUS
+wlanCfgParseAddEntry(IN P_ADAPTER_T prAdapter,
+		     PUINT_8 pucKeyHead, PUINT_8 pucKeyTail, PUINT_8 pucValueHead, PUINT_8 pucValueTail)
+{
+
+	UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX];
+	UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX];
+	UINT_32 u4Len;
+
+	kalMemZero(aucKey, sizeof(aucKey));
+	kalMemZero(aucValue, sizeof(aucValue));
+
+	if ((pucKeyHead == NULL)
+	    || (pucValueHead == NULL)
+	    )
+		return WLAN_STATUS_FAILURE;
+
+	if (pucKeyTail) {
+		if (pucKeyHead > pucKeyTail)
+			return WLAN_STATUS_FAILURE;
+		u4Len = pucKeyTail - pucKeyHead + 1;
+	} else
+		u4Len = kalStrnLen(pucKeyHead, WLAN_CFG_KEY_LEN_MAX - 1);
+
+	if (u4Len >= WLAN_CFG_KEY_LEN_MAX)
+		u4Len = WLAN_CFG_KEY_LEN_MAX - 1;
+
+	if (u4Len < WLAN_CFG_VALUE_LEN_MAX)
+		kalStrnCpy(aucKey, pucKeyHead, u4Len);
+	else
+		DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len);
+
+	if (pucValueTail) {
+		if (pucValueHead > pucValueTail)
+			return WLAN_STATUS_FAILURE;
+		u4Len = pucValueTail - pucValueHead + 1;
+	} else
+		u4Len = kalStrnLen(pucValueHead, WLAN_CFG_VALUE_LEN_MAX - 1);
+
+	if (u4Len >= WLAN_CFG_VALUE_LEN_MAX)
+		u4Len = WLAN_CFG_VALUE_LEN_MAX - 1;
+
+	if (u4Len < WLAN_CFG_VALUE_LEN_MAX)
+		kalStrnCpy(aucValue, pucValueHead, u4Len);
+	else
+		DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len);
+
+	return wlanCfgSet(prAdapter, aucKey, aucValue, 0);
+}
+
+enum {
+	WAIT_KEY_HEAD = 0,
+	WAIT_KEY_TAIL,
+	WAIT_VALUE_HEAD,
+	WAIT_VALUE_TAIL,
+	WAIT_COMMENT_TAIL
+};
+
+WLAN_STATUS wlanCfgParse(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen)
+{
+
+	struct WLAN_CFG_PARSE_STATE_S state;
+	PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
+	CHAR **args;
+	INT_32 nargs;
+
+	if (pucConfigBuf == NULL) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+	if (kalStrnLen(pucConfigBuf, 4000) >= 4000) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+	if (u4ConfigBufLen == 0)
+		return WLAN_STATUS_FAILURE;
+	args = apcArgv;
+	nargs = 0;
+	state.ptr = pucConfigBuf;
+	state.nexttoken = 0;
+	state.maxSize = u4ConfigBufLen;
+
+	for (;;) {
+		switch (wlanCfgFindNextToken(&state)) {
+		case STATE_EOF:
+			if (nargs > 1)
+				wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL);
+			goto exit;
+		case STATE_NEWLINE:
+			if (nargs > 1)
+				wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL);
+			nargs = 0;
+			break;
+		case STATE_TEXT:
+			if (nargs < WLAN_CFG_ARGV_MAX)
+				args[nargs++] = state.text;
+			break;
+		}
+	}
+
+exit:
+	return WLAN_STATUS_SUCCESS;
+
+#if 0
+	/* Old version */
+	UINT_32 i;
+	UINT_8 c;
+	PUINT_8 pbuf;
+	UINT_8 ucState;
+	PUINT_8 pucKeyTail = NULL;
+	PUINT_8 pucKeyHead = NULL;
+	PUINT_8 pucValueHead = NULL;
+	PUINT_8 pucValueTail = NULL;
+
+	ucState = WAIT_KEY_HEAD;
+	pbuf = pucConfigBuf;
+
+	for (i = 0; i < u4ConfigBufLen; i++) {
+		c = pbuf[i];
+		if (c == '\r' || c == '\n') {
+
+			if (ucState == WAIT_VALUE_TAIL) {
+				/* Entry found */
+				if (pucValueHead)
+					wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail,
+							     pucValueHead, pucValueTail);
+			}
+			ucState = WAIT_KEY_HEAD;
+			pucKeyTail = NULL;
+			pucKeyHead = NULL;
+			pucValueHead = NULL;
+			pucValueTail = NULL;
+
+		} else if (c == '=') {
+			if (ucState == WAIT_KEY_TAIL) {
+				pucKeyTail = &pbuf[i - 1];
+				ucState = WAIT_VALUE_HEAD;
+			}
+		} else if (c == ' ' || c == '\t') {
+			if (ucState == WAIT_KEY_HEAD)
+				;
+			else if (ucState == WAIT_KEY_TAIL) {
+				pucKeyTail = &pbuf[i - 1];
+				ucState = WAIT_VALUE_HEAD;
+			}
+		} else {
+
+			if (c == '#') {
+				/* comments */
+				if (ucState == WAIT_KEY_HEAD)
+					ucState = WAIT_COMMENT_TAIL;
+				else if (ucState == WAIT_VALUE_TAIL)
+					pucValueTail = &pbuf[i];
+
+			} else {
+				if (ucState == WAIT_KEY_HEAD) {
+					pucKeyHead = &pbuf[i];
+					pucKeyTail = &pbuf[i];
+					ucState = WAIT_KEY_TAIL;
+				} else if (ucState == WAIT_VALUE_HEAD) {
+					pucValueHead = &pbuf[i];
+					pucValueTail = &pbuf[i];
+					ucState = WAIT_VALUE_TAIL;
+				} else if (ucState == WAIT_VALUE_TAIL)
+					pucValueTail = &pbuf[i];
+			}
+		}
+
+	}			/* for */
+
+	if (ucState == WAIT_VALUE_TAIL) {
+		/* Entry found */
+		if (pucValueTail)
+			wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, pucValueHead, pucValueTail);
+	}
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}
+#endif
+
+#if CFG_SUPPORT_CFG_FILE
+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags)
+{
+	P_WLAN_CFG_T prWlanCfg;
+	/* P_WLAN_CFG_ENTRY_T prWlanCfgEntry; */
+	prAdapter->prWlanCfg = &prAdapter->rWlanCfg;
+	prWlanCfg = prAdapter->prWlanCfg;
+
+	kalMemZero(prWlanCfg, sizeof(WLAN_CFG_T));
+	ASSERT(prWlanCfg);
+	prWlanCfg->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX;
+	prWlanCfg->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX;
+	prWlanCfg->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX;
+#if 0
+	DBGLOG(INIT, INFO, "Init wifi config len %u max entry %u\n", u4ConfigBufLen, prWlanCfg->u4WlanCfgEntryNumMax);
+#endif
+	/* self test */
+	wlanCfgSet(prAdapter, "ConfigValid", "0x123", 0);
+	if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 0x123)
+		DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__);
+	wlanCfgSet(prAdapter, "ConfigValid", "1", 0);
+	if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 1)
+		DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__);
+#if 0				/* soc chip didn't support these parameters now */
+	/* Add initil config */
+	/* use g,wlan,p2p,ap as prefix */
+	/* Don't set cb here , overwrite by another api */
+	wlanCfgSet(prAdapter, "TxLdpc", "1", 0);
+	wlanCfgSet(prAdapter, "RxLdpc", "1", 0);
+	wlanCfgSet(prAdapter, "RxBeamformee", "1", 0);
+	wlanCfgSet(prAdapter, "RoamTh1", "100", 0);
+	wlanCfgSet(prAdapter, "RoamTh2", "150", 0);
+	wlanCfgSet(prAdapter, "wlanRxLdpc", "1", 0);
+	wlanCfgSet(prAdapter, "apRxLdpc", "1", 0);
+	wlanCfgSet(prAdapter, "p2pRxLdpc", "1", 0);
+#endif
+	/* Parse the pucConfigBuff */
+
+	if (pucConfigBuf && (u4ConfigBufLen > 0))
+		wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to initialize WLAN feature options
+*
+* @param prAdapter  Pointer of ADAPTER_T
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter)
+{
+#define STR2BYTE(s) (((((PUINT_8)s)[0]-'0')*10)+(((PUINT_8)s)[1]-'0'))
+	CHAR aucValue[WLAN_CFG_VALUE_LEN_MAX];
+	P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar;
+	P_REG_INFO_T prRegInfo = &prAdapter->prGlueInfo->rRegInfo;
+	P_TX_PWR_PARAM_T prTxPwr = &prRegInfo->rTxPwr;
+
+	kalMemZero(aucValue, sizeof(aucValue));
+	DBGLOG(INIT, LOUD, "CFG_FILE: Apply Config File\n");
+	/* Apply COUNTRY Config */
+	if (wlanCfgGet(prAdapter, "country", aucValue, "", 0) == WLAN_STATUS_SUCCESS) {
+		DBGLOG(INIT, LOUD, "CFG_FILE: Found Country Key, Value=%s\n", aucValue);
+		prAdapter->rWifiVar.rConnSettings.u2CountryCode =
+		    (((UINT_16) aucValue[0]) << 8) | ((UINT_16) aucValue[1]);
+		prRegInfo->au2CountryCode[0] = aucValue[0];
+		prRegInfo->au2CountryCode[1] = aucValue[1];
+	}
+	prWifiVar->ucApWpsMode = (UINT_8) wlanCfgGetUint32(prAdapter, "ApWpsMode", 0);
+	prWifiVar->ucCert11nMode = (UINT_8)wlanCfgGetUint32(prAdapter, "Cert11nMode", 0);
+	DBGLOG(INIT, LOUD, "CFG_FILE: ucApWpsMode = %u, ucCert11nMode = %u\n",
+		prWifiVar->ucApWpsMode, prWifiVar->ucCert11nMode);
+	if (prWifiVar->ucCert11nMode == 1)
+		nicWriteMcr(prAdapter, 0x11111115 , 1);
+
+	if (wlanCfgGet(prAdapter, "5G_support", aucValue, "", 0) == WLAN_STATUS_SUCCESS)
+		prRegInfo->ucSupport5GBand = (*aucValue == 'y') ? 1 : 0;
+	if (wlanCfgGet(prAdapter, "TxPower2G4CCK", aucValue, "", 0) == WLAN_STATUS_SUCCESS
+			&& kalStrLen(aucValue) == 2) {
+		prTxPwr->cTxPwr2G4Cck = STR2BYTE(aucValue);
+		DBGLOG(INIT, LOUD, "2.4G cck=%d\n", prTxPwr->cTxPwr2G4Cck);
+	}
+	if (wlanCfgGet(prAdapter, "TxPower2G4OFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS &&
+	    kalStrLen(aucValue) == 10) {
+		prTxPwr->cTxPwr2G4OFDM_BPSK = STR2BYTE(aucValue);
+		prTxPwr->cTxPwr2G4OFDM_QPSK = STR2BYTE(aucValue + 2);
+		prTxPwr->cTxPwr2G4OFDM_16QAM = STR2BYTE(aucValue + 4);
+		prTxPwr->cTxPwr2G4OFDM_48Mbps = STR2BYTE(aucValue + 6);
+		prTxPwr->cTxPwr2G4OFDM_54Mbps = STR2BYTE(aucValue + 8);
+		DBGLOG(INIT, LOUD, "2.4G OFDM=%d,%d,%d,%d,%d\n",
+			prTxPwr->cTxPwr2G4OFDM_BPSK, prTxPwr->cTxPwr2G4OFDM_QPSK,
+			prTxPwr->cTxPwr2G4OFDM_16QAM, prTxPwr->cTxPwr2G4OFDM_48Mbps,
+			prTxPwr->cTxPwr2G4OFDM_54Mbps);
+	}
+	if (wlanCfgGet(prAdapter, "TxPower2G4HT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS &&
+	    kalStrLen(aucValue) == 12) {
+		prTxPwr->cTxPwr2G4HT20_BPSK = STR2BYTE(aucValue);
+		prTxPwr->cTxPwr2G4HT20_QPSK = STR2BYTE(aucValue + 2);
+		prTxPwr->cTxPwr2G4HT20_16QAM = STR2BYTE(aucValue + 4);
+		prTxPwr->cTxPwr2G4HT20_MCS5 = STR2BYTE(aucValue + 6);
+		prTxPwr->cTxPwr2G4HT20_MCS6 = STR2BYTE(aucValue + 8);
+		prTxPwr->cTxPwr2G4HT20_MCS7 = STR2BYTE(aucValue + 10);
+		DBGLOG(INIT, LOUD, "2.4G HT20=%d,%d,%d,%d,%d,%d\n",
+			prTxPwr->cTxPwr2G4HT20_BPSK, prTxPwr->cTxPwr2G4HT20_QPSK,
+			prTxPwr->cTxPwr2G4HT20_16QAM, prTxPwr->cTxPwr2G4HT20_MCS5,
+			prTxPwr->cTxPwr2G4HT20_MCS6, prTxPwr->cTxPwr2G4HT20_MCS7);
+	}
+	if (wlanCfgGet(prAdapter, "TxPower2G4HT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS &&
+	    kalStrLen(aucValue) == 12) {
+		prTxPwr->cTxPwr2G4HT40_BPSK = STR2BYTE(aucValue);
+		prTxPwr->cTxPwr2G4HT40_QPSK = STR2BYTE(aucValue + 2);
+		prTxPwr->cTxPwr2G4HT40_16QAM = STR2BYTE(aucValue + 4);
+		prTxPwr->cTxPwr2G4HT40_MCS5 = STR2BYTE(aucValue + 6);
+		prTxPwr->cTxPwr2G4HT40_MCS6 = STR2BYTE(aucValue + 8);
+		prTxPwr->cTxPwr2G4HT40_MCS7 = STR2BYTE(aucValue + 10);
+		DBGLOG(INIT, LOUD, "2.4G HT40=%d,%d,%d,%d,%d,%d\n",
+			prTxPwr->cTxPwr2G4HT40_BPSK, prTxPwr->cTxPwr2G4HT40_QPSK,
+			prTxPwr->cTxPwr2G4HT40_16QAM, prTxPwr->cTxPwr2G4HT40_MCS5,
+			prTxPwr->cTxPwr2G4HT40_MCS6, prTxPwr->cTxPwr2G4HT40_MCS7);
+	}
+	if (wlanCfgGet(prAdapter, "TxPower5GOFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS
+			&& kalStrLen(aucValue) == 10) {
+		prTxPwr->cTxPwr5GOFDM_BPSK = STR2BYTE(aucValue);
+		prTxPwr->cTxPwr5GOFDM_QPSK = STR2BYTE(aucValue + 2);
+		prTxPwr->cTxPwr5GOFDM_16QAM = STR2BYTE(aucValue + 4);
+		prTxPwr->cTxPwr5GOFDM_48Mbps = STR2BYTE(aucValue + 6);
+		prTxPwr->cTxPwr5GOFDM_54Mbps = STR2BYTE(aucValue + 8);
+		DBGLOG(INIT, LOUD, "5G OFDM=%d,%d,%d,%d,%d\n",
+			prTxPwr->cTxPwr5GOFDM_BPSK, prTxPwr->cTxPwr5GOFDM_QPSK,
+			prTxPwr->cTxPwr5GOFDM_16QAM, prTxPwr->cTxPwr5GOFDM_48Mbps,
+			prTxPwr->cTxPwr5GOFDM_54Mbps);
+	}
+	if (wlanCfgGet(prAdapter, "TxPower5GHT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS
+			&& kalStrLen(aucValue) == 12) {
+		prTxPwr->cTxPwr5GHT20_BPSK = STR2BYTE(aucValue);
+		prTxPwr->cTxPwr5GHT20_QPSK = STR2BYTE(aucValue + 2);
+		prTxPwr->cTxPwr5GHT20_16QAM = STR2BYTE(aucValue + 4);
+		prTxPwr->cTxPwr5GHT20_MCS5 = STR2BYTE(aucValue + 6);
+		prTxPwr->cTxPwr5GHT20_MCS6 = STR2BYTE(aucValue + 8);
+		prTxPwr->cTxPwr5GHT20_MCS7 = STR2BYTE(aucValue + 10);
+		DBGLOG(INIT, LOUD, "5G HT20=%d,%d,%d,%d,%d,%d\n",
+			prTxPwr->cTxPwr5GHT20_BPSK, prTxPwr->cTxPwr5GHT20_QPSK,
+			prTxPwr->cTxPwr5GHT20_16QAM, prTxPwr->cTxPwr5GHT20_MCS5, prTxPwr->cTxPwr5GHT20_MCS6,
+			prTxPwr->cTxPwr5GHT20_MCS7);
+	}
+	if (wlanCfgGet(prAdapter, "TxPower5GHT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS
+			&& kalStrLen(aucValue) == 12) {
+		prTxPwr->cTxPwr5GHT40_BPSK = STR2BYTE(aucValue);
+		prTxPwr->cTxPwr5GHT40_QPSK = STR2BYTE(aucValue + 2);
+		prTxPwr->cTxPwr5GHT40_16QAM = STR2BYTE(aucValue + 4);
+		prTxPwr->cTxPwr5GHT40_MCS5 = STR2BYTE(aucValue + 6);
+		prTxPwr->cTxPwr5GHT40_MCS6 = STR2BYTE(aucValue + 8);
+		prTxPwr->cTxPwr5GHT40_MCS7 = STR2BYTE(aucValue + 10);
+		DBGLOG(INIT, LOUD, "5G HT40=%d,%d,%d,%d,%d,%d\n",
+			prTxPwr->cTxPwr5GHT40_BPSK, prTxPwr->cTxPwr5GHT40_QPSK,
+			prTxPwr->cTxPwr5GHT40_16QAM, prTxPwr->cTxPwr5GHT40_MCS5, prTxPwr->cTxPwr5GHT40_MCS6,
+			prTxPwr->cTxPwr5GHT40_MCS7);
+	}
+	/* TODO: Apply other Config */
+}
+#endif /* CFG_SUPPORT_CFG_FILE */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c
new file mode 100644
index 0000000000000..993ff061ed203
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c
@@ -0,0 +1,11050 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_oid.c#5
+*/
+
+/*! \file wlanoid.c
+    \brief This file contains the WLAN OID processing routines of Windows driver for
+	   MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: wlan_oid.c
+**
+** 09 05 2013 cp.wu
+** isolate logic regarding roaming & reassociation
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+**
+** 09 02 2013 cp.wu
+** add path to handle reassociation request
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 06 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * using the wlanSendSetQueryCmd to set the tx power control cmd.
+ *
+ * 01 06 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * change the set tx power cmd name.
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 12 20 2011 cp.wu
+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information
+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO
+ * to expose version information
+ *
+ * 12 05 2011 cp.wu
+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
+ * add CONNECT_BY_BSSID policy
+ *
+ * 11 22 2011 cp.wu
+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to
+ * asynchronous approach to avoid incomplete state termination
+ * 1. change RDD related compile option brace position.
+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state
+ * without join timeout timer ticking
+ * 3. otherwise, insert AIS_REQUEST into pending request queue
+ *
+ * 11 21 2011 cp.wu
+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing
+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer
+ * add more checking for such cases
+ *
+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered.
+ * add some tweaking to protect such cases because that net device has become invalid.
+ *
+ * 11 15 2011 cm.chang
+ * NULL
+ * Fix compiling warning
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 11 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters of bb and ar for xlog.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the debug module level.
+ *
+ * 11 09 2011 george.huang
+ * [WCXRP00000871] [MT6620 Wi-Fi][FW] Include additional wakeup condition, which is by
+ * consequent DTIM unicast indication add XLOG for Set PS mode entry
+ *
+ * 11 08 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error.
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 11 03 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG
+ *
+ * 11 02 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add RDD certification features.
+ *
+ * 10 21 2011 eddie.chen
+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout
+ * Add switch to ignore the STA aging timeout.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 15 2011 tsaiyuan.hsu
+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA
+ * correct fifo full control from query to set operation for CTIA.
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 08 17 2011 tsaiyuan.hsu
+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA
+ * add system config for CTIA.
+ *
+ * 08 15 2011 george.huang
+ * [MT6620 Wi-Fi][FW] handle TSF drift for connection detection
+ * .
+ *
+ * 07 28 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS cmd and event.
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 07 11 2011 wh.su
+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize,
+ * for customer not enable WAPI
+ * For make sure wapi initial value is set.
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content
+ * check with firmware for valid MAC address.
+ *
+ * 05 02 2011 eddie.chen
+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control
+ * Fix compile warning.
+ *
+ * 04 29 2011 george.huang
+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
+ * .
+ *
+ * 04 27 2011 george.huang
+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
+ * add more debug message
+ *
+ * 04 26 2011 eddie.chen
+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control
+ * Add rx path profiling.
+ *
+ * 04 12 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix the sta index in processing security frame
+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
+ * Add debug message.
+ *
+ * 04 08 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * separate settings of P2P and AIS
+ *
+ * 03 31 2011 puff.wen
+ * NULL
+ * .
+ *
+ * 03 29 2011 puff.wen
+ * NULL
+ * Add chennel switch for stress test
+ *
+ * 03 29 2011 cp.wu
+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning
+ * surpress klock warning with code path rewritten
+ *
+ * 03 24 2011 wh.su
+ * [WCXRP00000595] [MT6620 Wi-Fi][Driver] at CTIA indicate disconnect to make the ps profile can apply
+ * use disconnect event instead of ais abort for CTIA testing.
+ *
+ * 03 23 2011 george.huang
+ * [WCXRP00000586] [MT6620 Wi-Fi][FW] Modify for blocking absence request right after connected
+ * revise for CTIA power mode setting
+ *
+ * 03 22 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * link with supplicant commands
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 17 2011 yarco.yang
+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage
+ * .
+ *
+ * 03 15 2011 george.huang
+ * [WCXRP00000557] [MT6620 Wi-Fi] Support current consumption test mode commands
+ * Support current consumption measurement mode command
+ *
+ * 03 15 2011 eddie.chen
+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter
+ * Add sw debug counter for QM.
+ *
+ * 03 10 2011 cp.wu
+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
+ * deprecate configuration used by MT6620 E2
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 03 04 2011 cp.wu
+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection
+ * surpress compile warning occurred when compiled by GNU compiler collection.
+ *
+ * 03 03 2011 wh.su
+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue
+ * fixed the enter ctia test mode issue.
+ *
+ * 03 02 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * Update sigma CAPI for U-APSD setting
+ *
+ * 03 02 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * Support UAPSD/OppPS/NoA parameter setting
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as
+ * initial RSSI right after connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
+ *
+ * 01 27 2011 george.huang
+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting
+ * Support CTIA power mode setting.
+ *
+ * 01 26 2011 wh.su
+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux
+ * adding the SW cmd ioctl support, use set/get structure ioctl.
+ *
+ * 01 25 2011 cp.wu
+ * [WCXRP00000394] [MT6620 Wi-Fi][Driver] Count space needed for generating error message in
+ * scanning list into buffer size checking
+ * when doing size prechecking, check illegal MAC address as well
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Add Oid for sw control debug command
+ *
+ * 01 15 2011 puff.wen
+ * NULL
+ * Add Stress test
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * check if allow to switch to IBSS mode via concurrent module before setting to IBSS mode
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000342] [MT6620 Wi-Fi][Driver] show error code in scanning list when MAC address is not
+ * correctly configured in NVRAM
+ * show error code 0x10 when MAC address in NVRAM is not configured correctly.
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations
+ * to ease physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 12 28 2010 george.huang
+ * [WCXRP00000232] [MT5931 Wi-Fi][FW] Modifications for updated HW power on sequence and related design
+ * support WMM-PS U-APSD AC assignment.
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * report EEPROM used flag via NIC_CAPABILITY
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools
+ *
+ * 12 16 2010 cp.wu
+ * [WCXRP00000268] [MT6620 Wi-Fi][Driver] correction for WHQL failed items
+ * correction for OID_802_11_NETWORK_TYPES_SUPPORTED handlers
+ *
+ * 12 13 2010 cp.wu
+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork
+ * suppress warning reported by Klockwork.
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 11 30 2010 cp.wu
+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1
+ * .
+ *
+ * 11 26 2010 cp.wu
+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only
+ * with necessary data field checking
+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available
+ * but extra scan result used to indicate user is attached
+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown
+ *
+ * 11 25 2010 cp.wu
+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM
+ * add scanning with specified SSID facility to AIS-FSM
+ *
+ * 11 21 2010 wh.su
+ * [WCXRP00000192] [MT6620 Wi-Fi][Driver] Fixed fail trying to build connection with Security
+ * AP while enable WAPI message check
+ * Not set the wapi mode while the wapi assoc info set non-wapi ie.
+ *
+ * 11 05 2010 wh.su
+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value
+ * fixed the.pmkid value mismatch issue
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version
+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying
+ * current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version
+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 22 2010 cp.wu
+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration
+ * dos2unix conversion.
+ *
+ * 10 20 2010 cp.wu
+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
+ * use OID_CUSTOM_TEST_MODE as indication for driver reset
+ * by dropping pending TX packets
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version
+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android complete
+ * implementation of Android NVRAM access
+ *
+ * 10 06 2010 yuche.tsai
+ * NULL
+ * Update SLT 5G Test Channel Set.
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * code reorganization to improve isolation between GLUE and CORE layers.
+ *
+ * 10 06 2010 yuche.tsai
+ * NULL
+ * Update For SLT 5G Test Channel Selection Rule.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form
+ * Query buffer size needs to be enlarged due to result is filled in 4-bytes alignment boundary
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and
+ * replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form
+ * Extend result length to multiples of 4-bytes
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * eliminate unused variables which lead gcc to argue
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature
+ * Modify online scan as a run-time adjustable option (for Windows, in registry)
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
+ * use firmware reported mac address right after wlanAdapterStart() as permanent address
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add skeleton for NVRAM integration
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * Update SLT due to API change of SCAN module.
+ *
+ * 09 06 2010 cp.wu
+ * NULL
+ * Androi/Linux: return current operating channel information
+ *
+ * 09 06 2010 cp.wu
+ * NULL
+ * 1) initialize for correct parameter even for disassociation.
+ * 2) AIS-FSM should have a limit on trials to build connection
+ *
+ * 09 03 2010 yuche.tsai
+ * NULL
+ * Refine SLT IO control handler.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 08 30 2010 chinglan.wang
+ * NULL
+ * Modify the rescan condition.
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * Finish SLT TX/RX & Rate Changing Support.
+ *
+ * 08 27 2010 chinglan.wang
+ * NULL
+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 24 2010 cp.wu
+ * NULL
+ * 1) initialize variable for enabling short premable/short time slot.
+ * 2) add compile option for disabling online scan
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * .
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * update params defined in CMD_SET_NETWORK_ADDRESS_LIST
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * fix for check build WHQL testing:
+ * 1) do not assert query buffer if indicated buffer length is zero
+ * 2) sdio.c has bugs which cause freeing same pointer twice
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * revert changelist #15371, efuse read/write access will be done by RF test approach
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * add OID definitions for EFUSE read/write access.
+ *
+ * 08 04 2010 george.huang
+ * NULL
+ * handle change PS mode OID/ CMD
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request.
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * bypass u4FuncData for RF-Test query request as well.
+ *
+ * 08 04 2010 yarco.yang
+ * NULL
+ * Add TX_AMPDU and ADDBA_REJECT command
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 08 02 2010 george.huang
+ * NULL
+ * add WMM-PS test related OID/ CMD handlers
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc*
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo
+ * 2) change nicMediaStateChange() API prototype
+ *
+ * 07 26 2010 cp.wu
+ *
+ * re-commit code logic being overwriten.
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 21 2010 cp.wu
+ *
+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term
+ * 2) only clear scanning result when scan is permitted to do
+ *
+ * 07 20 2010 cp.wu
+ *
+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one
+ * 2) refine disconnection behaviour when issued during BG-SCAN process
+ *
+ * 07 19 2010 wh.su
+ *
+ * modify the auth and encry status variable.
+ *
+ * 07 16 2010 cp.wu
+ *
+ * remove work-around in case SCN is not available.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet.
+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * AIS-FSM integration with CNM channel request messages
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) sync to. CMD/EVENT document v0.03
+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
+ * 3) send command packet to indicate FW-PM after
+ *     a) 1st beacon is received after AIS has connected to an AP
+ *     b) IBSS-ALONE has been created
+ *     c) IBSS-MERGE has occurred
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add API in que_mgt to retrieve sta-rec index for security frames.
+ *
+ * 06 24 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add SCN compilation option.
+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implement SCAN-REQUEST oid as mailbox message dispatching.
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * integrate .
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * remove duplicate variable for migration.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * adding the compiling flag for oid pmkid.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * enable RX management frame handling.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration the security related function from firmware.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wlan_def.h.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * move timer callback to glue layer.
+ *
+ * 05 28 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * simplify cmd packet sending for RF test and MCR access OIDs
+ *
+ * 05 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * disable radio even when STA is not associated.
+ *
+ * 05 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct 2 OID behaviour to meet WHQL requirement.
+ *
+ * 05 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) Modify set mac address code
+ * 2) remove power management macro
+ *
+ * 05 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct BSSID_LIST oid when radio if turned off.
+ *
+ * 05 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll
+ * 2) correct address list parsing
+ *
+ * 05 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * disable wlanoidSetNetworkAddress() temporally.
+ *
+ * 05 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * some OIDs should be DRIVER_CORE instead of GLUE_EXTENSION
+ *
+ * 05 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally.
+ * 2) finish statistics OIDs
+ *
+ * 05 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change OID behavior to meet WHQL requirement.
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) do not take timeout mechanism for power mode oids
+ * 2) retrieve network type from connection status
+ * 3) after disassciation, set radio state to off
+ * 4) TCP option over IPv6 is supported
+ *
+ * 05 18 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement Wakeup-on-LAN except firmware integration part
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct wlanoidSet802dot11PowerSaveProfile implementation.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) enable CMD/EVENT ver 0.9 definition.
+ * 2) abandon use of ENUM_MEDIA_STATE
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct OID_802_11_DISASSOCIATE handling.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 05 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Add dissassocation support for wpa supplicant
+ *
+ * 05 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct return value.
+ *
+ * 05 13 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add NULL OID implementation for WOL-related OIDs.
+ *
+ * 05 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * for disassociation, still use parameter with current setting.
+ *
+ * 05 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * for disassociation, generate a WZC-compatible invalid SSID.
+ *
+ * 05 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * associate to illegal SSID when handling OID_802_11_DISASSOCIATE
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * reserve field of privacy filter and RTS threshold setting.
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * .
+ *
+ * 04 22 2010 cp.wu
+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support
+ * enable RX filter OID
+ *
+ * 04 19 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Add ioctl of power management
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * information buffer for query oid/ioctl is now buffered in prCmdInfo
+ *  * instead of glue-layer variable to improve multiple oid/ioctl capability
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct OID_802_11_CONFIGURATION query for infrastructure mode.
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) remove unused spin lock declaration
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * finish non-glue layer access to glue variables
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  * are done in adapter layer.
+ *
+ * 04 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * (1)improve none-glue code portability
+ * (2) disable set Multicast address during atomic context
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * ePowerCtrl is not necessary as a glue variable.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer.
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 04 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * .
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * statistics information OIDs are now handled by querying from firmware domain
+ *
+ * 03 28 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve glue code portability
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * indicate media stream mode after set is done
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add a temporary flag for integration with CMD/EVENT v0.9.
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior.
+ * the frequency is used for adhoc connection only
+ * 2) update with SD1 v0.9 CMD/EVENT documentation
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
+ *
+ *
+ * 03 22 2010 cp.wu
+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list
+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result
+ *
+ * 03 19 2010 wh.su
+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test
+ * adding the check for pass WHQL test item.
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
+ *
+* 03 16 2010 wh.su
+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test
+ * fixed some whql pre-test fail case.
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement custom OID: EEPROM read/write access
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_3_MULTICAST_LIST oid handling
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock
+ *  * 2) ensure wlanReleasePendingOid will clear all command queues
+ *
+ * 02 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set.
+ *
+ * 02 24 2010 wh.su
+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test
+ * Don't needed to check the auth mode, WHQL testing not specific at auth wpa2.
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * do not check SSID validity anymore.
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add checksum offloading support.
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  * 2. follow MSDN defined behavior when associates to another AP
+ *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * move ucCmdSeqNum as instance variable
+ *
+ * 02 04 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * when OID_CUSTOM_OID_INTERFACE_VERSION is queried, do modify connection states
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) implement timeout mechanism when OID is pending for longer than 1 second
+ *  * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on
+ *
+ * 01 27 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * .
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  * 4. correct some HAL implementation
+ *
+ * 01 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement following 802.11 OIDs:
+ * OID_802_11_RSSI,
+ * OID_802_11_RSSI_TRIGGER,
+ * OID_802_11_STATISTICS,
+ * OID_802_11_DISASSOCIATE,
+ * OID_802_11_POWER_MODE
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_11_MEDIA_STREAM_MODE
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * do not fill ucJoinOnly currently
+ *
+ * 01 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * enable to connect to ad-hoc network
+ *
+ * 01 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * .implement Set/Query BeaconInterval/AtimWindow
+ *
+ * 01 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * .Set/Get AT Info is not blocked even when driver is not in fg test mode
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ * and result is retrieved by get ATInfo instead
+ * 2) add 4 counter for recording aggregation statistics
+ *
+ * 12 28 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate redundant variables for connection_state
+**  \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-16 22:13:36 GMT mtk02752
+**  change hard-coded MAC address to match with FW (temporally)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-10 16:49:50 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-08 17:38:49 GMT mtk02752
+**  + add OID for RF test
+**  * MCR RD/WR are modified to match with cmd/event definition
+**  \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-12-08 11:32:20 GMT mtk02752
+**  add skeleton for RF test implementation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-12-03 16:43:24 GMT mtk01461
+**  Modify query SCAN list oid by adding prEventScanResult
+**
+**  \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-03 16:39:27 GMT mtk01461
+**  Sync CMD data structure in set ssid oid
+**  \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-03 16:28:22 GMT mtk01461
+**  Add invalid check of set SSID oid and fix query scan list oid
+**  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-30 17:33:08 GMT mtk02752
+**  implement wlanoidSetInfrastructureMode/wlanoidQueryInfrastructureMode
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-30 10:53:49 GMT mtk02752
+**  1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-30 09:22:48 GMT mtk02752
+**  correct wifi cmd length mismatch
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-25 21:34:33 GMT mtk02752
+**  sync EVENT_SCAN_RESULT_T with firmware
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 21:03:27 GMT mtk02752
+**  implement wlanoidQueryBssidList()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-25 18:17:17 GMT mtk02752
+**  refine GL_WLAN_INFO_T for buffering scan result
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-23 20:28:51 GMT mtk02752
+**  some OID will be set to WLAN_STATUS_PENDING until it is sent via wlanSendCommand()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-23 17:56:36 GMT mtk02752
+**  implement wlanoidSetBssidListScan(), wlanoidSetBssid() and wlanoidSetSsid()
+**
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-13 17:20:53 GMT mtk02752
+**  add Set BSSID/SSID path but disabled temporally due to FW is not ready yet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 12:28:58 GMT mtk02752
+**  add wlanoidSetBssidListScan -> cmd_info path
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-09 22:48:07 GMT mtk01084
+**  modify test cases entry
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-04 14:10:58 GMT mtk01084
+**  add new test interfaces
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-30 18:17:10 GMT mtk01084
+**  fix compiler warning
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:46:26 GMT mtk01084
+**  add test functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:07:56 GMT mtk01084
+**  include new file
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:29 GMT mtk01084
+**  modify for new HW architecture
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-02 13:48:49 GMT mtk01725
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-09-09 17:26:04 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-21 12:09:50 GMT mtk01461
+**  Update for MCR Write OID
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:35:18 GMT mtk01461
+**  Update wlanoidQueryMcrRead() for composing CMD_INFO_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 18:09:51 GMT mtk01426
+**  Remove kalIndicateStatusAndComplete() in wlanoidQueryOidInterfaceVersion()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-14 15:51:50 GMT mtk01426
+**  Add MCR read/write support
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:40 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:06:31 GMT mtk01426
+**  Init for develop
+**
+*/
+
+/******************************************************************************
+*                         C O M P I L E R   F L A G S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+*******************************************************************************
+*/
+#include "precomp.h"
+#include "mgmt/rsn.h"
+
+#include <stddef.h>
+
+/******************************************************************************
+*                              C O N S T A N T S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                             D A T A   T Y P E S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                            P U B L I C   D A T A
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                           P R I V A T E   D A T A
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                                 M A C R O S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                              F U N C T I O N S
+*******************************************************************************
+*/
+#if CFG_ENABLE_STATISTICS_BUFFERING
+static BOOLEAN IsBufferedStatisticsUsable(P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	if (prAdapter->fgIsStatValid == TRUE &&
+	    (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= CFG_STATISTICS_VALID_CYCLE)
+		return TRUE;
+	else
+		return FALSE;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the supported physical layer network
+*        type that can be used by the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter,
+				  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	UINT_32 u4NumItem = 0;
+	ENUM_PARAM_NETWORK_TYPE_T eSupportedNetworks[PARAM_NETWORK_TYPE_NUM];
+	PPARAM_NETWORK_TYPE_LIST prSupported;
+
+	/* The array of all physical layer network subtypes that the driver supports. */
+
+	DEBUGFUNC("wlanoidQueryNetworkTypesSupported");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	/* Init. */
+	for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; u4NumItem++)
+		eSupportedNetworks[u4NumItem] = 0;
+
+	u4NumItem = 0;
+
+	eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS;
+	u4NumItem++;
+
+	eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24;
+	u4NumItem++;
+
+	*pu4QueryInfoLen =
+	    (UINT_32) OFFSET_OF(PARAM_NETWORK_TYPE_LIST, eNetworkType) +
+	    (u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T));
+
+	if (u4QueryBufferLen < *pu4QueryInfoLen)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prSupported = (PPARAM_NETWORK_TYPE_LIST) pvQueryBuffer;
+	prSupported->NumberOfItems = u4NumItem;
+	kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T));
+
+	DBGLOG(OID, TRACE, "NDIS supported network type list: %u\n", prSupported->NumberOfItems);
+	DBGLOG_MEM8(OID, TRACE, prSupported, *pu4QueryInfoLen);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryNetworkTypesSupported */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current physical layer network
+*        type used by the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*             the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                             bytes written into the query buffer. If the
+*                             call failed due to invalid length of the query
+*                             buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter,
+			     OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	/* TODO: need to check the OID handler content again!! */
+
+	ENUM_PARAM_NETWORK_TYPE_T rCurrentNetworkTypeInUse = PARAM_NETWORK_TYPE_OFDM24;
+
+	DEBUGFUNC("wlanoidQueryNetworkTypeInUse");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) {
+		*pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED)
+		rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkType);
+	else
+		rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkTypeInUse);
+
+	*(P_ENUM_PARAM_NETWORK_TYPE_T) pvQueryBuffer = rCurrentNetworkTypeInUse;
+	*pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
+
+	DBGLOG(OID, TRACE, "Network type in use: %d\n", rCurrentNetworkTypeInUse);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryNetworkTypeInUse */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the physical layer network type used
+*        by the driver.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns the
+*                          amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted.
+* \retval WLAN_STATUS_INVALID_DATA The given network type is not in the
+*                                  supported list.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	/* TODO: need to check the OID handler content again!! */
+
+	ENUM_PARAM_NETWORK_TYPE_T eNewNetworkType;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	DEBUGFUNC("wlanoidSetNetworkTypeInUse");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) {
+		*pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	eNewNetworkType = *(P_ENUM_PARAM_NETWORK_TYPE_T) pvSetBuffer;
+	*pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
+
+	DBGLOG(OID, INFO, "New network type: %d mode\n", eNewNetworkType);
+
+	switch (eNewNetworkType) {
+
+	case PARAM_NETWORK_TYPE_DS:
+		prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_DS;
+		break;
+
+	case PARAM_NETWORK_TYPE_OFDM5:
+		prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM5;
+		break;
+
+	case PARAM_NETWORK_TYPE_OFDM24:
+		prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM24;
+		break;
+
+	case PARAM_NETWORK_TYPE_AUTOMODE:
+		prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_AUTOMODE;
+		break;
+
+	case PARAM_NETWORK_TYPE_FH:
+		DBGLOG(OID, INFO, "Not support network type: %d\n", eNewNetworkType);
+		rStatus = WLAN_STATUS_NOT_SUPPORTED;
+		break;
+
+	default:
+		DBGLOG(OID, INFO, "Unknown network type: %d\n", eNewNetworkType);
+		rStatus = WLAN_STATUS_INVALID_DATA;
+		break;
+	}
+
+	/* Verify if we support the new network type. */
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(OID, WARN, "Unknown network type: %d\n", eNewNetworkType);
+
+	return rStatus;
+}				/* wlanoidSetNetworkTypeInUse */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current BSSID.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                             bytes written into the query buffer. If the call
+*                             failed due to invalid length of the query buffer,
+*                             returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter,
+		  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	DEBUGFUNC("wlanoidQueryBssid");
+
+	ASSERT(prAdapter);
+
+	if (u4QueryBufferLen < MAC_ADDR_LEN) {
+		ASSERT(pu4QueryInfoLen);
+		*pu4QueryInfoLen = MAC_ADDR_LEN;
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED)
+		kalMemCopy(pvQueryBuffer, prAdapter->rWlanInfo.rCurrBssId.arMacAddress, MAC_ADDR_LEN);
+	else if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS) {
+		PARAM_MAC_ADDRESS aucTemp;	/*!< BSSID */
+
+		COPY_MAC_ADDR(aucTemp, prAdapter->rWlanInfo.rCurrBssId.arMacAddress);
+		aucTemp[0] &= ~BIT(0);
+		aucTemp[1] |= BIT(1);
+		COPY_MAC_ADDR(pvQueryBuffer, aucTemp);
+	} else
+		rStatus = WLAN_STATUS_ADAPTER_NOT_READY;
+
+	*pu4QueryInfoLen = MAC_ADDR_LEN;
+	return rStatus;
+}				/* wlanoidQueryBssid */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the list of all BSSIDs detected by
+*        the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                             bytes written into the query buffer. If the call
+*                             failed due to invalid length of the query buffer,
+*                             returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 i, u4BssidListExLen;
+	P_PARAM_BSSID_LIST_EX_T prList;
+	P_PARAM_BSSID_EX_T prBssidEx;
+	PUINT_8 cp;
+
+	DEBUGFUNC("wlanoidQueryBssidList");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	if (u4QueryBufferLen) {
+		ASSERT(pvQueryBuffer);
+
+		if (!pvQueryBuffer)
+			return WLAN_STATUS_INVALID_DATA;
+	}
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	u4BssidListExLen = 0;
+
+	if (prAdapter->fgIsRadioOff == FALSE) {
+		for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++)
+			u4BssidListExLen += ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4Length);
+	}
+
+	if (u4BssidListExLen)
+		u4BssidListExLen += 4;	/* u4NumberOfItems. */
+	else
+		u4BssidListExLen = sizeof(PARAM_BSSID_LIST_EX_T);
+
+	*pu4QueryInfoLen = u4BssidListExLen;
+
+	if (u4QueryBufferLen < *pu4QueryInfoLen)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	/* Clear the buffer */
+	kalMemZero(pvQueryBuffer, u4BssidListExLen);
+
+	prList = (P_PARAM_BSSID_LIST_EX_T) pvQueryBuffer;
+	cp = (PUINT_8) &prList->arBssid[0];
+
+	if (prAdapter->fgIsRadioOff == FALSE && prAdapter->rWlanInfo.u4ScanResultNum > 0) {
+		/* fill up for each entry */
+		for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
+			prBssidEx = (P_PARAM_BSSID_EX_T) cp;
+
+			/* copy structure */
+			kalMemCopy(prBssidEx,
+				   &(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
+
+			/*For WHQL test, Rssi should be in range -10 ~ -200 dBm */
+			if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM)
+				prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM;
+
+			if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) {
+				/* copy IEs */
+				kalMemCopy(prBssidEx->aucIEs,
+					   prAdapter->rWlanInfo.apucScanResultIEs[i],
+					   prAdapter->rWlanInfo.arScanResult[i].u4IELength);
+			}
+			/* 4-bytes alignement */
+			prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length);
+
+			cp += prBssidEx->u4Length;
+			prList->u4NumberOfItems++;
+		}
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryBssidList */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to request the driver to perform
+*        scanning.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_SSID_T prSsid;
+	PARAM_SSID_T rSsid;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	DEBUGFUNC("wlanoidSetBssidListScan()");
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	ASSERT(pu4SetInfoLen);
+	*pu4SetInfoLen = 0;
+
+	if (prAdapter->fgIsRadioOff) {
+		DBGLOG(OID, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	DBGLOG(OID, TRACE, "Scan\n");
+
+	if (pvSetBuffer != NULL && u4SetBufferLen != 0) {
+		COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, u4SetBufferLen);
+		prSsid = &rSsid;
+	} else {
+		prSsid = NULL;
+	}
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+	if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) {
+		if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) {
+			if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) {
+				aisFsmScanRequest(prAdapter, prSsid, NULL, 0);
+			} else {
+				/* reject the scan request */
+				rStatus = WLAN_STATUS_FAILURE;
+			}
+		} else {
+			/* reject the scan request */
+			rStatus = WLAN_STATUS_FAILURE;
+		}
+	} else
+#endif
+	{
+		if (prAdapter->fgEnOnlineScan == TRUE) {
+			aisFsmScanRequest(prAdapter, prSsid, NULL, 0);
+		} else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) {
+			aisFsmScanRequest(prAdapter, prSsid, NULL, 0);
+		} else {
+			/* reject the scan request */
+			rStatus = WLAN_STATUS_FAILURE;
+		}
+	}
+
+	return rStatus;
+}				/* wlanoidSetBssidListScan */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to request the driver to perform
+*        scanning with attaching information elements(IEs) specified from user space
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_SCAN_REQUEST_EXT_T prScanRequest;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_PARAM_SSID_T prSsid;
+	PUINT_8 pucIe;
+	UINT_32 u4IeLength;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_8 ucScanTime = AIS_SCN_DONE_TIMEOUT_SEC;
+
+	DEBUGFUNC("wlanoidSetBssidListScanExt()");
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, ERROR, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (prAdapter->fgTestMode) {
+		DBGLOG(OID, WARN, "didn't support Scan in test mode\n");
+		return WLAN_STATUS_FAILURE;
+	}
+
+	ASSERT(pu4SetInfoLen);
+	*pu4SetInfoLen = 0;
+
+	if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)) {
+		DBGLOG(OID, ERROR, "u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)\n");
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	if (prAdapter->fgIsRadioOff) {
+		DBGLOG(OID, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	DBGLOG(OID, TRACE, "ScanEx\n");
+
+	/* clear old scan backup results if exists */
+	{
+		P_SCAN_INFO_T prScanInfo;
+		P_LINK_T prBSSDescList;
+		P_BSS_DESC_T prBssDesc;
+
+		prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+		prBSSDescList = &prScanInfo->rBSSDescList;
+		LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+			if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
+				kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE);
+				prBssDesc->u2RawLength = 0;
+			}
+		}
+	}
+
+	if (pvSetBuffer != NULL && u4SetBufferLen != 0) {
+		prScanRequest = (P_PARAM_SCAN_REQUEST_EXT_T) pvSetBuffer;
+		prSsid = &(prScanRequest->rSsid);
+		pucIe = prScanRequest->pucIE;
+		u4IeLength = prScanRequest->u4IELength;
+	} else {
+		prScanRequest = NULL;
+		prSsid = NULL;
+		pucIe = NULL;
+		u4IeLength = 0;
+	}
+
+/* P_AIS_FSM_INFO_T prAisFsmInfo; */
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+/* #if CFG_SUPPORT_WFD */
+#if 0
+	if ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.ucWfdEnable) &&
+	    ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) {
+
+		if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState ==
+		    PARAM_MEDIA_STATE_CONNECTED) {
+			DBGLOG(OID, TRACE, "Twice the Scan Time for WFD\n");
+			ucScanTime *= 2;
+		}
+	}
+#endif /* CFG_SUPPORT_WFD */
+	cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer, SEC_TO_MSEC(ucScanTime));
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+	if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) {
+		if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) {
+			if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) {
+				aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength);
+			} else {
+				/* reject the scan request */
+				cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer);
+				rStatus = WLAN_STATUS_FAILURE;
+			}
+		} else {
+			/* reject the scan request */
+			cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer);
+			rStatus = WLAN_STATUS_FAILURE;
+		}
+	} else
+#endif
+	{
+		if (prAdapter->fgEnOnlineScan == TRUE) {
+			aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength);
+		} else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) {
+			aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength);
+		} else {
+			/* reject the scan request */
+			cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer);
+			rStatus = WLAN_STATUS_FAILURE;
+			DBGLOG(OID, WARN, "ScanEx fail %d!\n", prAdapter->fgEnOnlineScan);
+		}
+	}
+
+	return rStatus;
+}				/* wlanoidSetBssidListScanWithIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine will initiate the join procedure to attempt to associate
+*        with the specified BSSID.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_UINT_8 pAddr;
+	UINT_32 i;
+	INT_32 i4Idx = -1;
+	P_MSG_AIS_ABORT_T prAisAbortMsg;
+	UINT_8 ucReasonOfDisconnect;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = MAC_ADDR_LEN;
+	if (u4SetBufferLen != MAC_ADDR_LEN) {
+		*pu4SetInfoLen = MAC_ADDR_LEN;
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	pAddr = (P_UINT_8) pvSetBuffer;
+
+	/* re-association check */
+	if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+		if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) {
+			kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED);
+			ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION;
+		} else {
+			DBGLOG(OID, TRACE, "DisByBssid\n");
+			kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+			ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
+		}
+	} else {
+		ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
+	}
+
+	/* check if any scanned result matchs with the BSSID */
+	for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
+		if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) {
+			i4Idx = (INT_32) i;
+			break;
+		}
+	}
+
+	/* prepare message to AIS */
+	if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS
+	    || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) {
+		/* IBSS *//* beacon period */
+		prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod;
+		prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow;
+	}
+
+	/* Set Connection Request Issued Flag */
+	prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE;
+	prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_BSSID;
+
+	/* Send AIS Abort Message */
+	prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
+	if (!prAisAbortMsg) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ;
+	prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect;
+
+	/* Update the information to CONNECTION_SETTINGS_T */
+	prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0;
+	prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0';
+
+	COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr);
+
+	if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr))
+		prAisAbortMsg->fgDelayIndication = TRUE;
+	else
+		prAisAbortMsg->fgDelayIndication = FALSE;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
+
+	DBGLOG(OID, INFO, "SetBssid\n");
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidSetBssid() */
+
+WLAN_STATUS
+wlanoidSetConnect(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_PARAM_CONNECT_T pParamConn;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	UINT_32 i;
+	/*INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;*/
+	P_MSG_AIS_ABORT_T prAisAbortMsg;
+	BOOLEAN fgIsValidSsid = TRUE;
+	BOOLEAN fgEqualSsid = FALSE;
+	BOOLEAN fgEqualBssid = FALSE;
+	const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	/* MSDN:
+	 * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE
+	 */
+	if (prAdapter->fgIsRadioOff == TRUE)
+		prAdapter->fgIsRadioOff = FALSE;
+
+	if (u4SetBufferLen != sizeof(PARAM_CONNECT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+	else if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+	prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
+	if (!prAisAbortMsg) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+	prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ;
+
+	pParamConn = (P_PARAM_CONNECT_T) pvSetBuffer;
+	prConnSettings = &prAdapter->rWifiVar.rConnSettings;
+
+	if (pParamConn->u4SsidLen > 32) {
+		cnmMemFree(prAdapter, prAisAbortMsg);
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (!pParamConn->pucBssid && !pParamConn->pucSsid) {
+		cnmMemFree(prAdapter, prAisAbortMsg);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	kalMemZero(prConnSettings->aucSSID, sizeof(prConnSettings->aucSSID));
+	kalMemZero(prConnSettings->aucBSSID, sizeof(prConnSettings->aucBSSID));
+	prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY;
+	prConnSettings->fgIsConnByBssidIssued = FALSE;
+
+	if (pParamConn->pucSsid) {
+		prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI;
+		COPY_SSID(prConnSettings->aucSSID,
+			  prConnSettings->ucSSIDLen, pParamConn->pucSsid, (UINT_8) pParamConn->u4SsidLen);
+		if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
+			       prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen,
+			       pParamConn->pucSsid, pParamConn->u4SsidLen))
+			fgEqualSsid = TRUE;
+	}
+	if (pParamConn->pucBssid) {
+		if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) {
+			prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID;
+			prConnSettings->fgIsConnByBssidIssued = TRUE;
+			COPY_MAC_ADDR(prConnSettings->aucBSSID, pParamConn->pucBssid);
+			if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pParamConn->pucBssid))
+				fgEqualBssid = TRUE;
+		} else
+			DBGLOG(OID, TRACE, "wrong bssid %pM to connect\n", pParamConn->pucBssid);
+	} else
+		DBGLOG(OID, TRACE, "No Bssid set\n");
+	prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq;
+
+	/* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */
+	/* re-association check */
+	if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+		if (fgEqualSsid) {
+			prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_ROAMING;
+			if (fgEqualBssid) {
+				kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED);
+				prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION;
+			}
+		} else {
+			DBGLOG(OID, TRACE, "DisBySsid\n");
+			kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+			prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
+		}
+	} else
+		prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
+#if 0
+	/* check if any scanned result matchs with the SSID */
+	for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
+		PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid;
+		UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen;
+		INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi;
+
+		if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, pParamConn->u4SsidLen) &&
+		    i4RSSI >= i4MaxRSSI) {
+			i4Idx = (INT_32) i;
+			i4MaxRSSI = i4RSSI;
+		}
+		if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) {
+			i4Idx = (INT_32) i;
+			break;
+		}
+	}
+#endif
+	/* prepare message to AIS */
+	if (prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) {
+		/* IBSS *//* beacon period */
+		prConnSettings->u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod;
+		prConnSettings->u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow;
+	}
+
+	if (prAdapter->rWifiVar.fgSupportWZCDisassociation) {
+		if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) {
+			fgIsValidSsid = FALSE;
+
+			for (i = 0; i < ELEM_MAX_LEN_SSID; i++) {
+				if (pParamConn->pucSsid) {
+					if (!((0 < pParamConn->pucSsid[i]) && (pParamConn->pucSsid[i] <= 0x1F))) {
+						fgIsValidSsid = TRUE;
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/* Set Connection Request Issued Flag */
+	if (fgIsValidSsid)
+		prConnSettings->fgIsConnReqIssued = TRUE;
+	else
+		prConnSettings->fgIsConnReqIssued = FALSE;
+
+	if (fgEqualSsid || fgEqualBssid)
+		prAisAbortMsg->fgDelayIndication = TRUE;
+	else
+		/* Update the information to CONNECTION_SETTINGS_T */
+		prAisAbortMsg->fgDelayIndication = FALSE;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
+
+	DBGLOG(OID, INFO, "ssid %s, bssid %pM, conn policy %d, disc reason %d\n",
+			     prConnSettings->aucSSID, prConnSettings->aucBSSID,
+			     prConnSettings->eConnectionPolicy, prAisAbortMsg->ucReasonOfDisconnect);
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine will initiate the join procedure to attempt
+*        to associate with the new SSID. If the previous scanning
+*        result is aged, we will scan the channels at first.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_PARAM_SSID_T pParamSsid;
+	UINT_32 i;
+	INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;
+	P_MSG_AIS_ABORT_T prAisAbortMsg;
+	BOOLEAN fgIsValidSsid = TRUE;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	/* MSDN:
+	 * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE
+	 */
+	if (prAdapter->fgIsRadioOff == TRUE)
+		prAdapter->fgIsRadioOff = FALSE;
+
+	if (u4SetBufferLen < sizeof(PARAM_SSID_T) || u4SetBufferLen > sizeof(PARAM_SSID_T)) {
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	pParamSsid = (P_PARAM_SSID_T) pvSetBuffer;
+
+	if (pParamSsid->u4SsidLen > 32)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	/* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */
+	/* re-association check */
+	if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+		if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
+			       prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen,
+			       pParamSsid->aucSsid, pParamSsid->u4SsidLen)) {
+			kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED);
+		} else {
+			DBGLOG(OID, TRACE, "DisBySsid\n");
+			kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+		}
+	}
+	/* check if any scanned result matchs with the SSID */
+	for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
+		PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid;
+		UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen;
+		INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi;
+
+		if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, pParamSsid->u4SsidLen) &&
+		    i4RSSI >= i4MaxRSSI) {
+			i4Idx = (INT_32) i;
+			i4MaxRSSI = i4RSSI;
+		}
+	}
+
+	/* prepare message to AIS */
+	if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS
+	    || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) {
+		/* IBSS *//* beacon period */
+		prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod;
+		prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow;
+	}
+
+	if (prAdapter->rWifiVar.fgSupportWZCDisassociation) {
+		if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) {
+			fgIsValidSsid = FALSE;
+
+			for (i = 0; i < ELEM_MAX_LEN_SSID; i++) {
+				if (!((0 < pParamSsid->aucSsid[i]) && (pParamSsid->aucSsid[i] <= 0x1F))) {
+					fgIsValidSsid = TRUE;
+					break;
+				}
+			}
+		}
+	}
+
+	/* Set Connection Request Issued Flag */
+	if (fgIsValidSsid) {
+		prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE;
+
+		if (pParamSsid->u4SsidLen) {
+			prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI;
+		} else {
+			/* wildcard SSID */
+			prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_ANY;
+		}
+	} else {
+		prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE;
+	}
+
+	/* Send AIS Abort Message */
+	prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
+	if (!prAisAbortMsg) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ;
+	prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
+
+	COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID,
+		  prAdapter->rWifiVar.rConnSettings.ucSSIDLen, pParamSsid->aucSsid, (UINT_8) pParamSsid->u4SsidLen);
+
+	prAdapter->rWifiVar.rConnSettings.u4FreqInKHz = pParamSsid->u4CenterFreq;
+	if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
+		       prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, pParamSsid->aucSsid, pParamSsid->u4SsidLen)) {
+		prAisAbortMsg->fgDelayIndication = TRUE;
+	} else {
+		/* Update the information to CONNECTION_SETTINGS_T */
+		prAisAbortMsg->fgDelayIndication = FALSE;
+	}
+	DBGLOG(SCN, INFO, "SSID %s\n", prAdapter->rWifiVar.rConnSettings.aucSSID);
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of wlanoidSetSsid() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the currently associated SSID.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                             bytes written into the query buffer. If the call
+*                             failed due to invalid length of the query buffer,
+*                             returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter,
+		 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_SSID_T prAssociatedSsid;
+
+	DEBUGFUNC("wlanoidQuerySsid");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_SSID_T);
+
+	/* Check for query buffer length */
+	if (u4QueryBufferLen < *pu4QueryInfoLen) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	prAssociatedSsid = (P_PARAM_SSID_T) pvQueryBuffer;
+
+	kalMemZero(prAssociatedSsid->aucSsid, sizeof(prAssociatedSsid->aucSsid));
+
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+		prAssociatedSsid->u4SsidLen = prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen;
+
+		if (prAssociatedSsid->u4SsidLen) {
+			kalMemCopy(prAssociatedSsid->aucSsid,
+				   prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, prAssociatedSsid->u4SsidLen);
+		}
+	} else {
+		prAssociatedSsid->u4SsidLen = 0;
+
+		DBGLOG(OID, TRACE, "Null SSID\n");
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQuerySsid */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current 802.11 network type.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                             bytes written into the query buffer. If the call
+*                             failed due to invalid length of the query buffer,
+*                             returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter,
+			       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryInfrastructureMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(ENUM_PARAM_OP_MODE_T);
+
+	if (u4QueryBufferLen < sizeof(ENUM_PARAM_OP_MODE_T))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eOPMode;
+
+	/*
+	 ** According to OID_802_11_INFRASTRUCTURE_MODE
+	 ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE,
+	 ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned.
+	 */
+#if DBG
+	switch (*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer) {
+	case NET_TYPE_IBSS:
+		DBGLOG(OID, INFO, "IBSS mode\n");
+		break;
+	case NET_TYPE_INFRA:
+		DBGLOG(OID, INFO, "Infrastructure mode\n");
+		break;
+	default:
+		DBGLOG(OID, INFO, "Automatic mode\n");
+	}
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryInfrastructureMode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set mode to infrastructure or
+*        IBSS, or automatic switch between the two.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*             bytes read from the set buffer. If the call failed due to invalid
+*             length of the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter,
+			     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	ENUM_PARAM_OP_MODE_T eOpMode;
+
+	DEBUGFUNC("wlanoidSetInfrastructureMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	if (u4SetBufferLen < sizeof(ENUM_PARAM_OP_MODE_T))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	*pu4SetInfoLen = sizeof(ENUM_PARAM_OP_MODE_T);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	eOpMode = *(P_ENUM_PARAM_OP_MODE_T) pvSetBuffer;
+	/* Verify the new infrastructure mode. */
+	if (eOpMode >= NET_TYPE_NUM) {
+		DBGLOG(OID, TRACE, "Invalid mode value %d\n", eOpMode);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* check if possible to switch to AdHoc mode */
+	if (eOpMode == NET_TYPE_IBSS || eOpMode == NET_TYPE_DEDICATED_IBSS) {
+		if (cnmAisIbssIsPermitted(prAdapter) == FALSE) {
+			DBGLOG(OID, TRACE, "Mode value %d unallowed\n", eOpMode);
+			return WLAN_STATUS_FAILURE;
+		}
+	}
+
+	/* Save the new infrastructure mode setting. */
+	prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode;
+
+	/* Clean up the Tx key flag */
+	prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE;
+
+	prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE;
+#if CFG_SUPPORT_WAPI
+	prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0;
+	kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42);
+#endif
+
+#if CFG_SUPPORT_802_11W
+	prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
+	prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = FALSE;
+#endif
+
+#if CFG_SUPPORT_WPS2
+	kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200);
+	prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0;
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_INFRASTRUCTURE,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon, nicOidCmdTimeoutCommon, 0, NULL, pvSetBuffer, u4SetBufferLen);
+
+}				/* wlanoidSetInfrastructureMode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current 802.11 authentication
+*        mode.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter,
+		     OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryAuthMode");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T);
+
+	if (u4QueryBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eAuthMode;
+
+#if DBG
+	switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer) {
+	case AUTH_MODE_OPEN:
+		DBGLOG(OID, INFO, "Current auth mode: Open\n");
+		break;
+
+	case AUTH_MODE_SHARED:
+		DBGLOG(OID, INFO, "Current auth mode: Shared\n");
+		break;
+
+	case AUTH_MODE_AUTO_SWITCH:
+		DBGLOG(OID, INFO, "Current auth mode: Auto-switch\n");
+		break;
+
+	case AUTH_MODE_WPA:
+		DBGLOG(OID, INFO, "Current auth mode: WPA\n");
+		break;
+
+	case AUTH_MODE_WPA_PSK:
+		DBGLOG(OID, INFO, "Current auth mode: WPA PSK\n");
+		break;
+
+	case AUTH_MODE_WPA_NONE:
+		DBGLOG(OID, INFO, "Current auth mode: WPA None\n");
+		break;
+
+	case AUTH_MODE_WPA2:
+		DBGLOG(OID, INFO, "Current auth mode: WPA2\n");
+		break;
+
+	case AUTH_MODE_WPA2_PSK:
+		DBGLOG(OID, INFO, "Current auth mode: WPA2 PSK\n");
+		break;
+
+	default:
+		DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer);
+		break;
+	}
+#endif
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryAuthMode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the IEEE 802.11 authentication mode
+*        to the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_NOT_ACCEPTED
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 i, u4AkmSuite;
+	P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry;
+
+	DEBUGFUNC("wlanoidSetAuthMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+	ASSERT(pvSetBuffer);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	*pu4SetInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T);
+
+	if (u4SetBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	/* RF Test */
+	/* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */
+	/* return WLAN_STATUS_SUCCESS; */
+	/* } */
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	/* Check if the new authentication mode is valid. */
+	if (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer >= AUTH_MODE_NUM) {
+		DBGLOG(OID, TRACE, "Invalid auth mode %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer) {
+	case AUTH_MODE_WPA:
+	case AUTH_MODE_WPA_PSK:
+	case AUTH_MODE_WPA2:
+	case AUTH_MODE_WPA2_PSK:
+		/* infrastructure mode only */
+		if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_INFRA)
+			return WLAN_STATUS_NOT_ACCEPTED;
+		break;
+
+	case AUTH_MODE_WPA_NONE:
+		/* ad hoc mode only */
+		if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_IBSS)
+			return WLAN_STATUS_NOT_ACCEPTED;
+		break;
+
+	default:
+		break;
+	}
+
+	/* Save the new authentication mode. */
+	prAdapter->rWifiVar.rConnSettings.eAuthMode = *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer;
+
+#if DBG
+	switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) {
+	case AUTH_MODE_OPEN:
+		DBGLOG(RSN, TRACE, "New auth mode: open\n");
+		break;
+
+	case AUTH_MODE_SHARED:
+		DBGLOG(RSN, TRACE, "New auth mode: shared\n");
+		break;
+
+	case AUTH_MODE_AUTO_SWITCH:
+		DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n");
+		break;
+
+	case AUTH_MODE_WPA:
+		DBGLOG(RSN, TRACE, "New auth mode: WPA\n");
+		break;
+
+	case AUTH_MODE_WPA_PSK:
+		DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n");
+		break;
+
+	case AUTH_MODE_WPA_NONE:
+		DBGLOG(RSN, TRACE, "New auth mode: WPA None\n");
+		break;
+
+	case AUTH_MODE_WPA2:
+		DBGLOG(RSN, TRACE, "New auth mode: WPA2\n");
+		break;
+
+	case AUTH_MODE_WPA2_PSK:
+		DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n");
+		break;
+
+	default:
+		DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", prAdapter->rWifiVar.rConnSettings.eAuthMode);
+	}
+#endif
+
+	if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA) {
+		switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) {
+		case AUTH_MODE_WPA:
+			u4AkmSuite = WPA_AKM_SUITE_802_1X;
+			break;
+
+		case AUTH_MODE_WPA_PSK:
+			u4AkmSuite = WPA_AKM_SUITE_PSK;
+			break;
+
+		case AUTH_MODE_WPA_NONE:
+			u4AkmSuite = WPA_AKM_SUITE_NONE;
+			break;
+
+		case AUTH_MODE_WPA2:
+			u4AkmSuite = RSN_AKM_SUITE_802_1X;
+			break;
+
+		case AUTH_MODE_WPA2_PSK:
+			u4AkmSuite = RSN_AKM_SUITE_PSK;
+			break;
+
+		default:
+			u4AkmSuite = 0;
+		}
+	} else {
+		u4AkmSuite = 0;
+	}
+
+	/* Enable the specific AKM suite only. */
+	for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
+		prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
+
+		if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite)
+			prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE;
+		else
+			prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE;
+#if CFG_SUPPORT_802_11W
+		if (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) {
+			if ((u4AkmSuite == RSN_AKM_SUITE_PSK) &&
+			    prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_PSK_SHA256) {
+				DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n");
+				prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE;
+
+			}
+			if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) &&
+			    prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_802_1X_SHA256) {
+				DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n");
+				prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE;
+			}
+		}
+#endif
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidSetAuthMode */
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current 802.11 privacy filter
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryPrivacyFilter");
+
+	ASSERT(prAdapter);
+
+	ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T);
+
+	if (u4QueryBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer = prAdapter->rWlanInfo.ePrivacyFilter;
+
+#if DBG
+	switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer) {
+	case PRIVACY_FILTER_ACCEPT_ALL:
+		DBGLOG(OID, INFO, "Current privacy mode: open mode\n");
+		break;
+
+	case PRIVACY_FILTER_8021xWEP:
+		DBGLOG(OID, INFO, "Current privacy mode: filtering mode\n");
+		break;
+
+	default:
+		DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer);
+	}
+#endif
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryPrivacyFilter */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the IEEE 802.11 privacy filter
+*        to the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_NOT_ACCEPTED
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+
+	DEBUGFUNC("wlanoidSetPrivacyFilter");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+	ASSERT(pvSetBuffer);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	*pu4SetInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T);
+
+	if (u4SetBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	/* Check if the new authentication mode is valid. */
+	if (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer >= PRIVACY_FILTER_NUM) {
+		DBGLOG(OID, TRACE, "Invalid privacy filter %d\n", *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer) {
+	default:
+		break;
+	}
+
+	/* Save the new authentication mode. */
+	prAdapter->rWlanInfo.ePrivacyFilter = *(ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidSetPrivacyFilter */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to reload the available default settings for
+*        the specified type field.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
+	UINT_32 u4Len;
+	UINT_8 ucCmdSeqNum;
+
+	DEBUGFUNC("wlanoidSetReloadDefaults");
+
+	ASSERT(prAdapter);
+
+	ASSERT(pu4SetInfoLen);
+	*pu4SetInfoLen = sizeof(PARAM_RELOAD_DEFAULTS);
+
+	/* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */
+	/* return WLAN_STATUS_SUCCESS; */
+	/* } */
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	ASSERT(pvSetBuffer);
+	/* Verify the available reload options and reload the settings. */
+	switch (*(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer) {
+	case ENUM_RELOAD_WEP_KEYS:
+		/* Reload available default WEP keys from the permanent
+		   storage. */
+		prAdapter->rWifiVar.rConnSettings.eAuthMode = AUTH_MODE_OPEN;
+		/* ENUM_ENCRYPTION_DISABLED; */
+		prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT;
+		{
+			P_GLUE_INFO_T prGlueInfo;
+			P_CMD_INFO_T prCmdInfo;
+			P_WIFI_CMD_T prWifiCmd;
+			P_CMD_802_11_KEY prCmdKey;
+			UINT_8 aucBCAddr[] = BC_MAC_ADDR;
+
+			prGlueInfo = prAdapter->prGlueInfo;
+			prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY)));
+
+			if (!prCmdInfo) {
+				DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+				return WLAN_STATUS_FAILURE;
+			}
+			/* increase command sequence number */
+			ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+			/* compose CMD_802_11_KEY cmd pkt */
+			prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+			prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX;
+			prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY);
+			prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
+			prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
+			prCmdInfo->fgIsOid = TRUE;
+			prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY;
+			prCmdInfo->fgSetQuery = TRUE;
+			prCmdInfo->fgNeedResp = FALSE;
+			prCmdInfo->fgDriverDomainMCR = FALSE;
+			prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+			prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T);
+			prCmdInfo->pvInformationBuffer = pvSetBuffer;
+			prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
+
+			/* Setup WIFI_CMD_T */
+			prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+			prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+			prWifiCmd->ucCID = prCmdInfo->ucCID;
+			prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+			prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+			prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer);
+
+			kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY));
+
+			prCmdKey->ucAddRemove = 0;	/* Remove */
+			prCmdKey->ucKeyId = 0;	/* (UINT_8)(prRemovedKey->u4KeyIndex & 0x000000ff); */
+			kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, MAC_ADDR_LEN);
+
+			ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM);
+
+			prCmdKey->ucKeyType = 0;
+
+			/* insert into prCmdQueue */
+			kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+			/* wakeup txServiceThread later */
+			GLUE_SET_EVENT(prGlueInfo);
+
+			return WLAN_STATUS_PENDING;
+		}
+
+		break;
+
+	default:
+		DBGLOG(OID, TRACE, "Invalid reload option %d\n", *(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer);
+		rStatus = WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */
+	eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE;
+	wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, sizeof(eNetworkType), &u4Len);
+
+	return rStatus;
+}				/* wlanoidSetReloadDefaults */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a WEP key to the driver.
+*
+* \param[in]  prAdapter Pointer to the Adapter structure.
+* \param[in]  pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in]  u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+#ifdef LINUX
+UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */];
+UINT_8 aucBCAddr[] = BC_MAC_ADDR;
+#endif
+WLAN_STATUS
+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+#ifndef LINUX
+	UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */];
+	UINT_8 aucBCAddr[] = BC_MAC_ADDR;
+#endif
+	P_PARAM_WEP_T prNewWepKey;
+	P_PARAM_KEY_T prParamKey = (P_PARAM_KEY_T) keyBuffer;
+	UINT_32 u4KeyId, u4SetLen;
+
+	DEBUGFUNC("wlanoidSetAddWep");
+
+	ASSERT(prAdapter);
+
+	*pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial);
+
+	if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)) {
+		ASSERT(pu4SetInfoLen);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	prNewWepKey = (P_PARAM_WEP_T) pvSetBuffer;
+
+	/* Verify the total buffer for minimum length. */
+	if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial) + prNewWepKey->u4KeyLength) {
+		DBGLOG(OID, WARN, "Invalid total buffer length (%d) than minimum length (%d)\n",
+				   (UINT_8) u4SetBufferLen, (UINT_8) OFFSET_OF(PARAM_WEP_T, aucKeyMaterial));
+
+		*pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Verify the key structure length. */
+	if (prNewWepKey->u4Length > u4SetBufferLen) {
+		DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n",
+				   (UINT_8) prNewWepKey->u4Length, (UINT_8) u4SetBufferLen);
+
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Verify the key material length for maximum key material length:16 */
+	if (prNewWepKey->u4KeyLength > 16 /* LEGACY_KEY_MAX_LEN */) {
+		DBGLOG(OID, WARN, "Invalid key material length (%d) greater than maximum key material length (16)\n",
+				   (UINT_8) prNewWepKey->u4KeyLength);
+
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, 29) /* WEP_KEY_ID_FIELD */;
+
+	/* Verify whether key index is valid or not, current version
+	   driver support only 4 global WEP keys setting by this OID */
+	if (u4KeyId > MAX_KEY_NUM - 1) {
+		DBGLOG(OID, ERROR, "Error, invalid WEP key ID: %d\n", (UINT_8) u4KeyId);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	prParamKey->u4KeyIndex = u4KeyId;
+
+	/* Transmit key */
+	if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY)
+		prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY;
+
+	/* Per client key */
+	if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY)
+		prParamKey->u4KeyIndex |= IS_UNICAST_KEY;
+
+	prParamKey->u4KeyLength = prNewWepKey->u4KeyLength;
+
+	kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN);
+
+	kalMemCopy(prParamKey->aucKeyMaterial, prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength);
+
+	prParamKey->u4Length = OFFSET_OF(PARAM_KEY_T, aucKeyMaterial) + prNewWepKey->u4KeyLength;
+
+	wlanoidSetAddKey(prAdapter, (PVOID) prParamKey, prParamKey->u4Length, &u4SetLen);
+
+	return WLAN_STATUS_PENDING;
+}				/* wlanoidSetAddWep */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to request the driver to remove the WEP key
+*          at the specified key index.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	UINT_32 u4KeyId, u4SetLen;
+	PARAM_REMOVE_KEY_T rRemoveKey;
+	UINT_8 aucBCAddr[] = BC_MAC_ADDR;
+
+	DEBUGFUNC("wlanoidSetRemoveWep");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_KEY_INDEX);
+
+	if (u4SetBufferLen < sizeof(PARAM_KEY_INDEX))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	u4KeyId = *(PUINT_32) pvSetBuffer;
+
+	/* Dump PARAM_WEP content. */
+	DBGLOG(OID, INFO, "Set: Dump PARAM_KEY_INDEX content\n");
+	DBGLOG(OID, INFO, "Index : 0x%08x\n", u4KeyId);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	if (u4KeyId & IS_TRANSMIT_KEY) {
+		/* Bit 31 should not be set */
+		DBGLOG(OID, ERROR, "Invalid WEP key index: 0x%08x\n", u4KeyId);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	u4KeyId &= BITS(0, 7);
+
+	/* Verify whether key index is valid or not. Current version
+	   driver support only 4 global WEP keys. */
+	if (u4KeyId > MAX_KEY_NUM - 1) {
+		DBGLOG(OID, ERROR, "invalid WEP key ID %u\n", u4KeyId);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
+	rRemoveKey.u4KeyIndex = *(PUINT_32) pvSetBuffer;
+
+	kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN);
+
+	wlanoidSetRemoveKey(prAdapter, (PVOID)&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T), &u4SetLen);
+
+	return WLAN_STATUS_PENDING;
+}				/* wlanoidSetRemoveWep */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a key to the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer,
+		  IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	P_PARAM_KEY_T prNewKey;
+	P_CMD_802_11_KEY prCmdKey;
+	UINT_8 ucCmdSeqNum;
+
+#if 0
+	DEBUGFUNC("wlanoidSetAddKey");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+#endif
+
+	prNewKey = (P_PARAM_KEY_T) pvSetBuffer;
+
+#if 0
+	/* Verify the key structure length. */
+	if (prNewKey->u4Length > u4SetBufferLen) {
+		DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n",
+				   (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen);
+
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	/* Verify the key material length for key material buffer */
+	if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) {
+		DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength);
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Exception check */
+	if (prNewKey->u4KeyIndex & 0x0fffff00)
+		return WLAN_STATUS_INVALID_DATA;
+
+	/* Exception check, pairwise key must with transmit bit enabled */
+	if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY)
+		return WLAN_STATUS_INVALID_DATA;
+
+	if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN ||
+	      prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) {
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Exception check, pairwise key must with transmit bit enabled */
+	if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) {
+		if (((prNewKey->u4KeyIndex & 0xff) != 0) ||
+		    ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff)
+		     && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff)
+		     && (prNewKey->arBSSID[5] == 0xff))) {
+			return WLAN_STATUS_INVALID_DATA;
+		}
+	}
+
+	*pu4SetInfoLen = u4SetBufferLen;
+#endif
+
+	/* Dump PARAM_KEY content. */
+	DBGLOG(OID, TRACE, "Set: PARAM_KEY Length: 0x%08x, Key Index: 0x%08x, Key Length: 0x%08x\n",
+		prNewKey->u4Length, prNewKey->u4KeyIndex, prNewKey->u4KeyLength);
+	DBGLOG(OID, TRACE, "BSSID:\n");
+	DBGLOG_MEM8(OID, TRACE, prNewKey->arBSSID, sizeof(PARAM_MAC_ADDRESS));
+	DBGLOG(OID, TRACE, "Key RSC:\n");
+	DBGLOG_MEM8(OID, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC));
+	DBGLOG(OID, TRACE, "Key Material:\n");
+	DBGLOG_MEM8(OID, TRACE, prNewKey->aucKeyMaterial, prNewKey->u4KeyLength);
+
+	if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) {
+		/* Todo:: Store the legacy wep key for OID_802_11_RELOAD_DEFAULTS */
+		/* Todo:: Nothing */
+	}
+
+	if (prNewKey->u4KeyIndex & IS_TRANSMIT_KEY)
+		prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = TRUE;
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY)));
+
+	if (!prCmdInfo) {
+		DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+	DBGLOG(OID, TRACE, "ucCmdSeqNum = %d\n", ucCmdSeqNum);
+
+	/* compose CMD_802_11_KEY cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY);
+	prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
+	prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
+	prCmdInfo->fgIsOid = fgIsOid;
+	prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = u4SetBufferLen;
+	prCmdInfo->pvInformationBuffer = pvSetBuffer;
+	prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer);
+
+	kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY));
+
+	prCmdKey->ucAddRemove = 1;	/* Add */
+
+	prCmdKey->ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0;
+	prCmdKey->ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0;
+	prCmdKey->ucIsAuthenticator = ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) ? 1 : 0;
+
+	kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->arBSSID, MAC_ADDR_LEN);
+
+	prCmdKey->ucNetType = 0;	/* AIS */
+
+	prCmdKey->ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff);
+
+	/* Note: adjust the key length for WPA-None */
+	prCmdKey->ucKeyLen = (UINT_8) prNewKey->u4KeyLength;
+
+	kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen);
+
+	if (prNewKey->u4KeyLength == 5) {
+		prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40;
+	} else if (prNewKey->u4KeyLength == 13) {
+		prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104;
+	} else if (prNewKey->u4KeyLength == 16) {
+		if ((ucAlgorithmId != CIPHER_SUITE_CCMP) &&
+		    (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA))
+			prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128;
+		else {
+#if CFG_SUPPORT_802_11W
+			if (prCmdKey->ucKeyId >= 4) {
+				prCmdKey->ucAlgorithmId = CIPHER_SUITE_BIP;
+				P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+				prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+				prAisSpecBssInfo->fgBipKeyInstalled = TRUE;
+			} else
+#endif
+				prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP;
+			if (rsnCheckPmkidCandicate(prAdapter)) {
+				P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+				prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+				DBGLOG(RSN, TRACE,
+				       "Add key: Prepare a timer to indicate candidate PMKID Candidate\n");
+				cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer);
+				cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer,
+						   SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
+			}
+		}
+	} else if (prNewKey->u4KeyLength == 32) {
+		if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) {
+			if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED)
+				prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP;
+			else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) {
+				prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP;
+				prCmdKey->ucKeyLen = CCMP_KEY_LEN;
+			}
+		} else
+			prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP;
+	}
+
+	DBGLOG(RSN, TRACE, "prCmdKey->ucAlgorithmId=%d, key len=%d\n",
+			    prCmdKey->ucAlgorithmId, (UINT32) prNewKey->u4KeyLength);
+
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+
+	return WLAN_STATUS_PENDING;
+}
+
+WLAN_STATUS
+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_KEY_T prNewKey;
+
+	DEBUGFUNC("wlanoidSetAddKey");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	prNewKey = (P_PARAM_KEY_T) pvSetBuffer;
+
+	/* Verify the key structure length. */
+	if (prNewKey->u4Length > u4SetBufferLen) {
+		DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n",
+				   (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen);
+
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	/* Verify the key material length for key material buffer */
+	if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) {
+		DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength);
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Exception check */
+	if (prNewKey->u4KeyIndex & 0x0fffff00)
+		return WLAN_STATUS_INVALID_DATA;
+
+	/* Exception check, pairwise key must with transmit bit enabled */
+	if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) {
+		if (((prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN) &&
+			(prNewKey->u4KeyIndex & 0xff) != 0) ||
+			EQUAL_MAC_ADDR(prNewKey->arBSSID, "\xff\xff\xff\xff\xff\xff")) {
+			return WLAN_STATUS_INVALID_DATA;
+		}
+	} else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY)
+		return WLAN_STATUS_INVALID_DATA;
+
+	if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN ||
+	      prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) {
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+#if (CFG_SUPPORT_TDLS == 1)
+	/*
+	   supplicant will set key before updating station & enabling the link so we need to
+	   backup the key information and set key when link is enabled
+	 */
+	if (TdlsexKeyHandle(prAdapter, prNewKey) == TDLS_STATUS_SUCCESS)
+		return WLAN_STATUS_SUCCESS;
+#endif /* CFG_SUPPORT_TDLS */
+
+	return _wlanoidSetAddKey(prAdapter, pvSetBuffer, u4SetBufferLen, TRUE, CIPHER_SUITE_NONE, pu4SetInfoLen);
+}				/* wlanoidSetAddKey */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to request the driver to remove the key at
+*        the specified key index.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	P_PARAM_REMOVE_KEY_T prRemovedKey;
+	P_CMD_802_11_KEY prCmdKey;
+	UINT_8 ucCmdSeqNum;
+
+	DEBUGFUNC("wlanoidSetRemoveKey");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	ASSERT(pvSetBuffer);
+	prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer;
+
+	/* Dump PARAM_REMOVE_KEY content. */
+	DBGLOG(OID, TRACE, "Set: Dump PARAM_REMOVE_KEY content\n");
+	DBGLOG(OID, TRACE, "Length    : 0x%08x\n", prRemovedKey->u4Length);
+	DBGLOG(OID, TRACE, "Key Index : 0x%08x\n", prRemovedKey->u4KeyIndex);
+	DBGLOG(OID, TRACE, "BSSID:\n");
+	DBGLOG_MEM8(OID, TRACE, prRemovedKey->arBSSID, MAC_ADDR_LEN);
+
+	/* Check bit 31: this bit should always 0 */
+	if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) {
+		/* Bit 31 should not be set */
+		DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Check bits 8 ~ 29 should always be 0 */
+	if (prRemovedKey->u4KeyIndex & BITS(8, 29)) {
+		/* Bit 31 should not be set */
+		DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Clean up the Tx key flag */
+	if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY)
+		prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE;
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY)));
+
+	if (!prCmdInfo) {
+		DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_802_11_KEY cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY);
+	prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
+	prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
+	prCmdInfo->fgIsOid = TRUE;
+	prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T);
+	prCmdInfo->pvInformationBuffer = pvSetBuffer;
+	prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer);
+
+	kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY));
+
+	prCmdKey->ucAddRemove = 0;	/* Remove */
+	prCmdKey->ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff);
+	kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN);
+
+#if CFG_SUPPORT_802_11W
+	ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM + 2);
+#else
+	/* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */
+#endif
+
+	if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY)
+		prCmdKey->ucKeyType = 1;
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+
+	return WLAN_STATUS_PENDING;
+}				/* wlanoidSetRemoveKey */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current encryption status.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter,
+			     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	BOOLEAN fgTransmitKeyAvailable = TRUE;
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus = 0;
+
+	DEBUGFUNC("wlanoidQueryEncryptionStatus");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T);
+
+	fgTransmitKeyAvailable = prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist;
+
+	switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) {
+	case ENUM_ENCRYPTION3_ENABLED:
+		if (fgTransmitKeyAvailable)
+			eEncStatus = ENUM_ENCRYPTION3_ENABLED;
+		else
+			eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT;
+		break;
+
+	case ENUM_ENCRYPTION2_ENABLED:
+		if (fgTransmitKeyAvailable) {
+			eEncStatus = ENUM_ENCRYPTION2_ENABLED;
+			break;
+		}
+		eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT;
+		break;
+
+	case ENUM_ENCRYPTION1_ENABLED:
+		if (fgTransmitKeyAvailable)
+			eEncStatus = ENUM_ENCRYPTION1_ENABLED;
+		else
+			eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT;
+		break;
+
+	case ENUM_ENCRYPTION_DISABLED:
+		eEncStatus = ENUM_ENCRYPTION_DISABLED;
+		break;
+
+	default:
+		DBGLOG(OID, ERROR, "Unknown Encryption Status Setting:%d\n",
+				    prAdapter->rWifiVar.rConnSettings.eEncStatus);
+	}
+
+#if DBG
+	DBGLOG(OID, INFO,
+	       "Encryption status: %d Return:%d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus);
+#endif
+
+	*(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvQueryBuffer = eEncStatus;
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryEncryptionStatus */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the encryption status to the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_NOT_SUPPORTED
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEewEncrypt;
+
+	DEBUGFUNC("wlanoidSetEncryptionStatus");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	*pu4SetInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T);
+
+	/* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */
+	/* return WLAN_STATUS_SUCCESS; */
+	/* } */
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	eEewEncrypt = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer;
+	DBGLOG(OID, TRACE, "ENCRYPTION_STATUS %d\n", eEewEncrypt);
+
+	switch (eEewEncrypt) {
+	case ENUM_ENCRYPTION_DISABLED:	/* Disable WEP, TKIP, AES */
+		DBGLOG(RSN, TRACE, "Disable Encryption\n");
+		secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128);
+		break;
+
+	case ENUM_ENCRYPTION1_ENABLED:	/* Enable WEP. Disable TKIP, AES */
+		DBGLOG(RSN, TRACE, "Enable Encryption1\n");
+		secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128);
+		break;
+
+	case ENUM_ENCRYPTION2_ENABLED:	/* Enable WEP, TKIP. Disable AES */
+		secSetCipherSuite(prAdapter,
+				  CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP);
+		DBGLOG(RSN, TRACE, "Enable Encryption2\n");
+		break;
+
+	case ENUM_ENCRYPTION3_ENABLED:	/* Enable WEP, TKIP, AES */
+		secSetCipherSuite(prAdapter,
+				  CIPHER_FLAG_WEP40 |
+				  CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP);
+		DBGLOG(RSN, TRACE, "Enable Encryption3\n");
+		break;
+
+	default:
+		DBGLOG(RSN, WARN, "Unacceptible encryption status: %d\n",
+				   *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer);
+
+		rStatus = WLAN_STATUS_NOT_SUPPORTED;
+	}
+
+	if (rStatus == WLAN_STATUS_SUCCESS) {
+		/* Save the new encryption status. */
+		prAdapter->rWifiVar.rConnSettings.eEncStatus = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer;
+
+		DBGLOG(RSN, TRACE, "wlanoidSetEncryptionStatus to %d\n",
+				    prAdapter->rWifiVar.rConnSettings.eEncStatus);
+	}
+
+	return rStatus;
+}				/* wlanoidSetEncryptionStatus */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to test the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_802_11_TEST_T prTest;
+	PVOID pvTestData;
+	PVOID pvStatusBuffer;
+	UINT_32 u4StatusBufferSize;
+
+	DEBUGFUNC("wlanoidSetTest");
+
+	ASSERT(prAdapter);
+
+	ASSERT(pu4SetInfoLen);
+	ASSERT(pvSetBuffer);
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	prTest = (P_PARAM_802_11_TEST_T) pvSetBuffer;
+
+	DBGLOG(OID, TRACE, "Test - Type %u\n", prTest->u4Type);
+
+	switch (prTest->u4Type) {
+	case 1:		/* Type 1: generate an authentication event */
+		pvTestData = (PVOID) &prTest->u.AuthenticationEvent;
+		pvStatusBuffer = (PVOID) prAdapter->aucIndicationEventBuffer;
+		u4StatusBufferSize = prTest->u4Length - 8;
+		if (u4StatusBufferSize > sizeof(PARAM_AUTH_EVENT_T)) {
+			DBGLOG(OID, TRACE, "prTest->u4Length error %u\n", u4StatusBufferSize);
+			ASSERT(FALSE);
+		}
+		break;
+
+	case 2:		/* Type 2: generate an RSSI status indication */
+		pvTestData = (PVOID) &prTest->u.RssiTrigger;
+		pvStatusBuffer = (PVOID) &prAdapter->rWlanInfo.rCurrBssId.rRssi;
+		u4StatusBufferSize = sizeof(PARAM_RSSI);
+		break;
+
+	default:
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	ASSERT(u4StatusBufferSize <= 180);
+	if (u4StatusBufferSize > 180)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	/* Get the contents of the StatusBuffer from the test structure. */
+	kalMemCopy(pvStatusBuffer, pvTestData, u4StatusBufferSize);
+
+	kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+				     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, pvStatusBuffer, u4StatusBufferSize);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidSetTest */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the driver's WPA2 status.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_CAPABILITY_T prCap;
+	P_PARAM_AUTH_ENCRYPTION_T prAuthenticationEncryptionSupported;
+
+	DEBUGFUNC("wlanoidQueryCapability");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = 4 * sizeof(UINT_32) + 14 * sizeof(PARAM_AUTH_ENCRYPTION_T);
+
+	if (u4QueryBufferLen < *pu4QueryInfoLen)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prCap = (P_PARAM_CAPABILITY_T) pvQueryBuffer;
+
+	prCap->u4Length = *pu4QueryInfoLen;
+	prCap->u4Version = 2;	/* WPA2 */
+	prCap->u4NoOfPMKIDs = CFG_MAX_PMKID_CACHE;
+	prCap->u4NoOfAuthEncryptPairsSupported = 14;
+
+	prAuthenticationEncryptionSupported = &prCap->arAuthenticationEncryptionSupported[0];
+
+	/* fill 14 entries of supported settings */
+	prAuthenticationEncryptionSupported[0].eAuthModeSupported = AUTH_MODE_OPEN;
+
+	prAuthenticationEncryptionSupported[0].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED;
+
+	prAuthenticationEncryptionSupported[1].eAuthModeSupported = AUTH_MODE_OPEN;
+	prAuthenticationEncryptionSupported[1].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED;
+
+	prAuthenticationEncryptionSupported[2].eAuthModeSupported = AUTH_MODE_SHARED;
+	prAuthenticationEncryptionSupported[2].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED;
+
+	prAuthenticationEncryptionSupported[3].eAuthModeSupported = AUTH_MODE_SHARED;
+	prAuthenticationEncryptionSupported[3].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED;
+
+	prAuthenticationEncryptionSupported[4].eAuthModeSupported = AUTH_MODE_WPA;
+	prAuthenticationEncryptionSupported[4].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED;
+
+	prAuthenticationEncryptionSupported[5].eAuthModeSupported = AUTH_MODE_WPA;
+	prAuthenticationEncryptionSupported[5].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED;
+
+	prAuthenticationEncryptionSupported[6].eAuthModeSupported = AUTH_MODE_WPA_PSK;
+	prAuthenticationEncryptionSupported[6].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED;
+
+	prAuthenticationEncryptionSupported[7].eAuthModeSupported = AUTH_MODE_WPA_PSK;
+	prAuthenticationEncryptionSupported[7].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED;
+
+	prAuthenticationEncryptionSupported[8].eAuthModeSupported = AUTH_MODE_WPA_NONE;
+	prAuthenticationEncryptionSupported[8].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED;
+
+	prAuthenticationEncryptionSupported[9].eAuthModeSupported = AUTH_MODE_WPA_NONE;
+	prAuthenticationEncryptionSupported[9].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED;
+
+	prAuthenticationEncryptionSupported[10].eAuthModeSupported = AUTH_MODE_WPA2;
+	prAuthenticationEncryptionSupported[10].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED;
+
+	prAuthenticationEncryptionSupported[11].eAuthModeSupported = AUTH_MODE_WPA2;
+	prAuthenticationEncryptionSupported[11].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED;
+
+	prAuthenticationEncryptionSupported[12].eAuthModeSupported = AUTH_MODE_WPA2_PSK;
+	prAuthenticationEncryptionSupported[12].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED;
+
+	prAuthenticationEncryptionSupported[13].eAuthModeSupported = AUTH_MODE_WPA2_PSK;
+	prAuthenticationEncryptionSupported[13].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidQueryCapability */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the PMKID in the PMK cache.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                             bytes written into the query buffer. If the call
+*                             failed due to invalid length of the query buffer,
+*                             returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter,
+		  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	UINT_32 i;
+	P_PARAM_PMKID_T prPmkid;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+	DEBUGFUNC("wlanoidQueryPmkid");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	*pu4QueryInfoLen = OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo) +
+	    prAisSpecBssInfo->u4PmkidCacheCount * sizeof(PARAM_BSSID_INFO_T);
+
+	if (u4QueryBufferLen < *pu4QueryInfoLen)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prPmkid = (P_PARAM_PMKID_T) pvQueryBuffer;
+
+	prPmkid->u4Length = *pu4QueryInfoLen;
+	prPmkid->u4BSSIDInfoCount = prAisSpecBssInfo->u4PmkidCacheCount;
+
+	for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) {
+		kalMemCopy(prPmkid->arBSSIDInfo[i].arBSSID,
+			   prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, sizeof(PARAM_MAC_ADDRESS));
+		kalMemCopy(prPmkid->arBSSIDInfo[i].arPMKID,
+			   prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE));
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidQueryPmkid */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the PMKID to the PMK cache in the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	UINT_32 i, j;
+	P_PARAM_PMKID_T prPmkid;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+	DEBUGFUNC("wlanoidSetPmkid");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	/* It's possibble BSSIDInfoCount is zero, because OS wishes to clean PMKID */
+	if (u4SetBufferLen < OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	ASSERT(pvSetBuffer);
+	prPmkid = (P_PARAM_PMKID_T) pvSetBuffer;
+
+	if (u4SetBufferLen <
+	    ((prPmkid->u4BSSIDInfoCount * sizeof(PARAM_BSSID_INFO_T)) + OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo)))
+		return WLAN_STATUS_INVALID_DATA;
+
+	if (prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)
+		return WLAN_STATUS_INVALID_DATA;
+
+	DBGLOG(OID, TRACE, "Count %u\n", prPmkid->u4BSSIDInfoCount);
+
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	/* This OID replace everything in the PMKID cache. */
+	if (prPmkid->u4BSSIDInfoCount == 0) {
+		prAisSpecBssInfo->u4PmkidCacheCount = 0;
+		kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE);
+	}
+	if ((prAisSpecBssInfo->u4PmkidCacheCount + prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)) {
+		prAisSpecBssInfo->u4PmkidCacheCount = 0;
+		kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE);
+	}
+
+	/*
+	   The driver can only clear its PMKID cache whenever it make a media disconnect
+	   indication. Otherwise, it must change the PMKID cache only when set through this OID.
+	 */
+#if CFG_RSN_MIGRATION
+	for (i = 0; i < prPmkid->u4BSSIDInfoCount; i++) {
+		/* Search for desired BSSID. If desired BSSID is found,
+		   then set the PMKID */
+		if (!rsnSearchPmkidEntry(prAdapter, (PUINT_8) prPmkid->arBSSIDInfo[i].arBSSID, &j)) {
+			/* No entry found for the specified BSSID, so add one entry */
+			if (prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE - 1) {
+				j = prAisSpecBssInfo->u4PmkidCacheCount;
+				kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
+					   prPmkid->arBSSIDInfo[i].arBSSID, sizeof(PARAM_MAC_ADDRESS));
+				prAisSpecBssInfo->u4PmkidCacheCount++;
+			} else {
+				j = CFG_MAX_PMKID_CACHE;
+			}
+		}
+
+		if (j < CFG_MAX_PMKID_CACHE) {
+			kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID,
+				   prPmkid->arBSSIDInfo[i].arPMKID, sizeof(PARAM_PMKID_VALUE));
+			DBGLOG(RSN, TRACE, "Add BSSID %pM idx=%d PMKID value %pM\n",
+					    (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID), (UINT_32) j,
+					    (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID));
+			prAisSpecBssInfo->arPmkidCache[j].fgPmkidExist = TRUE;
+		}
+	}
+#endif
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidSetPmkid */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the set of supported data rates that
+*          the radio is capable of running
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query
+* \param[in] u4QueryBufferLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number
+*                             of bytes written into the query buffer. If the
+*                             call failed due to invalid length of the query
+*                             buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter,
+			   OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	PARAM_RATES eRate = {
+		/* BSSBasicRateSet for 802.11n Non-HT rates */
+		0x8C,		/* 6M */
+		0x92,		/* 9M */
+		0x98,		/* 12M */
+		0xA4,		/* 18M */
+		0xB0,		/* 24M */
+		0xC8,		/* 36M */
+		0xE0,		/* 48M */
+		0xEC		/* 54M */
+	};
+
+	DEBUGFUNC("wlanoidQuerySupportedRates");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_RATES_EX);
+
+	if (u4QueryBufferLen < *pu4QueryInfoLen) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	kalMemCopy(pvQueryBuffer, (PVOID) &eRate, sizeof(PARAM_RATES));
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidQuerySupportedRates() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query current desired rates.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryDesiredRates");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_RATES_EX);
+
+	if (u4QueryBufferLen < *pu4QueryInfoLen) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	kalMemCopy(pvQueryBuffer, (PVOID) &(prAdapter->rWlanInfo.eDesiredRates), sizeof(PARAM_RATES));
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of wlanoidQueryDesiredRates() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to Set the desired rates.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	UINT_32 i;
+
+	DEBUGFUNC("wlanoidSetDesiredRates");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen < sizeof(PARAM_RATES)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*pu4SetInfoLen = sizeof(PARAM_RATES);
+
+	if (u4SetBufferLen < sizeof(PARAM_RATES))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	kalMemCopy((PVOID) &(prAdapter->rWlanInfo.eDesiredRates), pvSetBuffer, sizeof(PARAM_RATES));
+
+	prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = PARAM_MAX_LEN_RATES;
+	for (i = 0; i < PARAM_MAX_LEN_RATES; i++)
+		prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = (UINT_16) (prAdapter->rWlanInfo.eDesiredRates[i]);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_LINK_ATTRIB,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_LINK_ATTRIB),
+				   (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen);
+
+}				/* end of wlanoidSetDesiredRates() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the maximum frame size in bytes,
+*        not including the header.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the
+*                               call failed due to invalid length of the query
+*                               buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryMaxFrameSize");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < sizeof(UINT_32)) {
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - ETHERNET_HEADER_SZ;
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryMaxFrameSize */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the maximum total packet length
+*        in bytes.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryMaxTotalSize");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < sizeof(UINT_32)) {
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ;
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryMaxTotalSize */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the vendor ID of the NIC.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter,
+		     OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+#if DBG
+	PUINT_8 cp;
+#endif
+	DEBUGFUNC("wlanoidQueryVendorId");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < sizeof(UINT_32)) {
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3);
+	*((PUINT_8) pvQueryBuffer + 3) = 1;
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+#if DBG
+	cp = (PUINT_8) pvQueryBuffer;
+	DBGLOG(OID, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], cp[1], cp[2], cp[3]);
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryVendorId */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current RSSI value.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*   bytes written into the query buffer. If the call failed due to invalid length of
+*   the query buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter,
+		 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryRssi");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_RSSI);
+
+	/* Check for query buffer length */
+	if (u4QueryBufferLen < *pu4QueryInfoLen) {
+		DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) {
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (prAdapter->fgIsLinkQualityValid == TRUE &&
+		   (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) {
+		PARAM_RSSI rRssi;
+
+		rRssi = (PARAM_RSSI) prAdapter->rLinkQuality.cRssi;	/* ranged from (-128 ~ 30) in unit of dBm */
+
+		if (rRssi > PARAM_WHQL_RSSI_MAX_DBM)
+			rRssi = PARAM_WHQL_RSSI_MAX_DBM;
+		else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM)
+			rRssi = PARAM_WHQL_RSSI_MIN_DBM;
+
+		kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI));
+		return WLAN_STATUS_SUCCESS;
+	}
+#ifdef LINUX
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_LINK_QUALITY,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryLinkQuality,
+				   nicOidCmdTimeoutCommon,
+				   *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen);
+#else
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_LINK_QUALITY,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryLinkQuality,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+#endif
+}				/* end of wlanoidQueryRssi() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current RSSI trigger value.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*   bytes written into the query buffer. If the call failed due to invalid length of
+*   the query buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter,
+			OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryRssiTrigger");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_NONE)
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+
+	*pu4QueryInfoLen = sizeof(PARAM_RSSI);
+
+	/* Check for query buffer length */
+	if (u4QueryBufferLen < *pu4QueryInfoLen) {
+		DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	*(PARAM_RSSI *) pvQueryBuffer = prAdapter->rWlanInfo.rRssiTriggerValue;
+	DBGLOG(OID, INFO, "RSSI trigger: %d dBm\n", *(PARAM_RSSI *) pvQueryBuffer);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryRssiTrigger */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a trigger value of the RSSI event.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns the
+*                          amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PARAM_RSSI rRssiTriggerValue;
+
+	DEBUGFUNC("wlanoidSetRssiTrigger");
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_RSSI);
+	rRssiTriggerValue = *(PARAM_RSSI *) pvSetBuffer;
+
+	if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM)
+		return
+		    /* Save the RSSI trigger value to the Adapter structure */
+		    prAdapter->rWlanInfo.rRssiTriggerValue = rRssiTriggerValue;
+
+	/* If the RSSI trigger value is equal to the current RSSI value, the
+	 * indication triggers immediately. We need to indicate the protocol
+	 * that an RSSI status indication event triggers. */
+	if (rRssiTriggerValue == (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) {
+		prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED;
+
+		kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+					     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+					     (PVOID) &prAdapter->rWlanInfo.rRssiTriggerValue, sizeof(PARAM_RSSI));
+	} else if (rRssiTriggerValue < (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi))
+		prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_GREATER;
+	else if (rRssiTriggerValue > (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi))
+		prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_LESS;
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidSetRssiTrigger */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a suggested value for the number of
+*        bytes of received packet data that will be indicated to the protocol
+*        driver. We just accept the set and ignore this value.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	DEBUGFUNC("wlanoidSetCurrentLookahead");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen < sizeof(UINT_32)) {
+		*pu4SetInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidSetCurrentLookahead */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the number of frames that the driver
+*        receives but does not indicate to the protocols due to errors.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryRcvError");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		/* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart;
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart;
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryRecvError,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryRcvError */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief This routine is called to query the number of frames that the NIC
+*          cannot receive due to lack of NIC receive buffer space.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS If success;
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryRcvNoBuffer");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) 0;	/* @FIXME */
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) 0;	/* @FIXME */
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryRecvNoBuffer,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryRcvNoBuffer */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief This routine is called to query the number of frames that the NIC
+*          received and it is CRC error.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS If success;
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryRcvCrcError");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart;
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart;
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryRecvCrcError,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryRcvCrcError */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query the current 802.11 statistics.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) {
+		DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics;
+
+		*pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+		prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer;
+
+		prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+		prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount;
+		prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount;
+		prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount;
+		prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount;
+		prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount;
+		prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount;
+		prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount;
+		prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount;
+		prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount;
+		prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount;
+		prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount;
+		prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount;
+		prStatistics->rTKIPLocalMICFailures.QuadPart = 0;
+		prStatistics->rTKIPICVErrors.QuadPart = 0;
+		prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0;
+		prStatistics->rTKIPReplays.QuadPart = 0;
+		prStatistics->rCCMPFormatErrors.QuadPart = 0;
+		prStatistics->rCCMPReplays.QuadPart = 0;
+		prStatistics->rCCMPDecryptErrors.QuadPart = 0;
+		prStatistics->rFourWayHandshakeFailures.QuadPart = 0;
+		prStatistics->rWEPUndecryptableCount.QuadPart = 0;
+		prStatistics->rWEPICVErrorCount.QuadPart = 0;
+		prStatistics->rDecryptSuccessCount.QuadPart = 0;
+		prStatistics->rDecryptFailureCount.QuadPart = 0;
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS_PL,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryStatistics,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryStatistics */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query the current 802.11 statistics.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryStatistics");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) {
+		DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics;
+
+		*pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+		prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer;
+
+		prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+		prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount;
+		prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount;
+		prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount;
+		prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount;
+		prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount;
+		prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount;
+		prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount;
+		prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount;
+		prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount;
+		prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount;
+		prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount;
+		prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount;
+		prStatistics->rTKIPLocalMICFailures.QuadPart = 0;
+		prStatistics->rTKIPICVErrors.QuadPart = 0;
+		prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0;
+		prStatistics->rTKIPReplays.QuadPart = 0;
+		prStatistics->rCCMPFormatErrors.QuadPart = 0;
+		prStatistics->rCCMPReplays.QuadPart = 0;
+		prStatistics->rCCMPDecryptErrors.QuadPart = 0;
+		prStatistics->rFourWayHandshakeFailures.QuadPart = 0;
+		prStatistics->rWEPUndecryptableCount.QuadPart = 0;
+		prStatistics->rWEPICVErrorCount.QuadPart = 0;
+		prStatistics->rDecryptSuccessCount.QuadPart = 0;
+		prStatistics->rDecryptFailureCount.QuadPart = 0;
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryStatistics,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryStatistics */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query current media streaming status.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter,
+			    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryMediaStreamMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE);
+
+	if (u4QueryBufferLen < *pu4QueryInfoLen) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*(P_ENUM_MEDIA_STREAM_MODE) pvQueryBuffer =
+	    prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidQueryMediaStreamMode */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to enter media streaming mode or exit media streaming mode
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	ENUM_MEDIA_STREAM_MODE eStreamMode;
+
+	DEBUGFUNC("wlanoidSetMediaStreamMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen < sizeof(ENUM_MEDIA_STREAM_MODE)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*pu4SetInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE);
+
+	eStreamMode = *(P_ENUM_MEDIA_STREAM_MODE) pvSetBuffer;
+
+	if (eStreamMode == ENUM_MEDIA_STREAM_OFF)
+		prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0;
+	else
+		prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_LINK_ATTRIB,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetMediaStreamMode,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_LINK_ATTRIB),
+				   (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen);
+}				/* wlanoidSetMediaStreamMode */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query the permanent MAC address of the NIC.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryPermanentAddr");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < MAC_ADDR_LEN)
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	COPY_MAC_ADDR(pvQueryBuffer, prAdapter->rWifiVar.aucPermanentAddress);
+	*pu4QueryInfoLen = MAC_ADDR_LEN;
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryPermanentAddr */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query the MAC address the NIC is currently using.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	CMD_BASIC_CONFIG rCmdBasicConfig;
+
+	DEBUGFUNC("wlanoidQueryCurrentAddr");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < MAC_ADDR_LEN)
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG));
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_BASIC_CONFIG,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryAddress,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_BASIC_CONFIG),
+				   (PUINT_8) &rCmdBasicConfig, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryCurrentAddr */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query NIC link speed.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryLinkSpeed");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	if (u4QueryBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) {
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (prAdapter->fgIsLinkRateValid == TRUE &&
+		   (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) {
+		*(PUINT_32) pvQueryBuffer = prAdapter->rLinkQuality.u2LinkSpeed * 5000;	/* change to unit of 100bps */
+		return WLAN_STATUS_SUCCESS;
+	} else {
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_GET_LINK_QUALITY,
+					   FALSE,
+					   TRUE,
+					   TRUE,
+					   nicCmdEventQueryLinkSpeed,
+					   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+	}
+}				/* end of wlanoidQueryLinkSpeed() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query MCR value.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo;
+	CMD_ACCESS_REG rCmdAccessReg;
+
+	DEBUGFUNC("wlanoidQueryMcrRead");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T);
+
+	if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvQueryBuffer;
+
+	/* 0x9000 - 0x9EFF reserved for FW */
+#if CFG_SUPPORT_SWCR
+	if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) {
+		swCrReadWriteCmd(prAdapter,
+				 SWCR_READ,
+				 (UINT_16) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), &prMcrRdInfo->u4McrData);
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif /* CFG_SUPPORT_SWCR */
+
+	/* Check if access F/W Domain MCR (due to WiFiSYS is placed from 0x6000-0000 */
+	if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) {
+		/* fill command */
+		rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset;
+		rCmdAccessReg.u4Data = 0;
+
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_ACCESS_REG,
+					   FALSE,
+					   TRUE,
+					   TRUE,
+					   nicCmdEventQueryMcrRead,
+					   nicOidCmdTimeoutCommon,
+					   sizeof(CMD_ACCESS_REG),
+					   (PUINT_8) &rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen);
+	} else {
+		HAL_MCR_RD(prAdapter, prMcrRdInfo->u4McrOffset & BITS(2, 31),	/* address is in DWORD unit */
+			   &prMcrRdInfo->u4McrData);
+
+		DBGLOG(OID, TRACE, "MCR Read: Offset = %#08x, Data = %#08x\n",
+				     prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData);
+		return WLAN_STATUS_SUCCESS;
+	}
+}				/* end of wlanoidQueryMcrRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to write MCR and enable specific function.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrWrInfo;
+	CMD_ACCESS_REG rCmdAccessReg;
+
+#if CFG_STRESS_TEST_SUPPORT
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]);
+	P_STA_RECORD_T prStaRec = prBssInfo->prStaRecOfAP;
+	UINT_32 u4McrOffset, u4McrData;
+#endif
+
+	DEBUGFUNC("wlanoidSetMcrWrite");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prMcrWrInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvSetBuffer;
+
+	/* 0x9000 - 0x9EFF reserved for FW */
+	/* 0xFFFE          reserved for FW */
+
+	/* -- Puff Stress Test Begin */
+#if CFG_STRESS_TEST_SUPPORT
+
+	/* 0xFFFFFFFE for Control Rate */
+	if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) {
+		if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM && prMcrWrInfo->u4McrData > 0)
+			prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prMcrWrInfo->u4McrData);
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+		DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n");
+		DBGLOG(OID, TRACE,
+		       "[Stress Test] Rate is Changed to index %d...\n", prAdapter->rWifiVar.eRateSetting);
+	}
+	/* 0xFFFFFFFD for Switch Channel */
+	else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) {
+		if (prMcrWrInfo->u4McrData <= 11 && prMcrWrInfo->u4McrData >= 1)
+			prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData;
+		nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex);
+		DBGLOG(OID, TRACE, "[Stress Test] Channel is switched to %d ...\n", prBssInfo->ucPrimaryChannel);
+
+		return WLAN_STATUS_SUCCESS;
+	}
+	/* 0xFFFFFFFFC for Control RF Band and SCO */
+	else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) {
+		/* Band */
+		if (prMcrWrInfo->u4McrData & 0x80000000) {
+			/* prBssInfo->eBand = BAND_5G; */
+			/* prBssInfo->ucPrimaryChannel = 52;  // Bond to Channel 52 */
+		} else {
+			prBssInfo->eBand = BAND_2G4;
+			prBssInfo->ucPrimaryChannel = 8;	/* Bond to Channel 6 */
+		}
+
+		/* Bandwidth */
+		if (prMcrWrInfo->u4McrData & 0x00010000) {
+			prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+			prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+
+			if (prMcrWrInfo->u4McrData == 0x00010002) {
+				prBssInfo->eBssSCO = CHNL_EXT_SCB;	/* U20 */
+				prBssInfo->ucPrimaryChannel += 2;
+			} else if (prMcrWrInfo->u4McrData == 0x00010001) {
+				prBssInfo->eBssSCO = CHNL_EXT_SCA;	/* L20 */
+				prBssInfo->ucPrimaryChannel -= 2;
+			} else {
+				prBssInfo->eBssSCO = CHNL_EXT_SCA;	/* 40 */
+			}
+		}
+
+		if (prMcrWrInfo->u4McrData & 0x00000000) {
+			prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
+			prBssInfo->eBssSCO = CHNL_EXT_SCN;
+		}
+		rlmBssInitForAPandIbss(prAdapter, prBssInfo);
+	}
+	/* 0xFFFFFFFB for HT Capability */
+	else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) {
+		/* Enable HT Capability */
+		if (prMcrWrInfo->u4McrData & 0x00000001) {
+			prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF;
+			DEBUGFUNC("[Stress Test]Enable HT capability...\n");
+		} else {
+			prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF);
+			DEBUGFUNC("[Stress Test]Disable HT capability...\n");
+		}
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+	}
+	/* 0xFFFFFFFA for Enable Random Rx Reset */
+	else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) {
+		rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset;
+		rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData;
+
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_RANDOM_RX_RESET_EN,
+					   TRUE,
+					   FALSE,
+					   TRUE,
+					   nicCmdEventSetCommon,
+					   nicOidCmdTimeoutCommon,
+					   sizeof(CMD_ACCESS_REG),
+					   (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen);
+	}
+	/* 0xFFFFFFF9 for Disable Random Rx Reset */
+	else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) {
+		rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset;
+		rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData;
+
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_RANDOM_RX_RESET_DE,
+					   TRUE,
+					   FALSE,
+					   TRUE,
+					   nicCmdEventSetCommon,
+					   nicOidCmdTimeoutCommon,
+					   sizeof(CMD_ACCESS_REG),
+					   (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen);
+	}
+	/* 0xFFFFFFF8 for Enable SAPP */
+	else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) {
+		rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset;
+		rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData;
+
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_SAPP_EN,
+					   TRUE,
+					   FALSE,
+					   TRUE,
+					   nicCmdEventSetCommon,
+					   nicOidCmdTimeoutCommon,
+					   sizeof(CMD_ACCESS_REG),
+					   (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen);
+	}
+	/* 0xFFFFFFF7 for Disable SAPP */
+	else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) {
+		rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset;
+		rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData;
+
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_SAPP_DE,
+					   TRUE,
+					   FALSE,
+					   TRUE,
+					   nicCmdEventSetCommon,
+					   nicOidCmdTimeoutCommon,
+					   sizeof(CMD_ACCESS_REG),
+					   (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen);
+	}
+
+	else
+#endif
+		/* -- Puff Stress Test End */
+
+		/* Check if access F/W Domain MCR */
+	if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) {
+
+		/* 0x9000 - 0x9EFF reserved for FW */
+#if CFG_SUPPORT_SWCR
+		if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) {
+			swCrReadWriteCmd(prAdapter,
+					 SWCR_WRITE,
+					 (UINT_16) (prMcrWrInfo->u4McrOffset & BITS(0, 15)), &prMcrWrInfo->u4McrData);
+			return WLAN_STATUS_SUCCESS;
+		}
+#endif /* CFG_SUPPORT_SWCR */
+
+#if 1
+		/* low power test special command */
+		if (prMcrWrInfo->u4McrOffset == 0x11111110) {
+			WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+			/* DbgPrint("Enter test mode\n"); */
+			prAdapter->fgTestMode = TRUE;
+			return rStatus;
+		}
+		if (prMcrWrInfo->u4McrOffset == 0x11111111) {
+			/* DbgPrint("nicpmSetAcpiPowerD3\n"); */
+
+			nicpmSetAcpiPowerD3(prAdapter);
+			kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3);
+			return WLAN_STATUS_SUCCESS;
+		}
+		if (prMcrWrInfo->u4McrOffset == 0x11111112) {
+
+			/* DbgPrint("LP enter sleep\n"); */
+
+			/* fill command */
+			rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset;
+			rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData;
+
+			return wlanSendSetQueryCmd(prAdapter,
+						   CMD_ID_ACCESS_REG,
+						   TRUE,
+						   FALSE,
+						   TRUE,
+						   nicCmdEventSetCommon,
+						   nicOidCmdTimeoutCommon,
+						   sizeof(CMD_ACCESS_REG),
+						   (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen);
+		}
+#endif
+
+#if 1
+		/* low power test special command */
+		if (prMcrWrInfo->u4McrOffset == 0x11111110) {
+			WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+			/* DbgPrint("Enter test mode\n"); */
+			prAdapter->fgTestMode = TRUE;
+			return rStatus;
+		}
+		if (prMcrWrInfo->u4McrOffset == 0x11111111) {
+			/* DbgPrint("nicpmSetAcpiPowerD3\n"); */
+
+			nicpmSetAcpiPowerD3(prAdapter);
+			kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3);
+			return WLAN_STATUS_SUCCESS;
+		}
+		if (prMcrWrInfo->u4McrOffset == 0x11111112) {
+
+			/* DbgPrint("LP enter sleep\n"); */
+
+			/* fill command */
+			rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset;
+			rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData;
+
+			return wlanSendSetQueryCmd(prAdapter,
+						   CMD_ID_ACCESS_REG,
+						   TRUE,
+						   FALSE,
+						   TRUE,
+						   nicCmdEventSetCommon,
+						   nicOidCmdTimeoutCommon,
+						   sizeof(CMD_ACCESS_REG),
+						   (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen);
+		}
+#endif
+		/* fill command */
+		rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset;
+		rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData;
+
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_ACCESS_REG,
+					   TRUE,
+					   FALSE,
+					   TRUE,
+					   nicCmdEventSetCommon,
+					   nicOidCmdTimeoutCommon,
+					   sizeof(CMD_ACCESS_REG),
+					   (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen);
+	} else {
+		HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, 31)),	/* address is in DWORD unit */
+			   prMcrWrInfo->u4McrData);
+
+		DBGLOG(OID, TRACE, "MCR Write: Offset = %#08x, Data = %#08x\n",
+				     prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData);
+
+		return WLAN_STATUS_SUCCESS;
+	}
+}				/* wlanoidSetMcrWrite */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query SW CTRL
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo;
+	WLAN_STATUS rWlanStatus;
+	UINT_16 u2Id, u2SubId;
+	UINT_32 u4Data;
+
+	CMD_SW_DBG_CTRL_T rCmdSwCtrl;
+
+	DEBUGFUNC("wlanoidQuerySwCtrlRead");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T);
+
+	if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvQueryBuffer;
+
+	u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16);
+	u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15));
+	u4Data = 0;
+	rWlanStatus = WLAN_STATUS_SUCCESS;
+
+	switch (u2Id) {
+		/* 0x9000 - 0x9EFF reserved for FW */
+		/* 0xFFFE          reserved for FW */
+
+#if CFG_SUPPORT_SWCR
+	case 0x9F00:
+		swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */ ,
+				 (UINT_16) u2SubId, &u4Data);
+		break;
+#endif /* CFG_SUPPORT_SWCR */
+
+	case 0xFFFF:
+		{
+			u4Data = 0x5AA56620;
+		}
+		break;
+
+	case 0x9000:
+	default:
+		{
+			rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id;
+			rCmdSwCtrl.u4Data = 0;
+			rWlanStatus = wlanSendSetQueryCmd(prAdapter,
+							  CMD_ID_SW_DBG_CTRL,
+							  FALSE,
+							  TRUE,
+							  TRUE,
+							  nicCmdEventQuerySwCtrlRead,
+							  nicOidCmdTimeoutCommon,
+							  sizeof(CMD_SW_DBG_CTRL_T),
+							  (PUINT_8) &rCmdSwCtrl, pvQueryBuffer, u4QueryBufferLen);
+		}
+	}			/* switch(u2Id) */
+
+	prSwCtrlInfo->u4Data = u4Data;
+
+	return rWlanStatus;
+
+}
+
+ /* end of wlanoidQuerySwCtrlRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to write SW CTRL
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo;
+	CMD_SW_DBG_CTRL_T rCmdSwCtrl;
+	WLAN_STATUS rWlanStatus;
+	UINT_16 u2Id, u2SubId;
+	UINT_32 u4Data;
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+	P_GLUE_INFO_T prGlueInfo;
+	CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg;
+#endif
+
+	DEBUGFUNC("wlanoidSetSwCtrlWrite");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+	prGlueInfo = prAdapter->prGlueInfo;
+#endif
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvSetBuffer;
+
+	u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16);
+	u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15));
+	u4Data = prSwCtrlInfo->u4Data;
+	rWlanStatus = WLAN_STATUS_SUCCESS;
+
+	switch (u2Id) {
+
+		/* 0x9000 - 0x9EFF reserved for FW */
+		/* 0xFFFE          reserved for FW */
+
+#if CFG_SUPPORT_SWCR
+	case 0x9F00:
+		swCrReadWriteCmd(prAdapter, SWCR_WRITE, (UINT_16) u2SubId, &u4Data);
+		break;
+#endif /* CFG_SUPPORT_SWCR */
+
+	case 0x1000:
+		if (u2SubId == 0x8000) {
+			/* CTIA power save mode setting (code: 0x10008000) */
+			prAdapter->u4CtiaPowerMode = u4Data;
+			prAdapter->fgEnCtiaPowerMode = TRUE;
+
+			/*  */
+			{
+				PARAM_POWER_MODE ePowerMode;
+
+				if (prAdapter->u4CtiaPowerMode == 0)
+					/* force to keep in CAM mode */
+					ePowerMode = Param_PowerModeCAM;
+				else if (prAdapter->u4CtiaPowerMode == 1)
+					ePowerMode = Param_PowerModeMAX_PSP;
+				else
+					ePowerMode = Param_PowerModeFast_PSP;
+
+				rWlanStatus = nicConfigPowerSaveProfile(prAdapter,
+									NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE);
+			}
+		}
+		break;
+	case 0x1001:
+		if (u2SubId == 0x0)
+			prAdapter->fgEnOnlineScan = (BOOLEAN) u4Data;
+		else if (u2SubId == 0x1)
+			prAdapter->fgDisBcnLostDetection = (BOOLEAN) u4Data;
+		else if (u2SubId == 0x2)
+			prAdapter->rWifiVar.fgSupportUAPSD = (BOOLEAN) u4Data;
+		else if (u2SubId == 0x3) {
+			prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15);
+			prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpDeliveryAC =
+			    (UINT_8) prAdapter->u4UapsdAcBmp;
+			prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpTriggerAC =
+			    (UINT_8) prAdapter->u4UapsdAcBmp;
+		} else if (u2SubId == 0x4)
+			prAdapter->fgDisStaAgingTimeoutDetection = (BOOLEAN) u4Data;
+		else if (u2SubId == 0x5)
+			prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = (UINT_8) u4Data;
+		else if (u2SubId == 0x0100)
+			prAdapter->rWifiVar.u8SupportRxGf = (UINT_8) u4Data;
+		else if (u2SubId == 0x0101) {
+			prAdapter->rWifiVar.u8SupportRxSgi20 = (UINT_8) u4Data;
+			prAdapter->rWifiVar.u8SupportRxSgi40 = (UINT_8) u4Data;
+		} else if (u2SubId == 0x0102)
+			prAdapter->rWifiVar.u8SupportRxSTBC = (UINT_8) u4Data;
+		break;
+
+#if CFG_SUPPORT_SWCR
+	case 0x1002:
+		if (u2SubId == 0x0) {
+			if (u4Data)
+				u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT);
+			swCrFrameCheckEnable(prAdapter, u4Data);
+		} else if (u2SubId == 0x1) {
+			BOOLEAN fgIsEnable;
+			UINT_8 ucType;
+			UINT_32 u4Timeout;
+
+			fgIsEnable = (BOOLEAN) (u4Data & 0xff);
+			ucType = 0;	/* ((u4Data>>4) & 0xf); */
+			u4Timeout = ((u4Data >> 8) & 0xff);
+			swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, u4Timeout);
+		}
+		break;
+#endif
+
+#if CFG_SUPPORT_802_11W
+	case 0x2000:
+		DBGLOG(RSN, TRACE, "802.11w test 0x%x\n", u2SubId);
+		if (u2SubId == 0x0)
+			rsnStartSaQuery(prAdapter);
+		if (u2SubId == 0x1)
+			rsnStopSaQuery(prAdapter);
+		if (u2SubId == 0x2)
+			rsnSaQueryRequest(prAdapter, NULL);
+		if (u2SubId == 0x3) {
+			P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]);
+
+			authSendDeauthFrame(prAdapter, prBssInfo->prStaRecOfAP, NULL, 7, NULL);
+		}
+		/* wext_set_mode */
+		/*
+		   if (u2SubId == 0x3) {
+		   prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_DISABLED;
+		   }
+		   if (u2SubId == 0x4) {
+		   //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
+		   prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL;
+		   }
+		   if (u2SubId == 0x5) {
+		   //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
+		   prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_REQUIRED;
+		   }
+		 */
+		break;
+#endif
+	case 0xFFFF:
+		{
+/* CMD_ACCESS_REG rCmdAccessReg; */
+#if 1				/* CFG_MT6573_SMT_TEST */
+			if (u2SubId == 0x0123) {
+
+				DBGLOG(HAL, TRACE, "set smt fixed rate: %u\n", u4Data);
+
+				if ((ENUM_REGISTRY_FIXED_RATE_T) (u4Data) < FIXED_RATE_NUM)
+					prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (u4Data);
+				else
+					prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE;
+
+				if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE)
+					/* Enable Auto (Long/Short) Preamble */
+					prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO;
+				else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS &&
+					    prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS)
+					   || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS &&
+					       prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS))
+					/* Force Short Preamble */
+					prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT;
+				else
+					/* Force Long Preamble */
+					prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG;
+
+				/* abort to re-connect */
+#if 1
+				DBGLOG(OID, TRACE, "DisBySwC\n");
+				kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+							     WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+#else
+				aisBssBeaconTimeout(prAdapter);
+#endif
+
+				return WLAN_STATUS_SUCCESS;
+
+			} else if (u2SubId == 0x1234) {
+				/* 1. Disable On-Lin Scan */
+				/* 3. Disable FIFO FULL no ack */
+				/* 4. Disable Roaming */
+				/* Disalbe auto tx power */
+				/* 2. Keep at CAM mode */
+				/* 5. Disable Beacon Timeout Detection */
+				rWlanStatus = nicEnterCtiaMode(prAdapter, TRUE, TRUE);
+			} else if (u2SubId == 0x1235) {
+				/* 1. Enaable On-Lin Scan */
+				/* 3. Enable FIFO FULL no ack */
+				/* 4. Enable Roaming */
+				/* Enable auto tx power */
+				/* 2. Keep at Fast PS */
+				/* 5. Enable Beacon Timeout Detection */
+				rWlanStatus = nicEnterCtiaMode(prAdapter, FALSE, TRUE);
+			}
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+			else if (u2SubId == 0x1240) {
+				DBGLOG(P2P, TRACE, "Disable Hotspot Optimization!\n");
+
+				arHotspotOptimizationCfg.fgHotspotOptimizationEn = FALSE;
+				arHotspotOptimizationCfg.u4Level = 0;
+				wlanoidSendSetQueryP2PCmd(prAdapter,
+							  CMD_ID_SET_HOTSPOT_OPTIMIZATION,
+							  TRUE,
+							  FALSE,
+							  TRUE,
+							  NULL,
+							  NULL,
+							  sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG),
+							  (PUINT_8) &arHotspotOptimizationCfg, NULL, 0);
+			} else if (u2SubId == 0x1241) {
+				DBGLOG(P2P, TRACE, "Enable Hotspot Optimization!\n");
+
+				arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE;
+				arHotspotOptimizationCfg.u4Level = 5;
+				wlanoidSendSetQueryP2PCmd(prAdapter,
+							  CMD_ID_SET_HOTSPOT_OPTIMIZATION,
+							  TRUE,
+							  FALSE,
+							  TRUE,
+							  NULL,
+							  NULL,
+							  sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG),
+							  (PUINT_8) &arHotspotOptimizationCfg, NULL, 0);
+			}
+#endif /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */
+			else if (u2SubId == 0x1250) {
+				DBGLOG(OID, TRACE, "LTE_COEX: SW SET DUAL BAND\n");
+				prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_NULL;
+			} else if (u2SubId == 0x1251) {
+				DBGLOG(OID, TRACE, "LTE_COEX: SW SET 2.4G BAND\n");
+				prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_2G4;
+			} else if (u2SubId == 0x1252) {
+				DBGLOG(OID, TRACE, "LTE_COEX: SW SET 5G BAND\n");
+				prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_5G;
+			}
+#endif
+		}
+		break;
+
+	case 0x9000:
+	default:
+		{
+			rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id;
+			rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data;
+			rWlanStatus = wlanSendSetQueryCmd(prAdapter,
+							  CMD_ID_SW_DBG_CTRL,
+							  TRUE,
+							  FALSE,
+							  TRUE,
+							  nicCmdEventSetCommon,
+							  nicOidCmdTimeoutCommon,
+							  sizeof(CMD_SW_DBG_CTRL_T),
+							  (PUINT_8) &rCmdSwCtrl, pvSetBuffer, u4SetBufferLen);
+		}
+	}			/* switch(u2Id)  */
+
+	return rWlanStatus;
+}
+
+   /* wlanoidSetSwCtrlWrite */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query EEPROM value.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo;
+	CMD_ACCESS_EEPROM rCmdAccessEeprom;
+
+	DEBUGFUNC("wlanoidQueryEepromRead");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T);
+
+	if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvQueryBuffer;
+
+	kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM));
+	rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_ACCESS_EEPROM,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryEepromRead,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_ACCESS_EEPROM),
+				   (PUINT_8) &rCmdAccessEeprom, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryEepromRead */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to write EEPROM value.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo;
+	CMD_ACCESS_EEPROM rCmdAccessEeprom;
+
+	DEBUGFUNC("wlanoidSetEepromWrite");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvSetBuffer;
+
+	kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM));
+	rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex;
+	rCmdAccessEeprom.u2Data = prEepromRwInfo->u2EepromData;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_ACCESS_EEPROM,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_ACCESS_EEPROM),
+				   (PUINT_8) &rCmdAccessEeprom, pvSetBuffer, u4SetBufferLen);
+
+}				/* wlanoidSetEepromWrite */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the number of the successfully transmitted
+*        packets.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryXmitOk");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart;
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart;
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryXmitOk,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryXmitOk */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the number of the successfully received
+*        packets.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryRcvOk");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart;
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart;
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryRecvOk,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryRcvOk */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the number of frames that the driver
+*        fails to transmit.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryXmitError");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart;
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart;
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryXmitError,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryXmitError */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the number of frames successfully
+*        transmitted after exactly one collision.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter,
+			     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryXmitOneCollision");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32)
+			    (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart -
+			     prAdapter->rStatStruct.rRetryCount.QuadPart);
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64)
+			    (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart -
+			     prAdapter->rStatStruct.rRetryCount.QuadPart);
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryXmitOneCollision,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* wlanoidQueryXmitOneCollision */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the number of frames successfully
+*        transmitted after more than one collision.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryXmitMoreCollisions");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart);
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart);
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryXmitMoreCollisions,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+}				/* wlanoidQueryXmitMoreCollisions */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the number of frames
+*                not transmitted due to excessive collisions.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryXmitMaxCollisions");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		*pu4QueryInfoLen = sizeof(UINT_32);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	} else if (u4QueryBufferLen < sizeof(UINT_32)
+		   || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) {
+		*pu4QueryInfoLen = sizeof(UINT_64);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+#if CFG_ENABLE_STATISTICS_BUFFERING
+	if (IsBufferedStatisticsUsable(prAdapter) == TRUE) {
+		if (u4QueryBufferLen == sizeof(UINT_32)) {
+			*pu4QueryInfoLen = sizeof(UINT_32);
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart;
+		} else {
+			*pu4QueryInfoLen = sizeof(UINT_64);
+			*(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart;
+		}
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_STATISTICS,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryXmitMaxCollisions,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+}				/* wlanoidQueryXmitMaxCollisions */
+
+#define MTK_CUSTOM_OID_INTERFACE_VERSION     0x00006620	/* for WPDWifi DLL */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query current the OID interface version,
+*        which is the interface between the application and driver.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter,
+				IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryOidInterfaceVersion");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	*(PUINT_32) pvQueryBuffer = MTK_CUSTOM_OID_INTERFACE_VERSION;
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	DBGLOG(OID, WARN, "Custom OID interface version: %#08X\n", *(PUINT_32) pvQueryBuffer);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryOidInterfaceVersion */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query current Multicast Address List.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+#ifndef LINUX
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_MAC_MCAST_ADDR,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryMcastAddr,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+#else
+	return WLAN_STATUS_SUCCESS;
+#endif
+}				/* end of wlanoidQueryMulticastList() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set Multicast Address List.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	UINT_8 ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;	/* Caller should provide this information */
+	CMD_MAC_MCAST_ADDR rCmdMacMcastAddr;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	/* The data must be a multiple of the Ethernet address size. */
+	if ((u4SetBufferLen % MAC_ADDR_LEN)) {
+		DBGLOG(OID, WARN, "Invalid MC list length %u\n", u4SetBufferLen);
+
+		*pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN;
+
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	/* Verify if we can support so many multicast addresses. */
+	if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) {
+		DBGLOG(OID, WARN, "Too many MC addresses\n");
+
+		return WLAN_STATUS_MULTICAST_FULL;
+	}
+
+	/* NOTE(Kevin): Windows may set u4SetBufferLen == 0 &&
+	 * pvSetBuffer == NULL to clear exist Multicast List.
+	 */
+	if (u4SetBufferLen)
+		ASSERT(pvSetBuffer);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN;
+	rCmdMacMcastAddr.ucNetTypeIndex = ucNetTypeIndex;
+	kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_MAC_MCAST_ADDR,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_MAC_MCAST_ADDR),
+				   (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen);
+}				/* end of wlanoidSetMulticastList() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set Packet Filter.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_NOT_SUPPORTED
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	UINT_32 u4NewPacketFilter;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen < sizeof(UINT_32)) {
+		*pu4SetInfoLen = sizeof(UINT_32);
+		DBGLOG(OID, INFO, "iput buffer is too small");
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+	ASSERT(pvSetBuffer);
+
+	/* Set the new packet filter. */
+	u4NewPacketFilter = *(PUINT_32) pvSetBuffer;
+
+	DBGLOG(OID, TRACE, "New packet filter: %#08x\n", u4NewPacketFilter);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	do {
+		/* Verify the bits of the new packet filter. If any bits are set that
+		   we don't support, leave. */
+		if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) {
+			rStatus = WLAN_STATUS_NOT_SUPPORTED;
+			break;
+		}
+#if DBG
+		/* Need to enable or disable promiscuous support depending on the new
+		   filter. */
+		if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS)
+			DBGLOG(OID, TRACE, "Enable promiscuous mode\n");
+		else
+			DBGLOG(OID, TRACE, "Disable promiscuous mode\n");
+
+		if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST)
+			DBGLOG(OID, TRACE, "Enable all-multicast mode\n");
+		else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST)
+			DBGLOG(OID, TRACE, "Enable multicast\n");
+		else
+			DBGLOG(OID, TRACE, "Disable multicast\n");
+
+		if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST)
+			DBGLOG(OID, TRACE, "Enable Broadcast\n");
+		else
+			DBGLOG(OID, TRACE, "Disable Broadcast\n");
+#endif
+	} while (FALSE);
+
+	if (rStatus == WLAN_STATUS_SUCCESS) {
+		/* Store the packet filter */
+
+		prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK;
+		prAdapter->u4OsPacketFilter |= u4NewPacketFilter;
+
+		return wlanSendSetQueryCmd(prAdapter,
+					   CMD_ID_SET_RX_FILTER,
+					   TRUE,
+					   FALSE,
+					   TRUE,
+					   nicCmdEventSetCommon,
+					   nicOidCmdTimeoutCommon,
+					   sizeof(UINT_32),
+					   (PUINT_8) &prAdapter->u4OsPacketFilter, pvSetBuffer, u4SetBufferLen);
+	} else {
+		return rStatus;
+	}
+}				/* wlanoidSetCurrentPacketFilter */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query current packet filter.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter,
+				OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryCurrentPacketFilter");
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	if (u4QueryBufferLen >= sizeof(UINT_32)) {
+		ASSERT(pvQueryBuffer);
+		*(PUINT_32) pvQueryBuffer = prAdapter->u4OsPacketFilter;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidQueryCurrentPacketFilter */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query ACPI device power state.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter,
+				 IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+#if DBG
+	PPARAM_DEVICE_POWER_STATE prPowerState;
+#endif
+
+	DEBUGFUNC("wlanoidQueryAcpiDevicePowerState");
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_DEVICE_POWER_STATE);
+
+#if DBG
+	prPowerState = (PPARAM_DEVICE_POWER_STATE) pvQueryBuffer;
+	switch (*prPowerState) {
+	case ParamDeviceStateD0:
+		DBGLOG(OID, INFO, "Query Power State: D0\n");
+		break;
+	case ParamDeviceStateD1:
+		DBGLOG(OID, INFO, "Query Power State: D1\n");
+		break;
+	case ParamDeviceStateD2:
+		DBGLOG(OID, INFO, "Query Power State: D2\n");
+		break;
+	case ParamDeviceStateD3:
+		DBGLOG(OID, INFO, "Query Power State: D3\n");
+		break;
+	default:
+		break;
+	}
+#endif
+
+	/* Since we will disconnect the newwork, therefore we do not
+	   need to check queue empty */
+	*(PPARAM_DEVICE_POWER_STATE) pvQueryBuffer = ParamDeviceStateD3;
+	/* WARNLOG(("Ready to transition to D3\n")); */
+	return WLAN_STATUS_SUCCESS;
+
+}				/* pwrmgtQueryPower */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set ACPI device power state.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PPARAM_DEVICE_POWER_STATE prPowerState;
+	BOOLEAN fgRetValue = TRUE;
+
+	DEBUGFUNC("wlanoidSetAcpiDevicePowerState");
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_DEVICE_POWER_STATE);
+
+	ASSERT(pvSetBuffer);
+	prPowerState = (PPARAM_DEVICE_POWER_STATE) pvSetBuffer;
+	switch (*prPowerState) {
+	case ParamDeviceStateD0:
+		DBGLOG(OID, INFO, "Set Power State: D0\n");
+		kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD0);
+		fgRetValue = nicpmSetAcpiPowerD0(prAdapter);
+		break;
+	case ParamDeviceStateD1:
+		DBGLOG(OID, INFO, "Set Power State: D1\n");
+		/* no break here */
+	case ParamDeviceStateD2:
+		DBGLOG(OID, INFO, "Set Power State: D2\n");
+		/* no break here */
+	case ParamDeviceStateD3:
+		DBGLOG(OID, INFO, "Set Power State: D3\n");
+		fgRetValue = nicpmSetAcpiPowerD3(prAdapter);
+		kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3);
+		break;
+	default:
+		break;
+	}
+
+	if (fgRetValue == TRUE)
+		return WLAN_STATUS_SUCCESS;
+	else
+		return WLAN_STATUS_FAILURE;
+}				/* end of wlanoidSetAcpiDevicePowerState() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current fragmentation threshold.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryFragThreshold");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	DBGLOG(OID, LOUD, "\n");
+
+#if CFG_TX_FRAGMENT
+
+	return WLAN_STATUS_SUCCESS;
+
+#else
+
+	return WLAN_STATUS_NOT_SUPPORTED;
+#endif /* CFG_TX_FRAGMENT */
+
+}				/* end of wlanoidQueryFragThreshold() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a new fragmentation threshold to the
+*        driver.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+#if CFG_TX_FRAGMENT
+
+	return WLAN_STATUS_SUCCESS;
+
+#else
+
+	return WLAN_STATUS_NOT_SUPPORTED;
+#endif /* CFG_TX_FRAGMENT */
+
+}				/* end of wlanoidSetFragThreshold() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the current RTS threshold.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryRtsThreshold");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	DBGLOG(OID, LOUD, "\n");
+
+	if (u4QueryBufferLen < sizeof(PARAM_RTS_THRESHOLD)) {
+		*pu4QueryInfoLen = sizeof(PARAM_RTS_THRESHOLD);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	*((PARAM_RTS_THRESHOLD *) pvQueryBuffer) = prAdapter->rWlanInfo.eRtsThreshold;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidQueryRtsThreshold */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a new RTS threshold to the driver.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PARAM_RTS_THRESHOLD *prRtsThreshold;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_RTS_THRESHOLD);
+	if (u4SetBufferLen < sizeof(PARAM_RTS_THRESHOLD)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	prRtsThreshold = (PARAM_RTS_THRESHOLD *) pvSetBuffer;
+	*prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* wlanoidSetRtsThreshold */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to turn radio off.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_MSG_AIS_ABORT_T prAisAbortMsg;
+
+	DEBUGFUNC("wlanoidSetDisassociate");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = 0;
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	/* prepare message to AIS */
+	prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE;
+
+	/* Send AIS Abort Message */
+	prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
+	if (!prAisAbortMsg) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ;
+	prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
+	prAisAbortMsg->fgDelayIndication = FALSE;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
+
+	/* indicate for disconnection */
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+		DBGLOG(OID, INFO, "DisconnectByOid\n");
+		kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, 0);
+	}
+#if !defined(LINUX)
+	prAdapter->fgIsRadioOff = TRUE;
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}				/* wlanoidSetDisassociate */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to query the power save profile.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter,
+				     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	if (u4QueryBufferLen != 0) {
+		ASSERT(pvQueryBuffer);
+
+/* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE)(prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); */
+		*(PPARAM_POWER_MODE) pvQueryBuffer =
+		    (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_AIS_INDEX].ucPsProfile);
+		*pu4QueryInfoLen = sizeof(PARAM_POWER_MODE);
+
+		/* hack for CTIA power mode setting function */
+		if (prAdapter->fgEnCtiaPowerMode) {
+			/* set to non-zero value (to prevent MMI query 0, before it intends to set 0, */
+			/* which will skip its following state machine) */
+			*(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) 2;
+		}
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to set the power save profile.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter,
+				   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS status;
+	PARAM_POWER_MODE ePowerMode;
+
+	DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_POWER_MODE);
+	if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) {
+		/* WARNLOG(("Invalid power mode %d\n", */
+		/* *(PPARAM_POWER_MODE) pvSetBuffer)); */
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer;
+
+	if (prAdapter->fgEnCtiaPowerMode) {
+		if (ePowerMode == Param_PowerModeCAM)
+			;
+		else {
+			/* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */
+
+			if (prAdapter->u4CtiaPowerMode == 0)
+				/* force to keep in CAM mode */
+				ePowerMode = Param_PowerModeCAM;
+			else if (prAdapter->u4CtiaPowerMode == 1)
+				ePowerMode = Param_PowerModeMAX_PSP;
+			else if (prAdapter->u4CtiaPowerMode == 2)
+				ePowerMode = Param_PowerModeFast_PSP;
+		}
+	}
+
+	status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE);
+
+	switch (ePowerMode) {
+	case Param_PowerModeCAM:
+		DBGLOG(OID, INFO, "Set Wi-Fi PS mode to CAM (%d)\n", ePowerMode);
+		break;
+	case Param_PowerModeMAX_PSP:
+		DBGLOG(OID, INFO, "Set Wi-Fi PS mode to MAX PS (%d)\n", ePowerMode);
+		break;
+	case Param_PowerModeFast_PSP:
+		DBGLOG(OID, INFO, "Set Wi-Fi PS mode to FAST PS (%d)\n", ePowerMode);
+		break;
+	default:
+		DBGLOG(OID, INFO, "invalid Wi-Fi PS mode setting (%d)\n", ePowerMode);
+		break;
+	}
+
+	return status;
+
+}				/* end of wlanoidSetAcpiDevicePowerStateMode() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query current status of AdHoc Mode.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidQueryAdHocMode() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set AdHoc Mode.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidSetAdHocMode() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query RF frequency.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryFrequency");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) {
+		if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+			*(PUINT_32) pvQueryBuffer =
+			    nicChannelNum2Freq(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].ucPrimaryChannel);
+		} else {
+			*(PUINT_32) pvQueryBuffer = 0;
+		}
+	} else {
+		*(PUINT_32) pvQueryBuffer = nicChannelNum2Freq(prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidQueryFrequency() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set RF frequency by User Settings.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PUINT_32 pu4FreqInKHz;
+
+	DEBUGFUNC("wlanoidSetFrequency");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+
+	if (u4SetBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	pu4FreqInKHz = (PUINT_32) pvSetBuffer;
+
+	prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(*pu4FreqInKHz);
+	prAdapter->rWifiVar.rConnSettings.eAdHocBand = *pu4FreqInKHz < 5000000 ? BAND_2G4 : BAND_5G;
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidSetFrequency() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set 802.11 channel of the radio frequency.
+*        This is a proprietary function call to Lunux currently.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetChannel(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	ASSERT(0);		/* // */
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the Beacon Interval from User Settings.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter,
+			   OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryBeaconInterval");
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	if (u4QueryBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+		if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)
+			*(PUINT_32) pvQueryBuffer = prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod;
+		else
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod;
+	} else {
+		if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)
+			*(PUINT_32) pvQueryBuffer = 0;
+		else
+			*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidQueryBeaconInterval() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the Beacon Interval to User Settings.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PUINT_32 pu4BeaconInterval;
+
+	DEBUGFUNC("wlanoidSetBeaconInterval");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+	if (u4SetBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	pu4BeaconInterval = (PUINT_32) pvSetBuffer;
+
+	if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) {
+		DBGLOG(OID, TRACE, "Invalid Beacon Interval = %u\n", *pu4BeaconInterval);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	prAdapter->rWlanInfo.u2BeaconPeriod = (UINT_16) *pu4BeaconInterval;
+
+	DBGLOG(OID, INFO, "Set beacon interval: %d\n", prAdapter->rWlanInfo.u2BeaconPeriod);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidSetBeaconInterval() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the ATIM window from User Settings.
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryAtimWindow");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	if (u4QueryBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)
+		*(PUINT_32) pvQueryBuffer = 0;
+	else
+		*(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2AtimWindow;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of wlanoidQueryAtimWindow() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the ATIM window to User Settings.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PUINT_32 pu4AtimWindow;
+
+	DEBUGFUNC("wlanoidSetAtimWindow");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+
+	if (u4SetBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	pu4AtimWindow = (PUINT_32) pvSetBuffer;
+
+	prAdapter->rWlanInfo.u2AtimWindow = (UINT_16) *pu4AtimWindow;
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidSetAtimWindow() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to Set the MAC address which is currently used by the NIC.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	ASSERT(0);		/* // */
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of wlanoidSetCurrentAddr() */
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Setting the checksum offload function.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	UINT_32 i, u4CSUMFlags;
+	CMD_BASIC_CONFIG rCmdBasicConfig;
+
+	DEBUGFUNC("wlanoidSetCSUMOffload");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+
+	if (u4SetBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	u4CSUMFlags = *(PUINT_32) pvSetBuffer;
+
+	kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG));
+
+	for (i = 0; i < 6; i++) {	/* set to broadcast address for not-specified */
+		rCmdBasicConfig.rMyMacAddr[i] = 0xff;
+	}
+
+	rCmdBasicConfig.ucNative80211 = 0;	/* @FIXME: for Vista */
+
+	if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP)
+		rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2);
+
+	if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP)
+		rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1);
+
+	if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP)
+		rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0);
+
+	if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP)
+		rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2);
+
+	if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP)
+		rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1);
+
+	if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6))
+		rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0);
+
+	prAdapter->u4CSUMFlags = u4CSUMFlags;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_BASIC_CONFIG,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_BASIC_CONFIG), (PUINT_8) &rCmdBasicConfig, pvSetBuffer, u4SetBufferLen);
+}
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Setting the IP address for pattern search function.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \return WLAN_STATUS_SUCCESS
+* \return WLAN_STATUS_ADAPTER_NOT_READY
+* \return WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 i, j;
+	P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList;
+	P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer;
+	P_PARAM_NETWORK_ADDRESS prNetworkAddress;
+	P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp;
+	UINT_32 u4IpAddressCount, u4CmdSize;
+	PUINT_8 pucBuf = (PUINT_8) pvSetBuffer;
+#if CFG_ENABLE_GTK_FRAME_FILTER
+	UINT_32 u4IpV4AddrListSize;
+	P_BSS_INFO_T prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+#endif
+
+	DEBUGFUNC("wlanoidSetNetworkAddress");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = 4;
+
+	if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST))
+		return WLAN_STATUS_INVALID_DATA;
+
+	*pu4SetInfoLen = 0;
+	u4IpAddressCount = 0;
+
+	prNetworkAddress = prNetworkAddressList->arAddress;
+	for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) {
+		if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP &&
+		    prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) {
+			u4IpAddressCount++;
+		}
+
+		prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress +
+							      (ULONG) (prNetworkAddress->u2AddressLength +
+								       OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
+	}
+
+	/* construct payload of command packet */
+	u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) +
+	    sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount;
+	if (u4IpAddressCount == 0)
+		u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST);
+
+	prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE);
+
+	if (prCmdNetworkAddressList == NULL)
+		return WLAN_STATUS_FAILURE;
+
+#if CFG_ENABLE_GTK_FRAME_FILTER
+	u4IpV4AddrListSize = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) +
+	    (u4IpAddressCount * sizeof(IPV4_NETWORK_ADDRESS));
+	if (prBssInfo->prIpV4NetAddrList)
+		FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList);
+	prBssInfo->prIpV4NetAddrList = (P_IPV4_NETWORK_ADDRESS_LIST) kalMemAlloc(u4IpV4AddrListSize, VIR_MEM_TYPE);
+	if (prBssInfo->prIpV4NetAddrList == NULL) {
+		kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize);
+		return WLAN_STATUS_FAILURE;
+	}
+	prBssInfo->prIpV4NetAddrList->ucAddrCount = (UINT_8) u4IpAddressCount;
+#endif
+
+	/* fill P_CMD_SET_NETWORK_ADDRESS_LIST */
+	prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+
+	/* only to set IP address to FW once ARP filter is enabled */
+	if (prAdapter->fgEnArpFilter) {
+		prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount;
+		prNetworkAddress = prNetworkAddressList->arAddress;
+
+		DBGLOG(OID, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount);
+
+		for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) {
+			if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP &&
+			    prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) {
+				prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress;
+
+				kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr,
+					   &(prNetAddrIp->in_addr), sizeof(UINT_32));
+
+#if CFG_ENABLE_GTK_FRAME_FILTER
+				kalMemCopy(prBssInfo->prIpV4NetAddrList->arNetAddr[j].aucIpAddr,
+					   &(prNetAddrIp->in_addr), sizeof(UINT_32));
+#endif
+
+				j++;
+
+				pucBuf = (PUINT_8) &prNetAddrIp->in_addr;
+				DBGLOG(OID, INFO,
+				       "prNetAddrIp->in_addr:%d:%d:%d:%d\n", pucBuf[0], pucBuf[1], pucBuf[2],
+					pucBuf[3]);
+			}
+
+			prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress +
+								      (ULONG) (prNetworkAddress->u2AddressLength +
+									       OFFSET_OF(PARAM_NETWORK_ADDRESS,
+											 aucAddress)));
+		}
+
+	} else {
+		prCmdNetworkAddressList->ucAddressCount = 0;
+	}
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_SET_IP_ADDRESS,
+				      TRUE,
+				      FALSE,
+				      TRUE,
+				      nicCmdEventSetIpAddress,
+				      nicOidCmdTimeoutCommon,
+				      u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen);
+
+	kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize);
+	return rStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Set driver to switch into RF test mode
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set,
+*                        should be NULL
+* \param[in] u4SetBufferLen The length of the set buffer, should be 0
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \return WLAN_STATUS_SUCCESS
+* \return WLAN_STATUS_ADAPTER_NOT_READY
+* \return WLAN_STATUS_INVALID_DATA
+* \return WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus;
+	CMD_TEST_CTRL_T rCmdTestCtrl;
+
+	DEBUGFUNC("wlanoidRftestSetTestMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = 0;
+
+	if (u4SetBufferLen == 0) {
+		if (prAdapter->fgTestMode == FALSE) {
+			/* switch to RF Test mode */
+			rCmdTestCtrl.ucAction = 0;	/* Switch mode */
+			rCmdTestCtrl.u.u4OpMode = 1;	/* RF test mode */
+
+			rStatus = wlanSendSetQueryCmd(prAdapter,
+						      CMD_ID_TEST_MODE,
+						      TRUE,
+						      TRUE,
+						      TRUE,
+						      nicCmdEventEnterRfTest,
+						      nicOidCmdEnterRFTestTimeout,
+						      sizeof(CMD_TEST_CTRL_T),
+						      (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen);
+		} else {
+			/* already in test mode .. */
+			rStatus = WLAN_STATUS_SUCCESS;
+		}
+	} else {
+		rStatus = WLAN_STATUS_INVALID_DATA;
+	}
+	DBGLOG(OID, INFO, "Enter TestMode, setBufLen %u, InTestMode %d, rStatus %u\n",
+				u4SetBufferLen, prAdapter->fgTestMode, rStatus);
+	return rStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Set driver to switch into normal operation mode from RF test mode
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+*                        should be NULL
+* \param[in] u4SetBufferLen The length of the set buffer, should be 0
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \return WLAN_STATUS_SUCCESS
+* \return WLAN_STATUS_ADAPTER_NOT_READY
+* \return WLAN_STATUS_INVALID_DATA
+* \return WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus;
+	CMD_TEST_CTRL_T rCmdTestCtrl;
+
+	DEBUGFUNC("wlanoidRftestSetTestMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = 0;
+
+	if (u4SetBufferLen == 0) {
+		if (prAdapter->fgTestMode == TRUE) {
+			/* switch to normal mode */
+			rCmdTestCtrl.ucAction = 0;	/* Switch mode */
+			rCmdTestCtrl.u.u4OpMode = 0;	/* normal mode */
+
+			rStatus = wlanSendSetQueryCmd(prAdapter,
+						      CMD_ID_TEST_MODE,
+						      TRUE,
+						      FALSE,
+						      TRUE,
+						      nicCmdEventLeaveRfTest,
+						      nicOidCmdTimeoutCommon,
+						      sizeof(CMD_TEST_CTRL_T),
+						      (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen);
+		} else {
+			/* already in normal mode .. */
+			rStatus = WLAN_STATUS_SUCCESS;
+		}
+	} else {
+		rStatus = WLAN_STATUS_INVALID_DATA;
+	}
+	DBGLOG(OID, INFO, "Abort TestMode, setBufLen %u, InTestMode %d, rStatus %u\n",
+					u4SetBufferLen, prAdapter->fgTestMode, rStatus);
+	return rStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief query for RF test parameter
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+* \retval WLAN_STATUS_NOT_SUPPORTED
+* \retval WLAN_STATUS_NOT_ACCEPTED
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter,
+			   OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	DEBUGFUNC("wlanoidRftestQueryAutoTest");
+
+	ASSERT(prAdapter);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T);
+
+	if (u4QueryBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) {
+		DBGLOG(OID, ERROR, "Invalid data. QueryBufferLen: %u.\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvQueryBuffer;
+	rStatus = rftestQueryATInfo(prAdapter,
+				    prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData, pvQueryBuffer, u4QueryBufferLen);
+
+	return rStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Set RF test parameter
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \return WLAN_STATUS_SUCCESS
+* \return WLAN_STATUS_ADAPTER_NOT_READY
+* \return WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	DEBUGFUNC("wlanoidRftestSetAutoTest");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T);
+
+	if (u4SetBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) {
+		DBGLOG(OID, ERROR, "Invalid data. SetBufferLen: %u.\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvSetBuffer;
+	rStatus = rftestSetATInfo(prAdapter, prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData);
+
+	return rStatus;
+}
+
+/* RF test OID set handler */
+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	P_CMD_TEST_CTRL_T pCmdTestCtrl;
+	UINT_8 ucCmdSeqNum;
+
+	ASSERT(prAdapter);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T)));
+
+	if (!prCmdInfo) {
+		DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* Setup common CMD Info Packet */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T);
+	prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
+	prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
+	prCmdInfo->fgIsOid = TRUE;
+	prCmdInfo->ucCID = CMD_ID_TEST_MODE;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T);
+	prCmdInfo->pvInformationBuffer = NULL;
+	prCmdInfo->u4InformationBufferLength = 0;
+
+	/* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer);
+	pCmdTestCtrl->ucAction = 1;	/* Set ATInfo */
+	pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex;
+	pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData;
+
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prAdapter->prGlueInfo);
+
+	return WLAN_STATUS_PENDING;
+}
+
+WLAN_STATUS
+rftestQueryATInfo(IN P_ADAPTER_T prAdapter,
+		  UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	P_CMD_TEST_CTRL_T pCmdTestCtrl;
+	UINT_8 ucCmdSeqNum;
+	P_EVENT_TEST_STATUS prTestStatus;
+
+	ASSERT(prAdapter);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) {
+		/* driver implementation */
+		prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer;
+
+		prTestStatus->rATInfo.u4FuncData =
+		    (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion);
+		u4QueryBufferLen = sizeof(EVENT_TEST_STATUS);
+
+		return WLAN_STATUS_SUCCESS;
+	} else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) {
+		/* driver implementation */
+		prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer;
+
+		prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION;
+		u4QueryBufferLen = sizeof(EVENT_TEST_STATUS);
+
+		return WLAN_STATUS_SUCCESS;
+	}
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T)));
+
+	if (!prCmdInfo) {
+		DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* Setup common CMD Info Packet */
+	prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T);
+	prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo;
+	prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
+	prCmdInfo->fgIsOid = TRUE;
+	prCmdInfo->ucCID = CMD_ID_TEST_MODE;
+	prCmdInfo->fgSetQuery = FALSE;
+	prCmdInfo->fgNeedResp = TRUE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T);
+	prCmdInfo->pvInformationBuffer = pvQueryBuffer;
+	prCmdInfo->u4InformationBufferLength = u4QueryBufferLen;
+
+	/* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer);
+	pCmdTestCtrl->ucAction = 2;	/* Get ATInfo */
+	pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex;
+	pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData;
+
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prAdapter->prGlueInfo);
+
+	return WLAN_STATUS_PENDING;
+}
+
+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen)
+{
+	CMD_TEST_CTRL_T rCmdTestCtrl;
+
+	ASSERT(prAdapter);
+
+	rCmdTestCtrl.ucAction = 5;	/* Set Channel Frequency */
+	rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_TEST_MODE,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon, sizeof(CMD_TEST_CTRL_T), (PUINT_8) &rCmdTestCtrl, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief command packet generation utility
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] ucCID              Command ID
+* \param[in] fgSetQuery         Set or Query
+* \param[in] fgNeedResp         Need for response
+* \param[in] pfCmdDoneHandler   Function pointer when command is done
+* \param[in] u4SetQueryInfoLen  The length of the set/query buffer
+* \param[in] pucInfoBuffer      Pointer to set/query buffer
+*
+*
+* \retval WLAN_STATUS_PENDING
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter,
+		    UINT_8 ucCID,
+		    BOOLEAN fgSetQuery,
+		    BOOLEAN fgNeedResp,
+		    BOOLEAN fgIsOid,
+		    PFN_CMD_DONE_HANDLER pfCmdDoneHandler,
+		    PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler,
+		    UINT_32 u4SetQueryInfoLen,
+		    PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_8 ucCmdSeqNum;
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen));
+
+	DEBUGFUNC("wlanSendSetQueryCmd");
+
+	if (!prCmdInfo) {
+		DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+	DBGLOG(OID, TRACE, "ucCmdSeqNum =%d, ucCID =%d\n", ucCmdSeqNum, ucCID);
+
+	/* Setup common CMD Info Packet */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX;
+	prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen);
+	prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler;
+	prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler;
+	prCmdInfo->fgIsOid = fgIsOid;
+	prCmdInfo->ucCID = ucCID;
+	prCmdInfo->fgSetQuery = fgSetQuery;
+	prCmdInfo->fgNeedResp = fgNeedResp;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen;
+	prCmdInfo->pvInformationBuffer = pvSetQueryBuffer;
+	prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen;
+
+	/* Setup WIFI_CMD_T (no payload) */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL)
+		kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen);
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+	return WLAN_STATUS_PENDING;
+}
+
+#if CFG_SUPPORT_WAPI
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called by WAPI ui to set wapi mode, which is needed to info the the driver
+*          to operation at WAPI mode while driver initialize.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	DEBUGFUNC("wlanoidSetWapiMode");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+	ASSERT(pvSetBuffer);
+
+	/* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi assoc ie at the check point */
+	/*        The Adapter Connection setting fgUseWapi will cleat whil oid set mode (infra),          */
+	/*        And set fgUseWapi True while set wapi assoc ie                                          */
+	/*        policay selection, add key all depend on this flag,                                     */
+	/*        The fgUseWapi may remove later                                                          */
+	if (*(PUINT_32) pvSetBuffer)
+		prAdapter->fgUseWapi = TRUE;
+	else
+		prAdapter->fgUseWapi = FALSE;
+
+#if 0
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + 4));
+
+	if (!prCmdInfo) {
+		DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_BUILD_CONNECTION cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4;
+	prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
+	prCmdInfo->pfCmdTimeoutHandler = NULL;
+	prCmdInfo->fgIsOid = TRUE;
+	prCmdInfo->ucCID = CMD_ID_WAPI_MODE;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = u4SetBufferLen;
+	prCmdInfo->pvInformationBuffer = pvSetBuffer;
+	prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	cp = (PUINT_8) (prWifiCmd->aucBuffer);
+
+	kalMemCopy(cp, (PUINT_8) pvSetBuffer, 4);
+
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+
+	return WLAN_STATUS_PENDING;
+#else
+	return WLAN_STATUS_SUCCESS;
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called by WAPI to set the assoc info, which is needed to add to
+*          Association request frame while join WAPI AP.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_WAPI_INFO_ELEM_T prWapiInfo;
+	PUINT_8 cp;
+	UINT_16 u2AuthSuiteCount = 0;
+	UINT_16 u2PairSuiteCount = 0;
+	UINT_32 u4AuthKeyMgtSuite = 0;
+	UINT_32 u4PairSuite = 0;
+	UINT_32 u4GroupSuite = 0;
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	DEBUGFUNC("wlanoidSetWapiAssocInfo");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	if (u4SetBufferLen < 20 /* From EID to Group cipher */) {
+		prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE;
+		DBGLOG(SEC, INFO, "fgWapiMode = FALSE due to u4SetBufferLen %u < 20!\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	prAdapter->rWifiVar.rConnSettings.fgWapiMode = TRUE;
+
+	/* if (prWapiInfo->ucElemId != ELEM_ID_WAPI) */
+	/* DBGLOG(SEC, TRACE, ("Not WAPI IE ?!\n")); */
+
+	/* if (prWapiInfo->ucLength < 18) */
+	/* return WLAN_STATUS_INVALID_LENGTH; */
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	prWapiInfo = (P_WAPI_INFO_ELEM_T) pvSetBuffer;
+
+	if (prWapiInfo->ucElemId != ELEM_ID_WAPI) {
+		DBGLOG(SEC, INFO, "Not WAPI IE ?! u4SetBufferLen = %u\n", u4SetBufferLen);
+		prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE;
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	if (prWapiInfo->ucLength < 18)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	/* Skip Version check */
+	cp = (PUINT_8) &prWapiInfo->u2AuthKeyMgtSuiteCount;
+
+	WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
+
+	if (u2AuthSuiteCount > 1)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	cp = (PUINT_8) &prWapiInfo->aucAuthKeyMgtSuite1[0];
+	WLAN_GET_FIELD_32(cp, &u4AuthKeyMgtSuite);
+
+	DBGLOG(SEC, TRACE, "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n",
+			    u2AuthSuiteCount,
+			    (UCHAR) (u4AuthKeyMgtSuite & 0x000000FF),
+			    (UCHAR) ((u4AuthKeyMgtSuite >> 8) & 0x000000FF),
+			    (UCHAR) ((u4AuthKeyMgtSuite >> 16) & 0x000000FF),
+			    (UCHAR) ((u4AuthKeyMgtSuite >> 24) & 0x000000FF));
+
+	if (u4AuthKeyMgtSuite != WAPI_AKM_SUITE_802_1X && u4AuthKeyMgtSuite != WAPI_AKM_SUITE_PSK)
+		ASSERT(FALSE);
+
+	cp += 4;
+	WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
+	if (u2PairSuiteCount > 1)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	cp += 2;
+	WLAN_GET_FIELD_32(cp, &u4PairSuite);
+	DBGLOG(SEC, TRACE, "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n",
+			    u2PairSuiteCount,
+			    (UCHAR) (u4PairSuite & 0x000000FF),
+			    (UCHAR) ((u4PairSuite >> 8) & 0x000000FF),
+			    (UCHAR) ((u4PairSuite >> 16) & 0x000000FF), (UCHAR) ((u4PairSuite >> 24) & 0x000000FF));
+
+	if (u4PairSuite != WAPI_CIPHER_SUITE_WPI)
+		ASSERT(FALSE);
+
+	cp += 4;
+	WLAN_GET_FIELD_32(cp, &u4GroupSuite);
+	DBGLOG(SEC, TRACE, "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n",
+			    (UCHAR) (u4GroupSuite & 0x000000FF),
+			    (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
+			    (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF));
+
+	if (u4GroupSuite != WAPI_CIPHER_SUITE_WPI)
+		ASSERT(FALSE);
+
+	prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite = u4AuthKeyMgtSuite;
+	prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher = u4PairSuite;
+	prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher = u4GroupSuite;
+
+	kalMemCopy(prAdapter->prGlueInfo->aucWapiAssocInfoIEs, pvSetBuffer, u4SetBufferLen);
+	prAdapter->prGlueInfo->u2WapiAssocInfoIESz = (UINT_16) u4SetBufferLen;
+	DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen);
+
+	return WLAN_STATUS_SUCCESS;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the wpi key to the driver.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	P_PARAM_WPI_KEY_T prNewKey;
+	P_CMD_802_11_KEY prCmdKey;
+	PUINT_8 pc;
+	UINT_8 ucCmdSeqNum;
+
+	DEBUGFUNC("wlanoidSetWapiKey");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	prNewKey = (P_PARAM_WPI_KEY_T) pvSetBuffer;
+
+	DBGLOG_MEM8(OID, TRACE, (PUINT_8) pvSetBuffer, 560);
+	pc = (PUINT_8) pvSetBuffer;
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	/* Exception check */
+	if (prNewKey->ucKeyID != 0x1 || prNewKey->ucKeyID != 0x0) {
+		prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0);
+		/* DBGLOG(SEC, INFO, ("Invalid WAPI key ID (%d)\r\n", prNewKey->ucKeyID)); */
+	}
+
+	/* Dump P_PARAM_WPI_KEY_T content. */
+	DBGLOG(OID, TRACE, "Set: Dump P_PARAM_WPI_KEY_T content\r\n");
+	DBGLOG(OID, TRACE, "TYPE      : %d\r\n", prNewKey->eKeyType);
+	DBGLOG(OID, TRACE, "Direction : %d\r\n", prNewKey->eDirection);
+	DBGLOG(OID, TRACE, "KeyID     : %d\r\n", prNewKey->ucKeyID);
+	DBGLOG(OID, TRACE, "AddressIndex:\r\n");
+	DBGLOG_MEM8(OID, TRACE, prNewKey->aucAddrIndex, 12);
+	prNewKey->u4LenWPIEK = 16;
+
+	DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPIEK, (UINT_8) prNewKey->u4LenWPIEK);
+	prNewKey->u4LenWPICK = 16;
+
+	DBGLOG(OID, TRACE, "CK Key(%d):\r\n", (UINT_8) prNewKey->u4LenWPICK);
+	DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPICK, (UINT_8) prNewKey->u4LenWPICK);
+	DBGLOG(OID, TRACE, "PN:\r\n");
+	if (prNewKey->eKeyType == 0) {
+		prNewKey->aucPN[0] = 0x5c;
+		prNewKey->aucPN[1] = 0x36;
+		prNewKey->aucPN[2] = 0x5c;
+		prNewKey->aucPN[3] = 0x36;
+		prNewKey->aucPN[4] = 0x5c;
+		prNewKey->aucPN[5] = 0x36;
+		prNewKey->aucPN[6] = 0x5c;
+		prNewKey->aucPN[7] = 0x36;
+		prNewKey->aucPN[8] = 0x5c;
+		prNewKey->aucPN[9] = 0x36;
+		prNewKey->aucPN[10] = 0x5c;
+		prNewKey->aucPN[11] = 0x36;
+		prNewKey->aucPN[12] = 0x5c;
+		prNewKey->aucPN[13] = 0x36;
+		prNewKey->aucPN[14] = 0x5c;
+		prNewKey->aucPN[15] = 0x36;
+	}
+
+	DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucPN, 16);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetBufferLen));
+
+	if (!prCmdInfo) {
+		DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+
+	/* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX;
+	prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY);
+	prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
+	prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
+	prCmdInfo->fgIsOid = TRUE;
+	prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = u4SetBufferLen;
+	prCmdInfo->pvInformationBuffer = pvSetBuffer;
+	prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
+
+	/* Setup WIFI_CMD_T */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer);
+
+	kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY));
+
+	prCmdKey->ucAddRemove = 1;	/* Add */
+
+	if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) {
+		prCmdKey->ucTxKey = 1;
+		prCmdKey->ucKeyType = 1;
+	}
+
+	kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->aucAddrIndex, MAC_ADDR_LEN);
+
+	prCmdKey->ucNetType = 0;	/* AIS */
+
+	prCmdKey->ucKeyId = prNewKey->ucKeyID;
+
+	prCmdKey->ucKeyLen = 32;
+
+	prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI;
+
+	kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucWPIEK, 16);
+
+	kalMemCopy(prCmdKey->aucKeyMaterial + 16, (PUINT_8) prNewKey->aucWPICK, 16);
+
+	kalMemCopy(prCmdKey->aucKeyRsc, (PUINT_8) prNewKey->aucPN, 16);
+
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+
+	return WLAN_STATUS_PENDING;
+}				/* wlanoidSetAddKey */
+#endif
+
+#if CFG_SUPPORT_WPS2
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called by WSC to set the assoc info, which is needed to add to
+*          Association request frame while join WPS AP.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	DEBUGFUNC("wlanoidSetWSCAssocInfo");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	if (u4SetBufferLen == 0)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	kalMemCopy(prAdapter->prGlueInfo->aucWSCAssocInfoIE, pvSetBuffer, u4SetBufferLen);
+	prAdapter->prGlueInfo->u2WSCAssocInfoIELen = (UINT_16) u4SetBufferLen;
+	DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen);
+
+	return WLAN_STATUS_SUCCESS;
+
+}
+#endif
+
+#if CFG_ENABLE_WAKEUP_ON_LAN
+WLAN_STATUS
+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_PM_PACKET_PATTERN prPacketPattern;
+
+	DEBUGFUNC("wlanoidSetAddWakeupPattern");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN);
+
+	if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer;
+
+	/* FIXME:
+	 * Send the struct to firmware */
+
+	return WLAN_STATUS_FAILURE;
+}
+
+WLAN_STATUS
+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_PM_PACKET_PATTERN prPacketPattern;
+
+	DEBUGFUNC("wlanoidSetAddWakeupPattern");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN);
+
+	if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer;
+
+	/* FIXME:
+	 * Send the struct to firmware */
+
+	return WLAN_STATUS_FAILURE;
+}
+
+WLAN_STATUS
+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	PUINT_32 pu4WakeupEventEnable;
+
+	DEBUGFUNC("wlanoidQueryEnableWakeup");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	if (u4QueryBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+
+	pu4WakeupEventEnable = (PUINT_32) pvQueryBuffer;
+
+	*pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable;
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+WLAN_STATUS
+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PUINT_32 pu4WakeupEventEnable;
+
+	DEBUGFUNC("wlanoidSetEnableWakup");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+
+	if (u4SetBufferLen < sizeof(UINT_32))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	pu4WakeupEventEnable = (PUINT_32) pvSetBuffer;
+	prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable;
+
+	/* FIXME:
+	 * Send Command Event for setting wakeup-pattern / Magic Packet to firmware
+	 * */
+
+	return WLAN_STATUS_FAILURE;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to configure PS related settings for WMM-PS test.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T prWmmPsTestInfo;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	CMD_SET_WMM_PS_TEST_STRUCT_T rSetWmmPsTestParam;
+	UINT_16 u2CmdBufLen;
+	P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo;
+	P_BSS_INFO_T prBssInfo;
+
+	DEBUGFUNC("wlanoidSetWiFiWmmPsTest");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T);
+
+	prWmmPsTestInfo = (P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T) pvSetBuffer;
+
+	rSetWmmPsTestParam.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+	rSetWmmPsTestParam.bmfgApsdEnAc = prWmmPsTestInfo->bmfgApsdEnAc;
+	rSetWmmPsTestParam.ucIsEnterPsAtOnce = prWmmPsTestInfo->ucIsEnterPsAtOnce;
+	rSetWmmPsTestParam.ucIsDisableUcTrigger = prWmmPsTestInfo->ucIsDisableUcTrigger;
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[rSetWmmPsTestParam.ucNetTypeIndex]);
+	prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
+	prPmProfSetupInfo->ucBmpDeliveryAC = (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3);
+	prPmProfSetupInfo->ucBmpTriggerAC = rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3);
+
+	u2CmdBufLen = sizeof(CMD_SET_WMM_PS_TEST_STRUCT_T);
+
+#if 0
+	/* it will apply the disable trig or not immediately */
+	if (prPmInfo->ucWmmPsDisableUcPoll && prPmInfo->ucWmmPsConnWithTrig)
+		; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); */
+	else
+		; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); */
+#endif
+
+	rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_WMM_PS_TEST_PARMS, TRUE, FALSE, TRUE, NULL,	/* TODO? */
+				      NULL, u2CmdBufLen, (PUINT_8) &rSetWmmPsTestParam, NULL, 0);
+
+	return rStatus;
+}				/* wlanoidSetWiFiWmmPsTest */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to configure enable/disable TX A-MPDU feature.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	CMD_TX_AMPDU_T rTxAmpdu;
+	UINT_16 u2CmdBufLen;
+	PBOOLEAN pfgEnable;
+
+	DEBUGFUNC("wlanoidSetTxAmpdu");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(BOOLEAN);
+
+	pfgEnable = (PBOOLEAN) pvSetBuffer;
+
+	rTxAmpdu.fgEnable = *pfgEnable;
+
+	u2CmdBufLen = sizeof(CMD_TX_AMPDU_T);
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_TX_AMPDU,
+				      TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rTxAmpdu, NULL, 0);
+
+	return rStatus;
+}				/* wlanoidSetTxAmpdu */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to configure reject/accept ADDBA Request.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	CMD_ADDBA_REJECT_T rAddbaReject;
+	UINT_16 u2CmdBufLen;
+	PBOOLEAN pfgEnable;
+
+	DEBUGFUNC("wlanoidSetAddbaReject");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(BOOLEAN);
+
+	pfgEnable = (PBOOLEAN) pvSetBuffer;
+
+	rAddbaReject.fgEnable = *pfgEnable;
+
+	u2CmdBufLen = sizeof(CMD_ADDBA_REJECT_T);
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_ADDBA_REJECT,
+				      TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rAddbaReject, NULL, 0);
+
+	return rStatus;
+}				/* wlanoidSetAddbaReject */
+
+#if CFG_SLT_SUPPORT
+
+WLAN_STATUS
+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL;
+	P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL;
+
+	DEBUGFUNC("wlanoidQuerySLTStatus");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T);
+
+	if (u4QueryBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvQueryBuffer);
+
+	prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvQueryBuffer;
+
+	prSltInfo = &(prAdapter->rWifiVar.rSltInfo);
+
+	switch (prMtkSltInfo->rSltFuncIdx) {
+	case ENUM_MTK_SLT_FUNC_LP_SET:
+		{
+			P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL;
+
+			ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T));
+
+			prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent;
+
+			prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt;
+		}
+		break;
+	default:
+		/* TBD... */
+		break;
+	}
+
+	return rWlanStatus;
+}				/* wlanoidQuerySLTStatus */
+
+WLAN_STATUS
+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL;
+	P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL;
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL;
+
+	/* 1. Action: Update or Initial Set
+	 * 2. Role.
+	 * 3. Target MAC address.
+	 * 4. RF BW & Rate Settings
+	 */
+
+	DEBUGFUNC("wlanoidUpdateSLTMode");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvSetBuffer;
+
+	prSltInfo = &(prAdapter->rWifiVar.rSltInfo);
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+
+	switch (prMtkSltInfo->rSltFuncIdx) {
+	case ENUM_MTK_SLT_FUNC_INITIAL:	/* Initialize */
+		{
+			P_PARAM_MTK_SLT_INITIAL_STRUCT_T prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) NULL;
+
+			ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_INITIAL_STRUCT_T));
+
+			prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) &prMtkSltInfo->unFuncInfoContent;
+
+			if (prSltInfo->prPseudoStaRec != NULL) {
+				/* The driver has been initialized. */
+				prSltInfo->prPseudoStaRec = NULL;
+			}
+
+			prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc(prAdapter,
+									       BSS_TYPE_IBSS,
+									       prMtkSltInit->aucTargetMacAddr,
+									       prMtkSltInit->aucTargetMacAddr);
+
+			prSltInfo->u2SiteID = prMtkSltInit->u2SiteID;
+
+			/* Bandwidth 2.4G: Channel 1~14
+			 * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64,
+			 *                       *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
+			 *                       149, 153, *157, 161,
+			 *                       184, 188, 192, 196, 200, 204, 208, 212, *216
+			 */
+			prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5;
+
+			switch (prSltInfo->ucChannel2G4) {
+			case 1:
+				prSltInfo->ucChannel5G = 36;
+				break;
+			case 6:
+				prSltInfo->ucChannel5G = 52;
+				break;
+			case 11:
+				prSltInfo->ucChannel5G = 104;
+				break;
+			case 16:
+				prSltInfo->ucChannel2G4 = 14;
+				prSltInfo->ucChannel5G = 161;
+				break;
+			default:
+				ASSERT(FALSE);
+			}
+
+			if (prSltInfo->prPseudoBssDesc == NULL) {
+				do {
+					prSltInfo->prPseudoBssDesc = scanAllocateBssDesc(prAdapter);
+
+					if (prSltInfo->prPseudoBssDesc == NULL) {
+						rWlanStatus = WLAN_STATUS_FAILURE;
+						break;
+					}
+					prBssDesc = prSltInfo->prPseudoBssDesc;
+				} while (FALSE);
+			} else {
+				prBssDesc = prSltInfo->prPseudoBssDesc;
+			}
+
+			if (prBssDesc) {
+				prBssDesc->eBSSType = BSS_TYPE_IBSS;
+
+				COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prMtkSltInit->aucTargetMacAddr);
+				COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr);
+
+				prBssDesc->u2BeaconInterval = 100;
+				prBssDesc->u2ATIMWindow = 0;
+				prBssDesc->ucDTIMPeriod = 1;
+
+				prBssDesc->u2IELength = 0;
+
+				prBssDesc->fgIsERPPresent = TRUE;
+				prBssDesc->fgIsHTPresent = TRUE;
+
+				prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX);
+				prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX);
+				prBssDesc->fgIsUnknownBssBasicRate = FALSE;
+
+				prBssDesc->fgIsLargerTSF = TRUE;
+
+				prBssDesc->eBand = BAND_2G4;
+
+				prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4;
+
+				prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN;
+
+				GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
+			}
+		}
+		break;
+	case ENUM_MTK_SLT_FUNC_RATE_SET:	/* Update RF Settings. */
+		if (prSltInfo->prPseudoStaRec == NULL) {
+			rWlanStatus = WLAN_STATUS_FAILURE;
+			break;
+		}
+
+		P_PARAM_MTK_SLT_TR_TEST_STRUCT_T prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) NULL;
+
+		ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_TR_TEST_STRUCT_T));
+
+		prStaRec = prSltInfo->prPseudoStaRec;
+		prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent;
+
+		if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) {
+			prBssInfo->eBand = BAND_5G;
+			prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel5G;
+		}
+		if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM24) {
+			prBssInfo->eBand = BAND_2G4;
+			prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel2G4;
+		}
+
+		if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) {
+			/* RF 40 */
+			/* It would controls RFBW capability in WTBL. */
+			prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+			/* This controls RF BW, RF BW would be 40 only if */
+			/* 1. PHY_TYPE_BIT_HT is TRUE. */
+			/* 2. SCO is SCA/SCB. */
+			prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+
+			/* U20/L20 Control. */
+			switch (prTRSetting->u4FixedRate & 0xC000) {
+			case FIXED_EXT_CHNL_U20:
+				prBssInfo->eBssSCO = CHNL_EXT_SCB;	/* +2 */
+				if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5)
+					prBssInfo->ucPrimaryChannel += 2;
+				else {
+					/* For channel 1, testing L20 at channel 8. */
+					if (prBssInfo->ucPrimaryChannel < 5)
+						prBssInfo->ucPrimaryChannel = 8;
+				}
+				break;
+			case FIXED_EXT_CHNL_L20:
+			default:	/* 40M */
+				prBssInfo->eBssSCO = CHNL_EXT_SCA;	/* -2 */
+				if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) {
+					prBssInfo->ucPrimaryChannel -= 2;
+				} else {
+					/* For channel 11 / 14. testing U20 at channel 3. */
+					if (prBssInfo->ucPrimaryChannel > 10)
+						prBssInfo->ucPrimaryChannel = 3;
+				}
+				break;
+			}
+		} else {
+			/* RF 20 */
+			prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
+			prBssInfo->eBssSCO = CHNL_EXT_SCN;
+		}
+
+		prBssInfo->fgErpProtectMode = FALSE;
+		prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE;
+		prBssInfo->eGfOperationMode = GF_MODE_NORMAL;
+
+		nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex);
+
+		prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M);
+
+		switch (prTRSetting->u4FixedRate & 0xFF) {
+		case RATE_OFDM_54M:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_54M_INDEX);
+			break;
+		case RATE_OFDM_48M:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_48M_INDEX);
+			break;
+		case RATE_OFDM_36M:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX);
+			break;
+		case RATE_OFDM_24M:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_24M_INDEX);
+			break;
+		case RATE_OFDM_6M:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_6M_INDEX);
+			break;
+		case RATE_CCK_11M_LONG:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_11M_INDEX);
+			break;
+		case RATE_CCK_1M_LONG:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_1M_INDEX);
+			break;
+		case RATE_GF_MCS_0:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX);
+			prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF;
+			break;
+		case RATE_MM_MCS_7:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX);
+			prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF;
+#if 0				/* Only for Current Measurement Mode. */
+			prStaRec->u2HtCapInfo |= (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M);
+#endif
+			break;
+		case RATE_GF_MCS_7:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX);
+			prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF;
+			break;
+		default:
+			prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX);
+			break;
+		}
+
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+
+		break;
+	case ENUM_MTK_SLT_FUNC_LP_SET:	/* Reset LP Test Result. */
+		{
+			P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL;
+
+			ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T));
+
+			prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent;
+
+			if (prSltInfo->prPseudoBssDesc == NULL) {
+				/* Please initial SLT Mode first. */
+				break;
+			}
+			prBssDesc = prSltInfo->prPseudoBssDesc;
+
+			switch (prLpSetting->rLpTestMode) {
+			case ENUM_MTK_LP_TEST_NORMAL:
+				/* In normal mode, we would use target MAC address to be the BSSID. */
+				COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr);
+				prSltInfo->fgIsDUT = FALSE;
+				break;
+			case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE:
+				/* 1. Lower AIFS of BCN queue.
+				 * 2. Fixed Random Number tobe 0.
+				 */
+				prSltInfo->fgIsDUT = FALSE;
+				/* In LP test mode, we would use MAC address of Golden Sample to be the BSSID. */
+				COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr);
+				break;
+			case ENUM_MTK_LP_TEST_DUT:
+				/* 1. Enter Sleep Mode.
+				 * 2. Fix random number a large value & enlarge AIFN of BCN queue.
+				 */
+				COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssDesc->aucSrcAddr);
+				prSltInfo->u4BeaconReceiveCnt = 0;
+				prSltInfo->fgIsDUT = TRUE;
+				break;
+			}
+
+		}
+
+		break;
+	default:
+		break;
+	}
+
+	return WLAN_STATUS_FAILURE;
+
+	return rWlanStatus;
+}				/* wlanoidUpdateSLTMode */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query NVRAM value.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo;
+	UINT_16 u2Data;
+	BOOLEAN fgStatus;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	DEBUGFUNC("wlanoidQueryNvramRead");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T);
+
+	if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvQueryBuffer;
+
+	if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_READ) {
+		/* change to byte offset */
+		fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo,
+						prNvramRwInfo->ucEepromIndex << 1,
+						&u2Data);
+
+		if (fgStatus) {
+			prNvramRwInfo->u2EepromData = u2Data;
+			DBGLOG(OID, INFO, "NVRAM Read: index=%#X, data=%#02X\r\n",
+					   prNvramRwInfo->ucEepromIndex, u2Data);
+		} else {
+			DBGLOG(OID, ERROR, "NVRAM Read Failed: index=%#x.\r\n", prNvramRwInfo->ucEepromIndex);
+			rStatus = WLAN_STATUS_FAILURE;
+		}
+	} else if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_GETSIZE) {
+		prNvramRwInfo->u2EepromData = CFG_FILE_WIFI_REC_SIZE;
+		DBGLOG(OID, INFO, "EEPROM size =%d\r\n", prNvramRwInfo->u2EepromData);
+	}
+
+	*pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T);
+
+	return rStatus;
+}				/* wlanoidQueryNvramRead */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to write NVRAM value.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo;
+	BOOLEAN fgStatus;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	DEBUGFUNC("wlanoidSetNvramWrite");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvSetBuffer;
+
+	/* change to byte offset */
+	fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo,
+					prNvramRwInfo->ucEepromIndex << 1,
+					prNvramRwInfo->u2EepromData);
+
+	if (fgStatus == FALSE) {
+		DBGLOG(OID, ERROR, "NVRAM Write Failed.\r\n");
+		rStatus = WLAN_STATUS_FAILURE;
+	}
+
+	return rStatus;
+}				/* wlanoidSetNvramWrite */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to get the config data source type.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	ASSERT(prAdapter);
+
+	*pu4QueryInfoLen = sizeof(ENUM_CFG_SRC_TYPE_T);
+
+	if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE)
+		*(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_NVRAM;
+	else
+		*(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_EEPROM;
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to get the config data source type.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	ASSERT(prAdapter);
+
+	*pu4QueryInfoLen = sizeof(P_ENUM_EEPROM_TYPE_T);
+
+#if CFG_SUPPORT_NIC_CAPABILITY
+	if (prAdapter->fgIsEepromUsed == TRUE)
+		*(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_PRESENT;
+	else
+		*(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO;
+#else
+	*(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO;
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to get the config data source type.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PUINT_8 pucCountry;
+	UINT_16 u2CountryCode;
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(u4SetBufferLen == 2);
+
+	*pu4SetInfoLen = 2;
+
+	pucCountry = pvSetBuffer;
+	u2CountryCode = (((UINT_16) pucCountry[0]) << 8) | ((UINT_16) pucCountry[1]);
+
+	/* previous country code == FF : ignore country code, current country code == FE : resume */
+	if (prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup == COUNTRY_CODE_FF) {
+		if (u2CountryCode != COUNTRY_CODE_FE) {
+			DBGLOG(OID, INFO, "Skip country code cmd (0x%04x)\n", u2CountryCode);
+			return WLAN_STATUS_SUCCESS;
+		}
+		DBGLOG(OID, INFO, "Resume handle country code cmd (0x%04x)\n", u2CountryCode);
+	}
+
+	prAdapter->rWifiVar.rConnSettings.u2CountryCode = u2CountryCode;
+	prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup = prAdapter->rWifiVar.rConnSettings.u2CountryCode;
+	DBGLOG(OID, LOUD, "u2CountryCodeBakup=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup);
+
+	/* Force to re-search country code in country domains */
+	prAdapter->prDomainInfo = NULL;
+	rlmDomainSendCmd(prAdapter, TRUE);
+
+	/* Update supported channel list in channel table based on current country domain */
+	wlanUpdateChannelTable(prAdapter->prGlueInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#if 0
+WLAN_STATUS
+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam;
+	CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam;
+
+	DEBUGFUNC("wlanoidSetNoaParam");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer;
+
+	kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T));
+	rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs;
+	rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs;
+	rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_NOA_PARAM,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T),
+				   (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen);
+}
+
+WLAN_STATUS
+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam;
+	CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam;
+
+	DEBUGFUNC("wlanoidSetOppPsParam");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer;
+
+	kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T));
+	rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_OPPPS_PARAM,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T),
+				   (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen);
+}
+
+WLAN_STATUS
+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam;
+	CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam;
+	P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo;
+	P_BSS_INFO_T prBssInfo;
+
+	DEBUGFUNC("wlanoidSetUApsdParam");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+	prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
+
+	prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer;
+
+	kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T));
+	rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD;
+	prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD;
+
+	rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe;
+	rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk;
+	rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo;
+	rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi;
+	prPmProfSetupInfo->ucBmpDeliveryAC =
+	    ((prUapsdParam->fgEnAPSD_AcBe << 0) |
+	     (prUapsdParam->fgEnAPSD_AcBk << 1) |
+	     (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3));
+	prPmProfSetupInfo->ucBmpTriggerAC =
+	    ((prUapsdParam->fgEnAPSD_AcBe << 0) |
+	     (prUapsdParam->fgEnAPSD_AcBk << 1) |
+	     (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3));
+
+	rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen;
+	prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_UAPSD_PARAM,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T),
+				   (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen);
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set BT profile or BT information and the
+*        driver will set the built-in PTA configuration into chip.
+*
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+
+	P_PTA_IPC_T prPtaIpc;
+
+	DEBUGFUNC("wlanoidSetBT.\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PTA_IPC_T);
+	if (u4SetBufferLen != sizeof(PTA_IPC_T)) {
+		WARNLOG(("Invalid length %u\n", u4SetBufferLen));
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail to set BT profile because of ACPI_D3\n");
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	ASSERT(pvSetBuffer);
+	prPtaIpc = (P_PTA_IPC_T) pvSetBuffer;
+
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG
+	DBGLOG(OID, INFO,
+		"BCM BWCS CMD: BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n",
+		prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2],
+		prPtaIpc->u.aucBTPParams[3];
+
+#endif
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SET_BWCS,
+			    TRUE, FALSE, FALSE, NULL, NULL, sizeof(PTA_IPC_T), (PUINT_8) prPtaIpc, NULL, 0);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query current BT profile and BTCR values
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] pvQueryBuffer      Pointer to the buffer that holds the result of
+*                               the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryBT(IN P_ADAPTER_T prAdapter,
+	       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+/* P_PARAM_PTA_IPC_T prPtaIpc; */
+/* UINT_32 u4QueryBuffLen; */
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PTA_IPC_T);
+
+	/* Check for query buffer length */
+	if (u4QueryBufferLen != sizeof(PTA_IPC_T)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	ASSERT(pvQueryBuffer);
+/* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */
+/* prPtaIpc->ucCmd = BT_CMD_PROFILE; */
+/* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */
+/* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); */
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#if 0
+WLAN_STATUS
+wlanoidQueryBtSingleAntenna(IN P_ADAPTER_T prAdapter,
+			    OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PTA_INFO_T prPtaInfo;
+	PUINT_32 pu4SingleAntenna;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	/* Check for query buffer length */
+	if (u4QueryBufferLen != sizeof(UINT_32)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	ASSERT(pvQueryBuffer);
+
+	prPtaInfo = &prAdapter->rPtaInfo;
+	pu4SingleAntenna = (PUINT_32) pvQueryBuffer;
+
+	if (prPtaInfo->fgSingleAntenna) {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 1\r\n")); */
+		*pu4SingleAntenna = 1;
+	} else {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 0\r\n")); */
+		*pu4SingleAntenna = 0;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+WLAN_STATUS
+wlanoidSetBtSingleAntenna(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+
+	PUINT_32 pu4SingleAntenna;
+	UINT_32 u4SingleAntenna;
+	P_PTA_INFO_T prPtaInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	prPtaInfo = &prAdapter->rPtaInfo;
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+	if (u4SetBufferLen != sizeof(UINT_32))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	if (IS_ARB_IN_RFTEST_STATE(prAdapter))
+		return WLAN_STATUS_SUCCESS;
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail to set antenna because of ACPI_D3\n");
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	ASSERT(pvSetBuffer);
+	pu4SingleAntenna = (PUINT_32) pvSetBuffer;
+	u4SingleAntenna = *pu4SingleAntenna;
+
+	if (u4SingleAntenna == 0) {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 0\r\n")); */
+		prPtaInfo->fgSingleAntenna = FALSE;
+	} else {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 1\r\n")); */
+		prPtaInfo->fgSingleAntenna = TRUE;
+	}
+	ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
+WLAN_STATUS
+wlanoidQueryPta(IN P_ADAPTER_T prAdapter,
+		OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PTA_INFO_T prPtaInfo;
+	PUINT_32 pu4Pta;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	/* Check for query buffer length */
+	if (u4QueryBufferLen != sizeof(UINT_32)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	ASSERT(pvQueryBuffer);
+
+	prPtaInfo = &prAdapter->rPtaInfo;
+	pu4Pta = (PUINT_32) pvQueryBuffer;
+
+	if (prPtaInfo->fgEnabled) {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */
+		*pu4Pta = 1;
+	} else {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */
+		*pu4Pta = 0;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+WLAN_STATUS
+wlanoidSetPta(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	PUINT_32 pu4PtaCtrl;
+	UINT_32 u4PtaCtrl;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(UINT_32);
+	if (u4SetBufferLen != sizeof(UINT_32))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	if (IS_ARB_IN_RFTEST_STATE(prAdapter))
+		return WLAN_STATUS_SUCCESS;
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(OID, WARN, "Fail to set BT setting because of ACPI_D3\n");
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	ASSERT(pvSetBuffer);
+	pu4PtaCtrl = (PUINT_32) pvSetBuffer;
+	u4PtaCtrl = *pu4PtaCtrl;
+
+	if (u4PtaCtrl == 0) {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); */
+		nicPtaSetFunc(prAdapter, FALSE);
+	} else {
+		/* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); */
+		nicPtaSetFunc(prAdapter, TRUE);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+#endif
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set Tx power profile.
+*
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	/* P_SET_TXPWR_CTRL_T pTxPwr = (P_SET_TXPWR_CTRL_T)pvSetBuffer; */
+	/* UINT_32 i; */
+	WLAN_STATUS rStatus;
+
+	DEBUGFUNC("wlanoidSetTxPower");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+
+#if 0
+	DBGLOG(OID, INFO, "c2GLegacyStaPwrOffset=%d\n", pTxPwr->c2GLegacyStaPwrOffset);
+	DBGLOG(OID, INFO, "c2GHotspotPwrOffset=%d\n", pTxPwr->c2GHotspotPwrOffset);
+	DBGLOG(OID, INFO, "c2GP2pPwrOffset=%d\n", pTxPwr->c2GP2pPwrOffset);
+	DBGLOG(OID, INFO, "c2GBowPwrOffset=%d\n", pTxPwr->c2GBowPwrOffset);
+	DBGLOG(OID, INFO, "c5GLegacyStaPwrOffset=%d\n", pTxPwr->c5GLegacyStaPwrOffset);
+	DBGLOG(OID, INFO, "c5GHotspotPwrOffset=%d\n", pTxPwr->c5GHotspotPwrOffset);
+	DBGLOG(OID, INFO, "c5GP2pPwrOffset=%d\n", pTxPwr->c5GP2pPwrOffset);
+	DBGLOG(OID, INFO, "c5GBowPwrOffset=%d\n", pTxPwr->c5GBowPwrOffset);
+	DBGLOG(OID, INFO, "ucConcurrencePolicy=%d\n", pTxPwr->ucConcurrencePolicy);
+
+	for (i = 0; i < 14; i++)
+		DBGLOG(OID, INFO, "acTxPwrLimit2G[%d]=%d\n", i, pTxPwr->acTxPwrLimit2G[i]);
+
+	for (i = 0; i < 4; i++)
+		DBGLOG(OID, INFO, "acTxPwrLimit5G[%d]=%d\n", i, pTxPwr->acTxPwrLimit5G[i]);
+#endif
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_SET_TXPWR_CTRL,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      TRUE,	/* fgIsOid */
+				      NULL,	/* pfCmdDoneHandler */
+				      NULL,	/* pfCmdTimeoutHandler */
+				      u4SetBufferLen,	/* u4SetQueryInfoLen */
+				      (PUINT_8) pvSetBuffer,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+
+	return rStatus;
+
+}
+
+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen)
+{
+	P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo;
+	P_CMD_DUMP_MEM prCmdDumpMem;
+	CMD_DUMP_MEM rCmdDumpMem;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE;
+
+	UINT_32 u4RemainLeng = 0;
+	UINT_32 u4CurAddr = 0;
+	UINT_8 ucFragNum = 0;
+
+	prCmdDumpMem = &rCmdDumpMem;
+	prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer;
+
+	u4RemainLeng = prMemDumpInfo->u4RemainLength;
+	u4CurAddr = prMemDumpInfo->u4Address + prMemDumpInfo->u4Length;
+	ucFragNum = prMemDumpInfo->ucFragNum + 1;
+
+	/* Query. If request length is larger than max length, do it as ping pong.
+	 * Send a command and wait for a event. Send next command while the event is received.
+	 *
+	 */
+	do {
+		UINT_32 u4CurLeng = 0;
+
+		if (u4RemainLeng > u4MemSize) {
+			u4CurLeng = u4MemSize;
+			u4RemainLeng -= u4MemSize;
+		} else {
+			u4CurLeng = u4RemainLeng;
+			u4RemainLeng = 0;
+		}
+
+		prCmdDumpMem->u4Address = u4CurAddr;
+		prCmdDumpMem->u4Length = u4CurLeng;
+		prCmdDumpMem->u4RemainLength = u4RemainLeng;
+		prCmdDumpMem->ucFragNum = ucFragNum;
+
+		DBGLOG(OID, TRACE, "[%d] 0x%X, len %u, remain len %u\n",
+				    ucFragNum,
+				    prCmdDumpMem->u4Address, prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength);
+
+		rStatus = wlanSendSetQueryCmd(prAdapter,
+					      CMD_ID_DUMP_MEM,
+					      FALSE,
+					      TRUE,
+					      TRUE,
+					      nicCmdEventQueryMemDump,
+					      nicOidCmdTimeoutCommon,
+					      sizeof(CMD_DUMP_MEM),
+					      (PUINT_8) prCmdDumpMem, pvQueryBuffer, u4QueryBufferLen);
+
+	} while (FALSE);
+
+	return rStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to dump memory.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo;
+
+	DEBUGFUNC("wlanoidQueryMemDump");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_32);
+
+	prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer;
+	DBGLOG(OID, TRACE, "Dump 0x%X, len %u\n", prMemDumpInfo->u4Address, prMemDumpInfo->u4Length);
+
+	prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length;
+	prMemDumpInfo->u4Length = 0;
+	prMemDumpInfo->ucFragNum = 0;
+
+	return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* end of wlanoidQueryMcrRead() */
+
+#if CFG_ENABLE_WIFI_DIRECT
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to set the p2p mode.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS status = WLAN_STATUS_SUCCESS;
+	P_PARAM_CUSTOM_P2P_SET_STRUCT_T prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) NULL;
+	/* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T)NULL; */
+	DEBUGFUNC("wlanoidSetP2pMode");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T);
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T)) {
+		DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) pvSetBuffer;
+
+	DBGLOG(P2P, INFO, "Set P2P enable %p [%u] mode[%u]\n", prSetP2P, prSetP2P->u4Enable, prSetP2P->u4Mode);
+
+	/*
+	 *    enable = 1, mode = 0  => init P2P network
+	 *    enable = 1, mode = 1  => init Soft AP network
+	 *    enable = 0                   => uninit P2P/AP network
+	 */
+
+	if (prSetP2P->u4Enable) {
+		p2pSetMode((prSetP2P->u4Mode == 1) ? TRUE : FALSE);
+
+		if (p2pLaunch(prAdapter->prGlueInfo))
+			ASSERT(prAdapter->fgIsP2PRegistered);
+
+	} else {
+		DBGLOG(P2P, TRACE, "prAdapter->fgIsP2PRegistered = %d\n", prAdapter->fgIsP2PRegistered);
+
+		if (prAdapter->fgIsP2PRegistered) {
+			DBGLOG(P2P, INFO, "p2pRemove\n");
+			p2pRemove(prAdapter->prGlueInfo);
+		}
+
+	}
+
+#if 0
+	prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T) cnmMemAlloc(prAdapter,
+								      RAM_TYPE_MSG,
+								      (sizeof(MSG_P2P_NETDEV_REGISTER_T)));
+
+	if (prP2pNetdevRegMsg == NULL) {
+		ASSERT(FALSE);
+		status = WLAN_STATUS_RESOURCES;
+		return status;
+	}
+
+	prP2pNetdevRegMsg->rMsgHdr.eMsgId = MID_MNY_P2P_NET_DEV_REGISTER;
+	prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? TRUE : FALSE;
+	prP2pNetdevRegMsg->ucMode = (UINT_8) prSetP2P->u4Mode;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF);
+#endif
+
+	return status;
+}
+#endif
+
+#if CFG_SUPPORT_BUILD_DATE_CODE
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to query build date code information from firmware
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	CMD_GET_BUILD_DATE_CODE rCmdGetBuildDateCode;
+
+	DEBUGFUNC("wlanoidQueryBuildDateCode");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(UINT_8) * 16;
+
+	if (u4QueryBufferLen < sizeof(UINT_8) * 16)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_BUILD_DATE_CODE,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventBuildDateCode,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_GET_BUILD_DATE_CODE),
+				   (PUINT_8) &rCmdGetBuildDateCode, pvQueryBuffer, u4QueryBufferLen);
+
+}				/* end of wlanoidQueryBuildDateCode() */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to query BSS info from firmware
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter,
+		    OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	EVENT_AIS_BSS_INFO_T rCmdBSSInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T);
+
+	if (u4QueryBufferLen < sizeof(EVENT_AIS_BSS_INFO_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+	kalMemZero(&rCmdBSSInfo, sizeof(EVENT_AIS_BSS_INFO_T));
+	/*
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_GET_BSS_INFO,
+				      FALSE,
+				      TRUE,
+				      TRUE,
+				      nicCmdEventGetBSSInfo,
+				      nicOidCmdTimeoutCommon,
+				      sizeof(P_EVENT_AIS_BSS_INFO_T),
+				      (PUINT_8) &rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen);
+	*/
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_GET_BSS_INFO,
+				      FALSE,
+				      TRUE,
+				      TRUE,
+				      nicCmdEventGetBSSInfo,
+				      nicOidCmdTimeoutCommon,
+				      sizeof(EVENT_AIS_BSS_INFO_T),
+				      (PUINT_8) & rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen);
+
+	return rStatus;
+}				/* wlanoidSetWiFiWmmPsTest */
+
+#if CFG_SUPPORT_BATCH_SCAN
+
+#define CMD_WLS_BATCHING		"WLS_BATCHING"
+
+#define BATCHING_SET            "SET"
+#define BATCHING_GET            "GET"
+#define BATCHING_STOP           "STOP"
+
+#define PARAM_SCANFREQ          "SCANFREQ"
+#define PARAM_MSCAN             "MSCAN"
+#define PARAM_BESTN	            "BESTN"
+#define PARAM_CHANNEL           "CHANNEL"
+#define PARAM_RTT               "RTT"
+
+WLAN_STATUS
+batchSetCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4WritenLen)
+{
+	P_CHANNEL_INFO_T prRfChannelInfo;
+	CMD_BATCH_REQ_T rCmdBatchReq;
+
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	PCHAR head, p, p2;
+	UINT_32 tokens;
+	INT_32 scanfreq, mscan, bestn, rtt;
+
+	DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", (PCHAR) pvSetBuffer, (UINT_32) u4SetBufferLen);
+
+	if (!pu4WritenLen)
+		return -EINVAL;
+	*pu4WritenLen = 0;
+
+	if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) {
+		DBGLOG(SCN, TRACE, "[BATCH] invalid len %u\n", (UINT_32) u4SetBufferLen);
+		return -EINVAL;
+	}
+
+	head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1;
+	kalMemSet(&rCmdBatchReq, 0, sizeof(CMD_BATCH_REQ_T));
+
+	if (!kalStrnCmp(head, BATCHING_SET, kalStrLen(BATCHING_SET))) {
+
+		DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n");
+
+		head += kalStrLen(BATCHING_SET) + 1;
+
+		/* SCANFREQ, MSCAN, BESTN */
+		tokens = kalSScanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", &scanfreq, &mscan, &bestn);
+		if (tokens != 3) {
+			DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, SCANFREQ=%d MSCAN=%d BESTN=%d\n",
+					    (UINT_32) tokens, scanfreq, mscan, bestn);
+			return -EINVAL;
+		}
+		/* RTT */
+		p = kalStrStr(head, PARAM_RTT);
+		if (!p) {
+			DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", head);
+			return -EINVAL;
+		}
+		tokens = kalSScanf(p, "RTT=%d", &rtt);
+		if (tokens != 1) {
+			DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, rtt=%d\n", (UINT_32) tokens, rtt);
+			return -EINVAL;
+		}
+		/* CHANNEL */
+		p = kalStrStr(head, PARAM_CHANNEL);
+		if (!p) {
+			DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n");
+			return -EINVAL;
+		}
+		head = p;
+		p = kalStrChr(head, '>');
+		if (!p) {
+			DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n");
+			return -EINVAL;
+		}
+		/* else {
+		 *p = '.'; // remove '>' because sscanf can not parse <%s>
+		 }*/
+		/*tokens = kalSScanf(head, "CHANNEL=<%s", c_channel);
+		   if (tokens != 1) {
+		   DBGLOG(SCN, TRACE, ("[BATCH] Parse fail: tokens=%d, CHANNEL=<%s>\n",
+		   tokens, c_channel));
+		   return -EINVAL;
+		   } */
+		rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED;
+		rCmdBatchReq.ucChannelListNum = 0;
+		prRfChannelInfo = &rCmdBatchReq.arChannelList[0];
+		p = head + kalStrLen(PARAM_CHANNEL) + 2;	/* c_channel; */
+		while ((p2 = kalStrSep((char **)&p, ",")) != NULL) {
+			if (p2 == NULL || *p2 == 0)
+				break;
+			if (*p2 == '\0')
+				continue;
+			if (*p2 == 'A') {
+				rCmdBatchReq.ucChannelType =
+				    rCmdBatchReq.ucChannelType ==
+				    SCAN_CHANNEL_2G4 ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G;
+			} else if (*p2 == 'B') {
+				rCmdBatchReq.ucChannelType =
+				    rCmdBatchReq.ucChannelType ==
+				    SCAN_CHANNEL_5G ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4;
+			} else {
+
+				/* Translate Freq from MHz to channel number. */
+				prRfChannelInfo->ucChannelNum = kalStrtol(p2, NULL, 0);
+				DBGLOG(SCN, TRACE, "Scanning Channel:%u,  freq: %d\n",
+						    (UINT_32) prRfChannelInfo->ucChannelNum,
+						    (UINT_32) nicChannelNum2Freq(prRfChannelInfo->ucChannelNum));
+				prRfChannelInfo->ucBand = prRfChannelInfo->ucChannelNum < 15 ? BAND_2G4 : BAND_5G;
+
+				rCmdBatchReq.ucChannelListNum++;
+				if (rCmdBatchReq.ucChannelListNum >= 32)
+					break;
+				prRfChannelInfo++;
+			}
+		}
+
+		/* set channel for test */
+#if 0
+		rCmdBatchReq.ucChannelType = 4;	/* SCAN_CHANNEL_SPECIFIED; */
+		rCmdBatchReq.ucChannelListNum = 0;
+		prRfChannelInfo = &rCmdBatchReq.arChannelList[0];
+		for (i = 1; i <= 14; i++) {
+
+			/* filter out some */
+			if (i == 1 || i == 5 || i == 11)
+				continue;
+
+			/* Translate Freq from MHz to channel number. */
+			prRfChannelInfo->ucChannelNum = i;
+			DBGLOG(SCN, TRACE, "Scanning Channel:%d,  freq: %d\n",
+					    prRfChannelInfo->ucChannelNum,
+					    nicChannelNum2Freq(prRfChannelInfo->ucChannelNum));
+			prRfChannelInfo->ucBand = BAND_2G4;
+
+			rCmdBatchReq.ucChannelListNum++;
+			prRfChannelInfo++;
+		}
+#endif
+#if 0
+		rCmdBatchReq.ucChannelType = 0;	/* SCAN_CHANNEL_FULL; */
+#endif
+
+		rCmdBatchReq.u4Scanfreq = scanfreq;
+		rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? CFG_BATCH_MAX_MSCAN : mscan;
+		rCmdBatchReq.ucBestn = bestn;
+		rCmdBatchReq.ucRtt = rtt;
+		DBGLOG(SCN, TRACE, "[BATCH] SCANFREQ=%u MSCAN=%u BESTN=%u RTT=%u\n",
+				    (UINT_32) rCmdBatchReq.u4Scanfreq,
+				    (UINT_32) rCmdBatchReq.ucMScan,
+				    (UINT_32) rCmdBatchReq.ucBestn, (UINT_32) rCmdBatchReq.ucRtt;
+
+		if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) {
+			DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n",
+					    rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? "FULL" :
+					    rCmdBatchReq.ucChannelType == SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all");
+		} else {
+			DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n");
+			prRfChannelInfo = &rCmdBatchReq.arChannelList[0];
+			for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; tokens++) {
+				DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n",
+						    prRfChannelInfo->ucBand == BAND_2G4 ? "2.4G" : "5G",
+						    prRfChannelInfo->ucChannelNum);
+				prRfChannelInfo++;
+			}
+		}
+
+		rCmdBatchReq.ucSeqNum = 1;
+		rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+		rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START;
+
+		*pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", rCmdBatchReq.ucMScan);
+
+	} else if (!kalStrnCmp(head, BATCHING_STOP, kalStrLen(BATCHING_STOP))) {
+
+		DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n");
+
+		rCmdBatchReq.ucSeqNum = 1;
+		rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+		rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP;
+	} else {
+		return -EINVAL;
+	}
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SET_BATCH_REQ,
+			    TRUE, FALSE, TRUE, NULL, NULL, sizeof(CMD_BATCH_REQ_T), (PUINT_8) &rCmdBatchReq, NULL, 0);
+
+	/* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */
+	/* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */
+
+	return rStatus;
+}
+
+WLAN_STATUS
+batchGetCmd(IN P_ADAPTER_T prAdapter,
+	    OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	CMD_BATCH_REQ_T rCmdBatchReq;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	P_EVENT_BATCH_RESULT_T prEventBatchResult;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+	prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pvQueryBuffer;
+
+	DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%u) XXX\n", (UINT_32) prEventBatchResult->ucScanCount);
+
+	*pu4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T);
+
+	rCmdBatchReq.ucSeqNum = 2;
+	rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT;
+	rCmdBatchReq.ucMScan = prEventBatchResult->ucScanCount;	/* Get which round result */
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_SET_BATCH_REQ,
+				      FALSE,
+				      TRUE,
+				      TRUE,
+				      nicCmdEventBatchScanResult,
+				      nicOidCmdTimeoutCommon,
+				      sizeof(CMD_BATCH_REQ_T),
+				      (PUINT_8) &rCmdBatchReq, (PVOID) pvQueryBuffer, u4QueryBufferLen);
+
+	return rStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, pu4SetInfoLen);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter,
+			    OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	return batchGetCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen, pu4QueryInfoLen);
+
+}				/* end of wlanoidQueryBatchScanResult() */
+
+#endif /* CFG_SUPPORT_BATCH_SCAN */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to request starting of schedule scan
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest;
+
+	DEBUGFUNC("wlanoidSetStartSchedScan()");
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(SCN, WARN, "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	ASSERT(pu4SetInfoLen);
+	*pu4SetInfoLen = 0;
+
+	if (u4SetBufferLen != sizeof(PARAM_SCHED_SCAN_REQUEST)) {
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (pvSetBuffer == NULL) {
+		return WLAN_STATUS_INVALID_DATA;
+	} else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED &&
+		   prAdapter->fgEnOnlineScan == FALSE) {
+		return WLAN_STATUS_FAILURE;
+	}
+
+	if (prAdapter->fgIsRadioOff) {
+		DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) pvSetBuffer;
+
+	if (scnFsmSchedScanRequest(prAdapter,
+				   (UINT_8) (prSchedScanRequest->u4SsidNum),
+				   prSchedScanRequest->arSsid,
+				   prSchedScanRequest->u4IELength,
+				   prSchedScanRequest->pucIE, prSchedScanRequest->u2ScanInterval) == TRUE) {
+		return WLAN_STATUS_SUCCESS;
+	} else {
+		return WLAN_STATUS_FAILURE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to request termination of schedule scan
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	ASSERT(prAdapter);
+
+	/* ask SCN module to stop scan request */
+	if (scnFsmSchedScanStopRequest(prAdapter) == TRUE)
+		return WLAN_STATUS_SUCCESS;
+	else
+		return WLAN_STATUS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a periodically scan action
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_CMD_SET_PSCAN_ENABLE prCmdPscnAction;
+	P_SCAN_INFO_T prScanInfo;
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	DBGLOG(SCN, TRACE, "wlanoidSetGSCNAction\n");
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	if (u4SetBufferLen != sizeof(CMD_SET_PSCAN_ENABLE))
+		return WLAN_STATUS_INVALID_LENGTH;
+	else if (pvSetBuffer == NULL)
+		return WLAN_STATUS_INVALID_DATA;
+
+	if (prAdapter->fgIsRadioOff) {
+		DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	prCmdPscnAction = (P_CMD_SET_PSCAN_ENABLE) pvSetBuffer;
+
+	if (prCmdPscnAction->ucPscanAct == ENABLE) {
+#if 0
+		DBGLOG(OID, INFO, "set  PCSN ENABLE\n");
+		if (scnFsmPSCNAction(prAdapter, (UINT_8) (prCmdPscnAction->ucPscanAct)) == TRUE) {
+
+			DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n");
+			return WLAN_STATUS_PENDING;
+		}
+		DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n");
+		return WLAN_STATUS_FAILURE;
+
+#endif
+		scnPSCNFsm(prAdapter, PSCN_SCANNING, NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, TRUE);
+	} else if (prCmdPscnAction->ucPscanAct == DISABLE) {
+#if 0
+		DBGLOG(OID, INFO, "disable PCSN\n");
+		scnFsmPSCNAction(prAdapter, (UINT_8) DISABLE);
+
+		DBGLOG(OID, TRACE, "set new PCSN\n");
+		scnCombineParamsIntoPSCN(prAdapter, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE);
+
+		DBGLOG(OID, INFO, "ENABLE or disable PCSN\n");
+		if (!prScanInfo->fgPscnOnnning) {
+			DBGLOG(OID, INFO, "ENABLE PCSN\n");
+			scnFsmPSCNAction(prAdapter, ENABLE);
+		} else {
+			DBGLOG(OID, INFO, "All PCSN is disabled...\n");
+		}
+#endif
+		scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE, FALSE);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a periodically scan action
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam;
+	/*UINT_8 i, j = 0;*/
+	DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam v1\n");
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+	if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) {
+		DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(P_PARAM_WIFI_GSCAN_CMD_PARAMS))\n");
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (pvSetBuffer == NULL) {
+		DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n");
+		return WLAN_STATUS_INVALID_DATA;
+	}
+	if (prAdapter->fgIsRadioOff) {
+		DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	prCmdGscnParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer;
+	/* KC-XXX memcpy(prCmdGscnParam, */
+	/*	(P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer, */
+	/*	sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS) ); */
+	DBGLOG(SCN, INFO,
+		"prCmdGscnParam : base_period[%u], max_ap_per_scan[%u] num_buckets[%u], report_threshold[%u]\n",
+		prCmdGscnParam->base_period, prCmdGscnParam->max_ap_per_scan, prCmdGscnParam->num_buckets,
+		prCmdGscnParam->report_threshold);
+#if 0
+	for (i = 0; i < prCmdGscnParam->num_buckets; i++) {
+
+		DBGLOG(OID, INFO,
+		    "prCmdGscnParam->buckets : band[%u], bucket[%u] num_buckets[%u], period[%u] report_events[%u]\n",
+		     prCmdGscnParam->buckets[i].band, prCmdGscnParam->buckets[i].bucket,
+		     prCmdGscnParam->buckets[i].num_channels, prCmdGscnParam->buckets[i].period,
+		     prCmdGscnParam->buckets[i].report_events));
+		DBGLOG(OID, INFO, "prCmdGscnParam->buckets[%d] has channel: ", i);
+		for (j = 0; j < prCmdGscnParam->buckets[i].num_channels; j++)
+			DBGLOG(OID, INFO, " %d,  ", prCmdGscnParam->buckets[i].channels[j].channel);
+		DBGLOG(OID, INFO, "\n");
+	}
+#endif
+	if (scnSetGSCNParam(prAdapter, prCmdGscnParam) == TRUE) {
+		DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n");
+		return WLAN_STATUS_PENDING;
+	} else {
+		return WLAN_STATUS_FAILURE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set configure  gscan PARAMs
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T
+*/
+/*----------------------------------------------------------------------------*/
+
+WLAN_STATUS
+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnScnConfigParam;
+	CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig;
+
+	DBGLOG(SCN, INFO, "wlanoidSetGSCNAConfig v1\n");
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+	if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) {
+		DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n");
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (pvSetBuffer == NULL) {
+		DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n");
+		return WLAN_STATUS_INVALID_DATA;
+	}
+	if (prAdapter->fgIsRadioOff) {
+		DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer\n");
+	prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer;
+	memcpy(prCmdGscnScnConfigParam, (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer,
+	       sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS));
+	DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam assign  prCmdGscnScnConfig\n");
+	rCmdGscnScnConfig.u4BufferThreshold = prCmdGscnScnConfigParam->report_threshold;
+	rCmdGscnScnConfig.ucNumApPerScn = prCmdGscnScnConfigParam->max_ap_per_scan;
+	rCmdGscnScnConfig.u4NumScnToCache = prCmdGscnScnConfigParam->num_scans;
+	DBGLOG(SCN, INFO, " report_threshold %d report_threshold %d  num_scans %d\n",
+			   rCmdGscnScnConfig.u4BufferThreshold,
+			   rCmdGscnScnConfig.ucNumApPerScn, rCmdGscnScnConfig.u4NumScnToCache);
+	if (scnFsmSetGSCNConfig(prAdapter, &rCmdGscnScnConfig) == TRUE) {
+		DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n");
+		return WLAN_STATUS_PENDING;
+	} else {
+		return WLAN_STATUS_FAILURE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to get a gscan result
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*
+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS prGetGscnScnResultParm;
+	CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd;
+
+	DEBUGFUNC("wlanoidGetGSCNResult()");
+	DBGLOG(SCN, INFO, "wlanoidGetGSCNResult v1\n");
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS)) {
+		DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n");
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (pvSetBuffer == NULL) {
+		DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n");
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	if (prAdapter->fgIsRadioOff) {
+		DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	prGetGscnScnResultParm = (P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) pvSetBuffer;
+	/* memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultParm, sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) ); */
+
+	rGetGscnScnResultCmd.u4Num = prGetGscnScnResultParm->get_num;
+	rGetGscnScnResultCmd.ucFlush = prGetGscnScnResultParm->flush;
+	rGetGscnScnResultCmd.ucVersion = PSCAN_VERSION;
+	kalMemZero(rGetGscnScnResultCmd.aucReserved, sizeof(rGetGscnScnResultCmd.aucReserved));
+
+	if (scnFsmGetGSCNResult(prAdapter, &rGetGscnScnResultCmd) == TRUE) {
+		DBGLOG(SCN, INFO, "wlanoidGetGSCNResult --->scnFsmGetGSCNResult\n");
+		return WLAN_STATUS_PENDING;
+	} else {
+		return WLAN_STATUS_FAILURE;
+	}
+
+}
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called by HS2.0 to set the assoc info, which is needed to add to
+*          Association request frame while join HS2.0 AP.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_IE_HS20_INDICATION_T prHS20IndicationIe;
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	DEBUGFUNC("wlanoidSetHS20AssocInfo");
+	DBGLOG(OID, LOUD, "\r\n");
+
+	if (u4SetBufferLen == 0)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pvSetBuffer;
+
+	prAdapter->prGlueInfo->ucHotspotConfig = prHS20IndicationIe->ucHotspotConfig;
+	prAdapter->prGlueInfo->fgConnectHS20AP = TRUE;
+
+	DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen);
+
+	kalMemCopy(prAdapter->prGlueInfo->aucHS20AssocInfoIE, pvSetBuffer, u4SetBufferLen);
+	prAdapter->prGlueInfo->u2HS20AssocInfoIELen = (UINT_16) u4SetBufferLen;
+	DBGLOG(SEC, TRACE, "HS20 Assoc Info IE sz %u\n", u4SetBufferLen);
+
+	return WLAN_STATUS_SUCCESS;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called by WSC to set the assoc info, which is needed to add to
+*          Association request frame while join WPS AP.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+#if 0
+	P_HS20_INFO_T prHS20Info = NULL;
+	P_IE_INTERWORKING_T prInterWorkingIe;
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	prHS20Info = &(prAdapter->rWifiVar.rHS20Info);
+
+	DEBUGFUNC("wlanoidSetInterworkingInfo");
+	DBGLOG(OID, TRACE, "\r\n");
+
+	if (u4SetBufferLen == 0)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	*pu4SetInfoLen = u4SetBufferLen;
+	prInterWorkingIe = (P_IE_INTERWORKING_T) pvSetBuffer;
+
+	prHS20Info->ucAccessNetworkOptions = prInterWorkingIe->ucAccNetOpt;
+	prHS20Info->ucVenueGroup = prInterWorkingIe->ucVenueGroup;
+	prHS20Info->ucVenueType = prInterWorkingIe->ucVenueType;
+	COPY_MAC_ADDR(prHS20Info->aucHESSID, prInterWorkingIe->aucHESSID);
+
+	DBGLOG(SEC, TRACE, "IW IE sz %ld\n", u4SetBufferLen);
+#endif
+	return WLAN_STATUS_SUCCESS;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called by WSC to set the Roaming Consortium IE info, which is needed to
+*          add to Association request frame while join WPS AP.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter,
+				  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+#if 0
+	P_HS20_INFO_T prHS20Info = NULL;
+	P_PARAM_HS20_ROAMING_CONSORTIUM_INFO prRCInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	prHS20Info = &(prAdapter->rWifiVar.rHS20Info);
+
+	/* DEBUGFUNC("wlanoidSetRoamingConsortiumInfo"); */
+	/* DBGLOG(HS2, TRACE, ("\r\n")); */
+
+	if (u4SetBufferLen == 0)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	*pu4SetInfoLen = u4SetBufferLen;
+	prRCInfo = (P_PARAM_HS20_ROAMING_CONSORTIUM_INFO) pvSetBuffer;
+
+	kalMemCopy(&(prHS20Info->rRCInfo), prRCInfo, sizeof(PARAM_HS20_ROAMING_CONSORTIUM_INFO));
+
+	/* DBGLOG(HS2, TRACE, ("RoamingConsortium IE sz %ld\n", u4SetBufferLen)); */
+#endif
+	return WLAN_STATUS_SUCCESS;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set_bssid_pool
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen)
+		ASSERT(pvSetBuffer);
+
+	if (u4SetBufferLen < sizeof(PARAM_HS20_SET_BSSID_POOL)) {
+		*pu4SetInfoLen = sizeof(PARAM_HS20_SET_BSSID_POOL);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, NETWORK_TYPE_AIS_INDEX);
+
+	return rWlanStatus;
+}				/* end of wlanoidSendHS20GASRequest() */
+
+#endif
+
+#if CFG_SUPPORT_ROAMING_ENC
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query the MAC address the NIC is currently using.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	CMD_ROAMING_INFO_T *prCmdRoamingInfo;
+
+	DEBUGFUNC("wlanoidSetRoamingInfo");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(CMD_ROAMING_INFO_T);
+
+	if (u4SetBufferLen < sizeof(CMD_ROAMING_INFO_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	prCmdRoamingInfo = (CMD_ROAMING_INFO_T *) pvSetBuffer;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_ROAMING_INFO,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_ROAMING_INFO_T), (PUINT_8) prCmdRoamingInfo, NULL, 0);
+}
+#endif /* CFG_SUPPORT_ROAMING_ENC */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set chip
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T prChipConfigInfo;
+	CMD_CHIP_CONFIG_T rCmdChipConfig;
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE);
+	DEBUGFUNC("wlanoidSetChipConfig");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prChipConfigInfo = (P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T) pvSetBuffer;
+	kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig));
+
+	rCmdChipConfig.u2Id = prChipConfigInfo->u2Id;
+	rCmdChipConfig.ucType = prChipConfigInfo->ucType;
+	rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType;
+	rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize;
+	if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) {
+		DBGLOG(OID, INFO, "Chip config Msg Size %u is not valid (set)\n", rCmdChipConfig.u2MsgSize);
+		rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE;
+	}
+	kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, rCmdChipConfig.u2MsgSize);
+
+	DBGLOG(OID, TRACE, "rCmdChipConfig.aucCmd=%s\n", rCmdChipConfig.aucCmd);
+#if 1
+	rWlanStatus = wlanSendSetQueryCmd(prAdapter,
+					  CMD_ID_CHIP_CONFIG,
+					  TRUE,
+					  FALSE,
+					  TRUE,
+					  nicCmdEventSetCommon,
+					  nicOidCmdTimeoutCommon,
+					  sizeof(CMD_CHIP_CONFIG_T),
+					  (PUINT_8) &rCmdChipConfig, pvSetBuffer, u4SetBufferLen);
+#endif
+	return rWlanStatus;
+}				/* wlanoidSetChipConfig */
+
+WLAN_STATUS
+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_CMD_WFD_DEBUG_MODE_INFO_T prCmdWfdDebugModeInfo;
+
+	DEBUGFUNC("wlanoidSetWFDDebugMode");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(CMD_WFD_DEBUG_MODE_INFO_T);
+
+	if (u4SetBufferLen < sizeof(CMD_WFD_DEBUG_MODE_INFO_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	prCmdWfdDebugModeInfo = (CMD_WFD_DEBUG_MODE_INFO_T *) pvSetBuffer;
+
+	DBGLOG(OID, INFO, "New WFD Debug: %d mode and period=0x%x\n", prCmdWfdDebugModeInfo->ucDebugMode,
+						prCmdWfdDebugModeInfo->u2PeriodInteval);
+
+	prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode = (UINT_8) prCmdWfdDebugModeInfo->ucDebugMode;
+	prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.u2WfdSNShowPeiroid =
+	    (UINT_16) prCmdWfdDebugModeInfo->u2PeriodInteval;
+
+	return WLAN_STATUS_SUCCESS;
+}				/*wlanoidSetWfdDebugMode */
+
+
+#if (CFG_SUPPORT_TXR_ENC == 1)
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to query the MAC address the NIC is currently using.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the
+*                          query buffer
+* \param[in] u4QueryBufLen The length of the query buffer
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_BUFFER_TOO_SHORT
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetTxRateInfo(
+	IN  P_ADAPTER_T prAdapter,
+	IN  PVOID       pvSetBuffer,
+	IN  UINT_32     u4SetBufferLen,
+	OUT PUINT_32    pu4SetInfoLen)
+{
+	CMD_RLM_INFO_T *prCmdTxRInfo;
+
+	DEBUGFUNC("wlanoidSetTxRateInfo");
+	DBGLOG(OID, LOUD, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(CMD_RLM_INFO_T);
+
+	if (u4SetBufferLen < sizeof(CMD_RLM_INFO_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	prCmdTxRInfo = (CMD_RLM_INFO_T *)pvSetBuffer;
+
+	DBGLOG(OID, INFO, "<tar_cmd> command = %u %u %u %u %d %u %u\n",
+		prCmdTxRInfo->u4Version,
+		prCmdTxRInfo->fgIsErrRatioEnhanceApplied,
+		prCmdTxRInfo->ucErrRatio2LimitMinRate,
+		prCmdTxRInfo->ucMinLegacyRateIdx,
+		prCmdTxRInfo->cMinRssiThreshold,
+		prCmdTxRInfo->fgIsRtsApplied,
+		prCmdTxRInfo->ucRecoverTime));
+
+	return wlanSendSetQueryCmd(prAdapter,
+		CMD_ID_TX_AR_ERR_CONFIG,
+		TRUE,
+		FALSE,
+		TRUE,
+		nicCmdEventSetCommon,
+		nicOidCmdTimeoutCommon,
+		sizeof(CMD_RLM_INFO_T),
+		(PUINT_8)prCmdTxRInfo,
+		NULL,
+		0
+		);
+}
+#endif /* CFG_SUPPORT_TXR_ENC */
+
+WLAN_STATUS
+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WIFI_SYSTEM_SUSPEND_CMD_T rSuspendCmd;
+
+	if (!prAdapter || !pvSetBuffer)
+		return WLAN_STATUS_INVALID_DATA;
+
+	rSuspendCmd.fgIsSystemSuspend = *(PBOOLEAN)pvSetBuffer;
+	return wlanSendSetQueryCmd(prAdapter,
+							CMD_ID_SET_SYSTEM_SUSPEND,
+							TRUE,
+							FALSE,
+							TRUE,
+							nicCmdEventSetCommon,
+							nicOidCmdTimeoutCommon,
+							sizeof(BOOLEAN),
+							(PUINT_8)&rSuspendCmd,
+							NULL,
+							0);
+}
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c
new file mode 100644
index 0000000000000..7ca7ee48922e1
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c
@@ -0,0 +1,1654 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/common/wlan_p2p.c#8
+*/
+
+/*! \file wlan_bow.c
+    \brief This file contains the Wi-Fi Direct commands processing routines for
+	   MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: wlan_p2p.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 11 24 2011 yuche.tsai
+ * NULL
+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control.
+ *
+ * 11 22 2011 yuche.tsai
+ * NULL
+ * Update RSSI link quality of P2P Network query method. (Bug fix)
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Add RSSI support for P2P network.
+ *
+ * 11 08 2011 yuche.tsai
+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support
+ * for service discovery version check.
+ * Add support for driver version query & p2p supplicant verseion set.
+ * For new service discovery mechanism sync.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * Support Channel Query.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * New 2.1 branch
+
+ *
+ * 08 23 2011 yuche.tsai
+ * NULL
+ * Fix Multicast Issue of P2P.
+ *
+ * 04 27 2011 george.huang
+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
+ * Support P2P ARP filter setting on early suspend/ late resume
+ *
+ * 04 08 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * separate settings of P2P and AIS
+ *
+ * 03 22 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * link with supplicant commands
+ *
+ * 03 17 2011 wh.su
+ * [WCXRP00000571] [MT6620 Wi-Fi] [Driver] Not check the p2p role during set key
+ * Skip the p2p role for adding broadcast key issue.
+ *
+ * 03 16 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * fixed compiling error while enable dbg.
+ *
+ * 03 08 2011 yuche.tsai
+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format
+ * issue[WCXRP00000509] [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module.
+ * .
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add Security check related code.
+ *
+ * 03 02 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Fix SD Request Query Length issue.
+ *
+ * 03 02 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Service Discovery Request.
+ *
+ * 03 01 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Update Service Discovery Wlan OID related function.
+ *
+ * 03 01 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Update Service Discovery Related wlanoid function.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Add Service Discovery Indication Related code.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Add Service Discovery Function.
+ *
+ * 01 05 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface
+ *  for supporting Wi-Fi Direct Service Discovery ioctl implementations for P2P Service Discovery
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to
+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous
+ * and physically-continuous type to ease slab system pressure
+ *
+ * 12 22 2010 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface
+ * for supporting Wi-Fi Direct Service Discovery
+ * 1. header file restructure for more clear module isolation
+ * 2. add function interface definition for implementing Service Discovery callbacks
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T
+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 23 2010 cp.wu
+ * NULL
+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * add subroutines for P2P to set multicast list.
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * .
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * support wlanoidSetP2pPowerSaveProfile() in P2P
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * Support wlanoidSetNetworkAddress() for P2P
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add API in que_mgt to retrieve sta-rec index for security frames.
+ *
+ * 06 24 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+**
+*/
+
+/******************************************************************************
+*                         C O M P I L E R   F L A G S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+*******************************************************************************
+*/
+#include "precomp.h"
+#include "gl_p2p_ioctl.h"
+
+/******************************************************************************
+*                              C O N S T A N T S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                             D A T A   T Y P E S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                            P U B L I C   D A T A
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                           P R I V A T E   D A T A
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                                 M A C R O S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+*******************************************************************************
+*/
+
+/******************************************************************************
+*                              F U N C T I O N S
+*******************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief command packet generation utility
+*
+* \param[in] prAdapter          Pointer to the Adapter structure.
+* \param[in] ucCID              Command ID
+* \param[in] fgSetQuery         Set or Query
+* \param[in] fgNeedResp         Need for response
+* \param[in] pfCmdDoneHandler   Function pointer when command is done
+* \param[in] u4SetQueryInfoLen  The length of the set/query buffer
+* \param[in] pucInfoBuffer      Pointer to set/query buffer
+*
+*
+* \retval WLAN_STATUS_PENDING
+* \retval WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter,
+			  UINT_8 ucCID,
+			  BOOLEAN fgSetQuery,
+			  BOOLEAN fgNeedResp,
+			  BOOLEAN fgIsOid,
+			  PFN_CMD_DONE_HANDLER pfCmdDoneHandler,
+			  PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler,
+			  UINT_32 u4SetQueryInfoLen,
+			  PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_8 ucCmdSeqNum;
+
+	ASSERT(prAdapter);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	ASSERT(prGlueInfo);
+
+	DEBUGFUNC("wlanoidSendSetQueryP2PCmd");
+	DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID);
+
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen));
+
+	if (!prCmdInfo) {
+		DBGLOG(P2P, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+	DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum);
+
+	/* Setup common CMD Info Packet */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = NETWORK_TYPE_P2P_INDEX;
+	prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen);
+	prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler;
+	prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler;
+	prCmdInfo->fgIsOid = fgIsOid;
+	prCmdInfo->ucCID = ucCID;
+	prCmdInfo->fgSetQuery = fgSetQuery;
+	prCmdInfo->fgNeedResp = fgNeedResp;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen;
+	prCmdInfo->pvInformationBuffer = pvSetQueryBuffer;
+	prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen;
+
+	/* Setup WIFI_CMD_T (no payload) */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL)
+		kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen);
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+	return WLAN_STATUS_PENDING;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set a key to Wi-Fi Direct driver
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	CMD_802_11_KEY rCmdKey;
+	P_PARAM_KEY_T prNewKey;
+
+	DEBUGFUNC("wlanoidSetAddP2PKey");
+	DBGLOG(REQ, INFO, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	prNewKey = (P_PARAM_KEY_T) pvSetBuffer;
+
+	/* Verify the key structure length. */
+	if (prNewKey->u4Length > u4SetBufferLen) {
+		DBGLOG(REQ, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n",
+				   (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen);
+
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+	/* Verify the key material length for key material buffer */
+	else if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) {
+		DBGLOG(REQ, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength);
+		*pu4SetInfoLen = u4SetBufferLen;
+		return WLAN_STATUS_INVALID_DATA;
+	}
+	/* Exception check */
+	else if (prNewKey->u4KeyIndex & 0x0fffff00)
+		return WLAN_STATUS_INVALID_DATA;
+	/* Exception check, pairwise key must with transmit bit enabled */
+	else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) {
+		return WLAN_STATUS_INVALID_DATA;
+	} else if (!(prNewKey->u4KeyLength == CCMP_KEY_LEN) && !(prNewKey->u4KeyLength == TKIP_KEY_LEN)) {
+		return WLAN_STATUS_INVALID_DATA;
+	}
+	/* Exception check, pairwise key must with transmit bit enabled */
+	else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) {
+		if (((prNewKey->u4KeyIndex & 0xff) != 0) ||
+		    ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff)
+		     && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff)
+		     && (prNewKey->arBSSID[5] == 0xff))) {
+			return WLAN_STATUS_INVALID_DATA;
+		}
+	}
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	/* fill CMD_802_11_KEY */
+	kalMemZero(&rCmdKey, sizeof(CMD_802_11_KEY));
+	rCmdKey.ucAddRemove = 1;	/* add */
+	rCmdKey.ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0;
+	rCmdKey.ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0;
+	if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) {	/* group client */
+		rCmdKey.ucIsAuthenticator = 0;
+	} else {		/* group owner */
+		rCmdKey.ucIsAuthenticator = 1;
+	}
+	COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prNewKey->arBSSID);
+	rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX;
+	if (prNewKey->u4KeyLength == CCMP_KEY_LEN)
+		rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP;	/* AES */
+	else if (prNewKey->u4KeyLength == TKIP_KEY_LEN)
+		rCmdKey.ucAlgorithmId = CIPHER_SUITE_TKIP;	/* TKIP */
+	rCmdKey.ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff);
+	rCmdKey.ucKeyLen = (UINT_8) prNewKey->u4KeyLength;
+	kalMemCopy(rCmdKey.aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, rCmdKey.ucKeyLen);
+
+	return wlanoidSendSetQueryP2PCmd(prAdapter,
+					 CMD_ID_ADD_REMOVE_KEY,
+					 TRUE,
+					 FALSE,
+					 TRUE,
+					 nicCmdEventSetCommon,
+					 NULL,
+					 sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to request Wi-Fi Direct driver to remove keys
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	CMD_802_11_KEY rCmdKey;
+	P_PARAM_REMOVE_KEY_T prRemovedKey;
+
+	DEBUGFUNC("wlanoidSetRemoveP2PKey");
+	ASSERT(prAdapter);
+
+	if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+	prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer;
+
+	/* Check bit 31: this bit should always 0 */
+	if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) {
+		/* Bit 31 should not be set */
+		DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* Check bits 8 ~ 29 should always be 0 */
+	if (prRemovedKey->u4KeyIndex & BITS(8, 29)) {
+		/* Bit 31 should not be set */
+		DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex);
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	/* There should not be any key operation for P2P Device */
+	if (kalP2PGetRole(prAdapter->prGlueInfo) == 0)
+		; /* return WLAN_STATUS_NOT_ACCEPTED; */
+
+	kalMemZero((PUINT_8) &rCmdKey, sizeof(CMD_802_11_KEY));
+
+	rCmdKey.ucAddRemove = 0;	/* remove */
+	if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) {	/* group client */
+		rCmdKey.ucIsAuthenticator = 0;
+	} else {		/* group owner */
+		rCmdKey.ucIsAuthenticator = 1;
+	}
+	kalMemCopy(rCmdKey.aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN);
+	rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX;
+	rCmdKey.ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff);
+
+	return wlanoidSendSetQueryP2PCmd(prAdapter,
+					 CMD_ID_ADD_REMOVE_KEY,
+					 TRUE,
+					 FALSE,
+					 TRUE,
+					 nicCmdEventSetCommon,
+					 NULL,
+					 sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Setting the IP address for pattern search function.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \return WLAN_STATUS_SUCCESS
+* \return WLAN_STATUS_ADAPTER_NOT_READY
+* \return WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetP2pNetworkAddress(IN P_ADAPTER_T prAdapter,
+			    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 i, j;
+	P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList;
+	P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer;
+	P_PARAM_NETWORK_ADDRESS prNetworkAddress;
+	P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp;
+	UINT_32 u4IpAddressCount, u4CmdSize;
+
+	DEBUGFUNC("wlanoidSetP2pNetworkAddress");
+	DBGLOG(P2P, TRACE, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = 4;
+
+	if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST))
+		return WLAN_STATUS_INVALID_DATA;
+
+	*pu4SetInfoLen = 0;
+	u4IpAddressCount = 0;
+
+	prNetworkAddress = prNetworkAddressList->arAddress;
+	for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) {
+		if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP &&
+		    prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) {
+			u4IpAddressCount++;
+		}
+
+		prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress +
+							      (ULONG) (prNetworkAddress->u2AddressLength +
+								       OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
+	}
+
+	/* construct payload of command packet */
+	u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) +
+	    sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount;
+
+	prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE);
+
+	if (prCmdNetworkAddressList == NULL)
+		return WLAN_STATUS_FAILURE;
+
+	/* fill P_CMD_SET_NETWORK_ADDRESS_LIST */
+	prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+	prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount;
+	prNetworkAddress = prNetworkAddressList->arAddress;
+	for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) {
+		if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP &&
+		    prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) {
+			prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress;
+
+			kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr,
+				   &(prNetAddrIp->in_addr), sizeof(UINT_32));
+
+			j++;
+		}
+
+		prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress +
+							      (ULONG) (prNetworkAddress->u2AddressLength +
+								       OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
+	}
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_SET_IP_ADDRESS,
+				      TRUE,
+				      FALSE,
+				      TRUE,
+				      nicCmdEventSetIpAddress,
+				      nicOidCmdTimeoutCommon,
+				      u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen);
+
+	kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize);
+	return rStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to query the power save profile.
+*
+* \param[in] prAdapter Pointer to the Adapter structure.
+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of
+*                           the query.
+* \param[in] u4QueryBufLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
+*                            bytes written into the query buffer. If the call
+*                            failed due to invalid length of the query buffer,
+*                            returns the amount of storage needed.
+*
+* \return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter,
+				IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryP2pPowerSaveProfile");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	if (u4QueryBufferLen != 0) {
+		ASSERT(pvQueryBuffer);
+
+		*(PPARAM_POWER_MODE) pvQueryBuffer =
+		    (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile);
+		*pu4QueryInfoLen = sizeof(PARAM_POWER_MODE);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to set the power save profile.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS status;
+	PARAM_POWER_MODE ePowerMode;
+
+	DEBUGFUNC("wlanoidSetP2pPowerSaveProfile");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_POWER_MODE);
+	if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) {
+		DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen);
+		return WLAN_STATUS_INVALID_LENGTH;
+	} else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) {
+		WARNLOG(("Invalid power mode %d\n", *(PPARAM_POWER_MODE) pvSetBuffer));
+		return WLAN_STATUS_INVALID_DATA;
+	}
+
+	ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer;
+
+	if (prAdapter->fgEnCtiaPowerMode) {
+		if (ePowerMode == Param_PowerModeCAM) {
+			/*Todo::  Nothing*/
+			/*Todo::  Nothing*/
+		} else {
+			/* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */
+
+			if (prAdapter->u4CtiaPowerMode == 0) {
+				/* force to keep in CAM mode */
+				ePowerMode = Param_PowerModeCAM;
+			} else if (prAdapter->u4CtiaPowerMode == 1) {
+				ePowerMode = Param_PowerModeMAX_PSP;
+			} else if (prAdapter->u4CtiaPowerMode == 2) {
+				ePowerMode = Param_PowerModeFast_PSP;
+			}
+		}
+	}
+
+	status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_P2P_INDEX, ePowerMode, TRUE);
+	return status;
+}				/* end of wlanoidSetP2pPowerSaveProfile() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to set the power save profile.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 i, j;
+	P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList;
+	P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer;
+	P_PARAM_NETWORK_ADDRESS prNetworkAddress;
+	P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp;
+	UINT_32 u4IpAddressCount, u4CmdSize;
+	PUINT_8 pucBuf = (PUINT_8) pvSetBuffer;
+
+	DEBUGFUNC("wlanoidSetP2pSetNetworkAddress");
+	DBGLOG(P2P, TRACE, "\n");
+	DBGLOG(P2P, INFO, "wlanoidSetP2pSetNetworkAddress (%d)\n", (INT_16) u4SetBufferLen);
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = 4;
+
+	if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST))
+		return WLAN_STATUS_INVALID_DATA;
+
+	*pu4SetInfoLen = 0;
+	u4IpAddressCount = 0;
+
+	prNetworkAddress = prNetworkAddressList->arAddress;
+	for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) {
+		if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP &&
+		    prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) {
+			u4IpAddressCount++;
+		}
+
+		prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress +
+							      (ULONG) (prNetworkAddress->u2AddressLength +
+								       OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
+	}
+
+	/* construct payload of command packet */
+	u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) +
+	    sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount;
+
+	if (u4IpAddressCount == 0)
+		u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST);
+
+	prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE);
+
+	if (prCmdNetworkAddressList == NULL)
+		return WLAN_STATUS_FAILURE;
+
+	/* fill P_CMD_SET_NETWORK_ADDRESS_LIST */
+	prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+
+	/* only to set IP address to FW once ARP filter is enabled */
+	if (prAdapter->fgEnArpFilter) {
+		prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount;
+		prNetworkAddress = prNetworkAddressList->arAddress;
+
+		DBGLOG(P2P, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount);
+		for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) {
+			if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP &&
+			    prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) {
+				prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress;
+
+				kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr,
+					   &(prNetAddrIp->in_addr), sizeof(UINT_32));
+
+				j++;
+
+				pucBuf = (PUINT_8) &prNetAddrIp->in_addr;
+				DBGLOG(P2P, INFO, "prNetAddrIp->in_addr:%d:%d:%d:%d\n",
+					(UINT_8) pucBuf[0], (UINT_8) pucBuf[1],
+					(UINT_8) pucBuf[2], (UINT_8) pucBuf[3]);
+			}
+
+			prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress +
+								      (ULONG) (prNetworkAddress->u2AddressLength +
+									       OFFSET_OF(PARAM_NETWORK_ADDRESS,
+											 aucAddress)));
+		}
+
+	} else {
+		prCmdNetworkAddressList->ucAddressCount = 0;
+	}
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,
+				      CMD_ID_SET_IP_ADDRESS,
+				      TRUE,
+				      FALSE,
+				      TRUE,
+				      nicCmdEventSetIpAddress,
+				      nicOidCmdTimeoutCommon,
+				      u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen);
+
+	kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize);
+	return rStatus;
+}				/* end of wlanoidSetP2pSetNetworkAddress() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set Multicast Address List.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	CMD_MAC_MCAST_ADDR rCmdMacMcastAddr;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	/* The data must be a multiple of the Ethernet address size. */
+	if ((u4SetBufferLen % MAC_ADDR_LEN)) {
+		DBGLOG(REQ, WARN, "Invalid MC list length %u\n", u4SetBufferLen);
+
+		*pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN;
+
+		return WLAN_STATUS_INVALID_LENGTH;
+	}
+
+	*pu4SetInfoLen = u4SetBufferLen;
+
+	/* Verify if we can support so many multicast addresses. */
+	if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) {
+		DBGLOG(REQ, WARN, "Too many MC addresses\n");
+
+		return WLAN_STATUS_MULTICAST_FULL;
+	}
+
+	/* NOTE(Kevin): Windows may set u4SetBufferLen == 0 &&
+	 * pvSetBuffer == NULL to clear exist Multicast List.
+	 */
+	if (u4SetBufferLen)
+		ASSERT(pvSetBuffer);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(REQ, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN;
+	rCmdMacMcastAddr.ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+	kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen);
+
+	/* This CMD response is no need to complete the OID. Or the event would unsync. */
+	return wlanoidSendSetQueryP2PCmd(prAdapter, CMD_ID_MAC_MCAST_ADDR, TRUE, FALSE, FALSE,
+					 nicCmdEventSetCommon,
+					 nicOidCmdTimeoutCommon,
+					 sizeof(CMD_MAC_MCAST_ADDR),
+					 (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen);
+
+}				/* end of wlanoidSetP2PMulticastList() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to send GAS frame for P2P Service Discovery Request
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen)
+		ASSERT(pvSetBuffer);
+
+	if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_REQUEST)) {
+		*pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_REQUEST);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+/* rWlanStatus = p2pFsmRunEventSDRequest(prAdapter, (P_PARAM_P2P_SEND_SD_REQUEST)pvSetBuffer); */
+
+	return rWlanStatus;
+}				/* end of wlanoidSendP2PSDRequest() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to send GAS frame for P2P Service Discovery Response
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen)
+		ASSERT(pvSetBuffer);
+
+	if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_RESPONSE)) {
+		*pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_RESPONSE);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+/* rWlanStatus = p2pFsmRunEventSDResponse(prAdapter, (P_PARAM_P2P_SEND_SD_RESPONSE)pvSetBuffer); */
+
+	return rWlanStatus;
+}				/* end of wlanoidGetP2PSDRequest() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to get GAS frame for P2P Service Discovery Request
+*
+* \param[in]  prAdapter        Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer    A pointer to the buffer that holds the result of
+*                              the query.
+* \param[in]  u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen  If the call is successful, returns the number of
+*                              bytes written into the query buffer. If the call
+*                              failed due to invalid length of the query buffer,
+*                              returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	/*PUINT_8 pucPacketBuffer = NULL, pucTA = NULL;*/
+/* PUINT_8 pucChannelNum = NULL; */
+	/*PUINT_16 pu2PacketLength = NULL;*/
+	/*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/
+	/*UINT_8 ucVersionNum = 0;*/
+/* UINT_8 ucChannelNum = 0, ucSeqNum = 0; */
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_REQUEST)) {
+		*pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_REQUEST);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	DBGLOG(P2P, TRACE, "Get Service Discovery Request\n");
+#if 0
+	ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter);
+	if (ucVersionNum == 0) {
+		P_PARAM_P2P_GET_SD_REQUEST prP2pGetSdReq = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer;
+
+		pucPacketBuffer = prP2pGetSdReq->aucPacketContent;
+		pu2PacketLength = &prP2pGetSdReq->u2PacketLength;
+		pucTA = &prP2pGetSdReq->rTransmitterAddr;
+	} else {
+		P_PARAM_P2P_GET_SD_REQUEST_EX prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST_EX) NULL;
+
+		prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer;
+		pucPacketBuffer = prP2pGetSdReqEx->aucPacketContent;
+		pu2PacketLength = &prP2pGetSdReqEx->u2PacketLength;
+		pucTA = &prP2pGetSdReqEx->rTransmitterAddr;
+		pucChannelNum = &prP2pGetSdReqEx->ucChannelNum;
+		ucSeqNum = prP2pGetSdReqEx->ucSeqNum;
+	}
+
+	rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter,
+						      pucPacketBuffer,
+						      (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_REQUEST)),
+						      (PUINT_32) pu2PacketLength, pucChannelNum, ucSeqNum);
+#else
+	*pu4QueryInfoLen = 0;
+	return rWlanStatus;
+#endif
+	/*
+	prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketBuffer;
+
+	kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN);
+
+	if (pu4QueryInfoLen) {
+		if (ucVersionNum == 0)
+			*pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST) + (*pu2PacketLength));
+		else
+			*pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST_EX) + (*pu2PacketLength));
+
+	}
+
+	return rWlanStatus;
+	*/
+}				/* end of wlanoidGetP2PSDRequest() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to get GAS frame for P2P Service Discovery Response
+*
+* \param[in]  prAdapter        Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer    A pointer to the buffer that holds the result of
+*                              the query.
+* \param[in]  u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen  If the call is successful, returns the number of
+*                              bytes written into the query buffer. If the call
+*                              failed due to invalid length of the query buffer,
+*                              returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	/*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/
+	/* UINT_8 ucSeqNum = 0, */
+	/*UINT_8 ucVersionNum = 0;*/
+	/*PUINT_8 pucPacketContent = (PUINT_8) NULL, pucTA = (PUINT_8) NULL;*/
+	/*PUINT_16 pu2PacketLength = (PUINT_16) NULL;*/
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_RESPONSE)) {
+		*pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_RESPONSE);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	DBGLOG(P2P, TRACE, "Get Service Discovery Response\n");
+
+#if 0
+	ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter);
+	if (ucVersionNum == 0) {
+		P_PARAM_P2P_GET_SD_RESPONSE prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_RESPONSE) NULL;
+
+		prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer;
+		pucPacketContent = prP2pGetSdRsp->aucPacketContent;
+		pucTA = &prP2pGetSdRsp->rTransmitterAddr;
+		pu2PacketLength = &prP2pGetSdRsp->u2PacketLength;
+	} else {
+		P_PARAM_P2P_GET_SD_RESPONSE_EX prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) NULL;
+
+		prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) pvQueryBuffer;
+		pucPacketContent = prP2pGetSdRspEx->aucPacketContent;
+		pucTA = &prP2pGetSdRspEx->rTransmitterAddr;
+		pu2PacketLength = &prP2pGetSdRspEx->u2PacketLength;
+		ucSeqNum = prP2pGetSdRspEx->ucSeqNum;
+	}
+
+/* rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, */
+/* pucPacketContent, */
+/* (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_RESPONSE)), */
+/* (PUINT_32)pu2PacketLength, */
+/* NULL, */
+/* ucSeqNum); */
+#else
+	*pu4QueryInfoLen = 0;
+	return rWlanStatus;
+#endif
+	/*
+	prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketContent;
+
+	kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN);
+
+	if (pu4QueryInfoLen) {
+		if (ucVersionNum == 0)
+			*pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE) + *pu2PacketLength);
+		else
+			*pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE_EX) + *pu2PacketLength);
+	}
+
+	return rWlanStatus;
+	*/
+}				/* end of wlanoidGetP2PSDResponse() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to terminate P2P Service Discovery Phase
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_PARAM_P2P_TERMINATE_SD_PHASE prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) NULL;
+	UINT_8 aucNullAddr[] = NULL_MAC_ADDR;
+
+	do {
+		if ((prAdapter == NULL) || (pu4SetInfoLen == NULL))
+			break;
+
+		if ((u4SetBufferLen) && (pvSetBuffer == NULL))
+			break;
+
+		if (u4SetBufferLen < sizeof(PARAM_P2P_TERMINATE_SD_PHASE)) {
+			*pu4SetInfoLen = sizeof(PARAM_P2P_TERMINATE_SD_PHASE);
+			rWlanStatus = WLAN_STATUS_BUFFER_TOO_SHORT;
+			break;
+		}
+
+		prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) pvSetBuffer;
+
+		if (EQUAL_MAC_ADDR(prP2pTerminateSD->rPeerAddr, aucNullAddr)) {
+			DBGLOG(P2P, TRACE, "Service Discovery Version 2.0\n");
+/* p2pFuncSetVersionNumOfSD(prAdapter, 2); */
+		}
+		/* rWlanStatus = p2pFsmRunEventSDAbort(prAdapter); */
+
+	} while (FALSE);
+
+	return rWlanStatus;
+}				/* end of wlanoidSetP2PTerminateSDPhase() */
+
+#if CFG_SUPPORT_ANTI_PIRACY
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	if (u4SetBufferLen)
+		ASSERT(pvSetBuffer);
+
+	return wlanoidSendSetQueryP2PCmd(prAdapter,
+					 CMD_ID_SEC_CHECK,
+					 FALSE,
+					 TRUE,
+					 TRUE,
+					 NULL,
+					 nicOidCmdTimeoutCommon,
+					 u4SetBufferLen, (PUINT_8) pvSetBuffer, pvSetBuffer, u4SetBufferLen);
+
+}				/* end of wlanoidSetSecCheckRequest() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to
+*
+* \param[in]  prAdapter        Pointer to the Adapter structure.
+* \param[out] pvQueryBuffer    A pointer to the buffer that holds the result of
+*                              the query.
+* \param[in]  u4QueryBufferLen The length of the query buffer.
+* \param[out] pu4QueryInfoLen  If the call is successful, returns the number of
+*                              bytes written into the query buffer. If the call
+*                              failed due to invalid length of the query buffer,
+*                              returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+* \retval WLAN_STATUS_MULTICAST_FULL
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	/* P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL; */
+	P_GLUE_INFO_T prGlueInfo;
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	if (u4QueryBufferLen > 256)
+		u4QueryBufferLen = 256;
+
+	*pu4QueryInfoLen = u4QueryBufferLen;
+
+#if DBG
+	DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen);
+#endif
+	kalMemCopy((PUINT_8) (pvQueryBuffer + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer)),
+		   prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen);
+
+	return rWlanStatus;
+}				/* end of wlanoidGetSecCheckResponse() */
+#endif
+
+WLAN_STATUS
+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam;
+	CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam;
+
+	DEBUGFUNC("wlanoidSetNoaParam");
+	DBGLOG(P2P, TRACE, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer;
+
+	kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T));
+	rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs;
+	rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs;
+	rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount;
+
+#if 0
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_NOA_PARAM,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T),
+				   (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen);
+#else
+	return wlanoidSendSetQueryP2PCmd(prAdapter,
+					 CMD_ID_SET_NOA_PARAM,
+					 TRUE,
+					 FALSE,
+					 TRUE,
+					 NULL,
+					 nicOidCmdTimeoutCommon,
+					 sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T),
+					 (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen);
+
+#endif
+
+}
+
+WLAN_STATUS
+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam;
+	CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam;
+
+	DEBUGFUNC("wlanoidSetOppPsParam");
+	DBGLOG(P2P, TRACE, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer;
+
+	kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T));
+	rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs;
+
+#if 0
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_OPPPS_PARAM,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T),
+				   (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen);
+#else
+	return wlanoidSendSetQueryP2PCmd(prAdapter,
+					 CMD_ID_SET_NOA_PARAM,
+					 TRUE,
+					 FALSE,
+					 TRUE,
+					 NULL,
+					 nicOidCmdTimeoutCommon,
+					 sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T),
+					 (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen);
+
+#endif
+
+}
+
+WLAN_STATUS
+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam;
+	CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam;
+	P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo;
+	P_BSS_INFO_T prBssInfo;
+
+	DEBUGFUNC("wlanoidSetUApsdParam");
+	DBGLOG(P2P, TRACE, "\n");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T);
+
+	if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvSetBuffer);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+	prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
+
+	prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer;
+
+	kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T));
+	rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD;
+	prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD;
+
+	rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe;
+	rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk;
+	rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo;
+	rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi;
+	prPmProfSetupInfo->ucBmpDeliveryAC =
+	    ((prUapsdParam->fgEnAPSD_AcBe << 0) |
+	     (prUapsdParam->fgEnAPSD_AcBk << 1) |
+	     (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3));
+	prPmProfSetupInfo->ucBmpTriggerAC =
+	    ((prUapsdParam->fgEnAPSD_AcBe << 0) |
+	     (prUapsdParam->fgEnAPSD_AcBk << 1) |
+	     (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3));
+
+	rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen;
+	prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen;
+
+#if 0
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_UAPSD_PARAM,
+				   TRUE,
+				   FALSE,
+				   TRUE,
+				   nicCmdEventSetCommon,
+				   nicOidCmdTimeoutCommon,
+				   sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T),
+				   (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen);
+#else
+	return wlanoidSendSetQueryP2PCmd(prAdapter,
+					 CMD_ID_SET_UAPSD_PARAM,
+					 TRUE,
+					 FALSE,
+					 TRUE,
+					 NULL,
+					 nicOidCmdTimeoutCommon,
+					 sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T),
+					 (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen);
+
+#endif
+}
+
+WLAN_STATUS
+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+
+	WLAN_STATUS rResult = WLAN_STATUS_FAILURE;
+/* PUINT_8 pucOpChnl = (PUINT_8)pvQueryBuffer; */
+
+	do {
+		if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL))
+			break;
+
+		if ((u4QueryBufferLen) && (pvQueryBuffer == NULL))
+			break;
+
+		if (u4QueryBufferLen < sizeof(UINT_8)) {
+			*pu4QueryInfoLen = sizeof(UINT_8);
+			rResult = WLAN_STATUS_BUFFER_TOO_SHORT;
+			break;
+		}
+#if 0
+		if (!p2pFuncGetCurrentOpChnl(prAdapter, pucOpChnl)) {
+			rResult = WLAN_STATUS_INVALID_DATA;
+			break;
+		}
+#else
+		rResult = WLAN_STATUS_INVALID_DATA;
+		break;
+#endif
+		/*
+		*pu4QueryInfoLen = sizeof(UINT_8);
+		rResult = WLAN_STATUS_SUCCESS;
+		*/
+
+	} while (FALSE);
+
+	return rResult;
+}				/* wlanoidQueryP2pOpChannel */
+
+WLAN_STATUS
+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	WLAN_STATUS rResult = WLAN_STATUS_FAILURE;
+/* PUINT_8 pucVersionNum = (PUINT_8)pvQueryBuffer; */
+
+	do {
+		if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL))
+			break;
+
+		if ((u4QueryBufferLen) && (pvQueryBuffer == NULL))
+			break;
+
+		if (u4QueryBufferLen < sizeof(UINT_8)) {
+			*pu4QueryInfoLen = sizeof(UINT_8);
+			rResult = WLAN_STATUS_BUFFER_TOO_SHORT;
+			break;
+		}
+
+	} while (FALSE);
+
+	return rResult;
+}				/* wlanoidQueryP2pVersion */
+
+WLAN_STATUS
+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rResult = WLAN_STATUS_FAILURE;
+	UINT_8 ucVersionNum;
+
+	do {
+		if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) {
+
+			rResult = WLAN_STATUS_INVALID_DATA;
+			break;
+		}
+
+		if ((u4SetBufferLen) && (pvSetBuffer == NULL)) {
+			rResult = WLAN_STATUS_INVALID_DATA;
+			break;
+		}
+
+		*pu4SetInfoLen = sizeof(UINT_8);
+
+		if (u4SetBufferLen < sizeof(UINT_8)) {
+			rResult = WLAN_STATUS_INVALID_LENGTH;
+			break;
+		}
+
+		ucVersionNum = *((PUINT_8) pvSetBuffer);
+
+		rResult = WLAN_STATUS_SUCCESS;
+	} while (FALSE);
+
+	return rResult;
+}				/* wlanoidSetP2pSupplicantVersion */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to set the WPS mode.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                          bytes read from the set buffer. If the call failed
+*                          due to invalid length of the set buffer, returns
+*                          the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS status;
+	UINT_32 u4IsWPSmode = 0;
+
+	DEBUGFUNC("wlanoidSetP2pWPSmode");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4SetInfoLen);
+
+	if (pvSetBuffer)
+		u4IsWPSmode = *(PUINT_32) pvSetBuffer;
+	else
+		u4IsWPSmode = 0;
+
+	if (u4IsWPSmode)
+		prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 1;
+	else
+		prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 0;
+
+	status = nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+	return status;
+}				/* end of wlanoidSetP2pWPSmode() */
+
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+WLAN_STATUS
+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	DEBUGFUNC("wlanoidQueryP2pRssi");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4QueryInfoLen);
+	if (u4QueryBufferLen)
+		ASSERT(pvQueryBuffer);
+
+	*pu4QueryInfoLen = sizeof(PARAM_RSSI);
+
+	/* Check for query buffer length */
+	if (u4QueryBufferLen < *pu4QueryInfoLen) {
+		DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen);
+		return WLAN_STATUS_BUFFER_TOO_SHORT;
+	}
+
+	if (prAdapter->fgIsP2pLinkQualityValid == TRUE &&
+	    (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) {
+		PARAM_RSSI rRssi;
+
+		rRssi = (PARAM_RSSI) prAdapter->rP2pLinkQuality.cRssi;	/* ranged from (-128 ~ 30) in unit of dBm */
+
+		if (rRssi > PARAM_WHQL_RSSI_MAX_DBM)
+			rRssi = PARAM_WHQL_RSSI_MAX_DBM;
+		else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM)
+			rRssi = PARAM_WHQL_RSSI_MIN_DBM;
+
+		kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI));
+		return WLAN_STATUS_SUCCESS;
+	}
+#ifdef LINUX
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_LINK_QUALITY,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryLinkQuality,
+				   nicOidCmdTimeoutCommon,
+				   *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen);
+#else
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_GET_LINK_QUALITY,
+				   FALSE,
+				   TRUE,
+				   TRUE,
+				   nicCmdEventQueryLinkQuality,
+				   nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen);
+
+#endif
+}				/* wlanoidQueryP2pRssi */
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h
new file mode 100644
index 0000000000000..89de18c89c1cc
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h
@@ -0,0 +1,238 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/CFG_Wifi_File.h#1
+*/
+
+/*! \file   CFG_Wifi_File.h
+    \brief  Collection of NVRAM structure used for YuSu project
+
+    In this file we collect all compiler flags and detail the driver behavior if
+    enable/disable such switch or adjust numeric parameters.
+*/
+
+/*
+** Log: CFG_Wifi_File.h
+ *
+ * 09 08 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628-specific definitions.
+ *
+ * 08 09 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP
+ *
+ * 05 27 2011 cp.wu
+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
+ * update NVRAM data structure definition.
+ *
+ * 03 10 2011 cp.wu
+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
+ * deprecate configuration used by MT6620 E2
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 25 2010 cp.wu
+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition
+ * follow-up for CMD_5G_PWR_OFFSET_T definition change
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add skeleton for NVRAM integration
+ *
+*/
+
+#ifndef _CFG_WIFI_FILE_H
+#define _CFG_WIFI_FILE_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_typedef.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+/* duplicated from nic_cmd_event.h to avoid header dependency */
+typedef struct _TX_PWR_PARAM_T {
+	INT_8 cTxPwr2G4Cck;	/* signed, in unit of 0.5dBm */
+	INT_8 acReserved[3];	/* form MT6628 acReserved[0]=cTxPwr2G4Dsss */
+	INT_8 cTxPwr2G4OFDM_BPSK;
+	INT_8 cTxPwr2G4OFDM_QPSK;
+	INT_8 cTxPwr2G4OFDM_16QAM;
+	INT_8 cTxPwr2G4OFDM_Reserved;
+	INT_8 cTxPwr2G4OFDM_48Mbps;
+	INT_8 cTxPwr2G4OFDM_54Mbps;
+
+	INT_8 cTxPwr2G4HT20_BPSK;
+	INT_8 cTxPwr2G4HT20_QPSK;
+	INT_8 cTxPwr2G4HT20_16QAM;
+	INT_8 cTxPwr2G4HT20_MCS5;
+	INT_8 cTxPwr2G4HT20_MCS6;
+	INT_8 cTxPwr2G4HT20_MCS7;
+
+	INT_8 cTxPwr2G4HT40_BPSK;
+	INT_8 cTxPwr2G4HT40_QPSK;
+	INT_8 cTxPwr2G4HT40_16QAM;
+	INT_8 cTxPwr2G4HT40_MCS5;
+	INT_8 cTxPwr2G4HT40_MCS6;
+	INT_8 cTxPwr2G4HT40_MCS7;
+
+	INT_8 cTxPwr5GOFDM_BPSK;
+	INT_8 cTxPwr5GOFDM_QPSK;
+	INT_8 cTxPwr5GOFDM_16QAM;
+	INT_8 cTxPwr5GOFDM_Reserved;
+	INT_8 cTxPwr5GOFDM_48Mbps;
+	INT_8 cTxPwr5GOFDM_54Mbps;
+
+	INT_8 cTxPwr5GHT20_BPSK;
+	INT_8 cTxPwr5GHT20_QPSK;
+	INT_8 cTxPwr5GHT20_16QAM;
+	INT_8 cTxPwr5GHT20_MCS5;
+	INT_8 cTxPwr5GHT20_MCS6;
+	INT_8 cTxPwr5GHT20_MCS7;
+
+	INT_8 cTxPwr5GHT40_BPSK;
+	INT_8 cTxPwr5GHT40_QPSK;
+	INT_8 cTxPwr5GHT40_16QAM;
+	INT_8 cTxPwr5GHT40_MCS5;
+	INT_8 cTxPwr5GHT40_MCS6;
+	INT_8 cTxPwr5GHT40_MCS7;
+} TX_PWR_PARAM_T, *P_TX_PWR_PARAM_T;
+
+typedef struct _PWR_5G_OFFSET_T {
+	INT_8 cOffsetBand0;	/* 4.915-4.980G */
+	INT_8 cOffsetBand1;	/* 5.000-5.080G */
+	INT_8 cOffsetBand2;	/* 5.160-5.180G */
+	INT_8 cOffsetBand3;	/* 5.200-5.280G */
+	INT_8 cOffsetBand4;	/* 5.300-5.340G */
+	INT_8 cOffsetBand5;	/* 5.500-5.580G */
+	INT_8 cOffsetBand6;	/* 5.600-5.680G */
+	INT_8 cOffsetBand7;	/* 5.700-5.825G */
+} PWR_5G_OFFSET_T, *P_PWR_5G_OFFSET_T;
+
+typedef struct _PWR_PARAM_T {
+	UINT_32 au4Data[28];
+	UINT_32 u4RefValue1;
+	UINT_32 u4RefValue2;
+} PWR_PARAM_T, *P_PWR_PARAM_T;
+
+typedef struct _MT6620_CFG_PARAM_STRUCT {
+	/* 256 bytes of MP data */
+	UINT_16 u2Part1OwnVersion;
+	UINT_16 u2Part1PeerVersion;
+	UINT_8 aucMacAddress[6];
+	UINT_8 aucCountryCode[2];
+	TX_PWR_PARAM_T rTxPwr;
+	UINT_8 aucEFUSE[144];
+	UINT_8 ucTxPwrValid;
+	UINT_8 ucSupport5GBand;
+	UINT_8 fg2G4BandEdgePwrUsed;
+	INT_8 cBandEdgeMaxPwrCCK;
+	INT_8 cBandEdgeMaxPwrOFDM20;
+	INT_8 cBandEdgeMaxPwrOFDM40;
+
+	UINT_8 ucRegChannelListMap;
+	UINT_8 ucRegChannelListIndex;
+	UINT_8 aucRegSubbandInfo[36];
+
+	UINT_8 aucReserved2[256 - 240];
+
+	/* 256 bytes of function data */
+	UINT_16 u2Part2OwnVersion;
+	UINT_16 u2Part2PeerVersion;
+	UINT_8 uc2G4BwFixed20M;
+	UINT_8 uc5GBwFixed20M;
+	UINT_8 ucEnable5GBand;
+	UINT_8 aucPreTailReserved;
+	UINT_8 uc2GRssiCompensation;
+	UINT_8 uc5GRssiCompensation;
+	UINT_8 fgRssiCompensationValidbit;
+	UINT_8 ucRxAntennanumber;
+	UINT_8 aucTailReserved[256 - 12];
+} MT6620_CFG_PARAM_STRUCT, *P_MT6620_CFG_PARAM_STRUCT, WIFI_CFG_PARAM_STRUCT, *P_WIFI_CFG_PARAM_STRUCT;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#ifndef DATA_STRUCT_INSPECTING_ASSERT
+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \
+{ \
+	switch (0) {case 0: case (expr): default:; } \
+}
+#endif
+
+#define CFG_FILE_WIFI_REC_SIZE    sizeof(WIFI_CFG_PARAM_STRUCT)
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#ifndef _lint
+/* We don't have to call following function to inspect the data structure.
+ * It will check automatically while at compile time.
+ * We'll need this to guarantee the same member order in different structures
+ * to simply handling effort in some functions.
+ */
+static inline VOID nvramOffsetCheck(VOID)
+{
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion) == 256);
+
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(WIFI_CFG_PARAM_STRUCT) == 512);
+
+	DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) & 0x0001) == 0);
+
+	DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) & 0x0001) == 0);
+}
+#endif
+
+#endif /* _CFG_WIFI_FILE_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h
new file mode 100644
index 0000000000000..a52053d5752db
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h
@@ -0,0 +1,1628 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/config.h#2
+*/
+
+/*! \file   "config.h"
+    \brief  This file includes the various configurable parameters for customers
+
+    This file ncludes the configurable parameters except the parameters indicate the turning-on/off of some features
+*/
+
+/*
+** Log: config.h
+ *
+ * 07 13 2012 cp.wu
+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for
+ * termination after SDIO error has happened
+ * [driver domain] add force reset by host-to-device interrupt mechanism
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 06 05 2012 tsaiyuan.hsu
+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1"
+ * resolve build waring for "WNM_UNIT_TEST not defined"..
+ *
+ * 06 04 2012 cp.wu
+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development
+ * discussed with WH, privacy bit in associate response is not necessary to be checked,
+ * and identified as association failure when mismatching with beacon/probe response
+ *
+ * 05 11 2012 cp.wu
+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience
+ * show MAC address & source while initiliazation
+ *
+ * 04 20 2012 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * correct macro
+ *
+ * 04 12 2012 terry.wu
+ * NULL
+ * Add AEE message support
+ * 1) Show AEE warning(red screen) if SDIO access error occurs
+ *
+ * 03 29 2012 eason.tsai
+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define
+ * add conditional define.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Enable CFG80211 Support.
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ * 11 23 2011 cp.wu
+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection
+ * add compile option to disable beacon content change detection.
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 10 28 2011 cp.wu
+ * [MT6620 Wi-Fi][Win32 Driver] Enable 5GHz support as default
+ * enable 5GHz as default for DaVinci trunk and V2.1 driver release .
+ *
+ * 10 18 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * surpress compiler warning for MT6628 build
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 10 03 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * enable divided firmware downloading.
+ *
+ * 10 03 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * add firmware download path in divided scatters.
+ *
+ * 10 03 2011 cp.wu
+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * add firmware downloading aggregated path.
+ *
+ * 09 28 2011 tsaiyuan.hsu
+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX
+ * enlarge window size only by 4.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * reuse firmware download logic of MT6620 for MT6628.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628-specific definitions.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms.
+ *
+ * 08 12 2011 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC.
+ *
+ * 08 09 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS definition for MT6620.
+ *
+ * 07 28 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS cmd and event.
+ *
+ * 07 22 2011 jeffrey.chang
+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time
+ * modify driver to set OSC stable time after f/w download
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Refine compile flag.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Add wifi direct connection enhancement method I, II & VI.
+ *
+ * 06 24 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content
+ * increase RX buffer number to have a 2:1 ping-pong ratio
+ *
+ * 06 23 2011 eddie.chen
+ * [WCXRP00000810] [MT5931][DRV/FW] Adjust TxRx Buffer number and Rx buffer size
+ * 1. Different TX RX buffer
+ * 2. Enlarge RX buffer and increase the number 8->11
+ * 3. Separate the WINSZIE and RX buffer number
+ * 4. Fix RX maximum size in MAC
+ *
+ * 06 20 2011 terry.wu
+ * NULL
+ * Add BoW Rate Limitation.
+ *
+ * 06 17 2011 terry.wu
+ * NULL
+ * .
+ *
+ * 06 17 2011 terry.wu
+ * NULL
+ * Add BoW 11N support.
+ *
+ * 06 07 2011 yuche.tsai
+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue
+ * Add compile flag for persistent group support.
+ *
+ * 06 01 2011 cm.chang
+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function
+ * Limit AIS to fixed channel same with BOW
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 14 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * Enable RX STBC capability
+ *
+ * 04 11 2011 george.huang
+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF
+ * .
+ *
+ * 04 08 2011 pat.lu
+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver
+ *
+ * 04 08 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * 1. correction: RX aggregation is not limited to SDIO but for all host interface options
+ * 2. add forward declarations for DBG-only symbols
+ *
+ * 04 06 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI  port
+ * 2. update perm_addr as well for MAC address
+ * 3. not calling check_mem_region() anymore for eHPI
+ * 4. correct MSC_CS macro for 0-based notation
+ *
+ * 04 01 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface
+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR
+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26
+ *
+ * 03 29 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with
+ * user space process for RESET_START and RESET_END events
+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism
+ *
+ * 03 22 2011 pat.lu
+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
+ *
+ * 03 18 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * enable the Anti_piracy check at driver .
+ *
+ * 03 17 2011 tsaiyuan.hsu
+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming
+ * enable roaming feature.
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one
+ * to reduce physically continuous memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 15 2011 eddie.chen
+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter
+ * Add sw debug counter for QM.
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 06 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Sync BOW Driver to latest person development branch version..
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add security check code.
+ *
+ * 03 01 2011 george.huang
+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames
+ * Fix compile issue
+ *
+ * 02 25 2011 george.huang
+ * [WCXRP00000497] [MT6620 Wi-Fi][FW] Change default UAPSD AC assignment
+ * Assign all AC default to be U-APSD enabled.
+ *
+ * 02 14 2011 wh.su
+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
+ * Let the privacy check at hotspot mode default enable.
+ *
+ * 02 09 2011 wh.su
+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
+ * adding the code for check STA privacy bit at AP mode, .
+ *
+ * 02 08 2011 cp.wu
+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number
+ * change version number to v1.2.0.0 for preparing v1.2 software package release.
+ *
+ * 02 01 2011 yarco.yang
+ * [WCXRP00000417] [MT6620 Driver] Change CFG_HANDLE_IST_IN_SDIO_CALLBACK from 1 to 0 for Interoperability
+ * .
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 19 2011 wh.su
+ * [WCXRP00000370] [MT6620 Wi-Fi][Driver] Disable Rx RDG for workaround pre-N ccmp issue
+ * Not announce support Rx RDG for wokaround pre-N ccmp construct AAD issue..
+ *
+ * 01 15 2011 puff.wen
+ * NULL
+ * Add Stress test
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause
+ * hardware header translation needs such information
+ * fill mac header length information for 802.1x frames.
+ *
+ * 01 11 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support BOW only for Linux.
+ *
+ * 01 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Enable BOW and 4 physical links.
+ *
+ * 01 08 2011 yuche.tsai
+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request,
+ * but the SSID length is still invalid.
+ * Modify CFG_SLT_SUPPORT default value.
+ *
+ * 01 08 2011 yuche.tsai
+ * [WCXRP00000341] [MT6620][SLT] Create Branch for SLT SW.
+ * Update configure flag.
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * report EEPROM used flag via NIC_CAPABILITY
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools
+ *
+ * 12 15 2010 yuche.tsai
+ * NULL
+ * Update SLT Descriptor number configure in driver.
+ *
+ * 12 13 2010 chinglan.wang
+ * NULL
+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function.
+ *
+ * 11 23 2010 george.huang
+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB
+ * Enable PM function by default
+ *
+ * 11 15 2010 wh.su
+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
+ * use config.mk WAPI config define.
+ *
+ * 11 08 2010 wh.su
+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
+ * use the config.mk define.
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 11 01 2010 yarco.yang
+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
+ * Add code to run WlanIST in SDIO callback.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 25 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add option for enable/disable TX PWR gain adjustment (default: off)
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
+ * enable the WAPI compiling flag as default
+ *
+ * 10 19 2010 cp.wu
+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration
+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion
+ * 2. shorten polling count for shorter response time
+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 10 14 2010 wh.su
+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android
+ * Add a define CFG_TEST_ANDROID_DIRECT_GO compiling flag
+ *
+ * 10 08 2010 cm.chang
+ * NULL
+ * Remove unused compiling flags (TX_RDG and TX_SGI)
+ *
+ * 10 07 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * add firmware download for MT5931.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 10 05 2010 yarco.yang
+ * [WCXRP00000082] [MT6620 Wi-Fi][Driver]High throughput performance tuning
+ * Change CFG_IST_LOOP_COUNT from 2 to 1 to reduce unnecessary SDIO bus access
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature
+ * Modify online scan as a run-time adjustable option (for Windows, in registry)
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE
+ *
+ * 09 20 2010 cm.chang
+ * NULL
+ * Disable RX STBC by BB HEC based on MT6620E1_PHY_BUG v05.docx
+ *
+ * 09 17 2010 chinglan.wang
+ * NULL
+ * Add performance test option
+ *
+ * 09 10 2010 chinglan.wang
+ * NULL
+ * Modify for Software Migration Phase 2.10 for E2 FPGA
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * Add a CFG for max common IE buffer size.
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * restore configuration as before.
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * HIFSYS Clock Source Workaround
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 30 2010 chinglan.wang
+ * NULL
+ * Enable the MT6620_FPGA_BWCS value.
+ *
+ * 08 30 2010 chinglan.wang
+ * NULL
+ * Disable the FW encryption.
+ *
+ * 08 27 2010 chinglan.wang
+ * NULL
+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * Add AT GO test configure mode under WinXP.
+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA
+ *
+ * 08 25 2010 cp.wu
+ * NULL
+ * add option for enabling AIS 5GHz scan
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 24 2010 cp.wu
+ * NULL
+ * 1) initialize variable for enabling short premable/short time slot.
+ * 2) add compile option for disabling online scan
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 23 2010 cp.wu
+ * NULL
+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Disable BOW Test.
+ *
+ * 08 23 2010 jeffrey.chang
+ * NULL
+ * fix config.h typo
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 21 2010 jeffrey.chang
+ * NULL
+ * 1) add sdio two setting
+ * 2) bug fix of sdio glue
+ *
+ * 08 09 2010 wh.su
+ * NULL
+ * let the firmware download default enabled.
+ *
+ * 08 07 2010 wh.su
+ * NULL
+ * adding the privacy related code for P2P network
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Add a configure flag for P2P unitest.
+ *
+ * 07 23 2010 cp.wu
+ *
+ * 1) re-enable AIS-FSM beacon timeout handling.
+ * 2) scan done API revised
+ *
+ * 07 23 2010 cp.wu
+ *
+ * 1) enable Ad-Hoc
+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event.
+ *
+ * 07 19 2010 wh.su
+ *
+ * update for security supporting.
+ *
+ * 07 19 2010 yuche.tsai
+ *
+ * Add for SLT support.
+ *
+ * 07 16 2010 cp.wu
+ *
+ * remove work-around in case SCN is not available.
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 13 2010 cp.wu
+ *
+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor
+ * underflow under concurrent network operation
+ *
+ * 07 09 2010 yarco.yang
+ *
+ * [MT6620 and MT5931] SW Migration: Add ADDBA support
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * take use of RLM module for parsing/generating HT IEs for 11n capability
+ *
+ * 07 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * for first connection, if connecting failed do not enter into scan state.
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * modify Beacon/ProbeResp to complete parsing,
+ * because host software has looser memory usage restriction
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add SCN compilation option.
+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * set default compiling flag for security disable.
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Support CFG_MQM_MIGRATION flag
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * enable RX management frame handling.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan_fsm into building.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan.c.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add bss.c.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wlan_def.h.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 31 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add config option for cfg80211.
+ *
+ * 05 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * set ATIMwindow default value to zero.
+ *
+ * 05 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add option for FPGA_BWCS & FPGA_V5
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) enable CMD/EVENT ver 0.9 definition.
+ * 2) abandon use of ENUM_MEDIA_STATE
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add CFG_STARTUP_DEBUG for debugging starting up issue.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic handling framework for wireless extension ioctls.
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change firmware name to WIFI_RAM_CODE.
+ *
+ * 05 07 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * disable bt-over-wifi configuration, turn it on after firmware finished implementation
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add multiple physical link support
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 22 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * re-enable power management
+ *
+ * 04 22 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ *
+ * 1) modify rx path code for supporting Wi-Fi direct
+ * 2) modify config.h since Linux dont need to consider retaining packet
+ *
+ * 04 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * enable TCP/IP checksum offloading by default.
+ *
+ * 04 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * set CFG_ENABLE_FULL_PM to 1 as default to
+ * 1) acquire own before hardware access
+ * 2) set own back after hardware access
+ *
+ * 04 15 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * change firmware name
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver
+ * disable RX-enhanced response temporally, it seems the CQ is not resolved yet.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver
+ * re-enable RX enhanced mode as WPD00003827 is resolved.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * turn off RX_ENHANCE mode by default.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) eliminate unused definitions
+ *  * 2) ready bit will be polled for limited iteration
+ *
+ * 04 02 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * firmware download: Linux uses different firmware path
+ *
+ * 04 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change to use WIFI_TCM_ALWAYS_ON as firmware image
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add a temporary flag for integration with CMD/EVENT v0.9.
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * firmware download load address & start address are now configured from config.h
+ *  * due to the different configurations on FPGA and ASIC
+ *
+ * 03 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add options for full PM support.
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 16 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * turn on FW-DOWNLOAD as default for release.
+ *
+ * 03 16 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * build up basic data structure and definitions to support BT-over-WiFi
+ *
+ * 03 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add two option for ACK and ENCRYPTION for firmware download
+ *
+ * 03 11 2010 cp.wu
+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING
+ *
+ * 03 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code clean: removing unused variables and structure definitions
+ *
+ * 03 05 2010 cp.wu
+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
+ * change CFG_NUM_OF_QM_RX_PKT_NUM to 120
+ *
+ * 03 04 2010 cp.wu
+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
+ * .
+ *
+ * 03 04 2010 cp.wu
+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
+ * increase RX buffer number to avoid RX buffer starvation.
+ *
+ * 02 24 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Changed the number of STA_RECs to 20
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add checksum offloading support.
+ *
+ * 02 11 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. add logic for firmware download
+ *  * 2. firmware image filename and start/load address are now retrieved from registry
+ *
+ * 02 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * prepare for implementing fw download logic
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  * and result is retrieved by get ATInfo instead
+ *  * 2) add 4 counter for recording aggregation statistics
+**  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-16 22:12:28 GMT mtk02752
+**  enable interrupt enhanced response, TX/RX Aggregation as default
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:38:43 GMT mtk02752
+**  eliminate compile options which are obsolete or for emulation purpose
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 13:56:26 GMT MTK02468
+**  Added RX buffer reordering configurations
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-12-04 12:09:09 GMT mtk02752
+**  once enhanced intr/rx response is taken, RX must be access in aggregated basis
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 17:54:50 GMT mtk02752
+**  correct a typo
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:47 GMT mtk01084
+**  add defines
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:33:37 GMT mtk02752
+**  add coalescing buffer definition for SD1_SD3_DATAPATH_INTEGRATION
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 20:32:40 GMT mtk02752
+**  add CFG_TX_MAX_PKT_NUM for limiting queued TX packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 13:34:44 GMT mtk02752
+**  add SD1_SD3_DATAPATH_INTEGRATION define for source control
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 13:54:11 GMT mtk01084
+**  enable INT enhance mode by default
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-30 18:17:14 GMT mtk01084
+**  add new define
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-10-29 19:47:36 GMT mtk01084
+**  not use HIF loopback mode
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-13 21:58:33 GMT mtk01084
+**  update for new macro define
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-09-09 17:26:08 GMT mtk01084
+**  add CFG_TEST_WITH_MT5921
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:02:30 GMT mtk01426
+**  Update CFG_RX_COALESCING_BUFFER_SIZE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-21 09:35:51 GMT mtk01461
+**  Add CFG_TX_DBG_MGT_BUF to debug MGMT Buffer depth
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:52:21 GMT mtk01426
+**  Add OOB_DATA_PRE_FIXED_LEN define
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-08 16:51:08 GMT mtk01084
+**  update for FW download part
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:33:37 GMT mtk01461
+**  Add SW pre test flag CFG_HIF_LOOPBACK_PRETEST
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 00:29:18 GMT mtk01461
+**  Fix CFG_COALESCING_BUFFER_SIZE if enable the CFG_TX_FRAGMENT
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-18 20:58:34 GMT mtk01426
+**  Add CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-17 20:17:36 GMT mtk01426
+**  Add CMD/Response related configure
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:21 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:21 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#ifdef MT6620
+#undef MT6620
+#endif
+
+#ifndef MT6628
+#define MT6628
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* 2 Flags for OS capability */
+
+#define MTK_WCN_SINGLE_MODULE		0	/* 1: without WMT */
+
+#ifdef LINUX
+#ifdef CONFIG_X86
+#define MTK_WCN_HIF_SDIO        0
+#else
+#define MTK_WCN_HIF_SDIO        0	/* samp */
+#endif
+#else
+#define MTK_WCN_HIF_SDIO            0
+#endif
+
+#if (CFG_SUPPORT_AEE == 1)
+#define CFG_ENABLE_AEE_MSG          1
+#else
+#define CFG_ENABLE_AEE_MSG          0
+#endif
+
+#if CFG_ENABLE_AEE_MSG
+#include <mt-plat/aee.h>
+#endif
+
+/* 2 Flags for Driver Features */
+#define CFG_TX_FRAGMENT                 1	/*!< 1: Enable TX fragmentation
+						   0: Disable */
+#define CFG_SUPPORT_PERFORMANCE_TEST    0	/*Only for performance Test */
+
+#define CFG_COUNTRY_CODE                NULL	/* "US" */
+
+#ifndef LINUX
+#define CFG_FW_FILENAME             L"WIFI_RAM_CODE"
+#define CFG_FW_FILENAME_E6          L"WIFI_RAM_CODE_E6"
+#else
+#define CFG_FW_FILENAME             "WIFI_RAM_CODE"
+#endif
+#ifndef LINUX
+#define CFG_SUPPORT_CFG_FILE     0
+#else
+#define CFG_SUPPORT_CFG_FILE     1
+#endif
+
+#define CFG_SUPPORT_CE_FCC_TXPWR_LIMIT 0 /* Support CE FCC Tx Power limit */
+
+#define CFG_SUPPORT_802_11D             1	/*!< 1(default): Enable 802.11d
+						   0: Disable */
+
+#define CFG_SUPPORT_RRM             0	/* Radio Reasource Measurement (802.11k) */
+#define CFG_SUPPORT_DFS             1	/* DFS (802.11h) */
+
+#if (CFG_SUPPORT_DFS == 1)	/* Add by Enlai */
+#define CFG_SUPPORT_QUIET           1	/* Quiet (802.11h) */
+#define CFG_SUPPORT_SPEC_MGMT       1	/* Spectrum Management (802.11h): TPC and DFS */
+#else
+#define CFG_SUPPORT_QUIET           0	/* Quiet (802.11h) */
+#define CFG_SUPPORT_SPEC_MGMT       0	/* Spectrum Management (802.11h): TPC and DFS */
+#endif
+
+#define CFG_SUPPORT_RX_RDG          0	/* 11n feature. RX RDG capability */
+#define CFG_SUPPORT_MFB             0	/* 802.11n MCS Feedback responder */
+#define CFG_SUPPORT_RX_STBC         1	/* 802.11n RX STBC (1SS) */
+#define CFG_SUPPORT_RX_SGI          1	/* 802.11n RX short GI for both 20M and 40M BW */
+#define CFG_SUPPORT_RX_HT_GF        1	/* 802.11n RX HT green-field capability */
+
+#define CFG_SUPPORT_ROAMING_ENC		0	/* enahnced roaming */
+
+#define CFG_SUPPORT_TDLS			1	/* IEEE802.11z TDLS */
+#define CFG_SUPPORT_TDLS_DBG		0	/* TDLS debug */
+#define CFG_SUPPORT_STATISTICS		1
+#define CFG_SUPPORT_DBG_POWERMODE	1	/* for debugging power always active mode */
+
+#define CFG_SUPPORT_GSCN   1
+
+#define CFG_SUPPORT_TXR_ENC			0	/* enhanced tx rate switch */
+
+#define CFG_SUPPORT_PERSIST_NETDEV		0	/* create NETDEV when system bootup */
+
+#define CFG_FORCE_USE_20BW			1
+/*------------------------------------------------------------------------------
+ * SLT Option
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SLT_SUPPORT                             0
+
+#define	MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE				0
+
+#if defined(MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE)
+#define CFG_AUTO_CHANNEL_SEL_SUPPORT				1
+#else
+#define CFG_AUTO_CHANNEL_SEL_SUPPORT				0
+#endif
+
+#ifdef NDIS60_MINIPORT
+#define CFG_NATIVE_802_11                       1
+
+#define CFG_TX_MAX_PKT_SIZE                     2304
+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60       0	/* !< 1: Enable TCP/IP header checksum offload
+							   0: Disable */
+#define CFG_TCP_IP_CHKSUM_OFFLOAD               0
+#define CFG_WHQL_DOT11_STATISTICS               1
+#define CFG_WHQL_ADD_REMOVE_KEY                 1
+#define CFG_WHQL_CUSTOM_IE                      1
+#define CFG_WHQL_SAFE_MODE_ENABLED              1
+
+#else
+#define CFG_TCP_IP_CHKSUM_OFFLOAD               1	/* !< 1: Enable TCP/IP header checksum offload
+							   0: Disable */
+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60       0
+#define CFG_TX_MAX_PKT_SIZE                     1600
+#define CFG_NATIVE_802_11                       0
+#endif
+
+/* 2 Flags for Driver Parameters */
+/*------------------------------------------------------------------------------
+ * Flags for EHPI Interface in Colibri Platform
+ *------------------------------------------------------------------------------
+ */
+#define CFG_EHPI_FASTER_BUS_TIMING                  0	/*!< 1: Do workaround for faster bus timing
+							   0(default): Disable */
+
+/*------------------------------------------------------------------------------
+ * Flags for HIFSYS Interface
+ *------------------------------------------------------------------------------
+ */
+#ifdef _lint
+#define _HIF_SDIO   0		/* samp */
+#endif
+
+#define CFG_SDIO_INTR_ENHANCE                        1	/*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode
+							   0: Disable */
+#define CFG_SDIO_RX_ENHANCE                          0	/*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode
+							   0: Disable */
+#define CFG_SDIO_TX_AGG                              1	/*!< 1: Enable SDIO TX enhance
+							   mode(Multiple frames in single BLOCK CMD)
+							   0(default): Disable */
+
+#define CFG_SDIO_RX_AGG                              1	/*!< 1: Enable SDIO RX enhance
+							   mode(Multiple frames in single BLOCK CMD)
+							   0(default): Disable */
+
+#if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0)
+#error "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1"
+#elif (CFG_SDIO_INTR_ENHANCE == 1 || CFG_SDIO_RX_ENHANCE == 1) && (CFG_SDIO_RX_AGG == 0)
+#error "CFG_SDIO_RX_AGG should be 1 once CFG_SDIO_INTR_ENHANCE and/or CFG_SDIO_RX_ENHANCE equals to 1"
+#endif
+
+#define CFG_SDIO_MAX_RX_AGG_NUM                     0	/*!< 1: Setting the maximum RX aggregation number
+							   0(default): no limited */
+
+#ifdef WINDOWS_CE
+#define CFG_SDIO_PATHRU_MODE                    1	/*!< 1: Support pass through (PATHRU) mode
+							   0: Disable */
+#else
+#define CFG_SDIO_PATHRU_MODE                    0	/*!< 0: Always disable if WINDOWS_CE is not defined */
+#endif
+
+#define CFG_MAX_RX_ENHANCE_LOOP_COUNT               3
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for Integration
+ *------------------------------------------------------------------------------
+ */
+#if defined(MT6620)
+#define MT6620_FPGA_BWCS    0
+#define MT6620_FPGA_V5      0
+
+#if (MT6620_FPGA_BWCS == 1) && (MT6620_FPGA_V5 == 1)
+#error
+#endif
+
+#if (MTK_WCN_HIF_SDIO == 1)
+#define CFG_MULTI_ECOVER_SUPPORT    1
+#elif !defined(LINUX)
+#define CFG_MULTI_ECOVER_SUPPORT    1
+#else
+#define CFG_MULTI_ECOVER_SUPPORT    0
+#endif
+
+#define CFG_ENABLE_CAL_LOG      0
+#define CFG_REPORT_RFBB_VERSION       0
+
+#elif defined(MT6628)
+
+#define CFG_MULTI_ECOVER_SUPPORT    0
+
+#define CFG_ENABLE_CAL_LOG      1
+#define CFG_REPORT_RFBB_VERSION       1
+
+#endif
+
+#define CFG_CHIP_RESET_SUPPORT                      1
+
+#if defined(MT6628)
+#define CFG_EMBED_FIRMWARE_BUILD_DATE_CODE  1
+#endif
+
+/*------------------------------------------------------------------------------
+ * Flags for workaround
+ *------------------------------------------------------------------------------
+ */
+#if defined(MT6620) && (MT6620_FPGA_BWCS == 0) && (MT6620_FPGA_V5 == 0)
+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND            0
+#else
+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND            0
+#endif
+
+/* SPM issue: suspend current is higher than deep idle */
+#define CFG_SPM_WORKAROUND_FOR_HOTSPOT                  1
+
+/*------------------------------------------------------------------------------
+ * Flags for driver version
+ *------------------------------------------------------------------------------
+ */
+#define CFG_DRV_OWN_VERSION \
+	((UINT_16)((NIC_DRIVER_MAJOR_VERSION << 8) | (NIC_DRIVER_MINOR_VERSION)))
+#define CFG_DRV_PEER_VERSION                    ((UINT_16)0x0000)
+
+/*------------------------------------------------------------------------------
+ * Flags for TX path which are OS dependent
+ *------------------------------------------------------------------------------
+ */
+/*! NOTE(Kevin): If the Network buffer is non-scatter-gather like structure(without
+ * NETIF_F_FRAGLIST in LINUX), then we can set CFG_TX_BUFFER_IS_SCATTER_LIST to "0"
+ * for zero copy TX packets.
+ * For scatter-gather like structure, we set "1", driver will do copy frame to
+ * internal coalescing buffer before write it to FIFO.
+ */
+#if defined(LINUX)
+#define CFG_TX_BUFFER_IS_SCATTER_LIST       1	/*!< 1: Do frame copy before write to TX FIFO.
+						   Used when Network buffer is scatter-gather.
+						   0(default): Do not copy frame */
+#else /* WINDOWS/WINCE */
+#define CFG_TX_BUFFER_IS_SCATTER_LIST       1
+#endif /* LINUX */
+
+#if CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST
+#define CFG_COALESCING_BUFFER_SIZE          (CFG_TX_MAX_PKT_SIZE * NIC_TX_BUFF_SUM)
+#else
+#define CFG_COALESCING_BUFFER_SIZE          (CFG_TX_MAX_PKT_SIZE)
+#endif /* CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST */
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for TX path
+ *------------------------------------------------------------------------------
+ */
+
+/*! Maximum number of SW TX packet queue */
+#define CFG_TX_MAX_PKT_NUM                      512	/* 256 must >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * 2;
+							   or wmm will fail when queue is full */
+
+/*! Maximum number of SW TX CMD packet buffer */
+#define CFG_TX_MAX_CMD_PKT_NUM                  32
+
+/*! Maximum number of associated STAs */
+#define CFG_NUM_OF_STA_RECORD                   20
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for RX path
+ *------------------------------------------------------------------------------
+ */
+
+/*! Max. descriptor number - sync. with firmware */
+#if CFG_SLT_SUPPORT
+#define CFG_NUM_OF_RX0_HIF_DESC                 42
+#else
+#define CFG_NUM_OF_RX0_HIF_DESC                 16
+#endif
+#define CFG_NUM_OF_RX1_HIF_DESC                 2
+
+/*! Max. buffer hold by QM */
+#define CFG_NUM_OF_QM_RX_PKT_NUM                120
+
+/*! Maximum number of SW RX packet buffer */
+#define CFG_RX_MAX_PKT_NUM                      ((CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC) * 3 \
+						+ CFG_NUM_OF_QM_RX_PKT_NUM)
+
+#define CFG_RX_REORDER_Q_THRESHOLD              8
+
+#ifndef LINUX
+#define CFG_RX_RETAINED_PKT_THRESHOLD \
+	(CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC + CFG_NUM_OF_QM_RX_PKT_NUM)
+#else
+#define CFG_RX_RETAINED_PKT_THRESHOLD           0
+#endif
+
+/*! Maximum RX packet size, if exceed this value, drop incoming packet */
+/* 7.2.3 Maganement frames */
+#define CFG_RX_MAX_PKT_SIZE   (28 + 2312 + 12 /*HIF_RX_HEADER_T*/)	/* TODO: it should be
+									   4096 under emulation mode */
+
+/*! Minimum RX packet size, if lower than this value, drop incoming packet */
+#define CFG_RX_MIN_PKT_SIZE                     10	/*!< 802.11 Control Frame is 10 bytes */
+
+#if CFG_SDIO_RX_AGG
+    /* extra size for CS_STATUS and enhanced response */
+#define CFG_RX_COALESCING_BUFFER_SIZE       ((CFG_NUM_OF_RX0_HIF_DESC  + 1) \
+						* CFG_RX_MAX_PKT_SIZE)
+#else
+#define CFG_RX_COALESCING_BUFFER_SIZE       (CFG_RX_MAX_PKT_SIZE)
+#endif
+
+/*! RX BA capability */
+#define CFG_NUM_OF_RX_BA_AGREEMENTS             8
+#define CFG_RX_BA_MAX_WINSIZE                   16
+#define CFG_RX_BA_INC_SIZE                      4
+#define CFG_RX_MAX_BA_TID_NUM                   8
+#define CFG_RX_REORDERING_ENABLED               1
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for CMD/RESPONSE
+ *------------------------------------------------------------------------------
+ */
+#define CFG_RESPONSE_POLLING_TIMEOUT            512
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for Protocol Stack
+ *------------------------------------------------------------------------------
+ */
+/*! Maximum number of BSS in the SCAN list */
+#define CFG_MAX_NUM_BSS_LIST                    64
+
+#define CFG_MAX_COMMON_IE_BUF_LEN         ((1500 * CFG_MAX_NUM_BSS_LIST) / 3)
+
+/*! Maximum size of Header buffer of each SCAN record */
+#define CFG_RAW_BUFFER_SIZE                      1024
+
+/*! Maximum size of IE buffer of each SCAN record */
+#define CFG_IE_BUFFER_SIZE                      512
+
+/*! Maximum number of STA records */
+#define CFG_MAX_NUM_STA_RECORD                  32
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for Power management
+ *------------------------------------------------------------------------------
+ */
+#define CFG_ENABLE_FULL_PM                      1
+#define CFG_ENABLE_WAKEUP_ON_LAN                0
+#if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || \
+	defined(CONFIG_ARCH_MT6753) || defined(CONFIG_ARCH_MT6580)
+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG			1	/* debug which packet wake up host */
+#else
+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG			0	/* debug which packet wake up host */
+#endif
+#define CFG_INIT_POWER_SAVE_PROF                    ENUM_PSP_FAST_SWITCH
+
+#define CFG_INIT_ENABLE_PATTERN_FILTER_ARP                    0
+
+#define CFG_INIT_UAPSD_AC_BMP                    0	/* (BIT(3) | BIT(2) | BIT(1) | BIT(0)) */
+
+/* #define CFG_SUPPORT_WAPI                        0 */
+#define CFG_SUPPORT_WPS                          1
+#define CFG_SUPPORT_WPS2                         1
+
+/*------------------------------------------------------------------------------
+ * 802.11i RSN Pre-authentication PMKID cahce maximun number
+ *------------------------------------------------------------------------------
+ */
+#define CFG_MAX_PMKID_CACHE                     16	/*!< max number of PMKID cache
+							   16(default) : The Max PMKID cache */
+/*------------------------------------------------------------------------------
+ * Auto Channel Selection Maximun Channel Number
+ *------------------------------------------------------------------------------
+ */
+
+#define MAX_AUTO_CHAL_NUM						23	/* Ch1~Ch14,Ch36,Ch40,Ch44,
+										   Ch48,Ch149,Ch153,Ch157,Ch161 */
+/*------------------------------------------------------------------------------
+ * FAST SCAN
+ *------------------------------------------------------------------------------
+ */
+#define CFG_ENABLE_FAST_SCAN                    0
+#define CFG_CN_SUPPORT_CLASS121                 0        /* Add Class 121, 5470-5725MHz, support for China domain */
+#if CFG_ENABLE_FAST_SCAN
+	#define CFG_FAST_SCAN_DWELL_TIME                  40
+	#define CFG_FAST_SCAN_REG_DOMAIN_DEF_IDX          10
+#endif
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for Ad-Hoc
+ *------------------------------------------------------------------------------
+ */
+#define CFG_INIT_ADHOC_FREQ                     (2462000)
+#define CFG_INIT_ADHOC_MODE                     AD_HOC_MODE_MIXED_11BG
+#define CFG_INIT_ADHOC_BEACON_INTERVAL          (100)
+#define CFG_INIT_ADHOC_ATIM_WINDOW              (0)
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for Maximum Scan SSID number
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SCAN_SSID_MAX_NUM                   (4)
+#define CFG_SCAN_SSID_MATCH_MAX_NUM             (16)
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for Load Setup Default
+ *------------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ * Flags for enable 802.11A Band setting
+ *------------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ * Flags and Parameters for Interrupt Process
+ *------------------------------------------------------------------------------
+ */
+#if defined(_HIF_SDIO) && defined(WINDOWS_CE)
+#define CFG_IST_LOOP_COUNT                  8
+#else
+#define CFG_IST_LOOP_COUNT                  8
+#endif /* _HIF_SDIO */
+
+#define CFG_INT_WRITE_CLEAR                     0
+
+#if defined(LINUX)
+#define CFG_DBG_GPIO_PINS                       0	/* if 1, use MT6516 GPIO pin to log TX behavior */
+#endif
+
+/* 2 Flags for Driver Debug Options */
+/*------------------------------------------------------------------------------
+ * Flags of TX Debug Option. NOTE(Kevin): Confirm with SA before modifying following flags.
+ *------------------------------------------------------------------------------
+ */
+#define CFG_DBG_MGT_BUF                         1	/*!< 1: Debug statistics usage of MGMT Buffer
+							   0: Disable */
+
+#define CFG_HIF_STATISTICS                      0
+
+#define CFG_HIF_RX_STARVATION_WARNING           0
+
+#define CFG_STARTUP_DEBUG                       0
+
+#define CFG_RX_PKTS_DUMP                        1
+
+/*------------------------------------------------------------------------------
+ * Flags of Firmware Download Option.
+ *------------------------------------------------------------------------------
+ */
+#define CFG_ENABLE_FW_DOWNLOAD                  1
+
+#define CFG_ENABLE_FW_DOWNLOAD_ACK              1
+#define CFG_ENABLE_FW_ENCRYPTION                1
+
+#if defined(MT6628)
+#define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION  0
+#define CFG_ENABLE_FW_DIVIDED_DOWNLOAD      1
+#endif
+
+#if defined(MT6620)
+#if MT6620_FPGA_BWCS
+#define CFG_FW_LOAD_ADDRESS                     0x10014000
+#define CFG_OVERRIDE_FW_START_ADDRESS           0
+#define CFG_FW_START_ADDRESS                    0x10014001
+#elif MT6620_FPGA_V5
+#define CFG_FW_LOAD_ADDRESS                     0x10008000
+#define CFG_OVERRIDE_FW_START_ADDRESS           0
+#define CFG_FW_START_ADDRESS                    0x10008001
+#else
+#define CFG_FW_LOAD_ADDRESS                     0x10008000
+#define CFG_OVERRIDE_FW_START_ADDRESS           0
+#define CFG_FW_START_ADDRESS                    0x10008001
+#endif
+#elif defined(MT6628)
+#define CFG_FW_LOAD_ADDRESS                     0x00060000
+#define CFG_OVERRIDE_FW_START_ADDRESS           1
+#define CFG_FW_START_ADDRESS                    0x00060000
+#define CFG_START_ADDRESS_IS_1ST_SECTION_ADDR   1
+#endif
+
+/*------------------------------------------------------------------------------
+ * Flags of Bluetooth-over-WiFi (BT 3.0 + HS) support
+ *------------------------------------------------------------------------------
+ */
+
+#ifdef LINUX
+#ifdef CONFIG_X86
+#define CFG_ENABLE_BT_OVER_WIFI         0
+#else
+#define CFG_ENABLE_BT_OVER_WIFI         1
+#endif
+#else
+#define CFG_ENABLE_BT_OVER_WIFI             0
+#endif
+
+#define CFG_BOW_SEPARATE_DATA_PATH              1
+
+#define CFG_BOW_PHYSICAL_LINK_NUM               4
+
+#define CFG_BOW_TEST                            0
+
+#define CFG_BOW_LIMIT_AIS_CHNL                  1
+
+#define CFG_BOW_SUPPORT_11N                     0
+
+#define CFG_BOW_RATE_LIMITATION                 1
+
+/*------------------------------------------------------------------------------
+ * Flags of Wi-Fi Direct support
+ *------------------------------------------------------------------------------
+ */
+#ifdef LINUX
+#ifdef CONFIG_X86
+#define CFG_ENABLE_WIFI_DIRECT          0
+#define CFG_SUPPORT_802_11W             0
+#else
+#define CFG_ENABLE_WIFI_DIRECT          1
+#define CFG_SUPPORT_802_11W             0	/*!< 0(default): Disable 802.11W */
+#endif
+#else
+#define CFG_ENABLE_WIFI_DIRECT              0
+#define CFG_SUPPORT_802_11W                 0	/* Not support at WinXP */
+#endif
+
+#define CFG_SUPPORT_PERSISTENT_GROUP     0
+
+#define CFG_TEST_WIFI_DIRECT_GO                 0
+
+#define CFG_TEST_ANDROID_DIRECT_GO              0
+
+#define CFG_UNITEST_P2P                         0
+
+/*
+ * Enable cfg80211 option after Android 2.2(Froyo) is suggested,
+ * cfg80211 on linux 2.6.29 is not mature yet
+ */
+#define CFG_ENABLE_WIFI_DIRECT_CFG_80211        1
+
+#define CFG_SUPPORT_HOTSPOT_OPTIMIZATION                1
+#define     CFG_HOTSPOT_OPTIMIZATION_BEACON_INTERVAL    300
+#define     CFG_HOTSPOT_OPTIMIZATION_DTIM               1
+
+/*------------------------------------------------------------------------------
+ * Configuration Flags (Linux Only)
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SUPPORT_EXT_CONFIG                  0
+
+/*------------------------------------------------------------------------------
+ * Statistics Buffering Mechanism
+ *------------------------------------------------------------------------------
+ */
+#if CFG_SUPPORT_PERFORMANCE_TEST
+#define CFG_ENABLE_STATISTICS_BUFFERING         1
+#else
+#define CFG_ENABLE_STATISTICS_BUFFERING         0
+#endif
+#define CFG_STATISTICS_VALID_CYCLE              2000
+#define CFG_LINK_QUALITY_VALID_PERIOD           5000
+
+/*------------------------------------------------------------------------------
+ * Migration Option
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SUPPORT_ADHOC                       0
+#define CFG_SUPPORT_AAA                         1
+
+#define CFG_SUPPORT_BCM                         0
+#define CFG_SUPPORT_BCM_BWCS                    0
+#define CFG_SUPPORT_BCM_BWCS_DEBUG              0
+
+#define CFG_SUPPORT_RDD_TEST_MODE       0
+
+#define CFG_SUPPORT_PWR_MGT                     1
+
+#define CFG_RSN_MIGRATION                       1
+
+#define CFG_PRIVACY_MIGRATION                   1
+
+#define CFG_ENABLE_HOTSPOT_PRIVACY_CHECK        1
+
+#define CFG_MGMT_FRAME_HANDLING                 1
+
+#define CFG_MGMT_HW_ACCESS_REPLACEMENT          0
+
+#if CFG_SUPPORT_PERFORMANCE_TEST
+
+#else
+
+#endif
+
+#define CFG_SUPPORT_AIS_5GHZ                    1
+#define CFG_SUPPORT_BEACON_CHANGE_DETECTION     0
+
+/*------------------------------------------------------------------------------
+ * Option for NVRAM and Version Checking
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SUPPORT_NVRAM                       1
+#define CFG_NVRAM_EXISTENCE_CHECK               1
+#define CFG_SW_NVRAM_VERSION_CHECK              1
+#define CFG_SUPPORT_NIC_CAPABILITY              1
+
+/*------------------------------------------------------------------------------
+ * CONFIG_TITLE : Stress Test Option
+ * OWNER        : Puff Wen
+ * Description  : For stress test only. DO NOT enable it while normal operation
+ *------------------------------------------------------------------------------
+ */
+#define CFG_STRESS_TEST_SUPPORT                 0
+
+/*------------------------------------------------------------------------------
+ * Flags for LINT
+ *------------------------------------------------------------------------------
+ */
+#define LINT_SAVE_AND_DISABLE	/*lint -save -e* */
+
+#define LINT_RESTORE		/*lint -restore */
+
+#define LINT_EXT_HEADER_BEGIN                   LINT_SAVE_AND_DISABLE
+
+#define LINT_EXT_HEADER_END                     LINT_RESTORE
+
+/*------------------------------------------------------------------------------
+ * Flags of Features
+ *------------------------------------------------------------------------------
+ */
+
+#define CFG_SUPPORT_QOS             1	/* Enable/disable QoS TX, AMPDU */
+#define CFG_SUPPORT_AMPDU_TX        1
+#define CFG_SUPPORT_AMPDU_RX        1
+#define CFG_SUPPORT_TSPEC           0	/* Enable/disable TS-related Action frames handling */
+#define CFG_SUPPORT_UAPSD           1
+#define CFG_SUPPORT_UL_PSMP         0
+
+#define CFG_SUPPORT_ROAMING         1	/* Roaming System */
+#define CFG_SUPPORT_SWCR            1
+
+#define CFG_SUPPORT_ANTI_PIRACY     1
+
+#define CFG_SUPPORT_OSC_SETTING     1
+
+#define CFG_SUPPORT_P2P_RSSI_QUERY        0
+
+#define CFG_SHOW_MACADDR_SOURCE     1
+
+#define CFG_SUPPORT_802_11V                    0	/* Support 802.11v Wireless Network Management */
+#define CFG_SUPPORT_802_11V_TIMING_MEASUREMENT 0
+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (CFG_SUPPORT_802_11V == 0)
+#error "CFG_SUPPORT_802_11V should be 1 once CFG_SUPPORT_802_11V_TIMING_MEASUREMENT equals to 1"
+#endif
+#if (CFG_SUPPORT_802_11V == 0)
+#define WNM_UNIT_TEST 0
+#endif
+
+#define CFG_DRIVER_COMPOSE_ASSOC_REQ   1
+
+#define CFG_STRICT_CHECK_CAPINFO_PRIVACY    0
+
+#define CFG_SUPPORT_WFD                     1
+
+#define CFG_SUPPORT_WFD_COMPOSE_IE          1
+
+/*------------------------------------------------------------------------------
+ * Flags of Packet Lifetime Profiling Mechanism
+ *------------------------------------------------------------------------------
+ */
+#define CFG_ENABLE_PKT_LIFETIME_PROFILE     1
+
+#define CFG_ENABLE_PER_STA_STATISTICS       1
+
+#define CFG_PRINT_RTP_PROFILE               0	/* If want to enable WFD Debug, please change it to 1. */
+#define CFG_PRINT_RTP_SN_SKIP               0
+
+#define CFG_SUPPORT_PWR_LIMIT_COUNTRY       1
+/*------------------------------------------------------------------------------
+ * Flags of bus error tolerance
+ *------------------------------------------------------------------------------
+ */
+#define CFG_FORCE_RESET_UNDER_BUS_ERROR     0
+
+/*------------------------------------------------------------------------------
+ * Build Date Code Integration
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SUPPORT_BUILD_DATE_CODE 1
+
+/*------------------------------------------------------------------------------
+ * Flags for prepare the FW compile flag
+ *------------------------------------------------------------------------------
+ */
+#define COMPILE_FLAG0_GET_STA_LINK_STATUS     (1<<0)
+#define COMPILE_FLAG0_WFD_ENHANCEMENT_PROTECT (1<<1)
+
+/*------------------------------------------------------------------------------
+ * Flags of Batch Scan SUPPORT
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SUPPORT_BATCH_SCAN              0
+#define CFG_BATCH_MAX_MSCAN                 2
+
+/*------------------------------------------------------------------------------
+ * Flags of Channel Environment SUPPORT
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SUPPORT_GET_CH_ENV              1
+
+/*------------------------------------------------------------------------------
+ * Flags of  THERMO_THROTTLING SUPPORT
+ *------------------------------------------------------------------------------
+ */
+
+#define CFG_SUPPORT_THERMO_THROTTLING       1
+#define WLAN_INCLUDE_PROC                   1
+
+#define CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE 1
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CONFIG_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h
new file mode 100644
index 0000000000000..af586063c21af
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h
@@ -0,0 +1,466 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/debug.h#1
+*/
+
+/*! \file   debug.h
+    \brief  Definition of SW debugging level.
+
+    In this file, it describes the definition of various SW debugging levels and
+    assert functions.
+*/
+
+/*
+** Log: debug.h
+ *
+ * 12 16 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * fixed the Windows DDK free build compiling error.
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Using the new XLOG define for dum Memory.
+ *
+ * 11 03 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Add dumpMemory8 at XLOG support.
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 07 2011 wh.su
+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!!
+ * .
+ *
+ * 09 23 2010 cp.wu
+ * NULL
+ * add BOW index for debugging message and passing compilation
+ *
+ * 07 20 2010 wh.su
+ *
+ * adding the wapi code.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Support CFG_MQM_MIGRATION flag
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add one more debug moduel for P2P.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add bss.c.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add debug module index for cnm and ais.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add CFG_STARTUP_DEBUG for debugging starting up issue.
+ *
+ * 04 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) surpress compiler warning
+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-29 19:47:50 GMT mtk01084
+**  add emu category
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-17 18:12:04 GMT mtk01426
+**  Don't use dynamic memory allocate for debug message
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:29 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+#ifndef BUILD_QA_DBG
+#define BUILD_QA_DBG 0
+#endif
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_typedef.h"
+
+extern UINT_8 aucDebugModule[];
+extern UINT_32 u4DebugModule;
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* Define debug category (class):
+ * (1) ERROR (2) WARN (3) STATE (4) EVENT (5) TRACE (6) INFO (7) LOUD (8) TEMP
+ */
+#define DBG_CLASS_ERROR         BIT(0)
+#define DBG_CLASS_WARN          BIT(1)
+#define DBG_CLASS_STATE         BIT(2)
+#define DBG_CLASS_EVENT         BIT(3)
+#define DBG_CLASS_TRACE         BIT(4)
+#define DBG_CLASS_INFO          BIT(5)
+#define DBG_CLASS_LOUD          BIT(6)
+#define DBG_CLASS_TEMP          BIT(7)
+#define DBG_CLASS_MASK          BITS(0, 7)
+
+#if defined(LINUX)
+#define DBG_PRINTF_64BIT_DEC    "lld"
+
+#else /* Windows */
+#define DBG_PRINTF_64BIT_DEC    "I64d"
+
+#endif
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Define debug module index */
+typedef enum _ENUM_DBG_MODULE_T {
+	DBG_INIT_IDX = 0,	/* For driver initial */
+	DBG_HAL_IDX,		/* For HAL(HW) Layer */
+	DBG_INTR_IDX,		/* For Interrupt */
+	DBG_REQ_IDX,
+	DBG_TX_IDX,
+	DBG_RX_IDX,
+	DBG_RFTEST_IDX,		/* For RF test mode */
+	DBG_EMU_IDX,		/* Developer specific */
+
+	DBG_SW1_IDX,		/* Developer specific */
+	DBG_SW2_IDX,		/* Developer specific */
+	DBG_SW3_IDX,		/* Developer specific */
+	DBG_SW4_IDX,		/* Developer specific */
+
+	DBG_HEM_IDX,		/* HEM */
+	DBG_AIS_IDX,		/* AIS */
+	DBG_RLM_IDX,		/* RLM */
+	DBG_MEM_IDX,		/* RLM */
+	DBG_CNM_IDX,		/* CNM */
+	DBG_RSN_IDX,		/* RSN */
+	DBG_BSS_IDX,		/* BSS */
+	DBG_SCN_IDX,		/* SCN */
+	DBG_SAA_IDX,		/* SAA */
+	DBG_AAA_IDX,		/* AAA */
+	DBG_P2P_IDX,		/* P2P */
+	DBG_QM_IDX,		/* QUE_MGT */
+	DBG_SEC_IDX,		/* SEC */
+	DBG_BOW_IDX,		/* BOW */
+	DBG_WAPI_IDX,		/* WAPI */
+	DBG_ROAMING_IDX,	/* ROAMING */
+	DBG_TDLS_IDX,		/* TDLS *//* CFG_SUPPORT_TDLS */
+	DBG_OID_IDX,
+	DBG_NIC_IDX,
+
+	DBG_MODULE_NUM		/* Notice the XLOG check */
+} ENUM_DBG_MODULE_T;
+
+/* XLOG */
+/* #define XLOG_DBG_MODULE_IDX    28 */ /* DBG_MODULE_NUM */
+/* #if (XLOG_DBG_MODULE_IDX != XLOG_DBG_MODULE_IDX) */
+/* #error "Please modify the DBG_MODULE_NUM and make sure this include at XLOG" */
+/* #endif */
+
+/* Define who owns developer specific index */
+#define DBG_YARCO_IDX           DBG_SW1_IDX
+#define DBG_KEVIN_IDX           DBG_SW2_IDX
+#define DBG_CMC_IDX             DBG_SW3_IDX
+#define DBG_GEORGE_IDX          DBG_SW4_IDX
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/* Debug print format string for the OS system time */
+#define OS_SYSTIME_DBG_FORMAT               "0x%08x"
+
+/* Debug print argument for the OS system time */
+#define OS_SYSTIME_DBG_ARGUMENT(systime)    (systime)
+
+/* Debug print format string for the MAC Address */
+#define MACSTR          "%pM"
+/* "%02x:%02x:%02x:%02x:%02x:%02x" */
+
+/* Debug print argument for the MAC Address */
+#define MAC2STR(a)	a
+/* ((PUINT_8)a)[0], ((PUINT_8)a)[1], ((PUINT_8)a)[2], ((PUINT_8)a)[3], ((PUINT_8)a)[4], ((PUINT_8)a)[5] */
+
+/* The pre-defined format to dump the value of a varaible with its name shown. */
+#define DUMPVAR(variable, format)           (#variable " = " format "\n", variable)
+
+/* The pre-defined format to dump the MAC type value with its name shown. */
+#define DUMPMACADDR(addr)                   (#addr " = %pM\n", (addr))
+
+/* Basiclly, we just do renaming of KAL functions although they should
+ * be defined as "Nothing to do" if DBG=0. But in some compiler, the macro
+ * syntax does not support  #define LOG_FUNC(x,...)
+ *
+ * A caller shall not invoke these three macros when DBG=0.
+ */
+
+/*LOG_FUNC("[wlan]%s:(" #_Module " " #_Class ") "_Fmt, __func__, ##__VA_ARGS__);*/
+
+#define LOG_FUNC                kalPrint
+
+#if defined(LINUX)
+#define DBGLOG(_Module, _Class, _Fmt, ...) \
+	do { \
+		if ((aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) == 0) \
+			break; \
+		LOG_FUNC("%s:(" #_Module " " #_Class ")"_Fmt, __func__, ##__VA_ARGS__); \
+	} while (0)
+#else
+#define DBGLOG(_Module, _Class, _Fmt)
+#endif
+
+#if DBG
+
+#define TMP_BUF_LEN   256
+#define TMP_WBUF_LEN  (TMP_BUF_LEN * 2)
+
+extern PINT_16 g_wbuf_p;
+extern PINT_8 g_buf_p;
+
+    /* If __FUNCTION__ is already defined by compiler, we just use it. */
+#if defined(__func__)
+#define DEBUGFUNC(_Func)
+#else
+#define DEBUGFUNC(_Func) \
+	static const char __func__[] = _Func
+#endif
+
+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \
+	{ \
+	    if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \
+		LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \
+		dumpMemory8((PUINT_8) (_StartAddr), (UINT_32) (_Length)); \
+	    } \
+	}
+
+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) \
+	{ \
+	    if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \
+		LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \
+		dumpMemory32((PUINT_32) (_StartAddr), (UINT_32) (_Length)); \
+	    } \
+	}
+    /*lint -restore */
+
+    /*lint -save -e961 use of '#undef' is discouraged */
+#undef ASSERT
+    /*lint -restore */
+
+#ifdef _lint
+#define ASSERT(_exp) \
+	{ \
+		if (!(_exp)) { \
+			do {} while (1); \
+		} \
+	}
+#else
+#define ASSERT(_exp) \
+	{ \
+	    if (!(_exp) && !fgIsBusAccessFailed) { \
+		LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \
+		kalBreakPoint(); \
+	    } \
+	}
+#endif /* _lint */
+
+#define ASSERT_REPORT(_exp, _fmt) \
+	{ \
+	    if (!(_exp) && !fgIsBusAccessFailed) { \
+		LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \
+		LOG_FUNC _fmt; \
+		kalBreakPoint(); \
+	    } \
+	}
+
+#define DISP_STRING(_str)       _str
+
+#else /* !DBG */
+
+#define DEBUGFUNC(_Func)
+#define INITLOG(_Fmt)
+#define ERRORLOG(_Fmt)
+#define WARNLOG(_Fmt)
+
+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length)
+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length)
+
+#undef ASSERT
+
+#if BUILD_QA_DBG
+#if defined(LINUX)		/* For debugging in Linux w/o GDB */
+#define ASSERT(_exp) \
+	{ \
+		if (!(_exp) && !fgIsBusAccessFailed) { \
+			LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \
+			kalBreakPoint(); \
+		} \
+	}
+
+#define ASSERT_REPORT(_exp, _fmt) \
+	{ \
+		if (!(_exp) && !fgIsBusAccessFailed) { \
+			LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \
+			LOG_FUNC _fmt; \
+			kalBreakPoint(); \
+		} \
+	}
+#else
+#ifdef WINDOWS_CE
+#define UNICODE_TEXT(_msg)  TEXT(_msg)
+#define ASSERT(_exp) \
+		{ \
+		    if (!(_exp) && !fgIsBusAccessFailed) { \
+			TCHAR rUbuf[256]; \
+			kalBreakPoint(); \
+			_stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \
+			    UNICODE_TEXT(__FILE__), \
+			    __LINE__, \
+			    UNICODE_TEXT(#_exp)); \
+			MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \
+		    } \
+		}
+
+#define ASSERT_REPORT(_exp, _fmt) \
+		{ \
+		    if (!(_exp) && !fgIsBusAccessFailed) { \
+			TCHAR rUbuf[256]; \
+			kalBreakPoint(); \
+			_stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \
+			    UNICODE_TEXT(__FILE__), \
+			    __LINE__, \
+			    UNICODE_TEXT(#_exp)); \
+			MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \
+		    } \
+		}
+#else
+#define ASSERT(_exp) \
+		{ \
+		    if (!(_exp) && !fgIsBusAccessFailed) { \
+			kalBreakPoint(); \
+		    } \
+		}
+
+#define ASSERT_REPORT(_exp, _fmt) \
+		{ \
+		    if (!(_exp) && !fgIsBusAccessFailed) { \
+			kalBreakPoint(); \
+		    } \
+		}
+#endif /* WINDOWS_CE */
+#endif /* LINUX */
+#else
+#define ASSERT(_exp) \
+	{ \
+	    if (!(_exp) && !fgIsBusAccessFailed) { \
+		LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \
+	    } \
+	}
+
+#define ASSERT_REPORT(_exp, _fmt) \
+	{ \
+	    if (!(_exp) && !fgIsBusAccessFailed) { \
+		LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \
+		LOG_FUNC _fmt; \
+	    } \
+	}
+#endif /* BUILD_QA_DBG */
+
+#define DISP_STRING(_str)       ""
+
+#endif /* DBG */
+
+#if CFG_STARTUP_DEBUG
+#if defined(LINUX)
+#define DBGPRINTF kalPrint
+#else
+#define DBGPRINTF DbgPrint
+#endif
+#else
+#define DBGPRINTF(...)
+#endif
+
+/* The following macro is used for debugging packed structures. */
+#ifndef DATA_STRUCT_INSPECTING_ASSERT
+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \
+{ \
+	switch (0) {case 0: case (expr): default:; } \
+}
+#endif
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length);
+
+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length);
+
+VOID wlanDebugInit(VOID);
+VOID wlanDebugUninit(VOID);
+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable);
+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd);
+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen);
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _DEBUG_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h
new file mode 100644
index 0000000000000..108860c80e2d4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h
@@ -0,0 +1,368 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1
+*/
+
+/*! \file   link.h
+    \brief  Definition for simple doubly linked list operations.
+
+    In this file we define the simple doubly linked list data structure and its
+    operation MACROs and INLINE functions.
+*/
+
+/*
+** Log: link.h
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error.
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * [WPD00003833] [MT6620 and MT5931] Driver migration
+ * .
+ *
+ *
+ *
+ *
+ * May 4 2009 mtk01084
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * add WIFI to BORA source control
+**  \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461
+**  Update driver to fix lint warning
+**  \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461
+**  Update for Driver Review
+**  \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461
+**  Add macro for checking valid list
+**  \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461
+**  Add LINK_IS_INVALID macro
+** Revision 1.1.1.1  2007/06/22 08:09:05  MTK01461
+** no message
+**
+*/
+
+#ifndef _LINK_H
+#define _LINK_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_typedef.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* May cause page fault & unalignment issue (data abort) */
+#define INVALID_LINK_POISON1    ((VOID *) 0x00100101)
+/* Used to verify that nonbody uses non-initialized link entries. */
+#define INVALID_LINK_POISON2    ((VOID *) 0x00100201)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Simple Doubly Linked List Structures - Entry Part */
+typedef struct _LINK_ENTRY_T {
+	struct _LINK_ENTRY_T *prNext, *prPrev;
+} LINK_ENTRY_T, *P_LINK_ENTRY_T;
+
+/* Simple Doubly Linked List Structures - List Part */
+typedef struct _LINK_T {
+	P_LINK_ENTRY_T prNext;
+	P_LINK_ENTRY_T prPrev;
+	UINT_32 u4NumElem;
+} LINK_T, *P_LINK_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#if 0				/* No one use it, temporarily mark it for [Lint - Info 773] */
+#define LINK_ADDR(rLink)        { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 }
+
+#define LINK_DECLARATION(rLink) \
+	struct _LINK_T rLink = LINK_ADDR(rLink)
+#endif
+
+#define LINK_INITIALIZE(prLink) \
+	do { \
+		((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \
+		((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \
+		((P_LINK_T)(prLink))->u4NumElem = 0; \
+	} while (0)
+
+#define LINK_ENTRY_INITIALIZE(prEntry) \
+	do { \
+		((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \
+		((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \
+	} while (0)
+
+#define LINK_ENTRY_INVALID(prEntry) \
+	do { \
+		((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \
+		((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \
+	} while (0)
+
+#define LINK_IS_EMPTY(prLink)           (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink))
+
+/* NOTE: We should do memory zero before any LINK been initiated, so we can check
+ * if it is valid before parsing the LINK.
+ */
+#define LINK_IS_INVALID(prLink)         (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL)
+
+#define LINK_IS_VALID(prLink)           (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL)
+
+#define LINK_ENTRY(ptr, type, member)   ENTRY_OF(ptr, type, member)
+
+/* Insert an entry into a link list's head */
+#define LINK_INSERT_HEAD(prLink, prEntry) \
+	{ \
+		linkAdd(prEntry, prLink); \
+		((prLink)->u4NumElem)++; \
+	}
+
+/* Append an entry into a link list's tail */
+#define LINK_INSERT_TAIL(prLink, prEntry) \
+	{ \
+		linkAddTail(prEntry, prLink); \
+		((prLink)->u4NumElem)++; \
+	}
+
+/* Peek head entry, but keep still in link list */
+#define LINK_PEEK_HEAD(prLink, _type, _member) \
+	( \
+		LINK_IS_EMPTY(prLink) ? \
+		NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \
+	)
+
+/* Peek tail entry, but keep still in link list */
+#define LINK_PEEK_TAIL(prLink, _type, _member) \
+	( \
+		LINK_IS_EMPTY(prLink) ? \
+		NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \
+	)
+
+/* Get first entry from a link list */
+/* NOTE: We assume the link entry located at the beginning of "prEntry Type",
+ * so that we can cast the link entry to other data type without doubts.
+ * And this macro also decrease the total entry count at the same time.
+ */
+#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \
+	{ \
+		ASSERT(prLink); \
+		if (LINK_IS_EMPTY(prLink)) { \
+			prEntry = (_P_TYPE)NULL; \
+		} \
+		else { \
+			prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \
+			linkDel((P_LINK_ENTRY_T)prEntry); \
+			((prLink)->u4NumElem)--; \
+		} \
+	}
+
+/* Assume the link entry located at the beginning of prEntry Type.
+ * And also decrease the total entry count.
+ */
+#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \
+	{ \
+		ASSERT(prLink); \
+		ASSERT(prEntry); \
+		linkDel((P_LINK_ENTRY_T)prEntry); \
+		((prLink)->u4NumElem)--; \
+	}
+
+/* Iterate over a link list */
+#define LINK_FOR_EACH(prEntry, prLink) \
+	for (prEntry = (prLink)->prNext; \
+		prEntry != (P_LINK_ENTRY_T)(prLink); \
+		prEntry = (P_LINK_ENTRY_T)prEntry->prNext)
+
+/* Iterate over a link list backwards */
+#define LINK_FOR_EACH_PREV(prEntry, prLink) \
+	for (prEntry = (prLink)->prPrev; \
+		prEntry != (P_LINK_ENTRY_T)(prLink); \
+		prEntry = (P_LINK_ENTRY_T)prEntry->prPrev)
+
+/* Iterate over a link list safe against removal of link entry */
+#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \
+	for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \
+		prEntry != (P_LINK_ENTRY_T)(prLink); \
+		prEntry = prNextEntry, prNextEntry = prEntry->prNext)
+
+/* Iterate over a link list of given type */
+#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \
+	for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \
+		&prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
+		prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember))
+
+/* Iterate backwards over a link list of given type */
+#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \
+	for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember);  \
+		&prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
+		prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember))
+
+/* Iterate over a link list of given type safe against removal of link entry */
+#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \
+	for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember),  \
+				prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \
+		&prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
+		prObj = prNextObj, \
+		prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember))
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is only for internal link list manipulation.
+*
+* \param[in] prNew  Pointer of new link head
+* \param[in] prPrev Pointer of previous link head
+* \param[in] prNext Pointer of next link head
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID __linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext)
+{
+	prNext->prPrev = prNew;
+	prNew->prNext = prNext;
+	prNew->prPrev = prPrev;
+	prPrev->prNext = prNew;
+
+}				/* end of __linkAdd() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will add a new entry after the specified link head.
+*
+* \param[in] prNew  New entry to be added
+* \param[in] prHead Specified link head to add it after
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink)
+{
+	__linkAdd(prNew, (P_LINK_ENTRY_T) prLink, prLink->prNext);
+
+}				/* end of linkAdd() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will add a new entry before the specified link head.
+*
+* \param[in] prNew  New entry to be added
+* \param[in] prHead Specified link head to add it before
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID linkAddTail(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink)
+{
+	__linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T) prLink);
+
+}				/* end of linkAddTail() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is only for internal link list manipulation.
+*
+* \param[in] prPrev Pointer of previous link head
+* \param[in] prNext Pointer of next link head
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID __linkDel(IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext)
+{
+	prNext->prPrev = prPrev;
+	prPrev->prNext = prNext;
+
+}				/* end of __linkDel() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will delete a specified entry from link list.
+*        NOTE: the entry is in an initial state.
+*
+* \param prEntry    Specified link head(entry)
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID linkDel(IN P_LINK_ENTRY_T prEntry)
+{
+	__linkDel(prEntry->prPrev, prEntry->prNext);
+
+	LINK_ENTRY_INITIALIZE(prEntry);
+
+}				/* end of linkDel() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will delete a specified entry from link list and then add it
+*        after the specified link head.
+*
+* \param[in] prEntry        Specified link head(entry)
+* \param[in] prOtherHead    Another link head to add it after
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID linkMove(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink)
+{
+	__linkDel(prEntry->prPrev, prEntry->prNext);
+	linkAdd(prEntry, prLink);
+
+}				/* end of linkMove() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will delete a specified entry from link list and then add it
+*        before the specified link head.
+*
+* \param[in] prEntry        Specified link head(entry)
+* \param[in] prOtherHead    Another link head to add it before
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID linkMoveTail(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink)
+{
+	__linkDel(prEntry->prPrev, prEntry->prNext);
+	linkAddTail(prEntry, prLink);
+
+}				/* end of linkMoveTail() */
+
+#endif /* _LINK_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h
new file mode 100644
index 0000000000000..fd83c79ffe103
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h
@@ -0,0 +1,188 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/aa_fsm.h#1
+*/
+
+/*! \file   aa_fsm.h
+    \brief  Declaration of functions and finite state machine for SAA/AAA Module.
+
+    Declaration of functions and finite state machine for SAA/AAA Module.
+*/
+
+/*
+** Log: aa_fsm.h
+ *
+ * 10 13 2011 cp.wu
+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS
+ * 1. short join failure count limit to 2
+ * 2. treat join timeout as kind of join failure as well
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * refine TX-DONE callback.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h.
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * Nov 24 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Revise MGMT Handler with Retain Status
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+#ifndef _AA_FSM_H
+#define _AA_FSM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* Retry interval for retransmiting authentication-request MMPDU. */
+#define TX_AUTHENTICATION_RETRY_TIMEOUT_TU          100	/* TU. */
+
+/* Retry interval for retransmiting association-request MMPDU. */
+#define TX_ASSOCIATION_RETRY_TIMEOUT_TU             100	/* TU. */
+
+/* Wait for a response to a transmitted authentication-request MMPDU. */
+#define DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU    512	/* TU. */
+
+/* Wait for a response to a transmitted association-request MMPDU. */
+#define DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU       512	/* TU. */
+
+/* The maximum time to wait for JOIN process complete. */
+#define JOIN_FAILURE_TIMEOUT_BEACON_INTERVAL        20	/* Beacon Interval, 20 * 100TU = 2 sec. */
+
+/* Retry interval for next JOIN request. */
+#define JOIN_RETRY_INTERVAL_SEC                     10	/* Seconds */
+
+/* Maximum Retry Count for accept a JOIN request. */
+#define JOIN_MAX_RETRY_FAILURE_COUNT                2	/* Times */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_AA_STATE_T {
+	AA_STATE_IDLE = 0,
+	SAA_STATE_SEND_AUTH1,
+	SAA_STATE_WAIT_AUTH2,
+	SAA_STATE_SEND_AUTH3,
+	SAA_STATE_WAIT_AUTH4,
+	SAA_STATE_SEND_ASSOC1,
+	SAA_STATE_WAIT_ASSOC2,
+	AAA_STATE_SEND_AUTH2,
+	AAA_STATE_SEND_AUTH4,	/* We may not use, because P2P GO didn't support WEP and 11r */
+	AAA_STATE_SEND_ASSOC2,
+	AA_STATE_RESOURCE,	/* A state for debugging the case of out of msg buffer. */
+	AA_STATE_NUM
+} ENUM_AA_STATE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines in saa_fsm.c                                                      */
+/*----------------------------------------------------------------------------*/
+VOID
+saaFsmSteps(IN P_ADAPTER_T prAdapter,
+	    IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb);
+
+WLAN_STATUS
+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter,
+			    WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb);
+
+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+WLAN_STATUS
+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+/*----------------------------------------------------------------------------*/
+/* Routines in aaa_fsm.c                                                      */
+/*----------------------------------------------------------------------------*/
+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS
+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _AA_FSM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h
new file mode 100644
index 0000000000000..b771bdacf2c62
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h
@@ -0,0 +1,573 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/ais_fsm.h#1
+*/
+
+/*! \file   ais_fsm.h
+    \brief  Declaration of functions and finite state machine for AIS Module.
+
+    Declaration of functions and finite state machine for AIS Module.
+*/
+
+/*
+** Log: ais_fsm.h
+ *
+ * 11 22 2011 cp.wu
+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition
+ * from synchronous to asynchronous approach to avoid incomplete state termination
+ * 1. change RDD related compile option brace position.
+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS
+ * is in Normal TR state without join timeout timer ticking
+ * 3. otherwise, insert AIS_REQUEST into pending request queue
+ *
+ * 04 25 2011 cp.wu
+ * [WCXRP00000676] [MT6620 Wi-Fi][Driver] AIS to reduce request channel period from 5 seconds to 2 seconds
+ * channel interval for joining is shortened to 2 seconds to avoid interruption of concurrent operating network.
+ *
+ * 02 26 2011 tsaiyuan.hsu
+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support
+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming.
+ *
+ * 02 22 2011 cp.wu
+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with
+ * a queue-based approach to improve response time for scanning request
+ * handle SCAN and RECONNECT with a FIFO approach.
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 14 2011 cp.wu
+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent
+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS.
+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol.
+ *
+ * 11 25 2010 cp.wu
+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM
+ * add scanning with specified SSID facility to AIS-FSM
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 09 06 2010 cp.wu
+ * NULL
+ * 1) initialize for correct parameter even for disassociation.
+ * 2) AIS-FSM should have a limit on trials to build connection
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 25 2010 cp.wu
+ * NULL
+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, RLM/CNM will handle
+ * the channel switching when BSS information is updated
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse()
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 07 30 2010 cp.wu
+ * NULL
+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
+ *
+ * 07 26 2010 cp.wu
+ *
+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period,
+ * just pend it til 5-sec. period finishes
+ *
+ * 07 26 2010 cp.wu
+ *
+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet
+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found
+ *
+ * 07 23 2010 cp.wu
+ *
+ * add AIS-FSM handling for beacon timeout event.
+ *
+ * 07 21 2010 cp.wu
+ *
+ * separate AIS-FSM states into different cases of channel request.
+ *
+ * 07 21 2010 cp.wu
+ *
+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term
+ * 2) only clear scanning result when scan is permitted to do
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Add Ad-Hoc support to AIS-FSM
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Refine AIS-FSM by divided into more states
+ *
+ * 07 09 2010 cp.wu
+ *
+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
+ * 3) implment DRV-SCN module, currently only accepts single scan request,
+ * other request will be directly dropped by returning BUSY
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * AIS-FSM integration with CNM channel request messages
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add definitions for module migration.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h.
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 23 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * reduce the background ssid idle time min and max value
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support
+ *  *  and will send Null frame to diagnose connection
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ *  * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Support dynamic channel selection
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 07 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add Media disconnect indication and related postpone functions
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add aisFsmRunEventJoinComplete()
+ *
+ * Nov 25 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add Virtual CMD & RESP for testing CMD PATH
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * add aisFsmInitializeConnectionSettings()
+ *
+ * Nov 20 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add CFG_TEST_MGMT_FSM for aisFsmTest()
+ *
+ * Nov 18 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add function prototype of aisFsmInit()
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+#ifndef _AIS_FSM_H
+#define _AIS_FSM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define AIS_BG_SCAN_INTERVAL_MIN_SEC        2	/* 30 // exponential to 960 */
+#define AIS_BG_SCAN_INTERVAL_MAX_SEC        2	/* 960 // 16min */
+
+#define AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4 2	/* 2.4G scan need about 0.5s, so delay 2s to reconnect is enough */
+#define AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND 5	/* 2.4G scan need about 3.3s, so delay 5s to reconnect is enough */
+
+#define AIS_IBSS_ALONE_TIMEOUT_SEC          20	/* seconds */
+
+#define AIS_BEACON_TIMEOUT_COUNT_ADHOC      30
+#define AIS_BEACON_TIMEOUT_COUNT_INFRA      10
+#define AIS_BEACON_TIMEOUT_GUARD_TIME_SEC   1	/* Second */
+
+#define AIS_BEACON_MAX_TIMEOUT_TU           100
+#define AIS_BEACON_MIN_TIMEOUT_TU           5
+#define AIS_BEACON_MAX_TIMEOUT_VALID        TRUE
+#define AIS_BEACON_MIN_TIMEOUT_VALID        TRUE
+
+#define AIS_BMC_MAX_TIMEOUT_TU              100
+#define AIS_BMC_MIN_TIMEOUT_TU              5
+#define AIS_BMC_MAX_TIMEOUT_VALID           TRUE
+#define AIS_BMC_MIN_TIMEOUT_VALID           TRUE
+
+#define AIS_JOIN_CH_GRANT_THRESHOLD         10
+#define AIS_JOIN_CH_REQUEST_INTERVAL        3000
+
+#define AIS_SCN_DONE_TIMEOUT_SEC            30	/* 15 for 2.4G + 5G */ /* 5 */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_AIS_STATE_T {
+	AIS_STATE_IDLE = 0,
+	AIS_STATE_SEARCH,
+	AIS_STATE_SCAN,
+	AIS_STATE_ONLINE_SCAN,
+	AIS_STATE_LOOKING_FOR,
+	AIS_STATE_WAIT_FOR_NEXT_SCAN,
+	AIS_STATE_REQ_CHANNEL_JOIN,
+	AIS_STATE_JOIN,
+	AIS_STATE_IBSS_ALONE,
+	AIS_STATE_IBSS_MERGE,
+	AIS_STATE_NORMAL_TR,
+	AIS_STATE_DISCONNECTING,
+	AIS_STATE_REQ_REMAIN_ON_CHANNEL,
+	AIS_STATE_REMAIN_ON_CHANNEL,
+	AIS_STATE_NUM
+} ENUM_AIS_STATE_T;
+
+typedef struct _MSG_AIS_ABORT_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucReasonOfDisconnect;
+	BOOLEAN fgDelayIndication;
+} MSG_AIS_ABORT_T, *P_MSG_AIS_ABORT_T;
+
+typedef struct _MSG_AIS_IBSS_PEER_FOUND_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucNetTypeIndex;
+	BOOLEAN fgIsMergeIn;	/* TRUE: Merge In, FALSE: Merge Out */
+	P_STA_RECORD_T prStaRec;
+} MSG_AIS_IBSS_PEER_FOUND_T, *P_MSG_AIS_IBSS_PEER_FOUND_T;
+
+typedef enum _ENUM_AIS_REQUEST_TYPE_T {
+	AIS_REQUEST_SCAN,
+	AIS_REQUEST_RECONNECT,
+	AIS_REQUEST_ROAMING_SEARCH,
+	AIS_REQUEST_ROAMING_CONNECT,
+	AIS_REQUEST_REMAIN_ON_CHANNEL,
+	AIS_REQUEST_NUM
+} ENUM_AIS_REQUEST_TYPE_T;
+
+typedef struct _AIS_REQ_HDR_T {
+	LINK_ENTRY_T rLinkEntry;
+	ENUM_AIS_REQUEST_TYPE_T eReqType;
+} AIS_REQ_HDR_T, *P_AIS_REQ_HDR_T;
+
+typedef struct _AIS_REQ_CHNL_INFO {
+	ENUM_BAND_T eBand;
+	ENUM_CHNL_EXT_T eSco;
+	UINT_8 ucChannelNum;
+	UINT_32 u4DurationMs;
+	UINT_64 u8Cookie;
+} AIS_REQ_CHNL_INFO, *P_AIS_REQ_CHNL_INFO;
+
+typedef struct _AIS_MGMT_TX_REQ_INFO_T {
+	BOOLEAN fgIsMgmtTxRequested;
+	P_MSDU_INFO_T prMgmtTxMsdu;
+	UINT_64 u8Cookie;
+} AIS_MGMT_TX_REQ_INFO_T, *P_AIS_MGMT_TX_REQ_INFO_T;
+
+typedef struct _AIS_FSM_INFO_T {
+	ENUM_AIS_STATE_T ePreviousState;
+	ENUM_AIS_STATE_T eCurrentState;
+
+	BOOLEAN fgTryScan;
+
+	BOOLEAN fgIsInfraChannelFinished;
+	BOOLEAN fgIsChannelRequested;
+	BOOLEAN fgIsChannelGranted;
+
+#if CFG_SUPPORT_ROAMING
+	BOOLEAN fgIsRoamingScanPending;
+#endif				/* CFG_SUPPORT_ROAMING */
+
+	UINT_8 ucAvailableAuthTypes;	/* Used for AUTH_MODE_AUTO_SWITCH */
+
+	P_BSS_DESC_T prTargetBssDesc;	/* For destination */
+
+	P_STA_RECORD_T prTargetStaRec;	/* For JOIN Abort */
+
+	UINT_32 u4SleepInterval;
+
+	TIMER_T rBGScanTimer;
+
+	TIMER_T rIbssAloneTimer;
+
+	TIMER_T rIndicationOfDisconnectTimer;
+
+	TIMER_T rJoinTimeoutTimer;
+
+	TIMER_T rChannelTimeoutTimer;
+
+	TIMER_T rScanDoneTimer;
+
+	TIMER_T rDeauthDoneTimer;
+
+	UINT_8 ucSeqNumOfReqMsg;
+	UINT_8 ucSeqNumOfChReq;
+	UINT_8 ucSeqNumOfScanReq;
+
+	UINT_32 u4ChGrantedInterval;
+
+	UINT_8 ucConnTrialCount;
+
+	UINT_8 ucScanSSIDLen;
+	UINT_8 aucScanSSID[ELEM_MAX_LEN_SSID];
+
+	UINT_32 u4ScanIELength;
+	UINT_8 aucScanIEBuf[MAX_IE_LENGTH];
+
+	/* Pending Request List */
+	LINK_T rPendingReqList;
+
+	/* Join Request Timestamp */
+	OS_SYSTIME rJoinReqTime;
+
+	/* for cfg80211 REMAIN_ON_CHANNEL support */
+	AIS_REQ_CHNL_INFO rChReqInfo;
+
+	/* Mgmt tx related. */
+	AIS_MGMT_TX_REQ_INFO_T rMgmtTxInfo;
+
+	/* Packet filter for AIS module. */
+	UINT_32 u4AisPacketFilter;
+
+} AIS_FSM_INFO_T, *P_AIS_FSM_INFO_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define aisChangeMediaState(_prAdapter, _eNewMediaState) \
+	    (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState = (_eNewMediaState))
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo);
+
+VOID aisFsmInit(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc);
+
+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc);
+
+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication);
+
+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter);
+#if 0
+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState);
+#endif
+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState);
+
+/*----------------------------------------------------------------------------*/
+/* Mailbox Message Handling                                                   */
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+/*----------------------------------------------------------------------------*/
+/* Handling for Ad-Hoc Network                                                */
+/*----------------------------------------------------------------------------*/
+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+/*----------------------------------------------------------------------------*/
+/* Handling of Incoming Mailbox Message from CNM                              */
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+/*----------------------------------------------------------------------------*/
+/* Generating Outgoing Mailbox Message to CNM                                 */
+/*----------------------------------------------------------------------------*/
+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* Event Indication                                                           */
+/*----------------------------------------------------------------------------*/
+VOID
+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter,
+				ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication);
+
+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb);
+
+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter);
+
+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags);
+
+WLAN_STATUS
+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter,
+			      IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+/*----------------------------------------------------------------------------*/
+/* Disconnection Handling                                                     */
+/*----------------------------------------------------------------------------*/
+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication);
+
+/*----------------------------------------------------------------------------*/
+/* Event Handling                                                             */
+/*----------------------------------------------------------------------------*/
+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter);
+
+VOID aisBssSecurityChanged(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS
+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+#if CFG_SUPPORT_ROAMING
+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan);
+
+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter);
+
+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec);
+
+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb);
+#endif /*CFG_SUPPORT_ROAMING */
+
+/*----------------------------------------------------------------------------*/
+/* Timeout Handling                                                           */
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+/*----------------------------------------------------------------------------*/
+/* OID/IOCTL Handling                                                         */
+/*----------------------------------------------------------------------------*/
+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength);
+
+/*----------------------------------------------------------------------------*/
+/* Internal State Checking                                                    */
+/*----------------------------------------------------------------------------*/
+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove);
+
+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType);
+
+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS
+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter,
+		   IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie);
+
+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0)
+VOID aisTest(VOID);
+#endif /* CFG_TEST_MGMT_FSM */
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _AIS_FSM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h
new file mode 100644
index 0000000000000..70b32bca102bc
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h
@@ -0,0 +1,112 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/assoc.h#1
+*/
+
+/*! \file  assoc.h
+    \brief This file contains the ASSOC REQ/RESP of
+	   IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: assoc.h
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add assocCheckTxReAssocRespFrame() proto type for P2P usage.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+*/
+
+#ifndef _ASSOC_H
+#define _ASSOC_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines in assoc.c                                                        */
+/*----------------------------------------------------------------------------*/
+UINT_16 assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+WLAN_STATUS
+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode);
+
+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode);
+
+WLAN_STATUS
+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter,
+			    IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode);
+
+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode);
+
+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _ASSOC_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h
new file mode 100644
index 0000000000000..4f76f03324dde
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h
@@ -0,0 +1,125 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/auth.h#1
+*/
+
+/*! \file  auth.h
+    \brief This file contains the authentication REQ/RESP of
+	   IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: auth.h
+ *
+ * 04 21 2011 terry.wu
+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
+ * Add network type parameter to authSendAuthFrame.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+*/
+
+#ifndef _AUTH_H
+#define _AUTH_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines in auth.c                                                         */
+/*----------------------------------------------------------------------------*/
+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo);
+
+#if !CFG_SUPPORT_AAA
+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum);
+#else
+WLAN_STATUS
+authSendAuthFrame(IN P_ADAPTER_T prAdapter,
+		  IN P_STA_RECORD_T prStaRec,
+		  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+		  IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode);
+#endif /* CFG_SUPPORT_AAA */
+
+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum);
+
+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS
+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter,
+			   IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode);
+
+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr);
+
+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS
+authSendDeauthFrame(IN P_ADAPTER_T prAdapter,
+		    IN P_STA_RECORD_T prStaRec,
+		    IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler);
+
+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode);
+
+WLAN_STATUS
+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter,
+			IN P_SW_RFB_T prSwRfb,
+			IN UINT_8 aucExpectedBSSID[],
+			IN UINT_16 u2ExpectedAuthAlgNum,
+			IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _AUTH_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h
new file mode 100644
index 0000000000000..5995d133a6cdf
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h
@@ -0,0 +1,184 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/bow_fsm.h#1
+*/
+
+/*! \file   bow_fsm.h
+    \brief  Declaration of functions and finite state machine for BOW Module.
+
+    Declaration of functions and finite state machine for BOW Module.
+*/
+
+/*
+** Log: bow_fsm.h
+ *
+ * 05 22 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Submit missing BoW header files.
+ *
+ * 03 27 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support multiple physical link.
+ *
+ * 02 16 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add bowNotifyAllLinkDisconnected  interface and change channel grant procedure for bow starting..
+ *
+ * 02 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add channel previledge into _BOW_FSM_INFO_T.
+ *
+ * 09 16 2010 chinghwa.yu
+ * NULL
+ * update bowChangeMediaState.
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Update BOW for the 1st time.
+ */
+
+#ifndef _BOW_FSM_H
+#define _BOW_FSM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define BOW_BG_SCAN_INTERVAL_MIN_SEC        2	/* 30 // exponential to 960 */
+#define BOW_BG_SCAN_INTERVAL_MAX_SEC        2	/* 960 // 16min */
+
+#define BOW_DELAY_TIME_OF_DISCONNECT_SEC    10
+
+#define BOW_BEACON_TIMEOUT_COUNT_STARTING   10
+#define BOW_BEACON_TIMEOUT_GUARD_TIME_SEC   1	/* Second */
+
+#define BOW_BEACON_MAX_TIMEOUT_TU           100
+#define BOW_BEACON_MIN_TIMEOUT_TU           5
+#define BOW_BEACON_MAX_TIMEOUT_VALID        TRUE
+#define BOW_BEACON_MIN_TIMEOUT_VALID        TRUE
+
+#define BOW_BMC_MAX_TIMEOUT_TU              100
+#define BOW_BMC_MIN_TIMEOUT_TU              5
+#define BOW_BMC_MAX_TIMEOUT_VALID           TRUE
+#define BOW_BMC_MIN_TIMEOUT_VALID           TRUE
+
+#define BOW_JOIN_CH_GRANT_THRESHOLD         10
+#define BOW_JOIN_CH_REQUEST_INTERVAL        2000
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _ENUM_BOW_STATE_T {
+	BOW_STATE_IDLE = 0,
+	BOW_STATE_SEARCH,
+	BOW_STATE_SCAN,
+	BOW_STATE_ONLINE_SCAN,
+	BOW_STATE_LOOKING_FOR,
+	BOW_STATE_WAIT_FOR_NEXT_SCAN,
+	BOW_STATE_REQ_CHANNEL_JOIN,
+	BOW_STATE_REQ_CHANNEL_ALONE,
+	BOW_STATE_REQ_CHANNEL_MERGE,
+	BOW_STATE_JOIN,
+	BOW_STATE_IBSS_ALONE,
+	BOW_STATE_IBSS_MERGE,
+	BOW_STATE_NORMAL_TR,
+	BOW_STATE_NUM
+} ENUM_BOW_STATE_T;
+
+typedef struct _BOW_FSM_INFO_T {
+	ENUM_BOW_STATE_T ePreviousState;
+	ENUM_BOW_STATE_T eCurrentState;
+
+	BOOLEAN fgTryScan;
+
+	/* Channel Privilege */
+
+	BOOLEAN fgIsInfraChannelFinished;
+	BOOLEAN fgIsChannelRequested;
+	BOOLEAN fgIsChannelGranted;
+	BOOLEAN fgIsScanPending;
+	UINT_32 u4ChGrantedInterval;
+
+	UINT_8 ucPrimaryChannel;
+	ENUM_BAND_T eBand;
+	UINT_16 u2BeaconInterval;
+
+	ENUM_BOW_STATE_T eReturnState;	/* Return state after current activity finished or abort. */
+	ENUM_BOW_STATE_T eForwardState;	/* Step to next state if ACTION frame is TX successfully. */
+
+	P_BSS_DESC_T prTargetBss;	/* BSS of target P2P Device. For Connection/Service Discovery */
+
+	P_STA_RECORD_T prTargetStaRec;
+	P_BSS_DESC_T prTargetBssDesc;	/* For destination */
+
+	UINT_8 aucPeerAddress[6];
+
+	UINT_8 ucRole;
+
+	BOOLEAN fgSupportQoS;
+
+	BOOLEAN fgIsRsponseProbe;	/* Indicate if BOW can response probe request frame. */
+
+	/* Sequence number of requested message. */
+	UINT_8 ucSeqNumOfChReq;
+	UINT_8 ucSeqNumOfReqMsg;
+	UINT_8 ucSeqNumOfScnMsg;
+	UINT_8 ucSeqNumOfScanReq;
+
+	UINT_8 ucSeqNumOfCancelMsg;
+
+	UINT_8 ucDialogToken;
+
+	/* Timer */
+	TIMER_T rStartingBeaconTimer;	/* For device discovery time of each discovery request from user. */
+	TIMER_T rStartingDiscoveryTimer;
+	TIMER_T rOperationListenTimer;	/* For Find phase under operational state. */
+	TIMER_T rFSMTimer;	/* A timer used for Action frame timeout usage. */
+	TIMER_T rIndicationOfDisconnectTimer;
+	TIMER_T rChGrantedTimer;
+
+	UINT_8 ucAvailableAuthTypes;	/* Used for AUTH_MODE_AUTO_SWITCH */
+
+} BOW_FSM_INFO_T, *P_BOW_FSM_INFO_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define bowChangeMediaState(_prAdapter, _eNewMediaState) \
+	    (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].eConnectionState = (_eNewMediaState))
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h
new file mode 100644
index 0000000000000..0597132b970ef
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h
@@ -0,0 +1,265 @@
+/*
+** Id: @(#) bss.h
+*/
+
+/*! \file   "bss.h"
+    \brief  In this file we define the function prototype used in BSS/IBSS.
+
+    The file contains the function declarations and defines for used in BSS/IBSS.
+*/
+
+/*
+** Log: bss.h
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 09 14 2011 yuche.tsai
+ * NULL
+ * Add P2P IE in assoc response.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue
+ * Make assoc req to append P2P IE if wifi direct is enabled.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
+ * Add code to send beacon and probe response WSC IE at Auto GO.
+ *
+ * 02 23 2011 eddie.chen
+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap
+ * Fix parsing WMM INFO and bmp delivery bitmap definition.
+ *
+ * 01 31 2011 george.huang
+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers
+ * Extend TIM PVB, from 2 to 3 octets.
+ *
+ * 11 29 2010 cp.wu
+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for
+ * initial TX rate selection of auto-rate algorithm
+ * update ucRcpi of STA_RECORD_T for AIS when
+ * 1) Beacons for IBSS merge is received
+ * 2) Associate Response for a connecting peer is received
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Update bssProcessProbeRequest() and bssSendBeaconProbeResponse() declarations
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * when IBSS is being merged-in, send command packet to PM for connected indication
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 25 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Create beacon update path, with expose bssUpdateBeaconContent()
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add CTRL FLAGS for Probe Response.
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add necessary changes to driver data paths.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h.
+ *
+ * 06 04 2010 george.huang
+ * [BORA00000678][MT6620]WiFi LP integration
+ * [PM] Support U-APSD for STA mode
+ *
+ * 05 28 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList
+ *
+ * 05 14 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Remove unused typedef.
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Fix file merge error
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support
+ *  *  *  and will send Null frame to diagnose connection
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add DTIM count update while TX Beacon
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+*/
+
+#ifndef _BSS_H
+#define _BSS_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* NOTE(Kevin): change define for george */
+/* #define MAX_LEN_TIM_PARTIAL_BMP     (((MAX_ASSOC_ID + 1) + 7) / 8) */ /* Required bits = (MAX_ASSOC_ID + 1) */
+#define MAX_LEN_TIM_PARTIAL_BMP                     ((CFG_STA_REC_NUM + 7) / 8)
+/* reserve length greater than maximum size of STA_REC */	/* obsoleted: Assume we only use AID:1~15 */
+
+/* CTRL FLAGS for Probe Response */
+#define BSS_PROBE_RESP_USE_P2P_DEV_ADDR             BIT(0)
+#define BSS_PROBE_RESP_INCLUDE_P2P_IE               BIT(1)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define bssAssignAssocID(_prStaRec)      ((_prStaRec)->ucIndex + 1)
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines for all Operation Modes                                           */
+/*----------------------------------------------------------------------------*/
+P_STA_RECORD_T
+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter,
+			   IN ENUM_STA_TYPE_T eStaType,
+			   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc);
+
+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec);
+
+VOID
+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter,
+		       IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP);
+
+WLAN_STATUS
+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler);
+
+WLAN_STATUS
+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter,
+		    IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler);
+
+/*----------------------------------------------------------------------------*/
+/* Routines for both IBSS(AdHoc) and BSS(AP)                                  */
+/*----------------------------------------------------------------------------*/
+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID
+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr);
+
+VOID
+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer,
+					  IN PUINT_8 pucDestAddr,
+					  IN PUINT_8 pucOwnMACAddress,
+					  IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo);
+
+WLAN_STATUS
+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter,
+			   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+			   IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags);
+
+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo);
+
+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec);
+
+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec);
+
+/*----------------------------------------------------------------------------*/
+/* Routines for IBSS(AdHoc) only                                              */
+/*----------------------------------------------------------------------------*/
+VOID
+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter,
+			 IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI);
+
+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc);
+
+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo);
+
+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+/*----------------------------------------------------------------------------*/
+/* Routines for BSS(AP) only                                                  */
+/*----------------------------------------------------------------------------*/
+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate);
+
+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId);
+
+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr);
+
+/*link function to p2p module for txBcnIETable*/
+
+/* WMM-2.2.2 WMM ACI to AC coding */
+typedef enum _ENUM_ACI_T {
+	ACI_BE = 0,
+	ACI_BK = 1,
+	ACI_VI = 2,
+	ACI_VO = 3,
+	ACI_NUM
+} ENUM_ACI_T, *P_ENUM_ACI_T;
+
+typedef enum _ENUM_AC_PRIORITY_T {
+	AC_BK_PRIORITY = 0,
+	AC_BE_PRIORITY,
+	AC_VI_PRIORITY,
+	AC_VO_PRIORITY
+} ENUM_AC_PRIORITY_T, *P_ENUM_AC_PRIORITY_T;
+
+#endif /* _BSS_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h
new file mode 100644
index 0000000000000..81b16b5888672
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h
@@ -0,0 +1,258 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm.h#1
+*/
+
+/*! \file   "cnm.h"
+    \brief
+*/
+
+/*
+** Log: cnm.h
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * change parameter name from PeerAddr to BSSID
+ *
+ * 06 20 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * 1. specify target's BSSID when requesting channel privilege.
+ * 2. pass BSSID information to firmware domain
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 03 10 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Provide function to decide if BSS can be activated or not
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 13 2010 cm.chang
+ *
+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Need bandwidth info when requesting channel privilege
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Modify CNM message handler for new flow
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 05 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add a new function to send abort message
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 08 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support partial part about cmd basic configuration
+ *
+ * Nov 18 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add prototype of cnmFsmEventInit()
+ *
+ * Nov 2 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+#ifndef _CNM_H
+#define _CNM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _ENUM_CH_REQ_TYPE_T {
+	CH_REQ_TYPE_JOIN,
+	CH_REQ_TYPE_P2P_LISTEN,
+
+	CH_REQ_TYPE_NUM
+} ENUM_CH_REQ_TYPE_T, *P_ENUM_CH_REQ_TYPE_T;
+
+typedef struct _MSG_CH_REQ_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucTokenID;
+	UINT_8 ucPrimaryChannel;
+	ENUM_CHNL_EXT_T eRfSco;
+	ENUM_BAND_T eRfBand;
+	ENUM_CH_REQ_TYPE_T eReqType;
+	UINT_32 u4MaxInterval;	/* In unit of ms */
+	UINT_8 aucBSSID[6];
+	UINT_8 aucReserved[2];
+} MSG_CH_REQ_T, *P_MSG_CH_REQ_T;
+
+typedef struct _MSG_CH_ABORT_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucTokenID;
+} MSG_CH_ABORT_T, *P_MSG_CH_ABORT_T;
+
+typedef struct _MSG_CH_GRANT_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucTokenID;
+	UINT_8 ucPrimaryChannel;
+	ENUM_CHNL_EXT_T eRfSco;
+	ENUM_BAND_T eRfBand;
+	ENUM_CH_REQ_TYPE_T eReqType;
+	UINT_32 u4GrantInterval;	/* In unit of ms */
+} MSG_CH_GRANT_T, *P_MSG_CH_GRANT_T;
+
+typedef struct _MSG_CH_REOCVER_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucTokenID;
+	UINT_8 ucPrimaryChannel;
+	ENUM_CHNL_EXT_T eRfSco;
+	ENUM_BAND_T eRfBand;
+	ENUM_CH_REQ_TYPE_T eReqType;
+} MSG_CH_RECOVER_T, *P_MSG_CH_RECOVER_T;
+
+typedef struct _CNM_INFO_T {
+	UINT_32 u4Reserved;
+} CNM_INFO_T, *P_CNM_INFO_T;
+
+#if CFG_ENABLE_WIFI_DIRECT
+/* Moved from p2p_fsm.h */
+typedef struct _DEVICE_TYPE_T {
+	UINT_16 u2CategoryId;	/* Category ID */
+	UINT_8 aucOui[4];	/* OUI */
+	UINT_16 u2SubCategoryId;	/* Sub Category ID */
+} __KAL_ATTRIB_PACKED__ DEVICE_TYPE_T, *P_DEVICE_TYPE_T;
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID cnmInit(P_ADAPTER_T prAdapter);
+
+VOID cnmUninit(P_ADAPTER_T prAdapter);
+
+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr);
+
+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr);
+
+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent);
+
+BOOLEAN
+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO);
+
+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel);
+
+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter);
+
+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter);
+
+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter);
+
+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter);
+
+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx);
+#if CFG_P2P_LEGACY_COEX_REVISE
+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel);
+#endif
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#ifndef _lint
+/* We don't have to call following function to inspect the data structure.
+ * It will check automatically while at compile time.
+ * We'll need this to guarantee the same member order in different structures
+ * to simply handling effort in some functions.
+ */
+static inline VOID cnmMsgDataTypeCheck(VOID)
+{
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == 0);
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == OFFSET_OF(MSG_CH_RECOVER_T, rMsgHdr));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucNetTypeIndex) ==
+				     OFFSET_OF(MSG_CH_RECOVER_T, ucNetTypeIndex));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucTokenID) == OFFSET_OF(MSG_CH_RECOVER_T, ucTokenID));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucPrimaryChannel) ==
+				     OFFSET_OF(MSG_CH_RECOVER_T, ucPrimaryChannel));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfSco) == OFFSET_OF(MSG_CH_RECOVER_T, eRfSco));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfBand) == OFFSET_OF(MSG_CH_RECOVER_T, eRfBand));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eReqType) == OFFSET_OF(MSG_CH_RECOVER_T, eReqType));
+
+}
+#endif /* _lint */
+
+#endif /* _CNM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h
new file mode 100644
index 0000000000000..c8f25b1b29a9f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h
@@ -0,0 +1,1164 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_mem.h#1
+*/
+
+/*! \file   "cnm_mem.h"
+    \brief  In this file we define the structure of the control unit of
+	    packet buffer and MGT/MSG Memory Buffer.
+*/
+
+/*
+** Log: cnm_mem.h
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ * 03 17 2011 yuche.tsai
+ * NULL
+ * Resize the Secondary Device Type array when WiFi Direct is enabled.
+ *
+ * 03 16 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * enable the protected while at P2P start GO, and skip some security check .
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * .
+ *
+ * 01 11 2011 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * Add per STA flow control when STA is in PS mode
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 12 23 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * 1. update WMM IE parsing, with ASSOC REQ handling
+ * 2. extend U-APSD parameter passing from driver to FW
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 11 29 2010 cm.chang
+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for
+ * initial TX rate selection of auto-rate algorithm
+ * Sync RCPI of STA_REC to FW as reference of initial TX rate
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD
+ * when entering RF test with AIS associated
+ * 1. remove redundant variables in STA_REC structure
+ * 2. add STA-REC uninitialization routine for clearing pending events
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 12 2010 cp.wu
+ *
+ * SAA will take a record for tracking request sequence number.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 07 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support state of STA record change from 1 to 1
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support sync command of STA_REC
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * modify some code for concurrent network.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Fix compile error for P2P related defination.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add P2P related fields.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * saa_fsm.c is migrated.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * restore utility function invoking via hem_mbox to direct calls
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * hem_mbox is migrated.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration
+ *
+ * 06 04 2010 george.huang
+ * [BORA00000678][MT6620]WiFi LP integration
+ * [BORA00000678] [MT6620]WiFi LP integration
+ * 1. add u8TimeStamp in MSDU_INFO
+ * 2. move fgIsRxTSFUpdated/fgIsTxTSFUpdated from static to BSS_INFO
+ * 3. add new member for supporting PM in STA_RECORD, which is for AP PS mode
+ *
+ * 05 31 2010 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling
+ *
+ * 05 28 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support checking  of duplicated buffer free
+ *
+ * 05 28 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM
+ *
+ * 05 21 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set
+ *
+ * 05 19 2010 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Fixed MAC RX Desc be overwritten issue
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 05 10 2010 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support Rx header translation for A-MSDU subframe
+ *
+ * 05 07 2010 george.huang
+ * [BORA00000678][MT6620]WiFi LP integration
+ * add more sanity check about setting timer
+ *
+ * 04 29 2010 george.huang
+ * [BORA00000678][MT6620]WiFi LP integration
+ * modify the compiling flag for RAM usage
+ *
+ * 04 28 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Modified some MQM-related data structures (SN counter, TX/RX BA table)
+ *
+ * 04 27 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Added new TX/RX BA tables in STA_REC
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support and will send Null frame to diagnose connection
+ *
+ * 04 09 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * [BORA00000644] WiFi phase 4 integration
+ * Added per-TID SN cache in STA_REC
+ *
+ * 03 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support power control
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 11 2010 yuche.tsai
+ * [BORA00000343][MT6620] Emulation For TX
+ * .
+ *
+ * 03 05 2010 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Remove Emulation definition
+ *
+ * 03 04 2010 cp.wu
+ * [BORA00000368]Integrate HIF part into BORA
+ * eliminate HIF_EMULATION in cnm_mem.h
+ *
+ * 03 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add cnmStaRecChangeState() declaration.
+ *
+ * 03 03 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Remove compiling warning for some emulation flags
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * move the AIS specific variable for security to AIS specific structure.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * Fixed the pre-authentication timer not correctly init issue,
+ * and modify the security related callback function prototype.
+ *
+ * 03 01 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * To store field AMPDU Parameters in STA_REC
+ *
+ * 02 26 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added fgIsWmmSupported in STA_RECORD_T.
+ *
+ * 02 26 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added fgIsUapsdSupported in STA_RECORD_T
+ *
+ * 02 13 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added arTspecTable in STA_REC for TSPEC management
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Enable mgmt buffer debug by default
+ *
+ * 02 12 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added BUFFER_SOURCE_BCN
+ *
+ * 02 10 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Renamed MSDU_INFO.ucFixedRateIndex as MSDU_INFO.ucFixedRateCode
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 02 02 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added SN info in MSDU_INFO_T
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 08 2010 cp.wu
+ * [BORA00000368]Integrate HIF part into BORA
+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h
+ * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem
+ * 3) use cnmMemAlloc() instead to allocate SRAM buffer
+ *
+ * 12 31 2009 cp.wu
+ * [BORA00000368]Integrate HIF part into BORA
+ * 1) surpress debug message emitted from hal_hif.c
+ * 2) add two set of field for recording buffer process time
+ *
+ * 12 31 2009 cp.wu
+ * [BORA00000368]Integrate HIF part into BORA
+ * 1. move wifi task initialization from wifi_task.c(rom) to wifi_init.c (TCM) for integrating F/W download later
+ *  *  *  *  * 2. WIFI_Event_Dispatcher() prototype changed to return to suspend mode from normal operation mode
+ *  *  *  *  * 2. HIF emulation logic revised
+ *
+ * 12 29 2009 yuche.tsai
+ * [BORA00000343][MT6620] Emulation For TX
+ * .Using global buffer declaring by SD1 instead of using another one.
+ *
+ * 12 25 2009 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM)
+ *  * MQM: BA handling
+ *  * TXM: Macros updates
+ *  * RXM: Macros/Duplicate Removal updates
+ *
+ * 12 24 2009 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * 12 23 2009 cp.wu
+ * [BORA00000368]Integrate HIF part into BORA
+ * allocating SRAM for emulation purpose by ruducing MEM_BANK3_BUF_SZ
+ *
+ * 12 21 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Remove individual DATA_BUF_BLOCK_NUM definition for emulation compiling flagsu1rwduu`wvpghlqg|fh+fmdkb
+ *
+ * 12 21 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support several data buffer banks.
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .For new FPGA memory size
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * 12 17 2009 george.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 17 2009 MTK02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Modified the DATA_BLOCK_SIZE from 1620 to 2048
+ *
+ * Dec 16 2009 mtk01426
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add CFG_TEST_SEC_EMULATION flag
+ *
+ * Dec 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add HT cap to sta record
+ *
+ * Dec 9 2009 mtk02752
+ * [BORA00000368] Integrate HIF part into BORA
+ * add cnmDataPktFree() for emulation loopback purpose
+ *
+ * Dec 8 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * add the buffer for key handshake 1x and cmd key order issue
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * move the tx call back function proto type to typedef.h
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add cnmGetStaRecByAddress() and modify variable in STA_RECORD_T
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * rename the port block flag
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add variables to STA_RECORD_T for assoc/auth
+ *
+ * Nov 23 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Fixed the value of STA_WAIT_QUEUE_NUM (from 7 to 5)
+ *
+ * Nov 20 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Removed u2FrameLength from SW_RFB
+ *
+ * Nov 20 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Fixed indenting
+ *
+ * Nov 20 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Updated MSDU_INFO and SW_RFB
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * update the variable for security
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * remove the variable to make the compiler ok
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * add the variable for security module
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix typo in define of MSG_BUF_BLOCK_SIZE
+ *
+ * Nov 13 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Let typedef STA_REC_T precede typedef MSDU_INFO_T and SW_RFB_T
+ *
+ * Nov 13 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Modified MSDU_INFO and STA_REC for TXM and MQM
+ *
+ * Nov 12 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Rename STA_REC_T to STA_RECORD_T and add ucIndex member
+ *
+ * Nov 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Make sure ucBufferSource the same offset in MSDU_INFO and SW_RFB
+ *
+ * Nov 6 2009 mtk01426
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+ * Nov 5 2009 mtk01426
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Update comment
+ *
+ * Oct 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add draft content of MSDU_INFO_T and SW_RFB_T
+ *
+ * Oct 30 2009 mtk01084
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+ * Oct 28 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+ * Oct 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix lint warning
+ *
+ * Oct 21 2009 mtk01426
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add CFG_TEST_RX_EMULATION flag
+ *
+ * Oct 20 2009 mtk01426
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+ * Oct 9 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Added field ucTC to MSDU_INFO_T and field pucHifRxPacket to SW_RFB_T
+ *
+ * Oct 8 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+#ifndef _CNM_MEM_H
+#define _CNM_MEM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#ifndef POWER_OF_2
+#define POWER_OF_2(n)                           BIT(n)
+#endif
+
+/* Size of a basic management buffer block in power of 2 */
+#define MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2        7	/* 7 to the power of 2 = 128 */
+#define MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2        5	/* 5 to the power of 2 = 32 */
+
+/* Size of a basic management buffer block */
+#define MGT_BUF_BLOCK_SIZE                      POWER_OF_2(MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2)
+#define MSG_BUF_BLOCK_SIZE                      POWER_OF_2(MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2)
+
+/* Total size of (n) basic management buffer blocks */
+#define MGT_BUF_BLOCKS_SIZE(n)                  ((UINT_32)(n) << MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2)
+#define MSG_BUF_BLOCKS_SIZE(n)                  ((UINT_32)(n) << MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2)
+
+/* Number of management buffer block */
+#define MAX_NUM_OF_BUF_BLOCKS                   32	/* Range: 1~32 */
+
+/* Size of overall management frame buffer */
+#define MGT_BUFFER_SIZE                         (MAX_NUM_OF_BUF_BLOCKS * MGT_BUF_BLOCK_SIZE)
+#define MSG_BUFFER_SIZE                         (MAX_NUM_OF_BUF_BLOCKS * MSG_BUF_BLOCK_SIZE)
+
+/* STA_REC related definitions */
+#define STA_REC_INDEX_BMCAST        0xFF
+#define STA_REC_INDEX_NOT_FOUND     0xFE
+#define STA_WAIT_QUEUE_NUM          5	/* Number of SW queues in each STA_REC: AC0~AC4 */
+#define SC_CACHE_INDEX_NUM          5	/* Number of SC caches in each STA_REC: AC0~AC4 */
+
+/* P2P related definitions */
+#ifdef CFG_ENABLE_WIFI_DIRECT
+/* Moved from p2p_fsm.h */
+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME               32	/* 0x1011 */
+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT        8	/* NOTE(Kevin): Shall <= 16 */
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#if ((MAX_NUM_OF_BUF_BLOCKS > 32) || (MAX_NUM_OF_BUF_BLOCKS <= 0))
+#error > #define MAX_NUM_OF_MGT_BUF_BLOCKS : Out of boundary !
+#elif MAX_NUM_OF_BUF_BLOCKS > 16
+typedef UINT_32 BUF_BITMAP;
+#elif MAX_NUM_OF_BUF_BLOCKS > 8
+typedef UINT_16 BUF_BITMAP;
+#else
+typedef UINT_8 BUF_BITMAP;
+#endif /* MAX_NUM_OF_MGT_BUF_BLOCKS */
+
+/* Control variable of TX management memory pool */
+typedef struct _BUF_INFO_T {
+	PUINT_8 pucBuf;
+
+#if CFG_DBG_MGT_BUF
+	UINT_32 u4AllocCount;
+	UINT_32 u4FreeCount;
+	UINT_32 u4AllocNullCount;
+#endif				/* CFG_DBG_MGT_BUF */
+
+	BUF_BITMAP rFreeBlocksBitmap;
+	UINT_8 aucAllocatedBlockNum[MAX_NUM_OF_BUF_BLOCKS];
+} BUF_INFO_T, *P_BUF_INFO_T;
+
+/* Wi-Fi divides RAM into three types
+ * MSG:     Mailbox message (Small size)
+ * BUF:     HW DMA buffers (HIF/MAC)
+ */
+typedef enum _ENUM_RAM_TYPE_T {
+	RAM_TYPE_MSG = 0,
+	RAM_TYPE_BUF
+} ENUM_RAM_TYPE_T, P_ENUM_RAM_TYPE_T;
+
+typedef enum _ENUM_BUFFER_SOURCE_T {
+	BUFFER_SOURCE_HIF_TX0 = 0,
+	BUFFER_SOURCE_HIF_TX1,
+	BUFFER_SOURCE_MAC_RX,
+	BUFFER_SOURCE_MNG,
+	BUFFER_SOURCE_BCN,
+	BUFFER_SOURCE_NUM
+} ENUM_BUFFER_SOURCE_T, *P_ENUM_BUFFER_SOURCE_T;
+
+typedef enum _ENUM_SEC_STATE_T {
+	SEC_STATE_INIT,
+	SEC_STATE_INITIATOR_PORT_BLOCKED,
+	SEC_STATE_RESPONDER_PORT_BLOCKED,
+	SEC_STATE_CHECK_OK,
+	SEC_STATE_SEND_EAPOL,
+	SEC_STATE_SEND_DEAUTH,
+	SEC_STATE_COUNTERMEASURE,
+	SEC_STATE_NUM
+} ENUM_SEC_STATE_T;
+
+typedef struct _TSPEC_ENTRY_T {
+	UINT_8 ucStatus;
+	UINT_8 ucToken;		/* Dialog Token in ADDTS_REQ or ADDTS_RSP */
+	UINT_16 u2MediumTime;
+	UINT_32 u4TsInfo;
+	/* PARAM_QOS_TS_INFO rParamTsInfo; */
+	/* Add other retained QoS parameters below */
+} TSPEC_ENTRY_T, *P_TSPEC_ENTRY_T, TSPEC_TABLE_ENTRY_T, *P_TSPEC_TABLE_ENTRY_T;
+
+typedef struct _SEC_INFO_T {
+
+	ENUM_SEC_STATE_T ePreviousState;
+	ENUM_SEC_STATE_T eCurrentState;
+
+	BOOLEAN fg2nd1xSend;
+	BOOLEAN fgKeyStored;
+
+	UINT_8 aucStoredKey[64];
+
+	BOOLEAN fgAllowOnly1x;
+} SEC_INFO_T, *P_SEC_INFO_T;
+
+#define MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS     3
+
+#define UPDATE_BSS_RSSI_INTERVAL_SEC            3	/* Seconds */
+
+/* Fragment information structure */
+typedef struct _FRAG_INFO_T {
+	UINT_16 u2NextFragSeqCtrl;
+	PUINT_8 pucNextFragStart;
+	P_SW_RFB_T pr1stFrag;
+	OS_SYSTIME rReceiveLifetimeLimit;	/* The receive time of 1st fragment */
+} FRAG_INFO_T, *P_FRAG_INFO_T;
+
+typedef struct _STAT_CNT_INFO_FW_T {
+	UINT32 u4NumOfTx;	/* number of packets sent from host */
+	UINT32 u4NumOfTxOK;	/* number of packets sent to air OK */
+	UINT32 u4NumOfTxRetry;	/* number of packets sent to air RETRY */
+	UINT32 u4TxDoneAirTimeMax;	/* maximum tx done air time */
+
+	UINT32 u4NumOfPtiRspTxOk;	/* number of PTI RSP sent to air OK */
+	UINT32 u4NumOfPtiRspTxErr;	/* number of PTI RSP sent to air ERROR */
+
+	UINT32 u4NumOfTxErr;	/* number of packets sent to air ERROR */
+
+	UINT32 u4NumOfRx;	/* number of received packets */
+	UINT32 u4NumOfPtiRspRx;	/* number of PTI RSP rcv */
+
+#define STAT_CNT_INFO_TX_ERR_FLUSHED				0x00000001
+#define STAT_CNT_INFO_TX_ERR_AGE_TIMEOUT			0x00000002
+#define STAT_CNT_INFO_TX_ERR_MPDU					0x00000004
+#define STAT_CNT_INFO_TX_ERR_RTS					0x00000010
+#define STAT_CNT_INFO_TX_ERR_LIFETIME				0x00000020
+#define STAT_CNT_INFO_TX_ERR_UNKNOWN				0x80000000
+	UINT32 u4TxErrBitmap;	/* TX error type */
+
+#define STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM		10	/* TX OK history */
+	UINT8 aucTxRateOkHis[STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM][2];
+	UINT32 u4TxRateOkHisId;
+
+#define STAT_CNT_INFO_MAX_RATE_ID					(32)	/* MCS0 ~ MCS31 */
+	UINT32 aucTxRateMap[STAT_CNT_INFO_MAX_RATE_ID];
+	UINT32 aucRxRateMap[STAT_CNT_INFO_MAX_RATE_ID];
+
+	UINT8 aucStateHis[100][3];	/* State history */
+	UINT32 u4StateHisId;	/* history ID */
+} STAT_CNT_INFO_FW_T;
+
+typedef struct _STAT_CNT_INFO_DRV_T {
+
+	UINT32 u4NumOfTxFromOs;	/* number of packets sent from OS */
+	UINT32 u4NumOfTxQueFull;	/* number of packets dropped due to queue full */
+	UINT32 u4NumOfTxToFw;	/* number of packets sent to firmware */
+
+	STAT_CNT_INFO_FW_T rFw;
+} STAT_CNT_INFO_DRV_T;
+
+/* Define STA record structure */
+struct _STA_RECORD_T {
+	LINK_ENTRY_T rLinkEntry;
+	UINT_8 ucIndex;		/* Not modify it except initializing */
+
+	BOOLEAN fgIsInUse;	/* Indicate if this entry is in use or not */
+	UINT_8 aucMacAddr[MAC_ADDR_LEN];	/* MAC address */
+
+	/* SAA/AAA */
+	ENUM_AA_STATE_T eAuthAssocState;	/* Store STATE Value used in SAA/AAA */
+	UINT_8 ucAuthAssocReqSeqNum;
+
+	ENUM_STA_TYPE_T eStaType;	/* Indicate the role of this STA in
+					 * the network (for example, P2P GO)
+					 */
+
+	UINT_8 ucNetTypeIndex;	/* ENUM_NETWORK_TYPE_INDEX_T */
+
+	UINT_8 ucStaState;	/* STATE_1,2,3 */
+
+	UINT_8 ucPhyTypeSet;	/* Available PHY Type Set of this peer
+				 * (may deduced from received BSS_DESC_T)
+				 */
+	UINT_8 ucDesiredPhyTypeSet;	/* The match result by AND operation of peer's
+					 * PhyTypeSet and ours.
+					 */
+	BOOLEAN fgHasBasicPhyType;	/* A flag to indicate a Basic Phy Type which
+					 * is used to generate some Phy Attribute IE
+					 * (e.g. capability, MIB) during association.
+					 */
+	UINT_8 ucNonHTBasicPhyType;	/* The Basic Phy Type chosen among the
+					 * ucDesiredPhyTypeSet.
+					 */
+
+	UINT_16 u2CapInfo;	/* For Infra Mode, to store Capability Info. from Association Resp(SAA).
+				 * For AP Mode, to store Capability Info. from Association Req(AAA).
+				 */
+	UINT_16 u2AssocId;	/* For Infra Mode, to store AID from Association Resp(SAA).
+				 * For AP Mode, to store the Assigned AID(AAA).
+				 */
+
+	UINT_16 u2ListenInterval;	/* Listen Interval from STA(AAA) */
+
+	UINT_16 u2DesiredNonHTRateSet;	/* Our Current Desired Rate Set after
+					 * match with STA's Operational Rate Set
+					 */
+
+	UINT_16 u2OperationalRateSet;	/* Operational Rate Set of peer BSS */
+	UINT_16 u2BSSBasicRateSet;	/* Basic Rate Set of peer BSS */
+
+	BOOLEAN fgIsMerging;	/* For IBSS Mode, to indicate that Merge is ongoing */
+
+	BOOLEAN fgDiagnoseConnection;	/* For Infra/AP Mode, to diagnose the Connection with
+					 * this peer by sending ProbeReq/Null frame */
+
+    /*------------------------------------------------------------------------------------------*/
+	/* 802.11n HT capabilities when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) is true          */
+	/* They have the same definition with fields of information element                         */
+    /*------------------------------------------------------------------------------------------*/
+	UINT_8 ucMcsSet;	/* MCS0~7 rate set of peer BSS */
+	BOOLEAN fgSupMcs32;	/* MCS32 is supported by peer BSS */
+	UINT_16 u2HtCapInfo;	/* HT cap info field by HT cap IE */
+	UINT_8 ucAmpduParam;	/* Field A-MPDU Parameters in HT cap IE */
+	UINT_16 u2HtExtendedCap;	/* HT extended cap field by HT cap IE */
+	UINT_32 u4TxBeamformingCap;	/* TX beamforming cap field by HT cap IE */
+	UINT_8 ucAselCap;	/* ASEL cap field by HT cap IE */
+
+	UINT_8 ucRCPI;		/* RCPI of peer */
+
+	UINT_8 ucDTIMPeriod;	/* Target BSS's DTIM Period, we use this
+				 * value for setup Listen Interval
+				 * TODO(Kevin): TBD
+				 */
+	UINT_8 ucAuthAlgNum;	/* For Infra/AP Mode, the Auth Algorithm Num used in Authentication(SAA/AAA) */
+	BOOLEAN fgIsReAssoc;	/* For Infra/AP Mode, to indicate ReAssoc Frame was in used(SAA/AAA) */
+
+	UINT_8 ucTxAuthAssocRetryCount;	/* For Infra Mode, the Retry Count of TX Auth/Assod Frame(SAA) */
+	UINT_8 ucTxAuthAssocRetryLimit;	/* For Infra Mode, the Retry Limit of TX Auth/Assod Frame(SAA) */
+
+	UINT_16 u2StatusCode;	/* Status of Auth/Assoc Req */
+	UINT_16 u2ReasonCode;	/* Reason that been Deauth/Disassoc */
+
+	P_IE_CHALLENGE_TEXT_T prChallengeText;	/* Point to an allocated buffer for storing Challenge Text
+						 * for Shared Key Authentication
+						 */
+
+	TIMER_T rTxReqDoneOrRxRespTimer;	/* For Infra Mode, a timer used to send a timeout event
+						 * while waiting for TX request done or RX response.
+						 */
+
+    /*------------------------------------------------------------------------------------------*/
+	/* Power Management related fields  (for STA/ AP/ P2P/ BOW power saving mode) */
+    /*------------------------------------------------------------------------------------------*/
+	BOOLEAN fgSetPwrMgtBit;	/* For Infra Mode, to indicate that outgoing frame need toggle
+				 * the Pwr Mgt Bit in its Frame Control Field.
+				 */
+
+	BOOLEAN fgIsInPS;	/* For AP Mode, to indicate the client PS state(PM).
+				 * TRUE: In PS Mode; FALSE: In Active Mode. */
+
+	BOOLEAN fgIsInPsPollSP;	/* For Infra Mode, to indicate we've sent a PS POLL to AP and start
+				 * the PS_POLL Service Period(LP)
+				 */
+
+	BOOLEAN fgIsInTriggerSP;	/* For Infra Mode, to indicate we've sent a Trigger Frame to AP and start
+					 * the Delivery Service Period(LP)
+					 */
+
+	UINT_8 ucBmpDeliveryAC;	/* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */
+
+	UINT_8 ucBmpTriggerAC;	/* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */
+
+	UINT_8 ucUapsdSp;	/* Max SP length */
+
+    /*------------------------------------------------------------------------------------------*/
+
+	BOOLEAN fgIsRtsEnabled;
+
+	OS_SYSTIME rUpdateTime;	/* (4) System Timestamp of Successful TX and RX  */
+
+	OS_SYSTIME rLastJoinTime;	/* (4) System Timestamp of latest JOIN process */
+
+	UINT_8 ucJoinFailureCount;	/* Retry Count of JOIN process */
+
+	LINK_T arStaWaitQueue[STA_WAIT_QUEUE_NUM];	/* For TXM to defer pkt forwarding to MAC TX DMA */
+
+	UINT_16 au2CachedSeqCtrl[TID_NUM + 1];	/* Duplicate removal for HT STA on a per-TID basis
+						 * ("+1" is for MMPDU and non-QoS)
+						 */
+
+#if 0
+	/* RXM */
+	P_RX_BA_ENTRY_T aprRxBaTable[TID_NUM];
+
+	/* TXM */
+	P_TX_BA_ENTRY_T aprTxBaTable[TID_NUM];
+#endif
+
+	FRAG_INFO_T rFragInfo[MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS];
+
+	SEC_INFO_T rSecInfo;	/* The security state machine */
+
+	BOOLEAN fgPortBlock;	/* The 802.1x Port Control flag */
+
+	BOOLEAN fgTransmitKeyExist;	/* Unicast key exist for this STA */
+
+	UINT_8 ucWTEntry;
+
+	BOOLEAN fgTxAmpduEn;	/* Enable TX AMPDU for this Peer */
+	BOOLEAN fgRxAmpduEn;	/* Enable RX AMPDU for this Peer */
+
+	PUINT_8 pucAssocReqIe;
+	UINT_16 u2AssocReqIeLen;
+    /*------------------------------------------------------------------------------------------*/
+	/* WMM/QoS related fields                                                                   */
+    /*------------------------------------------------------------------------------------------*/
+	BOOLEAN fgIsQoS;	/* If the STA is associated as a QSTA or QAP (for TX/RX) */
+	BOOLEAN fgIsWmmSupported;	/* If the peer supports WMM, set to TRUE (for association) */
+	BOOLEAN fgIsUapsdSupported;	/* Set according to the scan result (for association) */
+
+    /*------------------------------------------------------------------------------------------*/
+	/* P2P related fields                                                                       */
+    /*------------------------------------------------------------------------------------------*/
+#if CFG_ENABLE_WIFI_DIRECT
+	UINT_8 u2DevNameLen;
+	UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME];
+
+	UINT_8 aucDevAddr[MAC_ADDR_LEN];	/* P2P Device Address */
+
+	UINT_16 u2ConfigMethods;
+
+	UINT_8 ucDeviceCap;
+
+	UINT_8 ucSecondaryDevTypeCount;
+
+	DEVICE_TYPE_T rPrimaryDevTypeBE;
+
+	DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT];
+#endif				/* CFG_SUPPORT_P2P */
+
+    /*------------------------------------------------------------------------------------------*/
+	/* QM related fields                                                                       */
+    /*------------------------------------------------------------------------------------------*/
+
+	UINT_8 ucFreeQuota;	/* Per Sta flow controal. Valid when fgIsInPS is TRUE.
+					Change it for per Queue flow control  */
+	/* UINT_8 aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES];  */ /* used in future */
+	UINT_8 ucFreeQuotaForDelivery;
+	UINT_8 ucFreeQuotaForNonDelivery;
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE && CFG_ENABLE_PER_STA_STATISTICS
+	UINT_32 u4TotalTxPktsNumber;
+	UINT_32 u4TotalTxPktsTime;
+	UINT_32 u4TotalTxPktsHifTime;
+
+	UINT_32 u4MaxTxPktsTime;
+	UINT_32 u4MaxTxPktsHifTime;
+
+	UINT_32 u4ThresholdCounter;
+	UINT_32 u4EnqeueuCounter;
+	UINT_32 u4DeqeueuCounter;
+	UINT_32 u4PrevIntCount;
+	UINT_32 u4ThisIntCount;
+	UINT_32 u4NoTcResource;
+#endif
+
+#if 1
+    /*------------------------------------------------------------------------------------------*/
+	/* To be removed, this is to make que_mgt compilation success only                          */
+    /*------------------------------------------------------------------------------------------*/
+	/* When this STA_REC is in use, set to TRUE. */
+	BOOLEAN fgIsValid;
+
+	/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */
+	QUE_T arTxQueue[NUM_OF_PER_STA_TX_QUEUES];
+
+	/* When this STA is in PS Mode, set to TRUE. */
+	/* BOOLEAN fgIsPS; */
+
+	/* When this STA enters Power-Saving, FW will notify the driver with a Session ID */
+	UINT_8 ucPsSessionID;
+
+	BOOLEAN fgIsAp;
+
+	/* Reorder Parameter reference table */
+	P_RX_BA_ENTRY_T aprRxReorderParamRefTbl[CFG_RX_MAX_BA_TID_NUM];
+#endif
+
+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
+	TIMINGMSMT_PARAM_T rWNMTimingMsmt;
+#endif
+
+#if (CFG_SUPPORT_TDLS == 1)
+	BOOLEAN fgTdlsIsProhibited;	/* TRUE: AP prohibits TDLS links */
+	BOOLEAN fgTdlsIsChSwProhibited;	/* TRUE: AP prohibits TDLS chan switch */
+
+	BOOLEAN flgTdlsIsInitiator;	/* TRUE: the peer is the initiator */
+	IE_HT_CAP_T rTdlsHtCap;	/* temp to queue HT capability element */
+	BOOLEAN fgTdlsInSecurityMode;	/* TRUE: security mode */
+	PARAM_KEY_T rTdlsKeyTemp;	/* temp to queue the key information */
+
+#define TDLS_SETUP_TIMEOUT_SEC			5	/* unit: second */
+	OS_SYSTIME rTdlsSetupStartTime;	/* time when link setup is started */
+
+	OS_SYSTIME rTdlsTxQuotaEmptyTime;	/* time when TX quota is 0 */
+
+	STAT_CNT_INFO_DRV_T rTdlsStatistics;
+#endif				/* CFG_SUPPORT_TDLS */
+
+#if (CFG_SUPPORT_STATISTICS == 1)
+#define STATS_ENV_TIMEOUT_SEC				10	/* unit: second */
+	OS_SYSTIME rStatsEnvTxPeriodLastTime;
+
+#define STATS_ENV_TX_CNT_REPORT_TRIGGER		2500	/* 6Mbps */
+#define STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC	5	/* unit: second */
+	OS_SYSTIME rStatsEnvTxLastTime;
+	UINT32 u4StatsEnvTxCnt;
+
+	UINT32 u4NumOfNoTxQuota;
+
+	UINT32 u4RxReorderFallAheadCnt;
+	UINT32 u4RxReorderFallBehindCnt;
+	UINT32 u4RxReorderHoleCnt;
+	UINT32 u4RxReorderHoleTimeoutCnt;
+
+	UINT32 u4StatsRxPassToOsCnt;
+
+	/* delay from HIF to pass to OS: us */
+#define STATS_STAY_INT_BYTE_THRESHOLD		500
+	UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3];
+
+	UINT8 ucStatsGenDisplayCnt;
+#endif				/* CFG_SUPPORT_STATISTICS */
+};
+
+#if 0
+/* use nic_tx.h instead */
+/* MSDU_INFO and SW_RFB structure */
+typedef struct _MSDU_INFO_T {
+
+	/* 4  ----------------MSDU_INFO and SW_RFB Common Fields------------------ */
+
+	LINK_ENTRY_T rLinkEntry;
+	PUINT_8 pucBuffer;	/* Pointer to the associated buffer */
+
+	UINT_8 ucBufferSource;	/* HIF TX0, HIF TX1, MAC RX, or MNG Pool */
+	UINT_8 ucNetworkTypeIndex;	/* Network type index that this TX packet is assocaited with */
+	UINT_8 ucTC;		/* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */
+	UINT_8 ucTID;		/* Traffic Identification */
+
+	BOOLEAN fgIs802_11Frame;	/* Set to TRUE for 802.11 frame */
+	UINT_8 ucMacHeaderLength;
+	UINT_16 u2PayloadLength;
+	PUINT_8 pucMacHeader;	/* 802.11 header  */
+	PUINT_8 pucPayload;	/* 802.11 payload */
+
+	OS_SYSTIME rArrivalTime;	/* System Timestamp (4) */
+	P_STA_RECORD_T prStaRec;
+
+#if CFG_PROFILE_BUFFER_TRACING
+	ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2];
+	UINT_32 rActivityTime[2];
+#endif
+#if DBG && CFG_BUFFER_FREE_CHK
+	BOOLEAN fgBufferInSource;
+#endif
+
+	UINT_8 ucControlFlag;	/* For specify some Control Flags, e.g. Basic Rate */
+
+	/* 4  -----------------------Non-Common ------------------------- */
+	/* TODO: move flags to ucControlFlag */
+
+	BOOLEAN fgIs1xFrame;	/* Set to TRUE for 802.1x frame */
+
+	/* TXM: For TX Done handling, callback function & parameter (5) */
+	BOOLEAN fgIsTxFailed;	/* Set to TRUE if transmission failure */
+
+	PFN_TX_DONE_HANDLER pfTxDoneHandler;
+
+	UINT_64 u8TimeStamp;	/* record the TX timestamp */
+
+	/* TXM: For PS forwarding control (per-STA flow control) */
+	UINT_8 ucPsForwardingType;	/* Delivery-enabled, non-delivery-enabled, non-PS */
+	UINT_8 ucPsSessionID;	/* The Power Save session id for PS forwarding control */
+
+	/* TXM: For MAC TX DMA operations */
+	UINT_8 ucMacTxQueIdx;	/*  MAC TX queue: AC0-AC6, BCM, or BCN */
+	BOOLEAN fgNoAck;	/* Set to true if Ack is not required for this packet */
+	BOOLEAN fgBIP;		/* Set to true if BIP is used for this packet */
+	UINT_8 ucFragTotalCount;
+	UINT_8 ucFragFinishedCount;
+	UINT_16 u2FragThreshold;	/* Fragmentation threshold without WLAN Header & FCS */
+	BOOLEAN fgFixedRate;	/* If a fixed rate is used, set to TRUE. */
+	UINT_8 ucFixedRateCode;	/* The rate code copied to MAC TX Desc */
+	UINT_8 ucFixedRateRetryLimit;	/* The retry limit when a fixed rate is used */
+	BOOLEAN fgIsBmcQueueEnd;	/* Set to true if this packet is the end of BMC */
+
+	/* TXM: For flushing ACL frames */
+	UINT_16 u2PalLLH;	/* 802.11 PAL LLH */
+	/* UINT_16     u2LLH; */
+	UINT_16 u2ACLSeq;	/* u2LLH+u2ACLSeq for AM HCI flush ACL frame */
+
+	/* TXM for retransmitting a flushed packet */
+	BOOLEAN fgIsSnAssigned;
+	UINT_16 u2SequenceNumber;	/* To remember the Sequence Control field of this MPDU */
+
+} MSDU_INFO_T, *P_MSDU_INFO_T;
+#endif
+
+#if 0
+/* nic_rx.h */
+typedef struct _SW_RFB_T {
+
+	/* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */
+
+	LINK_ENTRY_T rLinkEntry;
+	PUINT_8 pucBuffer;	/* Pointer to the associated buffer */
+
+	UINT_8 ucBufferSource;	/* HIF TX0, HIF TX1, MAC RX, or MNG Pool */
+	UINT_8 ucNetworkTypeIndex;	/* Network type index that this TX packet is assocaited with */
+	UINT_8 ucTC;		/* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */
+	UINT_8 ucTID;		/* Traffic Identification */
+
+	BOOLEAN fgIs802_11Frame;	/* Set to TRUE for 802.11 frame */
+	UINT_8 ucMacHeaderLength;
+	UINT_16 u2PayloadLength;
+	PUINT_8 pucMacHeader;	/* 802.11 header  */
+	PUINT_8 pucPayload;	/* 802.11 payload */
+
+	OS_SYSTIME rArrivalTime;	/* System Timestamp (4) */
+	P_STA_RECORD_T prStaRec;
+
+#if CFG_PROFILE_BUFFER_TRACING
+	ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2];
+	UINT_32 rActivityTime[2];
+#endif
+#if DBG && CFG_BUFFER_FREE_CHK
+	BOOLEAN fgBufferInSource;
+#endif
+
+	UINT_8 ucControlFlag;	/* For specify some Control Flags, e.g. Basic Rate */
+
+	/* 4 -----------------------Non-Common ------------------------- */
+
+	/* For composing the HIF RX Header (TODO: move flags to ucControlFlag) */
+	PUINT_8 pucHifRxPacket;	/* Pointer to the Response packet to HIF RX0 or RX1 */
+	UINT_16 u2HifRxPacketLength;
+	UINT_8 ucHeaderOffset;
+	UINT_8 ucHifRxPortIndex;
+
+	UINT_16 u2SequenceControl;
+	BOOLEAN fgIsA4Frame;	/* (For MAC RX packet parsing) set to TRUE if 4 addresses are present */
+	BOOLEAN fgIsBAR;
+	BOOLEAN fgIsQoSData;
+	BOOLEAN fgIsAmsduSubframe;	/* Set to TRUE for A-MSDU Subframe */
+
+	/* For HIF RX DMA Desc */
+	BOOLEAN fgTUChecksumCheckRequired;
+	BOOLEAN fgIPChecksumCheckRequired;
+	UINT_8 ucEtherTypeOffset;
+
+} SW_RFB_T, *P_SW_RFB_T;
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+P_MSDU_INFO_T cnmMgtPktAlloc(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length);
+
+VOID cnmMgtPktFree(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID cnmMemInit(IN P_ADAPTER_T prAdapter);
+
+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length);
+
+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory);
+
+VOID cnmStaRecInit(IN P_ADAPTER_T prAdapter);
+
+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter);
+
+P_STA_RECORD_T cnmStaRecAlloc(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex);
+
+VOID cnmStaRecFree(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSyncToChip);
+
+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip);
+
+P_STA_RECORD_T cnmGetStaRecByIndex(IN P_ADAPTER_T prAdapter, IN UINT_8 ucIndex);
+
+P_STA_RECORD_T cnmGetStaRecByAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex, IN UINT_8 aucPeerMACAddress[]);
+
+VOID cnmStaRecResetStatus(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+VOID cnmStaRecChangeState(IN P_ADAPTER_T prAdapter, IN OUT P_STA_RECORD_T prStaRec, IN UINT_8 ucNewState);
+
+P_STA_RECORD_T
+cnmStaTheTypeGet(P_ADAPTER_T prAdapter,
+		 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#ifndef _lint
+/* Kevin: we don't have to call following function to inspect the data structure.
+ * It will check automatically while at compile time.
+ * We'll need this for porting driver to different RTOS.
+ */
+static inline VOID cnmMemDataTypeCheck(VOID)
+{
+#if 0
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == 0);
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == OFFSET_OF(SW_RFB_T, rLinkEntry));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucBuffer) == OFFSET_OF(SW_RFB_T, pucBuffer));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucBufferSource) == OFFSET_OF(SW_RFB_T, ucBufferSource));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucMacHeader) == OFFSET_OF(SW_RFB_T, pucMacHeader));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucMacHeaderLength) ==
+				     OFFSET_OF(SW_RFB_T, ucMacHeaderLength));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucPayload) == OFFSET_OF(SW_RFB_T, pucPayload));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, u2PayloadLength) == OFFSET_OF(SW_RFB_T, u2PayloadLength));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, prStaRec) == OFFSET_OF(SW_RFB_T, prStaRec));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucNetworkTypeIndex) ==
+				     OFFSET_OF(SW_RFB_T, ucNetworkTypeIndex));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTID) == OFFSET_OF(SW_RFB_T, ucTID));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgIs802_11Frame) == OFFSET_OF(SW_RFB_T, fgIs802_11Frame));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucControlFlag) == OFFSET_OF(SW_RFB_T, ucControlFlag));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rArrivalTime) == OFFSET_OF(SW_RFB_T, rArrivalTime));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTC) == OFFSET_OF(SW_RFB_T, ucTC));
+
+#if CFG_PROFILE_BUFFER_TRACING
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, eActivity[0]) == OFFSET_OF(SW_RFB_T, eActivity[0]));
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rActivityTime[0]) ==
+			 OFFSET_OF(SW_RFB_T, rActivityTime[0]));
+#endif
+
+#if DBG && CFG_BUFFER_FREE_CHK
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgBufferInSource) ==
+		 OFFSET_OF(SW_RFB_T, fgBufferInSource));
+#endif
+
+	DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(STA_RECORD_T, rLinkEntry) == 0);
+
+	return;
+#endif
+}
+#endif /* _lint */
+
+#endif /* _CNM_MEM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h
new file mode 100644
index 0000000000000..cc5d0fa1adfca
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h
@@ -0,0 +1,169 @@
+/*
+** Id: @(#)
+*/
+
+/*! \file   "cnm_scan.h"
+    \brief
+
+*/
+
+/*
+** Log: cnm_scan.h
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * remove unused definitions.
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge cnm_scan.h and hem_mbox.h
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 03 30 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support 2.4G OBSS scan
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ *  *  *  * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * Nov 18 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add function prototype of cnmScanInit()
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+#ifndef _CNM_SCAN_H
+#define _CNM_SCAN_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define SCN_CHANNEL_DWELL_TIME_MIN_MSEC         12
+#define SCN_CHANNEL_DWELL_TIME_EXT_MSEC         98
+
+#define SCN_TOTAL_PROBEREQ_NUM_FOR_FULL         3
+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_FULL      1
+
+#define SCN_TOTAL_PROBEREQ_NUM_FOR_PARTIAL      2
+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_PARTIAL   1
+
+#define SCN_INTERLACED_CHANNEL_GROUPS_NUM       3	/* Used by partial scan */
+
+#define SCN_PARTIAL_SCAN_NUM                    3
+
+#define SCN_PARTIAL_SCAN_IDLE_MSEC              100
+
+#define	MAXIMUM_OPERATION_CHANNEL_LIST	        46
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* The type of Scan Source */
+typedef enum _ENUM_SCN_REQ_SOURCE_T {
+	SCN_REQ_SOURCE_HEM = 0,
+	SCN_REQ_SOURCE_NET_FSM,
+	SCN_REQ_SOURCE_ROAMING,	/* ROAMING Module is independent of AIS FSM */
+	SCN_REQ_SOURCE_OBSS,	/* 2.4G OBSS scan */
+	SCN_REQ_SOURCE_NUM
+} ENUM_SCN_REQ_SOURCE_T, *P_ENUM_SCN_REQ_SOURCE_T;
+
+typedef enum _ENUM_SCAN_PROFILE_T {
+	SCAN_PROFILE_FULL = 0,
+	SCAN_PROFILE_PARTIAL,
+	SCAN_PROFILE_VOIP,
+	SCAN_PROFILE_FULL_2G4,
+	SCAN_PROFILE_NUM
+} ENUM_SCAN_PROFILE_T, *P_ENUM_SCAN_PROFILE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#if 0
+VOID cnmScanInit(VOID);
+
+VOID cnmScanRunEventScanRequest(IN P_MSG_HDR_T prMsgHdr);
+
+BOOLEAN cnmScanRunEventScanAbort(IN P_MSG_HDR_T prMsgHdr);
+
+VOID cnmScanProfileSelection(VOID);
+
+VOID cnmScanProcessStart(VOID);
+
+VOID cnmScanProcessStop(VOID);
+
+VOID cnmScanRunEventReqAISAbsDone(IN P_MSG_HDR_T prMsgHdr);
+
+VOID cnmScanRunEventCancelAISAbsDone(IN P_MSG_HDR_T prMsgHdr);
+
+VOID cnmScanPartialScanTimeout(UINT_32 u4Param);
+
+VOID cnmScanRunEventScnFsmComplete(IN P_MSG_HDR_T prMsgHdr);
+#endif
+
+#endif /* _CNM_SCAN_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h
new file mode 100644
index 0000000000000..a2ed9cd02fedf
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h
@@ -0,0 +1,235 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_timer.h#1
+*/
+
+/*! \file   cnm_timer.h
+    \brief  Declaration of timer obj and related timer macro for setup time out
+	    event.
+
+    In this file we declare the timer object and provide several macro for
+    Protocol functional blocks to setup their own time out event.
+*/
+
+/*
+** Log: cnm_timer.h
+ *
+ * 12 13 2011 cm.chang
+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer
+ * Add wake lock if timer timeout value is smaller than 5 seconds
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * cnm_timer has been migrated.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge cnm_scan.h and hem_mbox.h
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only)
+ *
+ * 06 04 2010 george.huang
+ * [BORA00000678][MT6620]WiFi LP integration
+ * [PM] Support U-APSD for STA mode
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Return timer token back to COS when entering wait off state
+ *
+ * 01 08 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb
+ *
+ * 01 06 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Fix system time is 32KHz instead of 1ms
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * add the copy time function
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix LINT warnning
+ *
+ * Oct 28 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+#ifndef _CNM_TIMER_H
+#define _CNM_TIMER_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#undef MSEC_PER_SEC
+#define MSEC_PER_SEC                    1000
+#undef USEC_PER_MSEC
+#define USEC_PER_MSEC                   1000
+#define USEC_PER_TU                     1024	/* microsecond */
+
+#define MSEC_PER_MIN                    (60 * MSEC_PER_SEC)
+
+#define MGMT_MAX_TIMEOUT_INTERVAL       ((UINT_32)0x7fffffff)
+
+#define WAKE_LOCK_MAX_TIME              5	/* Unit: sec */
+
+/* If WAKE_LOCK_MAX_TIME is too large, the whole system may always keep awake
+ * because of periodic timer of OBSS scanning
+ */
+#if (WAKE_LOCK_MAX_TIME >= OBSS_SCAN_MIN_INTERVAL)
+#error WAKE_LOCK_MAX_TIME is too large
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef VOID(*PFN_MGMT_TIMEOUT_FUNC) (P_ADAPTER_T, ULONG);
+
+typedef struct _TIMER_T {
+	LINK_ENTRY_T rLinkEntry;
+	OS_SYSTIME rExpiredSysTime;
+	UINT_16 u2Minutes;
+	UINT_16 u2Reserved;
+	ULONG ulData;
+	PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc;
+} TIMER_T, *P_TIMER_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/* Check if time "a" is before time "b" */
+/* In 32-bit variable, 0x00000001~0x7fffffff -> positive number,
+ *                     0x80000000~0xffffffff -> negative number
+ */
+#define TIME_BEFORE_64bit(a, b)       (a < b)
+
+#define TIME_BEFORE(a, b)        ((UINT_32)((UINT_32)(a) - (UINT_32)(b)) > 0x7fffffff)
+
+/* #define TIME_BEFORE(a,b)        ((INT_32)((INT_32)(b) - (INT_32)(a)) > 0)
+ * may cause UNexpect result between Free build and Check build for WinCE
+ */
+
+#define TIME_AFTER(a, b)         TIME_BEFORE(b, a)
+
+#define SYSTIME_TO_SEC(_systime)            ((_systime) / KAL_HZ)
+#define SEC_TO_SYSTIME(_sec)                ((_sec) * KAL_HZ)
+
+/* The macros to convert second & millisecond */
+#define MSEC_TO_SEC(_msec)                  ((_msec) / MSEC_PER_SEC)
+#define SEC_TO_MSEC(_sec)                   ((UINT_32)(_sec) * MSEC_PER_SEC)
+
+/* The macros to convert millisecond & microsecond */
+#define USEC_TO_MSEC(_usec)                 ((_usec) / USEC_PER_MSEC)
+#define MSEC_TO_USEC(_msec)                 ((UINT_32)(_msec) * USEC_PER_MSEC)
+
+/* The macros to convert TU & microsecond, TU & millisecond */
+#define TU_TO_USEC(_tu)                     ((_tu) * USEC_PER_TU)
+#define TU_TO_MSEC(_tu)                     USEC_TO_MSEC(TU_TO_USEC(_tu))
+
+/* The macros to convert TU & & OS system time, round up by 0.5 */
+#define TU_TO_SYSTIME(_tu)                  MSEC_TO_SYSTIME(TU_TO_MSEC(_tu))
+#define SYSTIME_TO_TU(_systime)             \
+	((SYSTIME_TO_USEC(_systime) + ((USEC_PER_TU / 2) - 1)) / USEC_PER_TU)
+
+/* The macros to convert OS system time & microsecond */
+#define SYSTIME_TO_USEC(_systime)           (SYSTIME_TO_MSEC(_systime) * USEC_PER_MSEC)
+
+/* The macro to get the current OS system time */
+#define GET_CURRENT_SYSTIME(_systime_p)     {*(_systime_p) = kalGetTimeTick(); }
+
+/* The macro to copy the system time */
+#define COPY_SYSTIME(_destTime, _srcTime)   {(_destTime) = (_srcTime); }
+
+/* The macro to get the system time difference between t1 and t2 (t1 - t2) */
+/* #define GET_SYSTIME_DIFFERENCE(_time1, _time2, _diffTime) \
+	(_diffTime) = (_time1) - (_time2) */
+
+/* The macro to check for the expiration, if TRUE means _currentTime >= _expirationTime */
+#define CHECK_FOR_EXPIRATION(_currentTime, _expirationTime) \
+	(((UINT_32)(_currentTime) - (UINT_32)(_expirationTime)) <= 0x7fffffffUL)
+
+/* The macro to check for the timeout */
+#define CHECK_FOR_TIMEOUT(_currentTime, _timeoutStartingTime, _timeout) \
+	CHECK_FOR_EXPIRATION((_currentTime), ((_timeoutStartingTime) + (_timeout)))
+
+/* The macro to set the expiration time with a specified timeout *//* Watch out for round up. */
+#define SET_EXPIRATION_TIME(_expirationTime, _timeout) \
+	{ \
+	    GET_CURRENT_SYSTIME(&(_expirationTime)); \
+	    (_expirationTime) += (OS_SYSTIME)(_timeout); \
+	}
+
+#define timerRenewTimer(adapter, tmr, interval) \
+	timerStartTimer(adapter, tmr, interval, (tmr)->function, (tmr)->data)
+
+#define MGMT_INIT_TIMER(_adapter_p, _timer, _callbackFunc) \
+	timerInitTimer(_adapter_p, &(_timer), (ULONG)(_callbackFunc))
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter);
+
+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter);
+
+VOID
+cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData);
+
+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer);
+
+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs);
+
+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+static inline INT_32 timerPendingTimer(IN P_TIMER_T prTimer)
+{
+	ASSERT(prTimer);
+
+	return prTimer->rLinkEntry.prNext != NULL;
+}
+
+#endif /* _CNM_TIMER_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h
new file mode 100644
index 0000000000000..868de4a6c40ac
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h
@@ -0,0 +1,446 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/hem_mbox.h#2
+*/
+
+/*! \file   hem_mbox.h
+    \brief
+
+*/
+
+/*
+** Log: hem_mbox.h
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 07 18 2011 cp.wu
+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for
+ * more than one SSID in a single scanning request
+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID
+ * support as well as uProbeDelay in NDIS 6.x driver model
+ *
+ * 06 07 2011 yuche.tsai
+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response.
+ * cnm_timer[WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue
+ * Add invitation support.
+ *
+ * 06 02 2011 cp.wu
+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction
+ * eliminate unused parameters for SAA-FSM
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * Allocate system RAM if fixed message or mgmt buffer is not available
+ *
+ * 11 08 2010 cm.chang
+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID
+ * Remove CNM channel reover message ID
+ *
+ * 09 16 2010 cm.chang
+ * NULL
+ * Remove unused message ID
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * add interface for RLM to trigger OBSS-SCAN.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add some message ID for P2P FSM under provisioning phase.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add Message Event ID for P2P Module.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Check-in P2P Device Discovery Feature.
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * remove unused mailbox message definitions.
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * message table should not be commented out by compilation option without modifying header file
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * AIS-FSM integration with CNM channel request messages
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Modify CNM message handler for new flow
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * restore utility function invoking via hem_mbox to direct calls
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add definitions for module migration.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * hem_mbox is migrated.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge cnm_scan.h and hem_mbox.h
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 29 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME
+ *
+ * 04 29 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Removed MID_RXM_MQM_BA_ACTION_FRAME
+ *
+ * 03 30 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support 2.4G OBSS scan
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ *  *  *  *  * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 03 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Develop partial DPD code
+ *
+ * 02 11 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added MID_RXM_MQM_QOS_ACTION_FRAME for RXM to indicate QoS Action frames to MQM
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * Dec 7 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Rename the parameter of mboxDummy()
+ *
+ * Dec 2 2009 MTK02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Added MID_RXM_MQM_BA_ACTION_FRAME
+ *
+ * Nov 24 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Remove Dummy MSG ID
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add JOIN REQ related MSG ID
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add AIS ABORT MSG ID
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add SCN MSG IDs
+ *
+ * Oct 28 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+#ifndef _HEM_MBOX_H
+#define _HEM_MBOX_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Message IDs */
+typedef enum _ENUM_MSG_ID_T {
+	MID_MNY_CNM_CH_REQ,	/* MANY notify CNM to obtain channel privilege */
+	MID_MNY_CNM_CH_ABORT,	/* MANY notify CNM to abort/release channel privilege */
+
+	MID_CNM_AIS_CH_GRANT,	/* CNM notify AIS for indicating channel granted */
+	MID_CNM_P2P_CH_GRANT,	/* CNM notify P2P for indicating channel granted */
+	MID_CNM_BOW_CH_GRANT,	/* CNM notify BOW for indicating channel granted */
+
+    /*--------------------------------------------------*/
+	/* SCN Module Mailbox Messages                      */
+    /*--------------------------------------------------*/
+	MID_AIS_SCN_SCAN_REQ,	/* AIS notify SCN for starting scan */
+	MID_AIS_SCN_SCAN_REQ_V2,	/* AIS notify SCN for starting scan with multiple SSID support */
+	MID_AIS_SCN_SCAN_CANCEL,	/* AIS notify SCN for cancelling scan */
+	MID_P2P_SCN_SCAN_REQ,	/* P2P notify SCN for starting scan */
+	MID_P2P_SCN_SCAN_REQ_V2,	/* P2P notify SCN for starting scan with multiple SSID support */
+	MID_P2P_SCN_SCAN_CANCEL,	/* P2P notify SCN for cancelling scan */
+	MID_BOW_SCN_SCAN_REQ,	/* BOW notify SCN for starting scan */
+	MID_BOW_SCN_SCAN_REQ_V2,	/* BOW notify SCN for starting scan with multiple SSID support */
+	MID_BOW_SCN_SCAN_CANCEL,	/* BOW notify SCN for cancelling scan */
+	MID_RLM_SCN_SCAN_REQ,	/* RLM notify SCN for starting scan (OBSS-SCAN) */
+	MID_RLM_SCN_SCAN_REQ_V2,	/* RLM notify SCN for starting scan (OBSS-SCAN) with multiple SSID support */
+	MID_RLM_SCN_SCAN_CANCEL,	/* RLM notify SCN for cancelling scan (OBSS-SCAN) */
+	MID_SCN_AIS_SCAN_DONE,	/* SCN notify AIS for scan completion */
+	MID_SCN_P2P_SCAN_DONE,	/* SCN notify P2P for scan completion */
+	MID_SCN_BOW_SCAN_DONE,	/* SCN notify BOW for scan completion */
+	MID_SCN_RLM_SCAN_DONE,	/* SCN notify RLM for scan completion (OBSS-SCAN) */
+
+    /*--------------------------------------------------*/
+	/* AIS Module Mailbox Messages                      */
+    /*--------------------------------------------------*/
+	MID_OID_AIS_FSM_JOIN_REQ,	/* OID/IOCTL notify AIS for join */
+	MID_OID_AIS_FSM_ABORT,	/* OID/IOCTL notify AIS for abort */
+	MID_AIS_SAA_FSM_START,	/* AIS notify SAA for Starting authentication/association fsm */
+	MID_AIS_SAA_FSM_ABORT,	/* AIS notify SAA for Aborting authentication/association fsm */
+	MID_SAA_AIS_JOIN_COMPLETE,	/* SAA notify AIS for indicating join complete */
+
+#if CFG_ENABLE_BT_OVER_WIFI
+    /*--------------------------------------------------*/
+	/* BOW Module Mailbox Messages                      */
+    /*--------------------------------------------------*/
+	MID_BOW_SAA_FSM_START,	/* BOW notify SAA for Starting authentication/association fsm */
+	MID_BOW_SAA_FSM_ABORT,	/* BOW notify SAA for Aborting authentication/association fsm */
+	MID_SAA_BOW_JOIN_COMPLETE,	/* SAA notify BOW for indicating join complete */
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+    /*--------------------------------------------------*/
+	/* P2P Module Mailbox Messages                      */
+    /*--------------------------------------------------*/
+	MID_P2P_SAA_FSM_START,	/* P2P notify SAA for Starting authentication/association fsm */
+	MID_P2P_SAA_FSM_ABORT,	/* P2P notify SAA for Aborting authentication/association fsm */
+	MID_SAA_P2P_JOIN_COMPLETE,	/* SAA notify P2P for indicating join complete */
+
+	MID_MNY_P2P_FUN_SWITCH,	/* Enable P2P FSM. */
+	MID_MNY_P2P_DEVICE_DISCOVERY,	/* Start device discovery. */
+	MID_MNY_P2P_CONNECTION_REQ,	/* Connection request. */
+	MID_MNY_P2P_CONNECTION_ABORT,	/* Abort connection request, P2P FSM return to IDLE. */
+	MID_MNY_P2P_BEACON_UPDATE,
+	MID_MNY_P2P_STOP_AP,
+	MID_MNY_P2P_CHNL_REQ,
+	MID_MNY_P2P_CHNL_ABORT,
+	MID_MNY_P2P_MGMT_TX,
+	MID_MNY_P2P_GROUP_DISSOLVE,
+	MID_MNY_P2P_MGMT_FRAME_REGISTER,
+	MID_MNY_P2P_NET_DEV_REGISTER,
+	MID_MNY_P2P_START_AP,
+	MID_MNY_P2P_MGMT_FRAME_UPDATE,
+	MID_MNY_P2P_EXTEND_LISTEN_INTERVAL,
+#if CFG_SUPPORT_WFD
+	MID_MNY_P2P_WFD_CFG_UPDATE,
+#endif
+#endif
+
+#if CFG_SUPPORT_ADHOC
+	MID_SCN_AIS_FOUND_IBSS,	/* SCN notify AIS that an IBSS Peer has been found and can merge into */
+#endif				/* CFG_SUPPORT_ADHOC */
+
+	MID_SAA_AIS_FSM_ABORT,	/* SAA notify AIS for indicating deauthentication/disassociation */
+
+    /*--------------------------------------------------*/
+	/* AIS MGMT-TX Support                              */
+    /*--------------------------------------------------*/
+	MID_MNY_AIS_REMAIN_ON_CHANNEL,
+	MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL,
+	MID_MNY_AIS_MGMT_TX,
+
+	MID_TOTAL_NUM
+} ENUM_MSG_ID_T, *P_ENUM_MSG_ID_T;
+
+/* Message header of inter-components */
+struct _MSG_HDR_T {
+	LINK_ENTRY_T rLinkEntry;
+	ENUM_MSG_ID_T eMsgId;
+};
+
+typedef VOID(*PFN_MSG_HNDL_FUNC) (P_ADAPTER_T, P_MSG_HDR_T);
+
+typedef struct _MSG_HNDL_ENTRY {
+	ENUM_MSG_ID_T eMsgId;
+	PFN_MSG_HNDL_FUNC pfMsgHndl;
+} MSG_HNDL_ENTRY_T, *P_MSG_HNDL_ENTRY_T;
+
+typedef enum _EUNM_MSG_SEND_METHOD_T {
+	MSG_SEND_METHOD_BUF = 0,	/* Message is put in the queue and will be
+					   executed when mailbox is checked. */
+	MSG_SEND_METHOD_UNBUF	/* The handler function is called immediately
+				   in the same context of the sender */
+} EUNM_MSG_SEND_METHOD_T, *P_EUNM_MSG_SEND_METHOD_T;
+
+typedef enum _ENUM_MBOX_ID_T {
+	MBOX_ID_0 = 0,
+	MBOX_ID_TOTAL_NUM
+} ENUM_MBOX_ID_T, *P_ENUM_MBOX_ID_T;
+
+/* Define Mailbox structure */
+typedef struct _MBOX_T {
+	LINK_T rLinkHead;
+} MBOX_T, *P_MBOX_T;
+
+typedef struct _MSG_SAA_FSM_START_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucSeqNum;
+	P_STA_RECORD_T prStaRec;
+} MSG_SAA_FSM_START_T, *P_MSG_SAA_FSM_START_T;
+
+typedef struct _MSG_SAA_FSM_COMP_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucSeqNum;
+	WLAN_STATUS rJoinStatus;
+	P_STA_RECORD_T prStaRec;
+	P_SW_RFB_T prSwRfb;
+} MSG_SAA_FSM_COMP_T, *P_MSG_SAA_FSM_COMP_T;
+
+typedef struct _MSG_SAA_FSM_ABORT_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucSeqNum;
+	P_STA_RECORD_T prStaRec;
+} MSG_SAA_FSM_ABORT_T, *P_MSG_SAA_FSM_ABORT_T;
+
+typedef struct _MSG_CONNECTION_ABORT_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucNetTypeIndex;
+} MSG_CONNECTION_ABORT_T, *P_MSG_CONNECTION_ABORT_T;
+
+typedef struct _MSG_REMAIN_ON_CHANNEL_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	ENUM_BAND_T eBand;
+	ENUM_CHNL_EXT_T eSco;
+	UINT_8 ucChannelNum;
+	UINT_32 u4DurationMs;
+	UINT_64 u8Cookie;
+} MSG_REMAIN_ON_CHANNEL_T, *P_MSG_REMAIN_ON_CHANNEL_T;
+
+typedef struct _MSG_CANCEL_REMAIN_ON_CHANNEL_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_64 u8Cookie;
+} MSG_CANCEL_REMAIN_ON_CHANNEL_T, *P_MSG_CANCEL_REMAIN_ON_CHANNEL_T;
+
+typedef struct _MSG_MGMT_TX_REQUEST_T {
+	MSG_HDR_T rMsgHdr;
+	P_MSDU_INFO_T prMgmtMsduInfo;
+	UINT_64 u8Cookie;	/* For indication. */
+	BOOLEAN fgNoneCckRate;
+	BOOLEAN fgIsWaitRsp;
+} MSG_MGMT_TX_REQUEST_T, *P_MSG_MGMT_TX_REQUEST_T;
+
+/* specific message data types */
+typedef MSG_SAA_FSM_START_T MSG_JOIN_REQ_T, *P_MSG_JOIN_REQ_T;
+typedef MSG_SAA_FSM_COMP_T MSG_JOIN_COMP_T, *P_MSG_JOIN_COMP_T;
+typedef MSG_SAA_FSM_ABORT_T MSG_JOIN_ABORT_T, *P_MSG_JOIN_ABORT_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId);
+
+VOID
+mboxSendMsg(IN P_ADAPTER_T prAdapter,
+	    IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod);
+
+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId);
+
+VOID mboxInitialize(IN P_ADAPTER_T prAdapter);
+
+VOID mboxDestroy(IN P_ADAPTER_T prAdapter);
+
+VOID mboxDummy(IN P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _HEM_MBOX_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h
new file mode 100644
index 0000000000000..88b99222133f4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h
@@ -0,0 +1,148 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/include/mgmt/hs20.h#2
+*/
+
+/*! \file   hs20.h
+    \brief This file contains the function declaration for hs20.c.
+*/
+
+/*
+** Log:
+ *
+ */
+
+#ifndef _HS20_H
+#define _HS20_H
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define BSSID_POOL_MAX_SIZE             8
+#define HS20_SIGMA_SCAN_RESULT_TIMEOUT  30	/* sec */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+#if CFG_ENABLE_GTK_FRAME_FILTER
+/*For GTK Frame Filter*/
+typedef struct _IPV4_NETWORK_ADDRESS_LIST {
+	UINT_8 ucAddrCount;
+	IPV4_NETWORK_ADDRESS arNetAddr[1];
+} IPV4_NETWORK_ADDRESS_LIST, *P_IPV4_NETWORK_ADDRESS_LIST;
+#endif
+
+/* Entry of BSSID Pool - For SIGMA Test */
+typedef struct _BSSID_ENTRY_T {
+	UINT_8 aucBSSID[MAC_ADDR_LEN];
+} BSSID_ENTRY_T, P_HS20_BSSID_POOL_ENTRY_T;
+
+struct _HS20_INFO_T {
+
+	/*Hotspot 2.0 Information */
+	UINT_8 aucHESSID[MAC_ADDR_LEN];
+	UINT_8 ucAccessNetworkOptions;
+	UINT_8 ucVenueGroup;	/* VenueInfo - Group */
+	UINT_8 ucVenueType;
+	UINT_8 ucHotspotConfig;
+
+	/*Roaming Consortium Information */
+	/* PARAM_HS20_ROAMING_CONSORTIUM_INFO rRCInfo; */
+
+	/*Hotspot 2.0 dummy AP Info */
+
+	/*Time Advertisement Information */
+	/* UINT_32                 u4UTCOffsetTime; */
+	/* UINT_8                  aucTimeZone[ELEM_MAX_LEN_TIME_ZONE]; */
+	/* UINT_8                  ucLenTimeZone; */
+
+	/* For SIGMA Test */
+	/* BSSID Pool */
+	BSSID_ENTRY_T arBssidPool[BSSID_POOL_MAX_SIZE];
+	UINT_8 ucNumBssidPoolEntry;
+	BOOLEAN fgIsHS2SigmaMode;
+
+};
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*For GTK Frame Filter*/
+#if DBG
+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList)    \
+	{   \
+	    UINT_32 u4Size = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) +  \
+				(((_prAddrList)->ucAddrCount) * sizeof(IPV4_NETWORK_ADDRESS));  \
+	    kalMemFree((_prAddrList), VIR_MEM_TYPE, u4Size);    \
+	    (_prAddrList) = NULL;   \
+	}
+#else
+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList)    \
+	{   \
+	    kalMemFree((_prAddrList), VIR_MEM_TYPE, 0);    \
+	    (_prAddrList) = NULL;   \
+	}
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo);
+
+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo);
+
+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo);
+
+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo);
+
+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE);
+
+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE);
+
+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID);
+
+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE);
+
+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb);
+
+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb);
+
+#if CFG_ENABLE_GTK_FRAME_FILTER
+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb);
+#endif
+
+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb);
+
+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo);
+
+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx);
+
+#endif
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h
new file mode 100644
index 0000000000000..cb89fd8793ee4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h
@@ -0,0 +1,153 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/mib.h#1
+*/
+
+/*! \file  mib.h
+    \brief This file contains the IEEE 802.11 family related MIB definition
+	   for MediaTek 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: mib.h
+ *
+ * 11 08 2010 wh.su
+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
+ * add the message check code from mt5921.
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h.
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+#ifndef _MIB_H
+#define _MIB_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+/* Entry in SMT AuthenticationAlgorithms Table: dot11AuthenticationAlgorithmsEntry */
+typedef struct _DOT11_AUTHENTICATION_ALGORITHMS_ENTRY {
+	BOOLEAN dot11AuthenticationAlgorithmsEnable;	/* dot11AuthenticationAlgorithmsEntry 3 */
+} DOT11_AUTHENTICATION_ALGORITHMS_ENTRY, *P_DOT11_AUTHENTICATION_ALGORITHMS_ENTRY;
+
+/* Entry in SMT dot11RSNAConfigPairwiseCiphersTalbe Table: dot11RSNAConfigPairwiseCiphersEntry */
+typedef struct _DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY {
+	UINT_32 dot11RSNAConfigPairwiseCipher;	/* dot11RSNAConfigPairwiseCiphersEntry 2 */
+	BOOLEAN dot11RSNAConfigPairwiseCipherEnabled;	/* dot11RSNAConfigPairwiseCiphersEntry 3 */
+} DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY, *P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY;
+
+/* Entry in SMT dot11RSNAConfigAuthenticationSuitesTalbe Table: dot11RSNAConfigAuthenticationSuitesEntry */
+typedef struct _DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY {
+	UINT_32 dot11RSNAConfigAuthenticationSuite;	/* dot11RSNAConfigAuthenticationSuitesEntry 2 */
+	BOOLEAN dot11RSNAConfigAuthenticationSuiteEnabled;	/* dot11RSNAConfigAuthenticationSuitesEntry 3 */
+} DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY, *P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY;
+
+/* ----- IEEE 802.11 MIB Major sections ----- */
+typedef struct _IEEE_802_11_MIB_T {
+	/* dot11PrivacyTable                            (dot11smt 5) */
+	UINT_8 dot11WEPDefaultKeyID;	/* dot11PrivacyEntry 2 */
+	BOOLEAN dot11TranmitKeyAvailable;
+	UINT_32 dot11WEPICVErrorCount;	/* dot11PrivacyEntry 5 */
+	UINT_32 dot11WEPExcludedCount;	/* dot11PrivacyEntry 6 */
+
+	/* dot11RSNAConfigTable                         (dot11smt 8) */
+	UINT_32 dot11RSNAConfigGroupCipher;	/* dot11RSNAConfigEntry 4 */
+
+	/* dot11RSNAConfigPairwiseCiphersTable          (dot11smt 9) */
+	DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY dot11RSNAConfigPairwiseCiphersTable[MAX_NUM_SUPPORTED_CIPHER_SUITES];
+
+	/* dot11RSNAConfigAuthenticationSuitesTable     (dot11smt 10) */
+	 DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY
+	    dot11RSNAConfigAuthenticationSuitesTable[MAX_NUM_SUPPORTED_AKM_SUITES];
+
+#if 0				/* SUPPORT_WAPI */
+	BOOLEAN fgWapiKeyInstalled;
+	PARAM_WPI_KEY_T rWapiPairwiseKey[2];
+	BOOLEAN fgPairwiseKeyUsed[2];
+	UINT_8 ucWpiActivedPWKey;	/* Must be 0 or 1, by wapi spec */
+	PARAM_WPI_KEY_T rWapiGroupKey[2];
+	BOOLEAN fgGroupKeyUsed[2];
+#endif
+} IEEE_802_11_MIB_T, *P_IEEE_802_11_MIB_T;
+
+/* ------------------ IEEE 802.11 non HT PHY characteristics ---------------- */
+typedef const struct _NON_HT_PHY_ATTRIBUTE_T {
+	UINT_16 u2SupportedRateSet;
+
+	BOOLEAN fgIsShortPreambleOptionImplemented;
+
+	BOOLEAN fgIsShortSlotTimeOptionImplemented;
+
+} NON_HT_PHY_ATTRIBUTE_T, *P_NON_HT_PHY_ATTRIBUTE_T;
+
+typedef const struct _NON_HT_ADHOC_MODE_ATTRIBUTE_T {
+
+	ENUM_PHY_TYPE_INDEX_T ePhyTypeIndex;
+
+	UINT_16 u2BSSBasicRateSet;
+
+} NON_HT_ADHOC_MODE_ATTRIBUTE_T, *P_NON_HT_ADHOC_MODE_ATTRIBUTE_T;
+
+typedef NON_HT_ADHOC_MODE_ATTRIBUTE_T NON_HT_AP_MODE_ATTRIBUTE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+extern NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[];
+extern NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[];
+extern NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[];
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _MIB_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h
new file mode 100644
index 0000000000000..11145c31dbfae
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h
@@ -0,0 +1,55 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_assoc.h#1
+*/
+
+/*! \file  p2p_assoc.h
+    \brief This file contains the Wi-Fi Direct ASSOC REQ/RESP of
+	   IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters.
+*/
+
+#ifndef _P2P_ASSOC_H
+#define _P2P_ASSOC_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h
new file mode 100644
index 0000000000000..869d7bf0ee614
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h
@@ -0,0 +1,56 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_bss.h#2
+*/
+
+/*! \file   "p2p_bss.h"
+    \brief  In this file we define the function prototype used in p2p BSS/IBSS.
+
+    The file contains the function declarations and defines for used in BSS/IBSS.
+*/
+
+#ifndef _P2P_BSS_H
+#define _P2P_BSS_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+UINT_32 p2pGetTxProbRspIeTableSize(VOID);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h
new file mode 100644
index 0000000000000..2541e1d2883e8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h
@@ -0,0 +1,2190 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_fsm.h#23
+*/
+
+/*! \file   p2p_fsm.h
+    \brief  Declaration of functions and finite state machine for P2P Module.
+
+    Declaration of functions and finite state machine for P2P Module.
+*/
+
+/*
+** Log: p2p_fsm.h
+**
+** 09 12 2012 wcpadmin
+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
+** .
+**
+** 08 14 2012 yuche.tsai
+** NULL
+** Fix compile error.
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 07 18 2012 yuche.tsai
+ * NULL
+ * add one file.
+ *
+ * 12 02 2011 yuche.tsai
+ * NULL
+ * Resolve class 3 error issue under AP mode.
+ *
+ * data frame may TX before Assoc Response TX.
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix work thread cancel issue.
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix default device name issue.
+ *
+ * 11 09 2011 yuche.tsai
+ * [WCXRP00001093] [Need Patch][Volunteer Patch] Service Discovery 2.0 state transition issue.
+ * Fix SD2.0 issue which may cause KE. (Monkey test)
+ *
+ * 11 08 2011 yuche.tsai
+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version
+ * query & set support for service discovery version check.
+ * Add support for driver version query & p2p supplicant verseion set.
+ * For new service discovery mechanism sync.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * Support Channel Query.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * New 2.1 branch
+
+ *
+ * 09 01 2011 yuche.tsai
+ * NULL
+ * Fix channel stay interval.
+ * Sync channel stay interval & channel request interval under AP mode..
+ *
+ * 08 30 2011 yuche.tsai
+ * [WCXRP00000953] [Volunteer Patch][Driver] Hot Spot Channel ASSERT issue.
+ * Fix hot spot FW assert issue when under concurrent case. (DBG enable only)
+ *
+ * 08 16 2011 cp.wu
+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence
+ * auto channel decision for 2.4GHz hot spot mode
+ *
+ * 08 16 2011 yuche.tsai
+ * NULL
+ * Fix scan policy for Active LISTEN scan.
+ *
+ * 08 09 2011 yuche.tsai
+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
+ * Invitation Feature add on.
+ *
+ * 08 02 2011 yuche.tsai
+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client,
+ * TX deauth to a disconnecting device issue.
+ * Support TX Deauth Issue.
+ *
+ * 07 26 2011 yuche.tsai
+ * [WCXRP00000875] [Volunteer Patch][WiFi Direct][Driver] MT6620 IOT issue with realtek test bed solution.
+ * Turn off persistent group support for V2.0 release.
+ *
+ * 07 18 2011 yuche.tsai
+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution.
+ * Fix compile error.
+ *
+ * 07 18 2011 yuche.tsai
+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution.
+ * Fix MT6620 WiFi Direct IOT Issue with BCM solution.
+ *
+ * 07 11 2011 yuche.tsai
+ * [WCXRP00000845] [Volunteer Patch][WiFi Direct] WiFi Direct Device Connection Robustness
+ * Enhance Connection Robustness.
+ *
+ * 07 08 2011 yuche.tsai
+ * [WCXRP00000841] [Volunteer Patch][WiFi Direct] Group Owner Setting.
+ * Update GO configure parameter.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Disable enhancement II for debugging.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Refine compile flag.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Add wifi direct connection enhancement method I, II & VI.
+ *
+ * 06 20 2011 yuche.tsai
+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue.
+ * Fix connection indication twice issue.
+ *
+ * 06 07 2011 yuche.tsai
+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue
+ * Fix RX SD request under AP mode issue.
+ *
+ * 05 04 2011 yuche.tsai
+ * NULL
+ * Support partial persistent group function.
+ *
+ * 04 20 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 08 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Add device discoverability support.
+ *
+ * 03 25 2011 yuche.tsai
+ * NULL
+ * Improve some error handleing.
+ *
+ * 03 22 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * link with supplicant commands
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * 1.Shorten the LISTEN interval.
+ * 2. Fix IF address issue when we are GO
+ * 3. Fix LISTEN channel issue.
+ *
+ * 03 21 2011 yuche.tsai
+ * NULL
+ * Change P2P Connection Request Flow.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
+ * Add beacon timeout support.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue
+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO.
+ *
+ * 03 18 2011 yuche.tsai
+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow
+ * Modify connection flow after Group Formation Complete, or device connect to a GO.
+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN.
+ *
+ * 03 15 2011 yuche.tsai
+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue
+ * Fix some configure method issue.
+ *
+ * 03 10 2011 yuche.tsai
+ * NULL
+ * Add P2P API.
+ *
+ * 03 07 2011 yuche.tsai
+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation.
+ * .
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 01 2011 yuche.tsai
+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation
+ * Update channel issue when doing GO formation..
+ *
+ * 03 01 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Update Service Discovery Related wlanoid function.
+ *
+ * 02 18 2011 wh.su
+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
+ * fixed the ioctl setting that index not map to spec defined config method.
+ *
+ * 02 18 2011 yuche.tsai
+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
+ * Fix WSC IE BE format issue.
+ *
+ * 02 17 2011 wh.su
+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
+ * append the WSC IE config method attribute at provision discovery request.
+ *
+ * 02 11 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add two function prototype.
+ *
+ * 02 10 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Support Disassoc & Deauthentication for Hot-Spot.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+
+2. Provision Discovery Request/Response
+
+ * Add Service Discovery Indication Related code.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add Support for MLME deauthentication for Hot-Spot.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue
+ * Fix Client Limit Issue.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+
+2. Provision Discovery Request/Response
+
+ * Add Service Discovery Function.
+ *
+ * 01 25 2011 terry.wu
+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter
+ * Add a new module parameter to indicate current runnig mode, P2P or AP.
+ *
+ * 01 19 2011 george.huang
+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability
+ * Null NOA attribute setting when no related parameters.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Modify some behavior of AP mode.
+ *
+ * 12 22 2010 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Fix Compile Error.
+ *
+ * 12 15 2010 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Refine Connection Flow.
+ *
+ * 12 08 2010 yuche.tsai
+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode.
+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client
+ * by checking the P2P IE in assoc req frame.
+ *
+ * 12 02 2010 yuche.tsai
+ * NULL
+ * Update P2P Connection Policy for Invitation.
+ *
+ * 12 02 2010 yuche.tsai
+ * NULL
+ * Update P2P Connection Policy for Invitation & Provision Discovery.
+ *
+ * 11 30 2010 yuche.tsai
+ * NULL
+ * Invitation & Provision Discovery Indication.
+ *
+ * 11 30 2010 yuche.tsai
+ * NULL
+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ
+ *
+ * 11 29 2010 yuche.tsai
+ * NULL
+ * Update P2P related function for INVITATION & PROVISION DISCOVERY.
+ *
+ * 11 26 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * Update P2P PS for NOA function.
+ *
+ * 11 25 2010 yuche.tsai
+ * NULL
+ * Update Code for Invitation Related Function.
+ *
+ * 11 17 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW]
+ * Set the Tx lowest rate at wlan table for normal operation
+ * fixed some ASSERT check.
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Add the code to support disconnect p2p group
+ *
+ * 10 08 2010 wh.su
+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
+ * update the frog's new p2p state machine.
+ *
+ * 10 04 2010 wh.su
+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
+ * fixed compiling error while enable p2p.
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 09 10 2010 wh.su
+ * NULL
+ * fixed the compiling error at WinXP.
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * Add connection abort message event prototype.
+ *
+ * 08 20 2010 kevin.huang
+ * NULL
+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete()
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Fix P2P Intended Interface Address Bug.
+ * Extend GO Nego Timeout Time.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Extend Listen Interval default value & remove deprecated variable.
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse()
+ *
+ * 08 12 2010 yuche.tsai
+ * NULL
+ * Add function prototype for join complete.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add some function proto type for P2P FSM under provisioning phase..
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Change P2P data structure for supporting
+ * 1. P2P Device discovery.
+ * 2. P2P Group Negotiation.
+ * 3. P2P JOIN
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Check-in P2P Device Discovery Feature.
+ *
+ * 08 03 2010 george.huang
+ * NULL
+ * handle event for updating NOA parameters indicated from FW
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Update P2P FSM header file.
+ *
+ * 07 23 2010 cp.wu
+ *
+ * P2P/RSN/WAPI IEs need to be declared with compact structure.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add for P2P Scan Result Parsing & Saving.
+ *
+ * 07 19 2010 yuche.tsai
+ *
+ * Update P2P FSM header file.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Fix some P2P function prototype.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * First draft for migration P2P FSM from FW to Driver.
+ *
+ * 03 18 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Rename CFG flag for P2P
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Modify parameter of p2pStartGO
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add Wi-Fi Direct SSID and P2P GO Test Mode
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+*/
+
+#ifndef _P2P_FSM_H
+#define _P2P_FSM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+#define CID52_53_54         0
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_P2P_STATE_T {
+	P2P_STATE_IDLE = 0,
+	P2P_STATE_SCAN,
+	P2P_STATE_AP_CHANNEL_DETECT,
+	P2P_STATE_REQING_CHANNEL,
+	P2P_STATE_CHNL_ON_HAND,	/* Requesting Channel to Send Specific Frame. */
+	P2P_STATE_GC_JOIN,	/* Sending Specific Frame. May extending channel by other event. */
+	P2P_STATE_NUM
+} ENUM_P2P_STATE_T, *P_ENUM_P2P_STATE_T;
+
+enum _ENUM_P2P_DEV_EXT_LISTEN_T {
+	P2P_DEV_NOT_EXT_LISTEN,
+	P2P_DEV_EXT_LISTEN_ING,
+	P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT,
+	P2P_DEV_EXT_LISTEN_NUM
+};
+
+typedef enum _ENUM_CHANNEL_REQ_TYPE_T {
+	CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL,
+	CHANNEL_REQ_TYPE_GC_JOIN_REQ,
+	CHANNEL_REQ_TYPE_GO_START_BSS
+} ENUM_CHANNEL_REQ_TYPE_T, *P_ENUM_CHANNEL_REQ_TYPE_T;
+
+typedef enum _ENUM_BUFFER_TYPE_T {
+	ENUM_FRAME_TYPE_EXTRA_IE_BEACON,
+	ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP,
+	ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP,
+	ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE,
+	ENUM_FRAME_TYPE_BEACON_TEMPLATE,
+	ENUM_FRAME_IE_NUM
+} ENUM_BUFFER_TYPE_T, *P_ENUM_BUFFER_TYPE_T;
+
+typedef enum _ENUM_HIDDEN_SSID_TYPE_T {
+	ENUM_HIDDEN_SSID_NONE,
+	ENUM_HIDDEN_SSID_LEN,
+	ENUM_HIDDEN_SSID_ZERO_CONTENT,
+	ENUM_HIDDEN_SSID_NUM
+} ENUM_HIDDEN_SSID_TYPE_T, *P_ENUM_HIDDEN_SSID_TYPE_T;
+
+typedef struct _P2P_SSID_STRUCT_T {
+	UINT_8 aucSsid[32];
+	UINT_8 ucSsidLen;
+} P2P_SSID_STRUCT_T, *P_P2P_SSID_STRUCT_T;
+
+typedef struct _P2P_STATION_INFO_T {
+	UINT_32 u4InactiveTime;
+	UINT_32 u4RxBytes;	/* TODO: */
+	UINT_32 u4TxBytes;	/* TODO: */
+	UINT_32 u4RxPackets;	/* TODO: */
+	UINT_32 u4TxPackets;	/* TODO: */
+	/* TODO: Add more for requirement. */
+} P2P_STATION_INFO_T, *P_P2P_STATION_INFO_T;
+
+typedef struct _AP_CRYPTO_SETTINGS_T {
+	UINT_32 u4WpaVersion;
+	UINT_32 u4CipherGroup;
+	INT_32 i4NumOfCiphers;
+	UINT_32 aucCiphersPairwise[5];
+	INT_32 i4NumOfAkmSuites;
+	UINT_32 aucAkmSuites[2];
+	BOOLEAN fgIsControlPort;
+	UINT_16 u2ControlPortBE;
+	BOOLEAN fgIsControlPortEncrypt;
+} AP_CRYPTO_SETTINGS_T, *P_AP_CRYPTO_SETTINGS_T;
+
+/*-------------------- P2P FSM ACTION STRUCT ---------------------*/
+typedef struct _P2P_CHNL_REQ_INFO_T {
+	BOOLEAN fgIsChannelRequested;
+	UINT_8 ucSeqNumOfChReq;
+	UINT_64 u8Cookie;
+	UINT_8 ucReqChnlNum;
+	ENUM_BAND_T eBand;
+	ENUM_CHNL_EXT_T eChnlSco;
+	UINT_32 u4MaxInterval;
+	ENUM_CHANNEL_REQ_TYPE_T eChannelReqType;
+
+	UINT_8 ucOriChnlNum;
+	ENUM_BAND_T eOriBand;
+	ENUM_CHNL_EXT_T eOriChnlSco;
+	UINT_32 NFC_BEAM;	/*NFC Beam + Indication */
+} P2P_CHNL_REQ_INFO_T, *P_P2P_CHNL_REQ_INFO_T;
+
+typedef struct _P2P_SCAN_REQ_INFO_T {
+	ENUM_SCAN_TYPE_T eScanType;
+	ENUM_SCAN_CHANNEL eChannelSet;
+	UINT_16 u2PassiveDewellTime;
+	UINT_8 ucSeqNumOfScnMsg;
+	BOOLEAN fgIsAbort;
+	BOOLEAN fgIsScanRequest;
+	UINT_8 ucNumChannelList;
+	RF_CHANNEL_INFO_T arScanChannelList[MAXIMUM_OPERATION_CHANNEL_LIST];
+	UINT_32 u4BufLength;
+	UINT_8 aucIEBuf[MAX_IE_LENGTH];
+	P2P_SSID_STRUCT_T rSsidStruct;	/* Currently we can only take one SSID scan request */
+	BOOLEAN fgIsGOInitialDone;
+} P2P_SCAN_REQ_INFO_T, *P_P2P_SCAN_REQ_INFO_T;
+
+typedef struct _P2P_CONNECTION_REQ_INFO_T {
+
+	BOOLEAN fgIsConnRequest;
+	P2P_SSID_STRUCT_T rSsidStruct;
+	UINT_8 aucBssid[MAC_ADDR_LEN];
+	/* For ASSOC Req. */
+	UINT_32 u4BufLength;
+	UINT_8 aucIEBuf[MAX_IE_LENGTH];
+} P2P_CONNECTION_REQ_INFO_T, *P_P2P_CONNECTION_REQ_INFO_T;
+
+typedef struct _P2P_MGMT_TX_REQ_INFO_T {
+	BOOLEAN fgIsMgmtTxRequested;
+	P_MSDU_INFO_T prMgmtTxMsdu;
+	UINT_64 u8Cookie;
+} P2P_MGMT_TX_REQ_INFO_T, *P_P2P_MGMT_TX_REQ_INFO_T;
+
+struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T {
+	MSG_HDR_T rMsgHdr;
+	UINT_32 wait; /* interval supplicant expected to stay in listen interval */
+};
+
+typedef struct _P2P_BEACON_UPDATE_INFO_T {
+	PUINT_8 pucBcnHdr;
+	UINT_32 u4BcnHdrLen;
+	PUINT_8 pucBcnBody;
+	UINT_32 u4BcnBodyLen;
+} P2P_BEACON_UPDATE_INFO_T, *P_P2P_BEACON_UPDATE_INFO_T;
+
+typedef struct _P2P_PROBE_RSP_UPDATE_INFO_T {
+	P_MSDU_INFO_T prProbeRspMsduTemplate;
+} P2P_PROBE_RSP_UPDATE_INFO_T, *P_P2P_PROBE_RSP_UPDATE_INFO_T;
+
+typedef struct _P2P_ASSOC_RSP_UPDATE_INFO_T {
+	PUINT_8 pucAssocRspExtIE;
+	UINT_16 u2AssocIELen;
+} P2P_ASSOC_RSP_UPDATE_INFO_T, *P_P2P_ASSOC_RSP_UPDATE_INFO_T;
+
+typedef struct _P2P_JOIN_INFO_T {
+	UINT_32 ucSeqNumOfReqMsg;
+	UINT_8 ucAvailableAuthTypes;
+	P_STA_RECORD_T prTargetStaRec;
+	P2P_SSID_STRUCT_T rSsidStruct;
+	BOOLEAN fgIsJoinComplete;
+	/* For ASSOC Rsp. */
+	UINT_32 u4BufLength;
+	UINT_8 aucIEBuf[MAX_IE_LENGTH];
+} P2P_JOIN_INFO_T, *P_P2P_JOIN_INFO_T;
+
+#if CFG_SUPPORT_WFD
+
+#define WFD_FLAGS_DEV_INFO_VALID            BIT(0)	/* 1. WFD_DEV_INFO, 2. WFD_CTRL_PORT, 3. WFD_MAT_TP. */
+#define WFD_FLAGS_SINK_INFO_VALID           BIT(1)	/* 1. WFD_SINK_STATUS, 2. WFD_SINK_MAC. */
+#define WFD_FLAGS_ASSOC_MAC_VALID        BIT(2)	/* 1. WFD_ASSOC_MAC. */
+#define WFD_FLAGS_EXT_CAPABILITY_VALID  BIT(3)	/* 1. WFD_EXTEND_CAPABILITY. */
+
+struct _WFD_CFG_SETTINGS_T {
+	UINT_32 u4WfdCmdType;
+	UINT_8 ucWfdEnable;
+	UINT_8 ucWfdCoupleSinkStatus;
+	UINT_8 ucWfdSessionAvailable;	/* 0: NA 1:Set 2:Clear */
+	UINT_8 ucWfdSigmaMode;
+	UINT_16 u2WfdDevInfo;
+	UINT_16 u2WfdControlPort;
+	UINT_16 u2WfdMaximumTp;
+	UINT_16 u2WfdExtendCap;
+	UINT_8 aucWfdCoupleSinkAddress[MAC_ADDR_LEN];
+	UINT_8 aucWfdAssociatedBssid[MAC_ADDR_LEN];
+	UINT_8 aucWfdVideoIp[4];
+	UINT_8 aucWfdAudioIp[4];
+	UINT_16 u2WfdVideoPort;
+	UINT_16 u2WfdAudioPort;
+	UINT_32 u4WfdFlag;
+	UINT_32 u4WfdPolicy;
+	UINT_32 u4WfdState;
+	UINT_8 aucWfdSessionInformationIE[24 * 8];
+	UINT_16 u2WfdSessionInformationIELen;
+	UINT_8 aucReserved1[2];
+	UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN];
+	UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN];
+	UINT_32 u4WfdAdvancedFlag;
+	/* Group 1 64 bytes */
+	UINT_8 aucWfdLocalIp[4];
+	UINT_16 u2WfdLifetimeAc2;	/* Unit is 2 TU */
+	UINT_16 u2WfdLifetimeAc3;	/* Unit is 2 TU */
+	UINT_16 u2WfdCounterThreshold;	/* Unit is ms */
+	UINT_8 aucReverved2[54];
+	/* Group 2 64 bytes */
+	UINT_8 aucReverved3[64];
+	/* Group 3 64 bytes */
+	UINT_8 aucReverved4[64];
+
+};
+
+struct _WFD_DBG_CFG_SETTINGS_T {
+	UINT_8 ucWfdDebugMode;
+	UINT_16 u2WfdSNShowPeiroid;
+	UINT_8 Reserved;
+
+};
+
+#endif
+
+struct _P2P_FSM_INFO_T {
+	/* State related. */
+	ENUM_P2P_STATE_T ePreviousState;
+	ENUM_P2P_STATE_T eCurrentState;
+
+	/* Channel related. */
+	P2P_CHNL_REQ_INFO_T rChnlReqInfo;
+
+	/* Scan related. */
+	P2P_SCAN_REQ_INFO_T rScanReqInfo;
+
+	/* Connection related. */
+	P2P_CONNECTION_REQ_INFO_T rConnReqInfo;
+
+	/* Mgmt tx related. */
+	P2P_MGMT_TX_REQ_INFO_T rMgmtTxInfo;
+
+	/* Beacon related. */
+	P2P_BEACON_UPDATE_INFO_T rBcnContentInfo;
+
+	/* Probe Response related. */
+	P2P_PROBE_RSP_UPDATE_INFO_T rProbeRspContentInfo;
+
+	/* Assoc Rsp related. */
+	P2P_ASSOC_RSP_UPDATE_INFO_T rAssocRspContentInfo;
+
+	/* GC Join related. */
+	P2P_JOIN_INFO_T rJoinInfo;
+
+	/* FSM Timer */
+/* TIMER_T rP2pFsmTimeoutTimer; */
+
+	/* GC Target BSS. */
+	P_BSS_DESC_T prTargetBss;
+
+	/* GC Connection Request. */
+	BOOLEAN fgIsConnectionRequested;
+
+	BOOLEAN fgIsApMode;
+
+	/* Channel grant interval. */
+	UINT_32 u4GrantInterval;
+
+	/* Packet filter for P2P module. */
+	UINT_32 u4P2pPacketFilter;
+
+	/* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Prepare for use vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
+	/* Msg event queue. */
+	LINK_T rMsgEventQueue;
+
+#if CFG_SUPPORT_WFD
+	WFD_CFG_SETTINGS_T rWfdConfigureSettings;
+	WFD_DBG_CFG_SETTINGS_T rWfdDebugSetting;
+#endif
+
+	BOOLEAN fgIsWPSMode;
+
+	enum _ENUM_P2P_DEV_EXT_LISTEN_T eListenExted;
+};
+
+/*---------------- Messages -------------------*/
+typedef struct _MSG_P2P_SCAN_REQUEST_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	P_P2P_SSID_STRUCT_T prSSID;
+	INT_32 i4SsidNum;
+	UINT_32 u4NumChannel;
+	PUINT_8 pucIEBuf;
+	UINT_32 u4IELen;
+	BOOLEAN fgIsAbort;
+	RF_CHANNEL_INFO_T arChannelListInfo[1];
+} MSG_P2P_SCAN_REQUEST_T, *P_MSG_P2P_SCAN_REQUEST_T;
+
+typedef struct _MSG_P2P_CHNL_REQUEST_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_64 u8Cookie;
+	UINT_32 u4Duration;
+	ENUM_CHNL_EXT_T eChnlSco;
+	RF_CHANNEL_INFO_T rChannelInfo;
+} MSG_P2P_CHNL_REQUEST_T, *P_MSG_P2P_CHNL_REQUEST_T;
+
+typedef struct _MSG_P2P_CHNL_ABORT_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_64 u8Cookie;
+} MSG_P2P_CHNL_ABORT_T, *P_MSG_P2P_CHNL_ABORT_T;
+
+typedef struct _MSG_P2P_CONNECTION_REQUEST_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	P2P_SSID_STRUCT_T rSsid;
+	UINT_8 aucBssid[MAC_ADDR_LEN];
+	ENUM_CHNL_EXT_T eChnlSco;
+	RF_CHANNEL_INFO_T rChannelInfo;
+	UINT_32 u4IELen;
+	UINT_8 aucIEBuf[1];
+	/* TODO: Auth Type, OPEN, SHARED, FT, EAP... */
+} MSG_P2P_CONNECTION_REQUEST_T, *P_MSG_P2P_CONNECTION_REQUEST_T;
+
+typedef struct _MSG_P2P_CONNECTION_ABORT_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member. */
+	UINT_8 aucTargetID[MAC_ADDR_LEN];
+	UINT_16 u2ReasonCode;
+	BOOLEAN fgSendDeauth;
+} MSG_P2P_CONNECTION_ABORT_T, *P_MSG_P2P_CONNECTION_ABORT_T;
+
+typedef struct _MSG_P2P_MGMT_TX_REQUEST_T {
+	MSG_HDR_T rMsgHdr;
+	P_MSDU_INFO_T prMgmtMsduInfo;
+	UINT_64 u8Cookie;	/* For indication. */
+	BOOLEAN fgNoneCckRate;
+	BOOLEAN fgIsWaitRsp;
+} MSG_P2P_MGMT_TX_REQUEST_T, *P_MSG_P2P_MGMT_TX_REQUEST_T;
+
+typedef struct _MSG_P2P_START_AP_T {
+	MSG_HDR_T rMsgHdr;
+	UINT_32 u4DtimPeriod;
+	UINT_32 u4BcnInterval;
+	UINT_8 aucSsid[32];
+	UINT_16 u2SsidLen;
+	UINT_8 ucHiddenSsidType;
+	BOOLEAN fgIsPrivacy;
+	AP_CRYPTO_SETTINGS_T rEncryptionSettings;
+	INT_32 i4InactiveTimeout;
+} MSG_P2P_START_AP_T, *P_MSG_P2P_START_AP_T;
+
+typedef struct _MSG_P2P_BEACON_UPDATE_T {
+	MSG_HDR_T rMsgHdr;
+	UINT_32 u4BcnHdrLen;
+	UINT_32 u4BcnBodyLen;
+	PUINT_8 pucBcnHdr;
+	PUINT_8 pucBcnBody;
+	UINT_8 aucBuffer[1];	/* Header & Body are put here. */
+} MSG_P2P_BEACON_UPDATE_T, *P_MSG_P2P_BEACON_UPDATE_T;
+
+typedef struct _MSG_P2P_MGMT_FRAME_UPDATE_T {
+	MSG_HDR_T rMsgHdr;
+	ENUM_BUFFER_TYPE_T eBufferType;
+	UINT_32 u4BufferLen;
+	UINT_8 aucBuffer[1];
+} MSG_P2P_MGMT_FRAME_UPDATE_T, *P_MSG_P2P_MGMT_FRAME_UPDATE_T;
+
+typedef struct _MSG_P2P_SWITCH_OP_MODE_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	ENUM_OP_MODE_T eOpMode;
+} MSG_P2P_SWITCH_OP_MODE_T, *P_MSG_P2P_SWITCH_OP_MODE_T;
+
+typedef struct _MSG_P2P_MGMT_FRAME_REGISTER_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_16 u2FrameType;
+	BOOLEAN fgIsRegister;
+} MSG_P2P_MGMT_FRAME_REGISTER_T, *P_MSG_P2P_MGMT_FRAME_REGISTER_T;
+
+typedef struct _MSG_P2P_NETDEV_REGISTER_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	BOOLEAN fgIsEnable;
+	UINT_8 ucMode;
+} MSG_P2P_NETDEV_REGISTER_T, *P_MSG_P2P_NETDEV_REGISTER_T;
+
+#if CFG_SUPPORT_WFD
+typedef struct _MSG_WFD_CONFIG_SETTINGS_CHANGED_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings;
+} MSG_WFD_CONFIG_SETTINGS_CHANGED_T, *P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T;
+#endif
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState);
+
+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo);
+
+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+WLAN_STATUS
+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter,
+			      IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+#if CFG_SUPPORT_WFD
+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+#endif
+
+#if 0
+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */
+/* ///////////////////////////////////////////////////////////////////////////////////// */
+/* ///////////////////////////////////////////////////////////////////////////////////// */
+/* ///////////////////////////////////////////////////////////////////////////////////// */
+/* ///////////////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */
+#endif
+
+/* 3 --------------- WFA P2P DEFAULT PARAMETERS --------------- */
+#define P2P_WILDCARD_SSID                           "DIRECT-"
+#define P2P_WILDCARD_SSID_LEN                       7
+#define P2P_GROUP_ID_LEN                            9
+
+#define P2P_DRIVER_VERSION                          2	/* Update when needed. */
+
+#define P2P_DEFAULT_DEV_NAME                        "Wireless Client"
+#define P2P_DEFAULT_DEV_NAME_LEN                    15
+#define P2P_DEFAULT_PRIMARY_CATEGORY_ID             10
+#define P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID         5
+#define P2P_DEFAULT_CONFIG_METHOD                   \
+	(WPS_ATTRI_CFG_METHOD_PUSH_BUTTON | WPS_ATTRI_CFG_METHOD_KEYPAD | WPS_ATTRI_CFG_METHOD_DISPLAY)
+#define P2P_DEFAULT_LISTEN_CHANNEL                  1
+
+#define P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT        0	/* NOTE(Kevin): Shall <= 16 */
+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT        13
+
+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE         51	/* Contains 6 sub-band. */
+
+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT        8	/* NOTE(Kevin): Shall <= 16 */
+
+#define P2P_MAXIMUM_CLIENT_COUNT                    8
+#define P2P_MAXIMUM_NOA_COUNT                       8
+
+#define P2P_MAXIMUM_ATTRIBUTE_LEN                   251
+
+#define P2P_CTWINDOW_DEFAULT                        25	/* in TU=(1024usec) */
+
+#define P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE           768
+
+/* P2P 3.1.2.1.3 - Find Phase */
+#define P2P_MAX_DISCOVERABLE_INTERVAL    8	/* 3 */
+#define P2P_MIN_DISCOVERABLE_INTERVAL    5	/* 1 */
+
+#define P2P_LISTEN_SCAN_UNIT             100	/* MS */
+
+/* FSM Time Related constrain. */
+#define P2P_SERACH_STATE_PERIOD_MS       1000	/* Deprecated. */
+
+#define P2P_GO_CHANNEL_STAY_INTERVAL     1000
+
+#define P2P_GO_NEGO_TIMEOUT_MS           500
+#define P2P_CONNECTION_TIMEOUT_SEC       120
+
+#define P2P_INVITAION_TIMEOUT_MS         500		/* Timeout Wait Invitation Resonse. */
+#define P2P_PROVISION_DISCOVERY_TIMEOUT_MS     500	/* Timeout Wait Provision Discovery Resonse. */
+
+/* 3  --------------- WFA P2P IE --------------- */
+/* P2P 4.1.1 - P2P IE format */
+#define P2P_OUI_TYPE_LEN                            4
+#define P2P_IE_OUI_HDR                              (ELEM_HDR_LEN + P2P_OUI_TYPE_LEN)	/* == OFFSET_OF(IE_P2P_T,
+												aucP2PAttributes[0]) */
+
+/* P2P 4.1.1 - General P2P Attribute */
+#define P2P_ATTRI_HDR_LEN                           3	/* ID(1 octet) + Length(2 octets) */
+#define P2P_ATTRI_LEN_NOTICE_OF_ABSENCE                 (P2P_ATTRI_HDR_LEN + 2)	/* 5 */
+
+/* P2P 4.1.1 - P2P Attribute ID definitions */
+#define P2P_ATTRI_ID_STATUS                                 0
+#define P2P_ATTRI_ID_REASON_CODE                            1
+#define P2P_ATTRI_ID_P2P_CAPABILITY                         2
+#define P2P_ATTRI_ID_P2P_DEV_ID                             3
+#define P2P_ATTRI_ID_GO_INTENT                              4
+#define P2P_ATTRI_ID_CFG_TIMEOUT                            5
+#define P2P_ATTRI_ID_LISTEN_CHANNEL                         6
+#define P2P_ATTRI_ID_P2P_GROUP_BSSID                        7
+#define P2P_ATTRI_ID_EXT_LISTEN_TIMING                      8
+#define P2P_ATTRI_ID_INTENDED_P2P_IF_ADDR                   9
+#define P2P_ATTRI_ID_P2P_MANAGEABILITY                      10
+#define P2P_ATTRI_ID_CHANNEL_LIST                           11
+#define P2P_ATTRI_ID_NOTICE_OF_ABSENCE                      12
+#define P2P_ATTRI_ID_P2P_DEV_INFO                           13
+#define P2P_ATTRI_ID_P2P_GROUP_INFO                         14
+#define P2P_ATTRI_ID_P2P_GROUP_ID                           15
+#define P2P_ATTRI_ID_P2P_INTERFACE                          16
+#define P2P_ATTRI_ID_OPERATING_CHANNEL                      17
+#define P2P_ATTRI_ID_INVITATION_FLAG                        18
+#define P2P_ATTRI_ID_VENDOR_SPECIFIC                        221
+
+/* Maximum Length of P2P Attributes */
+#define P2P_ATTRI_MAX_LEN_STATUS                            1	/* 0 */
+#define P2P_ATTRI_MAX_LEN_REASON_CODE                       1	/* 1 */
+#define P2P_ATTRI_MAX_LEN_P2P_CAPABILITY                    2	/* 2 */
+#define P2P_ATTRI_MAX_LEN_P2P_DEV_ID                        6	/* 3 */
+#define P2P_ATTRI_MAX_LEN_GO_INTENT                         1	/* 4 */
+#define P2P_ATTRI_MAX_LEN_CFG_TIMEOUT                       2	/* 5 */
+#if CID52_53_54
+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL                    5	/* 6 */
+#else
+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL                    5	/* 6 */
+#endif
+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_BSSID                   6	/* 7 */
+#define P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING                 4	/* 8 */
+#define P2P_ATTRI_MAX_LEN_INTENDED_P2P_IF_ADDR              6	/* 9 */
+#define P2P_ATTRI_MAX_LEN_P2P_MANAGEABILITY                 1	/* 10 */
+/* #define P2P_ATTRI_MAX_LEN_CHANNEL_LIST                      3 + (n* (2 + num_of_ch)) */ /* 11 */
+#define P2P_ATTRI_LEN_CHANNEL_LIST                                  3	/* 11 */
+#define P2P_ATTRI_LEN_CHANNEL_ENTRY                                  2	/* 11 */
+
+/* #define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE                 2 + (n* (13)) */ /* 12 */
+#define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE                 (2 + (P2P_MAXIMUM_NOA_COUNT*(13)))	/* 12 */
+
+#define P2P_ATTRI_MAX_LEN_P2P_DEV_INFO                      (17 + (8 * (8)) + 36)	/* 13 */
+/* #define P2P_ATTRI_MAX_LEN_P2P_GROUP_INFO                    n* (25 + (m* (8)) + 32)  */ /* 14 */
+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_ID                      38	/* 15 */
+#define P2P_ATTRI_MAX_LEN_P2P_INTERFACE                     253	/* 7 + 6* [0~41]  */ /* 16 */
+#if CID52_53_54
+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL                 5	/* 17 */
+#else
+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL                 5	/* 17 */
+#endif
+#define P2P_ATTRI_MAX_LEN_INVITATION_FLAGS                  1	/* 18 */
+
+/* P2P 4.1.2 - P2P Status definitions */
+#define P2P_STATUS_SUCCESS                                  0
+#define P2P_STATUS_FAIL_INFO_IS_CURRENTLY_UNAVAILABLE   1
+#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM                  2
+#define P2P_STATUS_FAIL_LIMIT_REACHED                       3
+#define P2P_STATUS_FAIL_INVALID_PARAM                       4
+#define P2P_STATUS_FAIL_UNABLE_ACCOMMODATE_REQ              5
+#define P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR               6
+#define P2P_STATUS_FAIL_NO_COMMON_CHANNELS                  7
+#define P2P_STATUS_FAIL_UNKNOWN_P2P_GROUP                   8
+#define P2P_STATUS_FAIL_SAME_INTENT_VALUE_15                9
+#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVISION_METHOD       10
+#define P2P_STATUS_FAIL_REJECTED_BY_USER                    11
+
+/* P2P 4.1.3 - P2P Minor Reason Code definitions */
+#define P2P_REASON_SUCCESS                                  0
+#define P2P_REASON_DISASSOCIATED_DUE_CROSS_CONNECTION       1
+#define P2P_REASON_DISASSOCIATED_DUE_UNMANAGEABLE           2
+#define P2P_REASON_DISASSOCIATED_DUE_NO_P2P_COEXIST_PARAM   3
+#define P2P_REASON_DISASSOCIATED_DUE_MANAGEABLE             4
+
+/* P2P 4.1.4 - Device Capability Bitmap definitions */
+#define P2P_DEV_CAPABILITY_SERVICE_DISCOVERY                BIT(0)
+#define P2P_DEV_CAPABILITY_CLIENT_DISCOVERABILITY           BIT(1)
+#define P2P_DEV_CAPABILITY_CONCURRENT_OPERATION             BIT(2)
+#define P2P_DEV_CAPABILITY_P2P_INFRA_MANAGED                BIT(3)
+#define P2P_DEV_CAPABILITY_P2P_DEVICE_LIMIT                 BIT(4)
+#define P2P_DEV_CAPABILITY_P2P_INVITATION_PROCEDURE         BIT(5)
+
+/* P2P 4.1.4 - Group Capability Bitmap definitions */
+#define P2P_GROUP_CAPABILITY_P2P_GROUP_OWNER                BIT(0)
+#define P2P_GROUP_CAPABILITY_PERSISTENT_P2P_GROUP           BIT(1)
+#define P2P_GROUP_CAPABILITY_P2P_GROUP_LIMIT                BIT(2)
+#define P2P_GROUP_CAPABILITY_INTRA_BSS_DISTRIBUTION         BIT(3)
+#define P2P_GROUP_CAPABILITY_CROSS_CONNECTION               BIT(4)
+#define P2P_GROUP_CAPABILITY_PERSISTENT_RECONNECT           BIT(5)
+#define P2P_GROUP_CAPABILITY_GROUP_FORMATION                BIT(6)
+
+/* P2P 4.1.6 - GO Intent field definitions */
+#define P2P_GO_INTENT_TIE_BREAKER_FIELD                     BIT(0)
+#define P2P_GO_INTENT_VALUE_MASK                            BITS(1, 7)
+#define P2P_GO_INTENT_VALUE_OFFSET                          1
+
+/* P2P 4.1.12 - Manageability Bitmap definitions */
+#define P2P_DEVICE_MANAGEMENT                               BIT(0)
+
+/* P2P 4.1.14 - CTWindow and OppPS Parameters definitions */
+#define P2P_CTW_OPPPS_PARAM_OPPPS_FIELD                     BIT(7)
+#define P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK                   BITS(0, 6)
+
+#define ELEM_MAX_LEN_P2P_FOR_PROBE_REQ                      \
+	    (P2P_OUI_TYPE_LEN + \
+	     (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \
+	     (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_ID) + \
+	     (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL) + \
+	     (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL))
+
+#define ELEM_MAX_LEN_P2P_FOR_ASSOC_REQ                      \
+	    (P2P_OUI_TYPE_LEN + \
+	     (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \
+	     (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING) + \
+	     (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_INFO))
+
+/* P2P 4.1.16 - P2P Client Infor Descriptor */
+#define P2P_CLIENT_INFO_DESC_HDR_LEN                        1	/* Length(1 octets) */
+
+/* P2P 4.1.20 - P2P Invitation Flags Attribute*/
+#define P2P_INVITATION_FLAGS_INVITATION_TYPE       BIT(0)
+#define P2P_INVITATION_TYPE_INVITATION                      0
+#define P2P_INVITATION_TYPE_REINVOKE                          1
+/* 3  --------------- WPS Data Element Definitions --------------- */
+/* P2P 4.2.2 - General WSC Attribute */
+#define WSC_ATTRI_HDR_LEN                                   4	/* ID(2 octet) + Length(2 octets) */
+#define WSC_ATTRI_MAX_LEN_VERSION                           1
+#define WSC_ATTRI_MAX_LEN_DEVICE_PASSWORD_ID                2
+#define WSC_ATTRI_LEN_CONFIG_METHOD                         2
+
+/* WPS 11 - Data Element Definitions */
+#define WPS_ATTRI_ID_VERSION            0x104A
+#define WPS_ATTRI_ID_CONFIGURATION_METHODS   0x1008
+#define WPS_ATTRI_ID_DEVICE_PASSWORD    0x1012
+#define WPS_ATTRI_ID_DEVICE_NAME        0x1011
+#define WPS_ATTRI_ID_PRI_DEVICE_TYPE    0x1054
+#define WPS_ATTRI_ID_SEC_DEVICE_TYPE    0x1055
+
+#define WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE           300
+
+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME   32	/* 0x1011 */
+
+#define WPS_ATTRI_CFG_METHOD_USBA           BIT(0)
+#define WPS_ATTRI_CFG_METHOD_ETHERNET       BIT(1)
+#define WPS_ATTRI_CFG_METHOD_LABEL          BIT(2)
+#define WPS_ATTRI_CFG_METHOD_DISPLAY        BIT(3)
+#define WPS_ATTRI_CFG_METHOD_EXT_NFC        BIT(4)
+#define WPS_ATTRI_CFG_METHOD_INT_NFC        BIT(5)
+#define WPS_ATTRI_CFG_METHOD_NFC_IF         BIT(6)
+#define WPS_ATTRI_CFG_METHOD_PUSH_BUTTON    BIT(7)
+#define WPS_ATTRI_CFG_METHOD_KEYPAD         BIT(8)
+
+#define P2P_FLAGS_PROVISION_COMPLETE                            0x00000001
+#define P2P_FLAGS_PROVISION_DISCOVERY_COMPLETE        0x00000002
+#define P2P_FLAGS_PROVISION_DISCOVERY_WAIT_RESPONSE 0x00000004
+#define P2P_FLAGS_PROVISION_DISCOVERY_RESPONSE_WAIT  0x00000008
+#define P2P_FLAGS_MASK_PROVISION                                    0x00000017
+#define P2P_FLAGS_MASK_PROVISION_COMPLETE                   0x00000015
+#define P2P_FLAGS_PROVISION_DISCOVERY_INDICATED        0x00000010
+#define P2P_FLAGS_INVITATION_TOBE_GO                            0x00000100
+#define P2P_FLAGS_INVITATION_TOBE_GC                            0x00000200
+#define P2P_FLAGS_INVITATION_SUCCESS                            0x00000400
+#define P2P_FLAGS_INVITATION_WAITING_TARGET                            0x00000800
+#define P2P_FLAGS_MASK_INVITATION                                  0x00000F00
+#define P2P_FLAGS_FORMATION_ON_GOING                          0x00010000
+#define P2P_FLAGS_FORMATION_LOCAL_PWID_RDY              0x00020000
+#define P2P_FLAGS_FORMATION_TARGET_PWID_RDY           0x00040000
+#define P2P_FLAGS_FORMATION_COMPLETE                            0x00080000
+#define P2P_FLAGS_MASK_FORMATION                                  0x000F0000
+#define P2P_FLAGS_DEVICE_DISCOVER_REQ                        0x00100000
+#define P2P_FLAGS_DEVICE_DISCOVER_DONE                       0x00200000
+#define P2P_FLAGS_DEVICE_INVITATION_WAIT                      0x00400000
+#define P2P_FLAGS_DEVICE_SERVICE_DISCOVER_WAIT         0x00800000
+#define P2P_FLAGS_MASK_DEVICE_DISCOVER                        0x00F00000
+
+#define P2P_FLAGS_DEVICE_FORMATION_REQUEST                 0x01000000
+
+/* MACRO for flag operation */
+#define SET_FLAGS(_FlagsVar, _BitsToSet) \
+	{(_FlagsVar) = ((_FlagsVar) | (_BitsToSet))}
+
+#define TEST_FLAGS(_FlagsVar, _BitsToCheck) \
+	(((_FlagsVar) & (_BitsToCheck)) == (_BitsToCheck))
+
+#define CLEAR_FLAGS(_FlagsVar, _BitsToClear) \
+	{(_FlagsVar) &= ~(_BitsToClear)}
+
+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_I     0
+
+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_II     0
+
+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_III     0
+
+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_IV     0
+
+#define CFG_DISABLE_DELAY_PROVISION_DISCOVERY      0
+
+#define CFG_CONNECTION_POLICY_2_0                            0
+
+/* Device Password ID */
+enum wps_dev_password_id {
+	DEV_PW_DEFAULT = 0x0000,
+	DEV_PW_USER_SPECIFIED = 0x0001,
+	DEV_PW_MACHINE_SPECIFIED = 0x0002,
+	DEV_PW_REKEY = 0x0003,
+	DEV_PW_PUSHBUTTON = 0x0004,
+	DEV_PW_REGISTRAR_SPECIFIED = 0x0005
+};
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE)
+#pragma pack(1)
+#endif
+
+/* 3  --------------- WFA P2P IE and Attributes --------------- */
+
+/* P2P 4.1.1 - P2P Information Element */
+typedef struct _IE_P2P_T {
+	UINT_8 ucId;		/* Element ID */
+	UINT_8 ucLength;	/* Length */
+	UINT_8 aucOui[3];	/* OUI */
+	UINT_8 ucOuiType;	/* OUI Type */
+	UINT_8 aucP2PAttributes[1];	/* P2P Attributes */
+} __KAL_ATTRIB_PACKED__ IE_P2P_T, *P_IE_P2P_T;
+
+/* P2P 4.1.1 - General P2P Attribute */
+typedef struct _P2P_ATTRIBUTE_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucBody[1];	/* Body field */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRIBUTE_T, ATTRIBUTE_HDR_T, *P_P2P_ATTRIBUTE_T, *P_ATTRIBUTE_HDR_T;
+
+/* P2P 4.1.2 - P2P Status Attribute */
+typedef struct _P2P_ATTRI_STATUS_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucStatusCode;	/* Status Code */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_STATUS_T, *P_P2P_ATTRI_STATUS_T;
+
+/* P2P 4.1.3 - P2P Minor Reason Code Attribute */
+typedef struct _P2P_ATTRI_REASON_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucMinorReasonCode;	/* Minor Reason Code */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_REASON_T, *P_P2P_ATTRI_REASON_T;
+
+/* P2P 4.1.4 - P2P Capability Attribute */
+typedef struct _P2P_ATTRI_CAPABILITY_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucDeviceCap;	/* Device Capability Bitmap */
+	UINT_8 ucGroupCap;	/* Group Capability Bitmap */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CAPABILITY_T, *P_P2P_ATTRI_CAPABILITY_T;
+
+/* P2P 4.1.5 - P2P Device ID Attribute */
+typedef struct _P2P_ATTRI_DEV_ID_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucDevAddr[MAC_ADDR_LEN];	/* P2P Device Address */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_ID_T, *P_P2P_ATTRI_DEV_ID_T;
+
+/* P2P 4.1.6 - Group Owner Intent Attribute */
+typedef struct _P2P_ATTRI_GO_INTENT_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucGOIntent;	/* Group Owner Intent */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GO_INTENT_T, *P_P2P_ATTRI_GO_INTENT_T;
+
+/* P2P 4.1.7 - Configuration Timeout Attribute */
+typedef struct _P2P_ATTRI_CFG_TIMEOUT_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucGOCfgTimeout;	/* GO Configuration Timeout */
+	UINT_8 ucClientCfgTimeout;	/* Client Configuration Timeout */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CFG_TIMEOUT_T, *P_P2P_ATTRI_CFG_TIMEOUT_T;
+
+/* P2P 4.1.8 - Listen Channel Attribute */
+typedef struct _P2P_ATTRI_LISTEN_CHANNEL_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucCountryString[3];	/* Country String */
+	UINT_8 ucOperatingClass;	/* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */
+	UINT_8 ucChannelNumber;	/* Channel Number */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_LISTEN_CHANNEL_T, *P_P2P_ATTRI_LISTEN_CHANNEL_T;
+
+/* P2P 4.1.9 - P2P Group BSSID Attribute */
+typedef struct _P2P_ATTRI_GROUP_BSSID_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucBssid[MAC_ADDR_LEN];	/* P2P Group BSSID */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_BSSID_T, *P_P2P_ATTRI_GROUP_BSSID_T;
+
+/* P2P 4.1.10 - Extended Listen Timing Attribute */
+typedef struct _P2P_ATTRI_EXT_LISTEN_TIMING_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_16 u2AvailPeriod;	/* Availability Period */
+	UINT_16 u2AvailInterval;	/* Availability Interval */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_EXT_LISTEN_TIMING_T, *P_P2P_ATTRI_EXT_LISTEN_TIMING_T;
+
+/* P2P 4.1.11 - Intended P2P Interface Address Attribute */
+typedef struct _P2P_ATTRI_INTENDED_IF_ADDR_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucIfAddr[MAC_ADDR_LEN];	/* P2P Interface Address */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTENDED_IF_ADDR_T, *P_P2P_ATTRI_INTENDED_IF_ADDR_T;
+
+/* P2P 4.1.12 - P2P Manageability Attribute */
+typedef struct _P2P_ATTRI_MANAGEABILITY_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucManageability;	/* P2P Manageability Bitmap */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_MANAGEABILITY_T, *P_P2P_ATTRI_MANAGEABILITY_T;
+
+/* P2P 4.1.13 - Channel List Attribute */
+typedef struct _P2P_ATTRI_CHANNEL_LIST_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucCountryString[3];	/* Country String */
+	UINT_8 aucChannelEntry[1];	/* Channel Entry List */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CHANNEL_T, *P_P2P_ATTRI_CHANNEL_T;
+
+typedef struct _CHANNEL_ENTRY_FIELD_T {
+	UINT_8 ucRegulatoryClass;	/* Regulatory Class */
+	UINT_8 ucNumberOfChannels;	/* Number Of Channels */
+	UINT_8 aucChannelList[1];	/* Channel List */
+} __KAL_ATTRIB_PACKED__ CHANNEL_ENTRY_FIELD_T, *P_CHANNEL_ENTRY_FIELD_T;
+
+/* P2P 4.1.14 - Notice of Absence Attribute */
+typedef struct _P2P_ATTRI_NOA_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucIndex;		/* Index */
+	UINT_8 ucCTWOppPSParam;	/* CTWindow and OppPS Parameters */
+	UINT_8 aucNoADesc[1];	/* NoA Descriptor */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_NOA_T, *P_P2P_ATTRI_NOA_T;
+
+typedef struct _NOA_DESCRIPTOR_T {
+	UINT_8 ucCountType;	/* Count/Type */
+	UINT_32 u4Duration;	/* Duration */
+	UINT_32 u4Interval;	/* Interval */
+	UINT_32 u4StartTime;	/* Start Time */
+} __KAL_ATTRIB_PACKED__ NOA_DESCRIPTOR_T, *P_NOA_DESCRIPTOR_T;
+
+typedef struct _P2P_ATTRI_DEV_INFO_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucDevAddr[MAC_ADDR_LEN];	/* P2P Device Address */
+	UINT_16 u2ConfigMethodsBE;	/* Config Method */
+	DEVICE_TYPE_T rPrimaryDevTypeBE;	/* Primary Device Type */
+	UINT_8 ucNumOfSecondaryDevType;	/* Number of Secondary Device Types */
+	DEVICE_TYPE_T arSecondaryDevTypeListBE[1];	/* Secondary Device Type List */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_INFO_T, *P_P2P_ATTRI_DEV_INFO_T;
+
+/* WPS 7.1 & 11 WPS TLV Data Format - Device Name */
+typedef struct _DEVICE_NAME_TLV_T {
+	UINT_16 u2Id;		/* WPS Attribute Type */
+	UINT_16 u2Length;	/* Data Length */
+	UINT_8 aucName[32];	/* Device Name */ /* TODO: Fixme */
+} __KAL_ATTRIB_PACKED__ DEVICE_NAME_TLV_T, *P_DEVICE_NAME_TLV_T;
+
+/* P2P 4.1.16 - P2P Group Info Attribute */
+typedef struct _P2P_CLIENT_INFO_DESC_T {
+	UINT_8 ucLength;	/* Length */
+	UINT_8 aucDevAddr[MAC_ADDR_LEN];	/* P2P Device Address */
+	UINT_8 aucIfAddr[MAC_ADDR_LEN];	/* P2P Interface Address */
+	UINT_8 ucDeviceCap;	/* Device Capability Bitmap */
+	UINT_16 u2ConfigMethodsBE;	/* Config Method */
+	DEVICE_TYPE_T rPrimaryDevTypeBE;	/* Primary Device Type */
+	UINT_8 ucNumOfSecondaryDevType;	/* Number of Secondary Device Types */
+	DEVICE_TYPE_T arSecondaryDevTypeListBE[1];	/* Secondary Device Type List */
+} __KAL_ATTRIB_PACKED__ P2P_CLIENT_INFO_DESC_T, *P_P2P_CLIENT_INFO_DESC_T;
+
+typedef struct _P2P_ATTRI_GROUP_INFO_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	P2P_CLIENT_INFO_DESC_T arClientDesc[1];	/* P2P Client Info Descriptors */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_INFO_T, *P_P2P_ATTRI_GROUP_INFO_T;
+
+/* P2P 4.1.17 - P2P Group ID Attribute */
+typedef struct _P2P_ATTRI_GROUP_ID_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucDevAddr[MAC_ADDR_LEN];	/* P2P Device Address */
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];	/* SSID */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_ID_T, *P_P2P_ATTRI_GROUP_ID_T;
+
+/* P2P 4.1.18 - P2P Interface Attribute */
+typedef struct _P2P_ATTRI_INTERFACE_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucDevAddr[MAC_ADDR_LEN];	/* P2P Device Address */
+	UINT_8 ucIfAddrCount;	/* P2P Interface Address Count */
+	UINT_8 aucIfAddrList[MAC_ADDR_LEN];	/* P2P Interface Address List */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTERFACE_T, *P_P2P_ATTRI_INTERFACE_T;
+
+/* P2P 4.1.19 - Operating Channel Attribute */
+typedef struct _P2P_ATTRI_OPERATING_CHANNEL_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucCountryString[3];	/* Country String */
+	UINT_8 ucOperatingClass;	/* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */
+	UINT_8 ucChannelNumber;	/* Channel Number */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_OPERATING_CHANNEL_T, *P_P2P_ATTRI_OPERATING_CHANNEL_T;
+
+/* P2P 4.1.20 - Invitation Flags Attribute */
+typedef struct _P2P_ATTRI_INVITATION_FLAG_T {
+	UINT_8 ucId;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucInviteFlagsBitmap;	/* Invitation Flags Bitmap */
+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INVITATION_FLAG_T, *P_P2P_ATTRI_INVITATION_FLAG_T;
+
+/* P2P 4.1.1 - General WSC Attribute */
+typedef struct _WSC_ATTRIBUTE_T {
+	UINT_16 u2Id;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucBody[1];	/* Body field */
+} __KAL_ATTRIB_PACKED__ WSC_ATTRIBUTE_T, *P_WSC_ATTRIBUTE_T;
+
+/* WSC 1.0 Table 28 */
+typedef struct _WSC_ATTRI_VERSION_T {
+	UINT_16 u2Id;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 ucVersion;	/* Version 1.0 or 1.1 */
+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_VERSION_T, *P_WSC_ATTRI_VERSION_T;
+
+typedef struct _WSC_ATTRI_DEVICE_PASSWORD_ID_T {
+	UINT_16 u2Id;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_16 u2DevPasswordId;	/* Device Password ID */
+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_DEVICE_PASSWORD_ID_T, *P_WSC_ATTRI_DEVICE_PASSWORD_ID_T;
+
+typedef struct _WSC_ATTRI_CONFIGURATION_METHOD_T {
+	UINT_16 u2Id;		/* Attribute ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_16 u2ConfigMethods;	/* Configure Methods */
+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_CONFIGURATION_METHOD_T, *P_WSC_ATTRI_CONFIGURATION_METHOD_T;
+
+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE)
+#pragma pack()
+#endif
+
+/* 3  --------------- WFA P2P Attributes Handler prototype --------------- */
+typedef UINT_32(*PFN_APPEND_ATTRI_FUNC) (P_ADAPTER_T, BOOLEAN, PUINT_16, PUINT_8, UINT_16);
+
+typedef VOID(*PFN_HANDLE_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T);
+
+typedef VOID(*PFN_VERIFY_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T, PUINT_16);
+
+typedef UINT_32(*PFN_CALCULATE_VAR_ATTRI_LEN_FUNC) (P_ADAPTER_T, P_STA_RECORD_T);
+
+typedef struct _APPEND_VAR_ATTRI_ENTRY_T {
+	UINT_16 u2EstimatedFixedAttriLen;	/* For fixed length */
+	PFN_CALCULATE_VAR_ATTRI_LEN_FUNC pfnCalculateVariableAttriLen;
+	PFN_APPEND_ATTRI_FUNC pfnAppendAttri;
+} APPEND_VAR_ATTRI_ENTRY_T, *P_APPEND_VAR_ATTRI_ENTRY_T;
+
+typedef enum _ENUM_CONFIG_METHOD_SEL {
+	ENUM_CONFIG_METHOD_SEL_AUTO,
+	ENUM_CONFIG_METHOD_SEL_USER,
+	ENUM_CONFIG_METHOD_SEL_NUM
+} ENUM_CONFIG_METHOD_SEL, *P_ENUM_CONFIG_METHOD_SEL;
+
+typedef enum _ENUM_P2P_FORMATION_POLICY {
+	ENUM_P2P_FORMATION_POLICY_AUTO = 0,
+	ENUM_P2P_FORMATION_POLICY_PASSIVE,	/* Device would wait GO NEGO REQ instead of sending it actively. */
+	ENUM_P2P_FORMATION_POLICY_NUM
+} ENUM_P2P_FORMATION_POLICY, P_ENUM_P2P_FORMATION_POLICY;
+
+typedef enum _ENUM_P2P_INVITATION_POLICY {
+	ENUM_P2P_INVITATION_POLICY_USER = 0,
+	ENUM_P2P_INVITATION_POLICY_ACCEPT_FIRST,
+	ENUM_P2P_INVITATION_POLICY_DENY_ALL,
+	ENUM_P2P_INVITATION_POLICY_NUM
+} ENUM_P2P_INVITATION_POLICY, P_ENUM_P2P_INVITATION_POLICY;
+
+/* 3 --------------- Data Structure for P2P Operation --------------- */
+/* 3 Session for CONNECTION SETTINGS of P2P */
+struct _P2P_CONNECTION_SETTINGS_T {
+	UINT_8 ucDevNameLen;
+	UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME];
+
+	DEVICE_TYPE_T rPrimaryDevTypeBE;
+
+	ENUM_P2P_FORMATION_POLICY eFormationPolicy;	/* Formation Policy. */
+
+    /*------------WSC Related Param---------------*/
+	UINT_16 u2ConfigMethodsSupport;	/* Preferred configure method.
+					 * Some device may not have keypad.
+					 */
+	ENUM_CONFIG_METHOD_SEL eConfigMethodSelType;
+	UINT_16 u2TargetConfigMethod;	/* Configure method selected by user or auto. */
+	UINT_16 u2LocalConfigMethod;	/* Configure method of target. */
+	BOOLEAN fgIsPasswordIDRdy;
+    /*------------WSC Related Param---------------*/
+
+	UINT_8 ucClientConfigTimeout;
+	UINT_8 ucGoConfigTimeout;
+
+	UINT_8 ucSecondaryDevTypeCount;
+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT
+	DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT];
+#endif
+
+#if 0
+	UINT_8 ucRfChannelListCount;
+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT
+	UINT_8 aucChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT];	/* Channel Numbering
+									depends on 802.11mb Annex J. */
+
+#endif
+#else
+	UINT_8 ucRfChannelListSize;
+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE
+	UINT_8 aucChannelEntriesField[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE];
+#endif
+#endif
+
+	/* Go Intent */
+	UINT_8 ucTieBreaker;
+	UINT_8 ucGoIntent;
+
+	/* For Device Capability */
+	BOOLEAN fgSupportServiceDiscovery;
+	BOOLEAN fgSupportClientDiscoverability;
+	BOOLEAN fgSupportConcurrentOperation;
+	BOOLEAN fgSupportInfraManaged;
+	BOOLEAN fgSupportInvitationProcedure;
+
+	/* For Group Capability */
+	BOOLEAN fgSupportPersistentP2PGroup;
+	BOOLEAN fgSupportIntraBSSDistribution;
+	BOOLEAN fgSupportCrossConnection;
+	BOOLEAN fgSupportPersistentReconnect;
+
+	BOOLEAN fgP2pGroupLimit;
+
+	BOOLEAN fgSupportOppPS;
+	UINT_16 u2CTWindow;
+
+	BOOLEAN fgIsScanReqIssued;
+	BOOLEAN fgIsServiceDiscoverIssued;
+
+    /*============ Target Device Connection Settings ============*/
+
+	/* Discover Target Device Info. */
+	BOOLEAN fgIsDevId;
+	BOOLEAN fgIsDevType;
+
+	/* Encryption mode of Target Device */
+	ENUM_PARAM_AUTH_MODE_T eAuthMode;
+
+	/* SSID
+	 *  1. AP Mode, this is the desired SSID user specified.
+	 *  2. Client Mode, this is the target SSID to be connected to.
+	 */
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];
+	UINT_8 ucSSIDLen;
+
+	/* Operating channel requested. */
+	UINT_8 ucOperatingChnl;
+	ENUM_BAND_T eBand;
+
+	/* Linten channel requested. */
+	UINT_8 ucListenChnl;
+
+	/* For device discover address/type. */
+	UINT_8 aucTargetDevAddr[MAC_ADDR_LEN];	/* P2P Device Address, for P2P Device Discovery & P2P Connection. */
+
+#if CFG_ENABLE_WIFI_DIRECT
+	P_P2P_DEVICE_DESC_T prTargetP2pDesc;
+#endif
+
+	UINT_8 ucLastStatus;	/* P2P FSM would append status attribute according to this field. */
+
+#if !CFG_DISABLE_DELAY_PROVISION_DISCOVERY
+	UINT_8 ucLastDialogToken;
+	UINT_8 aucIndicateDevAddr[MAC_ADDR_LEN];
+#endif
+
+#if 0
+	UINT_8 ucTargetRfChannelListCount;
+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT
+	UINT_8 aucTargetChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT];	/* Channel Numbering
+										depends on 802.11mb Annex J. */
+#endif
+#endif
+
+};
+
+typedef struct _NOA_TIMING_T {
+	BOOLEAN fgIsInUse;	/* Indicate if this entry is in use or not */
+	UINT_8 ucCount;		/* Count */
+
+	UINT_8 aucReserved[2];
+
+	UINT_32 u4Duration;	/* Duration */
+	UINT_32 u4Interval;	/* Interval */
+	UINT_32 u4StartTime;	/* Start Time */
+} NOA_TIMING_T, *P_NOA_TIMING_T;
+
+typedef enum _ENUM_P2P_IOCTL_T {
+	P2P_IOCTL_IDLE = 0,
+	P2P_IOCTL_DEV_DISCOVER,
+	P2P_IOCTL_INVITATION_REQ,
+	P2P_IOCTL_SERV_DISCOVER,
+	P2P_IOCTL_WAITING,
+	P2P_IOCTL_NUM
+} ENUM_P2P_IOCTL_T;
+
+/*---------------- Service Discovery Related -------------------*/
+typedef enum _ENUM_SERVICE_TX_TYPE_T {
+	ENUM_SERVICE_TX_TYPE_BY_DA,
+	ENUM_SERVICE_TX_TYPE_BY_CHNL,
+	ENUM_SERVICE_TX_TYPE_NUM
+} ENUM_SERVICE_TX_TYPE_T;
+
+typedef struct _SERVICE_DISCOVERY_FRAME_DATA_T {
+	QUE_ENTRY_T rQueueEntry;
+	P_MSDU_INFO_T prSDFrame;
+	ENUM_SERVICE_TX_TYPE_T eServiceType;
+	UINT_8 ucSeqNum;
+	union {
+
+		UINT_8 ucChannelNum;
+		UINT_8 aucPeerAddr[MAC_ADDR_LEN];
+	} uTypeData;
+	BOOLEAN fgIsTxDoneIndicate;
+} SERVICE_DISCOVERY_FRAME_DATA_T, *P_SERVICE_DISCOVERY_FRAME_DATA_T;
+
+struct _P2P_FSM_INFO_T_DEPRECATED {
+	/* P2P FSM State */
+	ENUM_P2P_STATE_T eCurrentState;
+
+	/* Channel */
+	BOOLEAN fgIsChannelRequested;
+
+	ENUM_P2P_STATE_T ePreviousState;
+
+	ENUM_P2P_STATE_T eReturnState;	/* Return state after current activity finished or abort. */
+
+	UINT_8 aucTargetIfAddr[PARAM_MAC_ADDR_LEN];
+	P_BSS_DESC_T prTargetBss;	/* BSS of target P2P Device. For Connection/Service Discovery */
+
+	P_STA_RECORD_T prTargetStaRec;
+
+	BOOLEAN fgIsRsponseProbe;	/* Indicate if P2P FSM can response probe request frame. */
+
+	/* Sequence number of requested message. */
+	UINT_8 ucSeqNumOfReqMsg;	/* Used for SAA FSM request message. */
+
+	/* Channel Privilege */
+	UINT_8 ucSeqNumOfChReq;	/* Used for Channel Request message. */
+
+	UINT_8 ucSeqNumOfScnMsg;	/* Used for SCAN FSM request message. */
+	UINT_8 ucSeqNumOfCancelMsg;
+
+	UINT_8 ucDialogToken;
+	UINT_8 ucRxDialogToken;
+
+	/* Timer */
+	TIMER_T rDeviceDiscoverTimer;	/* For device discovery time of each discovery request from user. */
+	TIMER_T rOperationListenTimer;	/* For Find phase under operational state. */
+	TIMER_T rFSMTimer;	/* A timer used for Action frame timeout usage. */
+
+	TIMER_T rRejoinTimer;	/* A timer used for Action frame timeout usage. */
+
+	/* Flag to indicate Provisioning */
+	BOOLEAN fgIsConnectionRequested;
+
+	/* Current IOCTL. */
+	ENUM_P2P_IOCTL_T eP2pIOCTL;
+
+	UINT_8 ucAvailableAuthTypes;	/* Used for AUTH_MODE_AUTO_SWITCH */
+
+    /*--------SERVICE DISCOVERY--------*/
+	QUE_T rQueueGASRx;	/* Input Request/Response. */
+	QUE_T rQueueGASTx;	/* Output Response. */
+	P_SERVICE_DISCOVERY_FRAME_DATA_T prSDRequest;
+	UINT_8 ucVersionNum;	/* GAS packet sequence number for...Action Frame? */
+	UINT_8 ucGlobalSeqNum;	/* Sequence Number of RX SD packet. */
+    /*--------Service DISCOVERY--------*/
+
+    /*--------DEVICE DISCOVERY---------*/
+	UINT_8 aucTargetGroupID[PARAM_MAC_ADDR_LEN];
+	UINT_16 u2TargetGroupSsidLen;
+	UINT_8 aucTargetSsid[32];
+	UINT_8 aucSearchingP2pDevice[PARAM_MAC_ADDR_LEN];
+	UINT_8 ucDLToken;
+    /*----------------------------------*/
+
+	/* Indicating Peer Status. */
+	UINT_32 u4Flags;
+
+	/*Indicating current running mode. */
+	BOOLEAN fgIsApMode;
+
+    /*------------INVITATION------------*/
+	ENUM_P2P_INVITATION_POLICY eInvitationRspPolicy;
+    /*----------------------------------*/
+
+};
+
+struct _P2P_SPECIFIC_BSS_INFO_T {
+	/* For GO(AP) Mode - Compose TIM IE */
+	UINT_16 u2SmallestAID;
+	UINT_16 u2LargestAID;
+	UINT_8 ucBitmapCtrl;
+	/* UINT_8                  aucPartialVirtualBitmap[MAX_LEN_TIM_PARTIAL_BMP]; */
+
+	/* For GC/GO OppPS */
+	BOOLEAN fgEnableOppPS;
+	UINT_16 u2CTWindow;
+
+	/* For GC/GO NOA */
+	UINT_8 ucNoAIndex;
+	UINT_8 ucNoATimingCount;	/* Number of NoA Timing */
+	NOA_TIMING_T arNoATiming[P2P_MAXIMUM_NOA_COUNT];
+
+	BOOLEAN fgIsNoaAttrExisted;
+
+	/* For P2P Device */
+	UINT_8 ucRegClass;	/* Regulatory Class for channel. */
+	UINT_8 ucListenChannel;	/* Linten Channel only on channels 1, 6 and 11 in the 2.4 GHz. */
+
+	UINT_8 ucPreferredChannel;	/* Operating Channel, should be one of channel list
+					in p2p connection settings. */
+	ENUM_CHNL_EXT_T eRfSco;
+	ENUM_BAND_T eRfBand;
+
+	/* Extended Listen Timing. */
+	UINT_16 u2AvailabilityPeriod;
+	UINT_16 u2AvailabilityInterval;
+
+#if 0				/* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */
+	UINT_16 u2IELenForBCN;
+	UINT_8 aucBeaconIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE];
+
+/* UINT_16                 u2IELenForProbeRsp; */
+/* UINT_8                  aucProbeRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; */
+
+	UINT_16 u2IELenForAssocRsp;
+	UINT_8 aucAssocRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE];
+
+#else
+	UINT_16 u2AttributeLen;
+	UINT_8 aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE];
+
+	UINT_16 u2WscAttributeLen;
+	UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE];
+#endif
+	UINT_8 aucGroupID[MAC_ADDR_LEN];
+	UINT_16 u2GroupSsidLen;
+	UINT_8 aucGroupSsid[ELEM_MAX_LEN_SSID];
+
+	PARAM_CUSTOM_NOA_PARAM_STRUCT_T rNoaParam;
+	PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T rOppPsParam;
+
+	UINT_16 u2WpaIeLen;
+	UINT_8 aucWpaIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_WPA];
+};
+
+typedef struct _MSG_P2P_DEVICE_DISCOVER_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_32 u4DevDiscoverTime;	/* 0: Infinite, 1~X: in unit of MS. */
+	BOOLEAN fgIsSpecificType;
+#if CFG_ENABLE_WIFI_DIRECT
+	P2P_DEVICE_TYPE_T rTargetDeviceType;
+#endif
+	UINT_8 aucTargetDeviceID[MAC_ADDR_LEN];
+} MSG_P2P_DEVICE_DISCOVER_T, *P_MSG_P2P_DEVICE_DISCOVER_T;
+
+typedef struct _MSG_P2P_INVITATION_REQUEST_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 aucDeviceID[MAC_ADDR_LEN];	/* Target Device ID to be invited. */
+} MSG_P2P_INVITATION_REQUEST_T, *P_MSG_P2P_INVITATION_REQUEST_T;
+
+typedef struct _MSG_P2P_FUNCTION_SWITCH_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	BOOLEAN fgIsFuncOn;
+} MSG_P2P_FUNCTION_SWITCH_T, *P_MSG_P2P_FUNCTION_SWITCH_T;
+
+typedef struct _MSG_P2P_SERVICE_DISCOVERY_REQUEST_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 aucDeviceID[MAC_ADDR_LEN];
+	BOOLEAN fgNeedTxDoneIndicate;
+	UINT_8 ucSeqNum;
+} MSG_P2P_SERVICE_DISCOVERY_REQUEST_T, *P_MSG_P2P_SERVICE_DISCOVERY_REQUEST_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define p2pChangeMediaState(_prAdapter, _eNewMediaState) \
+do { \
+	(_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState = (_eNewMediaState));\
+	wfdChangeMediaState((_prAdapter), NETWORK_TYPE_P2P_INDEX, (_eNewMediaState)); \
+} while (0)
+
+#define ATTRI_ID(_fp)       (((P_P2P_ATTRIBUTE_T) _fp)->ucId)
+#define ATTRI_LEN(_fp)      \
+	    (((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[0]) | \
+	     ((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[1] << 8))
+
+#define ATTRI_SIZE(_fp)     (P2P_ATTRI_HDR_LEN + ATTRI_LEN(_fp))
+
+#define P2P_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \
+	for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \
+		(_u2Offset) += ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += ATTRI_SIZE(_pucAttriBuf)))
+
+#define P2P_IE(_fp)          ((P_IE_P2P_T) _fp)
+
+#define WSC_ATTRI_ID(_fp)     \
+	     (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[0] << 8) | \
+	     ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[1]))
+
+#define WSC_ATTRI_LEN(_fp)      \
+	    (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \
+	     ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[1]))
+
+#define WSC_ATTRI_SIZE(_fp)     (WSC_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp))
+
+#define WSC_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \
+	for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \
+		(_u2Offset) += WSC_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WSC_ATTRI_SIZE(_pucAttriBuf)))
+
+#define WSC_IE(_fp)          ((P_IE_P2P_T) _fp)
+
+#define WFD_ATTRI_ID(_fp)       (((P_WFD_ATTRIBUTE_T) _fp)->ucElemID)
+
+#define WFD_ATTRI_LEN(_fp)      \
+	    (((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \
+	     ((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[1]))
+
+#define WFD_ATTRI_SIZE(_fp)     (WFD_ATTRI_HDR_LEN + WFD_ATTRI_LEN(_fp))
+
+#define WFD_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \
+	for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \
+		(_u2Offset) += WFD_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WFD_ATTRI_SIZE(_pucAttriBuf)))
+
+#if DBG
+#define ASSERT_BREAK(_exp) \
+	{ \
+	    if (!(_exp)) { \
+		ASSERT(FALSE); \
+		break; \
+	    } \
+	}
+
+#else
+#define ASSERT_BREAK(_exp)
+#endif
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*======P2P State======*/
+VOID
+p2pStateInit_LISTEN(IN P_ADAPTER_T prAdapter,
+		    IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+		    IN P_P2P_SPECIFIC_BSS_INFO_T prSP2pBssInfo, IN UINT_8 ucListenChannel);
+
+VOID p2pStateAbort_LISTEN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion);
+
+VOID p2pStateAbort_SEARCH_SCAN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion);
+
+VOID p2pStateAbort_GO_OPERATION(IN P_ADAPTER_T prAdapter);
+
+VOID p2pStateAbort_GC_OPERATION(IN P_ADAPTER_T prAdapter);
+
+VOID
+p2pStateInit_CONFIGURATION(IN P_ADAPTER_T prAdapter,
+			   IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+			   IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecBssInfo);
+
+VOID p2pStateAbort_CONFIGURATION(IN P_ADAPTER_T prAdapter);
+
+VOID p2pStateInit_JOIN(IN P_ADAPTER_T prAdapter);
+
+VOID p2pStateAbort_JOIN(IN P_ADAPTER_T prAdapter);
+
+/*====== P2P Functions ======*/
+
+VOID p2pFuncInitGO(IN P_ADAPTER_T prAdapter);
+
+VOID
+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter,
+		  IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode);
+
+VOID
+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter,
+		    IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW);
+
+VOID p2pFuncRunEventProvisioningComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+WLAN_STATUS p2pFuncSetGroupID(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucGroupID, IN PUINT_8 pucSsid, IN UINT_8 ucSsidLen);
+
+WLAN_STATUS
+p2pFuncSendDeviceDiscoverabilityReqFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken);
+
+WLAN_STATUS
+p2pFuncSendDeviceDiscoverabilityRspFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken);
+
+UINT_8 p2pFuncGetVersionNumOfSD(IN P_ADAPTER_T prAdapter);
+
+/*====== P2P FSM ======*/
+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventDeviceDiscoveryRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventDeviceDiscoveryAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventRxGroupNegotiationReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS
+p2pFsmRunEventGroupNegotiationRequestTxDone(IN P_ADAPTER_T prAdapter,
+					    IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+WLAN_STATUS
+p2pFsmRunEventGroupNegotiationResponseTxDone(IN P_ADAPTER_T prAdapter,
+					     IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+WLAN_STATUS
+p2pFsmRunEventGroupNegotiationConfirmTxDone(IN P_ADAPTER_T prAdapter,
+					    IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+WLAN_STATUS
+p2pFsmRunEventProvisionDiscoveryRequestTxDone(IN P_ADAPTER_T prAdapter,
+					      IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+WLAN_STATUS
+p2pFsmRunEventProvisionDiscoveryResponseTxDone(IN P_ADAPTER_T prAdapter,
+					       IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+WLAN_STATUS
+p2pFsmRunEventInvitationRequestTxDone(IN P_ADAPTER_T prAdapter,
+				      IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb);
+
+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb);
+
+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS
+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter,
+			   IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+#if 1
+#endif
+
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/* //////////////////////////////////////////////////////////////////////// */
+/*======Mail Box Event Message=====*/
+
+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventConnectionTrigger(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventP2PFunctionSwitch(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventConnectionPause(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID
+p2pIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter,
+				IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN UINT_8 aucTargetAddr[]);
+
+VOID p2pUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb);
+
+/*======Mail Box Event Message=====*/
+
+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter);
+
+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter);
+
+VOID p2pFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_P2P_STATE_T eNextState);
+
+VOID p2pStartGO(IN P_ADAPTER_T prAdapter);
+
+VOID p2pAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen);
+
+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID p2pFsmRunEventIOReqTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param);
+
+VOID p2pFsmRunEventSearchPeriodTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param);
+
+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG u4Param);
+
+VOID p2pFsmRunEventRejoinTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Parm);
+
+/*=============== P2P Function Related ================*/
+
+/*=============== P2P Function Related ================*/
+
+#if CFG_TEST_WIFI_DIRECT_GO
+VOID p2pTest(IN P_ADAPTER_T prAdapter);
+#endif /* CFG_TEST_WIFI_DIRECT_GO */
+
+VOID p2pGenerateP2P_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID p2pGenerateP2P_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID
+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pCalculateP2P_IELenForBeacon(IN P_ADAPTER_T prAdapter,
+			       IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+UINT_32
+p2pCalculateP2P_IELenForAssocRsp(IN P_ADAPTER_T prAdapter,
+				 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+UINT_32
+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter,
+				 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pGenerateWSC_IEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID
+p2pGenerateWSC_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_16 p2pCalculateWSC_IELenForProbeReq(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+UINT_32
+p2pCalculateWSC_IELenForProbeResp(IN P_ADAPTER_T prAdapter,
+				  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+UINT_32
+p2pAppendAttriStatus(IN P_ADAPTER_T prAdapter,
+		     IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriCapability(IN P_ADAPTER_T prAdapter,
+			 IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriGoIntent(IN P_ADAPTER_T prAdapter,
+		       IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriCfgTimeout(IN P_ADAPTER_T prAdapter,
+			 IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriGroupBssid(IN P_ADAPTER_T prAdapter,
+			 IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriDeviceIDForBeacon(IN P_ADAPTER_T prAdapter,
+				IN BOOLEAN fgIsAssocFrame,
+				IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriDeviceIDForProbeReq(IN P_ADAPTER_T prAdapter,
+				  IN BOOLEAN fgIsAssocFrame,
+				  IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriDeviceIDForDeviceDiscoveryReq(IN P_ADAPTER_T prAdapter,
+					    IN BOOLEAN fgIsAssocFrame,
+					    IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriListenChannel(IN P_ADAPTER_T prAdapter,
+			    IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriIntendP2pIfAddr(IN P_ADAPTER_T prAdapter,
+			      IN BOOLEAN fgIsAssocFrame,
+			      IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriChannelList(IN P_ADAPTER_T prAdapter,
+			  IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32 p2pCalculateAttriLenChannelList(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+UINT_32
+p2pAppendAttriNoA(IN P_ADAPTER_T prAdapter,
+		  IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriDeviceInfo(IN P_ADAPTER_T prAdapter,
+			 IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32 p2pCalculateAttriLenDeviceInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+UINT_32
+p2pAppendAttriGroupInfo(IN P_ADAPTER_T prAdapter,
+			IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32 p2pCalculateAttriLenGroupInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+UINT_32
+p2pAppendAttriP2pGroupID(IN P_ADAPTER_T prAdapter,
+			 IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriOperatingChannel(IN P_ADAPTER_T prAdapter,
+			       IN BOOLEAN fgIsAssocFrame,
+			       IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriInvitationFlag(IN P_ADAPTER_T prAdapter,
+			     IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+VOID
+p2pGenerateWscIE(IN P_ADAPTER_T prAdapter,
+		 IN UINT_8 ucOuiType,
+		 IN BOOLEAN fgIsAssocFrame,
+		 IN PUINT_16 pu2Offset,
+		 IN PUINT_8 pucBuf,
+		 IN UINT_16 u2BufSize, IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize);
+
+UINT_32
+p2pAppendAttriWSCConfigMethod(IN P_ADAPTER_T prAdapter,
+			      IN BOOLEAN fgIsAssocFrame,
+			      IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriWSCVersion(IN P_ADAPTER_T prAdapter,
+			 IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriWSCGONegReqDevPasswordId(IN P_ADAPTER_T prAdapter,
+				       IN BOOLEAN fgIsAssocFrame,
+				       IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pAppendAttriWSCGONegRspDevPasswordId(IN P_ADAPTER_T prAdapter,
+				       IN BOOLEAN fgIsAssocFrame,
+				       IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+WLAN_STATUS
+p2pGetWscAttriList(IN P_ADAPTER_T prAdapter,
+		   IN UINT_8 ucOuiType,
+		   IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen);
+
+WLAN_STATUS
+p2pGetAttriList(IN P_ADAPTER_T prAdapter,
+		IN UINT_8 ucOuiType,
+		IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen);
+
+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+WLAN_STATUS p2pSendProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+BOOLEAN p2pFsmRunEventRxProbeRequestFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc);
+
+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID p2pFsmRunEventRxGroupNegotiationRspFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID p2pFsmRunEventRxGroupNegotiationCfmFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+#if 0				/* frog */
+BOOLEAN scanMatchFilterOfP2P(IN P_SW_RFB_T prSWRfb, IN PP_BSS_DESC_T pprBssDesc);
+#endif /* frog */
+
+VOID
+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter,
+			       UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam);
+
+VOID p2pFuncCompleteIOCTL(IN P_ADAPTER_T prAdapter, IN WLAN_STATUS rWlanStatus);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#ifndef _lint
+/* Kevin: we don't have to call following function to inspect the data structure.
+ * It will check automatically while at compile time.
+ * We'll need this for porting driver to different RTOS.
+ */
+static inline VOID p2pDataTypeCheck(VOID)
+{
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(IE_P2P_T) == (2 + 4 + 1));	/* all UINT_8 */
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRIBUTE_T) == (3 + 1));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_STATUS_T) == (3 + 1));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_REASON_T) == (3 + 1));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CAPABILITY_T) == (3 + 2));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_ID_T) == (3 + 6));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GO_INTENT_T) == (3 + 1));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CFG_TIMEOUT_T) == (3 + 2));
+#if CID52_53_54
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5));
+#else
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5));
+#endif
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_BSSID_T) == (3 + 6));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_EXT_LISTEN_TIMING_T) == (3 + 4));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTENDED_IF_ADDR_T) == (3 + 6));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_MANAGEABILITY_T) == (3 + 1));
+
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CHANNEL_T) == (3 + 4));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(CHANNEL_ENTRY_FIELD_T) == 3);
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_NOA_T) == (3 + 3));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(NOA_DESCRIPTOR_T) == 13);
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_TYPE_T) == 8);
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_INFO_T) == (3 + 6 + 2 + 8 + 1 + 8));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_NAME_TLV_T) == (4 + 32));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_CLIENT_INFO_DESC_T) == (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_INFO_T) == (3 + (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8)));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_ID_T) == (3 + 38));
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTERFACE_T) == (3 + 13));
+#if CID52_53_54
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5));
+#else
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5));
+#endif
+
+}
+#endif /* _lint */
+
+#endif /* _P2P_FSM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h
new file mode 100644
index 0000000000000..1ac1770debcab
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h
@@ -0,0 +1,155 @@
+#ifndef _P2P_FUNC_H
+#define _P2P_FUNC_H
+
+#define P2P_EXT_LISTEN_TIME_MS                               600
+#define P2P_OFF_CHNL_TX_DEFAULT_TIME_MS                      1000
+
+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo);
+
+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo);
+
+VOID
+p2pFuncStartGO(IN P_ADAPTER_T prAdapter,
+	       IN P_BSS_INFO_T prBssInfo,
+	       IN PUINT_8 pucSsidBuf,
+	       IN UINT_8 ucSsidLen,
+	       IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP);
+
+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo);
+
+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo);
+
+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo);
+
+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo);
+
+VOID
+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter,
+			    IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb);
+
+WLAN_STATUS
+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter,
+		   IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie);
+
+WLAN_STATUS
+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter,
+		    IN P_BSS_INFO_T prP2pBssInfo,
+		    IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo,
+		    IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen);
+
+BOOLEAN
+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter,
+		    IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode);
+
+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode);
+
+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings);
+
+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType);
+
+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags);
+
+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo);
+
+VOID
+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter,
+			  IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen);
+
+P_BSS_DESC_T
+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter,
+			IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo,
+			IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo);
+
+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID
+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter,
+			 IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter);
+
+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter);
+
+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo);
+
+BOOLEAN
+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter,
+		    IN UINT_8 ucOuiType,
+		    IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen);
+
+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu);
+
+#if 0				/* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */
+UINT_32
+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter,
+				     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+#else
+UINT_32
+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter,
+				   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32
+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter,
+				   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+#endif
+UINT_32
+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter,
+				     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32
+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter,
+				     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32
+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter,
+			  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+			  IN P_STA_RECORD_T prStaRec,
+			  IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize);
+
+VOID
+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter,
+		      IN BOOLEAN fgIsAssocFrame,
+		      IN PUINT_16 pu2Offset,
+		      IN PUINT_8 pucBuf,
+		      IN UINT_16 u2BufSize,
+		      IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize);
+
+UINT_32
+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter,
+				    IN BOOLEAN fgIsAssocFrame,
+				    IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter,
+				  IN BOOLEAN fgIsAssocFrame,
+				  IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+VOID
+p2pFuncDissolve(IN P_ADAPTER_T prAdapter,
+		IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode);
+
+P_IE_HDR_T
+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter,
+		 IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore);
+
+P_ATTRIBUTE_HDR_T
+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter,
+		    IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID);
+
+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter,
+				IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx,
+				IN ENUM_PARAM_MEDIA_STATE_T eConnectionState);
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h
new file mode 100644
index 0000000000000..efb75855695f9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h
@@ -0,0 +1,156 @@
+#ifndef _P2P_IE_H
+#define _P2P_IE_H
+
+#if CFG_SUPPORT_WFD
+
+#define ELEM_MAX_LEN_WFD 62	/* TODO: Move to appropriate place */
+
+/*---------------- WFD Data Element Definitions ----------------*/
+/* WFD 4.1.1 - WFD IE format */
+#define WFD_OUI_TYPE_LEN                     4
+#define WFD_IE_OUI_HDR                       (ELEM_HDR_LEN + WFD_OUI_TYPE_LEN)	/* == OFFSET_OF(IE_P2P_T,
+												aucP2PAttributes[0]) */
+
+/* WFD 4.1.1 - General WFD Attribute */
+#define WFD_ATTRI_HDR_LEN                    3		/* ID(1 octet) + Length(2 octets) */
+
+/* WFD Attribute Code */
+#define WFD_ATTRI_ID_DEV_INFO                0
+#define WFD_ATTRI_ID_ASSOC_BSSID             1
+#define WFD_ATTRI_ID_COUPLED_SINK_INFO       6
+#define WFD_ATTRI_ID_EXT_CAPABILITY          7
+#define WFD_ATTRI_ID_SESSION_INFO            9
+#define WFD_ATTRI_ID_ALTER_MAC_ADDRESS       10
+
+/* Maximum Length of WFD Attributes */
+#define WFD_ATTRI_MAX_LEN_DEV_INFO           6	/* 0 */
+#define WFD_ATTRI_MAX_LEN_ASSOC_BSSID        6	/* 1 */
+#define WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO  7	/* 6 */
+#define WFD_ATTRI_MAX_LEN_EXT_CAPABILITY     2	/* 7 */
+#define WFD_ATTRI_MAX_LEN_SESSION_INFO       0	/* 9 */	/* 24 * #Clients */
+#define WFD_ATTRI_MAX_LEN_ALTER_MAC_ADDRESS  6	/* 10 */
+
+/* WFD 1.10 5.1.1 */
+typedef struct _IE_WFD_T {
+	UINT_8 ucId;		/* Element ID */
+	UINT_8 ucLength;	/* Length */
+	UINT_8 aucOui[3];	/* OUI */
+	UINT_8 ucOuiType;	/* OUI Type */
+	UINT_8 aucWFDAttributes[1];	/* WFD Subelement */
+} __KAL_ATTRIB_PACKED__ IE_WFD_T, *P_IE_WFD_T;
+
+typedef struct _WFD_ATTRIBUTE_T {
+	UINT_8 ucElemID;	/* Subelement ID */
+	UINT_16 u2Length;	/* Length */
+	UINT_8 aucBody[1];	/* Body field */
+} __KAL_ATTRIB_PACKED__ WFD_ATTRIBUTE_T, *P_WFD_ATTRIBUTE_T;
+
+typedef struct _WFD_DEVICE_INFORMATION_IE_T {
+	UINT_8 ucElemID;
+	UINT_16 u2Length;
+	UINT_16 u2WfdDevInfo;
+	UINT_16 u2SessionMgmtCtrlPort;
+	UINT_16 u2WfdDevMaxSpeed;
+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_IE_T, *P_WFD_DEVICE_INFORMATION_IE_T;
+
+typedef struct _WFD_ASSOCIATED_BSSID_IE_T {
+	UINT_8 ucElemID;
+	UINT_16 u2Length;
+	UINT_8 aucAssocBssid[MAC_ADDR_LEN];
+} __KAL_ATTRIB_PACKED__ WFD_ASSOCIATED_BSSID_IE_T, *P_WFD_ASSOCIATED_BSSID_IE_T;
+
+typedef struct _WFD_COUPLE_SINK_INFORMATION_IE_T {
+	UINT_8 ucElemID;
+	UINT_16 u2Length;
+	UINT_8 ucCoupleSinkStatusBp;
+	UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN];
+} __KAL_ATTRIB_PACKED__ WFD_COUPLE_SINK_INFORMATION_IE_T, *P_WFD_COUPLE_SINK_INFORMATION_IE_T;
+
+typedef struct _WFD_EXTENDED_CAPABILITY_IE_T {
+	UINT_8 ucElemID;
+	UINT_16 u2Length;
+	UINT_16 u2WfdExtCapabilityBp;
+} __KAL_ATTRIB_PACKED__ WFD_EXTENDED_CAPABILITY_IE_T, *P_WFD_EXTENDED_CAPABILITY_IE_T;
+
+typedef struct _WFD_SESSION_INFORMATION_IE_T {
+	UINT_8 ucElemID;
+	UINT_16 u2Length;
+	PUINT_8 pucWfdDevInfoDesc[1];
+} __KAL_ATTRIB_PACKED__ WFD_SESSION_INFORMATION_IE_T, *P_WFD_SESSION_INFORMATION_IE_T;
+
+typedef struct _WFD_DEVICE_INFORMATION_DESCRIPTOR_T {
+	UINT_8 ucLength;
+	UINT_8 aucDevAddr[MAC_ADDR_LEN];
+	UINT_8 aucAssocBssid[MAC_ADDR_LEN];
+	UINT_16 u2WfdDevInfo;
+	UINT_16 u2WfdDevMaxSpeed;
+	UINT_8 ucCoupleSinkStatusBp;
+	UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN];
+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_DESCRIPTOR_T, *P_WFD_DEVICE_INFORMATION_DESCRIPTOR_T;
+
+#endif
+
+UINT_32
+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter,
+			   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+#if CFG_SUPPORT_WFD
+
+UINT_32
+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter,
+			  IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter,
+			     IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter,
+				  IN BOOLEAN fgIsAssocFrame,
+				  IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter,
+				IN BOOLEAN fgIsAssocFrame,
+				IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+UINT_32
+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter,
+			      IN BOOLEAN fgIsAssocFrame,
+			      IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize);
+
+UINT_32
+wfdFuncCalculateWfdIELenForProbeResp(IN P_ADAPTER_T prAdapter,
+				     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID wfdFuncGenerateWfdIEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32
+wfdFuncCalculateWfdIELenForAssocReq(IN P_ADAPTER_T prAdapter,
+				    IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID wfdFuncGenerateWfdIEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32
+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter,
+				    IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32
+wfdFuncCalculateWfdIELenForBeacon(IN P_ADAPTER_T prAdapter,
+				  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+VOID wfdFuncGenerateWfdIEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+#endif
+
+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec);
+
+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h
new file mode 100644
index 0000000000000..32bc14c109591
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h
@@ -0,0 +1,74 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm.h#1
+*/
+
+/*! \file   "rlm.h"
+    \brief
+*/
+
+#ifndef _P2P_RLM_H
+#define _P2P_RLM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+extern VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon);
+
+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter);
+
+VOID
+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter,
+			 IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize);
+
+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum);
+
+BOOLEAN
+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter,
+			    IN UINT_8 ucCheckChnl,
+			    IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel);
+
+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h
new file mode 100644
index 0000000000000..5b6e756f48dd4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h
@@ -0,0 +1,64 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm_obss.h#1
+*/
+
+/*! \file   "rlm_obss.h"
+    \brief
+*/
+
+#ifndef _P2P_RLM_OBSS_H
+#define _P2P_RLM_OBSS_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb);
+
+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb);
+
+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus);
+
+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend);
+
+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h
new file mode 100644
index 0000000000000..8db6aa5c31e0c
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h
@@ -0,0 +1,81 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_scan.h#1
+*/
+
+/*! \file   "scan.h"
+    \brief
+
+*/
+
+#ifndef _P2P_SCAN_H
+#define _P2P_SCAN_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb);
+
+P_P2P_DEVICE_DESC_T
+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc);
+
+P_P2P_DEVICE_DESC_T
+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter,
+		      IN P_BSS_DESC_T prBssDesc,
+		      IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound);
+
+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc);
+
+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum);
+
+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc);
+
+VOID
+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter,
+				 IN P_SW_RFB_T prSwRfb,
+				 IN P_WLAN_STATUS prStatus,
+				 IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame);
+
+VOID scanRemoveAllP2pBssDesc(P_ADAPTER_T prAdapter);
+
+VOID scanRemoveP2pBssDesc(P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc);
+
+P_BSS_DESC_T
+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h
new file mode 100644
index 0000000000000..8f0c4c1564a85
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h
@@ -0,0 +1,43 @@
+#ifndef _P2P_STATE_H
+#define _P2P_STATE_H
+
+BOOLEAN
+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter,
+		  IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState);
+
+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState);
+
+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo);
+
+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState);
+
+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo);
+
+VOID
+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter,
+				IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+				IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState);
+
+VOID
+p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo);
+
+VOID
+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter,
+			   IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+			   IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState);
+
+VOID
+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter,
+			     IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState);
+
+VOID
+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter,
+		     IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+		     IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc);
+
+VOID
+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter,
+		      IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+		      IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h
new file mode 100644
index 0000000000000..c80430ae4eb54
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h
@@ -0,0 +1,230 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/privacy.h#1
+*/
+
+/*! \file   privacy.h
+    \brief This file contains the function declaration for privacy.c.
+*/
+
+/*
+** Log: privacy.h
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * modify some code for concurrent network.
+ *
+ * 06 19 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * consdier the concurrent network setting.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration the security related function from firmware.
+ *
+ * 03 01 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Refine the variable and parameter for security.
+ *
+ * 02 25 2010 wh.su
+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
+ * For support the WHQL test, do the remove key code refine.
+ *
+ * Dec 10 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * change the cmd return type
+ *
+ * Dec 8 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the function declaration for auth mode and encryption status setting from build connection command
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the function declaration for wapi
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the tx done callback handle function
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the function declaration for mac header privacy bit setting
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the structure for parsing the EAPoL frame
+ *
+ * Dec 3 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the class error function parameter
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding some security function declaration
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the ap selection structure
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+**
+*/
+
+#ifndef _PRIVACY_H
+#define _PRIVACY_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define MAX_KEY_NUM                             4
+#define WEP_40_LEN                              5
+#define WEP_104_LEN                             13
+#define LEGACY_KEY_MAX_LEN                      16
+#define CCMP_KEY_LEN                            16
+#define TKIP_KEY_LEN                            32
+#define MAX_KEY_LEN                             32
+#define MIC_RX_KEY_OFFSET                       16
+#define MIC_TX_KEY_OFFSET                       24
+#define MIC_KEY_LEN                             8
+
+#define WEP_KEY_ID_FIELD      BITS(0, 29)
+#define KEY_ID_FIELD          BITS(0, 7)
+
+#define IS_TRANSMIT_KEY       BIT(31)
+#define IS_UNICAST_KEY        BIT(30)
+#define IS_AUTHENTICATOR      BIT(28)
+
+#define CIPHER_SUITE_NONE               0
+#define CIPHER_SUITE_WEP40              1
+#define CIPHER_SUITE_TKIP               2
+#define CIPHER_SUITE_TKIP_WO_MIC        3
+#define CIPHER_SUITE_CCMP               4
+#define CIPHER_SUITE_WEP104             5
+#define CIPHER_SUITE_BIP                6
+#define CIPHER_SUITE_WEP128             7
+#define CIPHER_SUITE_WPI                8
+
+#define WPA_KEY_INFO_KEY_TYPE BIT(3)	/* 1 = Pairwise, 0 = Group key */
+#define WPA_KEY_INFO_MIC      BIT(8)
+#define WPA_KEY_INFO_SECURE   BIT(9)
+
+#define MASK_2ND_EAPOL       (WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC)
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef struct _IEEE_802_1X_HDR {
+	UINT_8 ucVersion;
+	UINT_8 ucType;
+	UINT_16 u2Length;
+	/* followed by length octets of data */
+} IEEE_802_1X_HDR, *P_IEEE_802_1X_HDR;
+
+typedef struct _EAPOL_KEY {
+	UINT_8 ucType;
+	/* Note: key_info, key_length, and key_data_length are unaligned */
+	UINT_8 aucKeyInfo[2];	/* big endian */
+	UINT_8 aucKeyLength[2];	/* big endian */
+	UINT_8 aucReplayCounter[8];
+	UINT_8 aucKeyNonce[16];
+	UINT_8 aucKeyIv[16];
+	UINT_8 aucKeyRsc[8];
+	UINT_8 aucKeyId[8];	/* Reserved in IEEE 802.11i/RSN */
+	UINT_8 aucKeyMic[16];
+	UINT_8 aucKeyDataLength[2];	/* big endian */
+	/* followed by key_data_length bytes of key_data */
+} EAPOL_KEY, *P_EAPOL_KEY;
+
+/* WPA2 PMKID candicate structure */
+typedef struct _PMKID_CANDICATE_T {
+	UINT_8 aucBssid[MAC_ADDR_LEN];
+	UINT_32 u4PreAuthFlags;
+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T;
+
+#if 0
+/* WPA2 PMKID cache structure */
+typedef struct _PMKID_ENTRY_T {
+	PARAM_BSSID_INFO_T rBssidInfo;
+	BOOLEAN fgPmkidExist;
+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T;
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx);
+
+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPort);
+
+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec);
+
+BOOLEAN secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec);
+
+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb);
+
+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags);
+
+BOOLEAN
+secProcessEAPOL(IN P_ADAPTER_T prAdapter,
+		IN P_MSDU_INFO_T prMsduInfo,
+		IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen);
+
+VOID
+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter,
+			IN P_MSDU_INFO_T pMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus);
+
+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec);
+
+VOID secClearPmkid(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PRIVACY_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h
new file mode 100644
index 0000000000000..123dbebdacaf2
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h
@@ -0,0 +1,93 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rate.h#1
+*/
+
+/*! \file  rate.h
+    \brief This file contains the rate utility function of
+	   IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: rate.h
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+*/
+
+#ifndef _RATE_H
+#define _RATE_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines in rate.c                                                         */
+/*----------------------------------------------------------------------------*/
+VOID
+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate,
+		      IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate,
+		      OUT PUINT_16 pu2OperationalRateSet,
+		      OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate);
+
+VOID
+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet,
+			    IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen);
+
+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex);
+
+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _RATE_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h
new file mode 100644
index 0000000000000..1af3841ecec25
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h
@@ -0,0 +1,396 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm.h#2
+*/
+
+/*! \file   "rlm.h"
+    \brief
+*/
+
+/*
+** Log: rlm.h
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 09 30 2011 cm.chang
+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band
+ * .
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 01 13 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Refine function when rcv a 20/40M public action frame
+ *
+ * 01 13 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * Use SCO of BSS_INFO to replace user-defined setting variables
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 10 18 2010 cm.chang
+ * [WCXRP00000114] [MT6620 Wi-Fi] [Driver] Fix compiling warning in Linux about RLM network index checking
+ * Enum member cannot be used as compiling option decision in Linux
+ *
+ * 09 10 2010 cm.chang
+ * NULL
+ * Always update Beacon content if FW sync OBSS info
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
+ * There is no CFG_SUPPORT_BOW in driver domain source.
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 06 28 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * 1st draft code for RLM module
+ *
+ * 06 02 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add RX HT GF compiling option
+ *
+ * 06 02 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Roll back to remove CFG_SUPPORT_BCM_TEST.
+ *
+ * 06 01 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Update BCM Test and RW configuration.
+ *
+ * 05 31 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add some compiling options to control 11n functions
+ *
+ * 05 18 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs
+ *
+ * 05 17 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * MT6620 does not support L-SIG TXOP
+ *
+ * 05 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft support for 20/40M bandwidth for AP mode
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft code to support protection in AP mode
+ *
+ * 04 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Different invoking order for WTBL entry of associated AP
+ *
+ * 03 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Not carry  HT cap when being associated with b/g only AP
+ *
+ * 03 03 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Move default value of HT capability to rlm.h
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Use bss info array for concurrent handle
+ *
+ * 01 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+ *
+ * 01 08 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ *
+ * Modify the prototype of rlmRecAssocRspHtInfo()
+ *
+ * Dec 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add several function prototypes for HT operation
+ *
+ * Nov 18 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+**
+*/
+
+#ifndef _RLM_H
+#define _RLM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define ELEM_EXT_CAP_DEFAULT_VAL \
+	(ELEM_EXT_CAP_20_40_COEXIST_SUPPORT /*| ELEM_EXT_CAP_PSMP_CAP*/)
+
+#if CFG_SUPPORT_RX_STBC
+#define FIELD_HT_CAP_INFO_RX_STBC   HT_CAP_INFO_RX_STBC_1_SS
+#else
+#define FIELD_HT_CAP_INFO_RX_STBC   HT_CAP_INFO_RX_STBC_NO_SUPPORTED
+#endif
+
+#if CFG_SUPPORT_RX_SGI
+#define FIELD_HT_CAP_INFO_SGI_20M   HT_CAP_INFO_SHORT_GI_20M
+#define FIELD_HT_CAP_INFO_SGI_40M   HT_CAP_INFO_SHORT_GI_40M
+#else
+#define FIELD_HT_CAP_INFO_SGI_20M   0
+#define FIELD_HT_CAP_INFO_SGI_40M   0
+#endif
+
+#if CFG_SUPPORT_RX_HT_GF
+#define FIELD_HT_CAP_INFO_HT_GF     HT_CAP_INFO_HT_GF
+#else
+#define FIELD_HT_CAP_INFO_HT_GF     0
+#endif
+
+#define HT_CAP_INFO_DEFAULT_VAL \
+	(HT_CAP_INFO_SUP_CHNL_WIDTH | FIELD_HT_CAP_INFO_HT_GF | \
+	 FIELD_HT_CAP_INFO_SGI_20M | FIELD_HT_CAP_INFO_SGI_40M | \
+	 FIELD_HT_CAP_INFO_RX_STBC | HT_CAP_INFO_DSSS_CCK_IN_40M)
+
+#define AMPDU_PARAM_DEFAULT_VAL \
+	(AMPDU_PARAM_MAX_AMPDU_LEN_64K | AMPDU_PARAM_MSS_NO_RESTRICIT)
+
+#define SUP_MCS_TX_DEFAULT_VAL \
+	SUP_MCS_TX_SET_DEFINED	/* TX defined and TX/RX equal (TBD) */
+
+#if CFG_SUPPORT_MFB
+#define FIELD_HT_EXT_CAP_MFB    HT_EXT_CAP_MCS_FEEDBACK_BOTH
+#else
+#define FIELD_HT_EXT_CAP_MFB    HT_EXT_CAP_MCS_FEEDBACK_NO_FB
+#endif
+
+#if CFG_SUPPORT_RX_RDG
+#define FIELD_HT_EXT_CAP_RDR    HT_EXT_CAP_RD_RESPONDER
+#else
+#define FIELD_HT_EXT_CAP_RDR    0
+#endif
+
+#if CFG_SUPPORT_MFB || CFG_SUPPORT_RX_RDG
+#define FIELD_HT_EXT_CAP_HTC    HT_EXT_CAP_HTC_SUPPORT
+#else
+#define FIELD_HT_EXT_CAP_HTC    0
+#endif
+
+#define HT_EXT_CAP_DEFAULT_VAL \
+	(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE | \
+	 FIELD_HT_EXT_CAP_MFB | FIELD_HT_EXT_CAP_HTC | \
+	 FIELD_HT_EXT_CAP_RDR)
+
+#define TX_BEAMFORMING_CAP_DEFAULT_VAL              0
+#define ASEL_CAP_DEFAULT_VAL                        0
+
+/* Define bandwidth from user setting */
+#define CONFIG_BW_20_40M            0
+#define CONFIG_BW_20M               1	/* 20MHz only */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/* It is used for RLM module to judge if specific network is valid
+ * Note: Ad-hoc mode of AIS is not included now. (TBD)
+ */
+#define RLM_NET_PARAM_VALID(_prBssInfo) \
+	(IS_BSS_ACTIVE(_prBssInfo) && \
+	 ((_prBssInfo)->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || \
+	  (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT || \
+	  (_prBssInfo)->eCurrentOPMode == OP_MODE_IBSS || \
+	  RLM_NET_IS_BOW(_prBssInfo)) \
+	)
+
+#define RLM_NET_IS_11N(_prBssInfo) \
+	((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11N)
+#define RLM_NET_IS_11GN(_prBssInfo) \
+	((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11GN)
+
+/* This macro is used to sweep all 3 networks */
+#define RLM_NET_FOR_EACH(_ucNetIdx) \
+	for ((_ucNetIdx) = 0; \
+		(_ucNetIdx) < NETWORK_TYPE_INDEX_NUM; \
+		(_ucNetIdx)++)
+
+/* This macro is used to sweep all networks excluding BOW */
+#if CFG_ENABLE_BT_OVER_WIFI
+    /* Note: value of enum NETWORK_TYPE_BOW_INDEX is validated in
+     *       rlmStuctureCheck().
+     */
+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) \
+	for ((_ucNetIdx) = 0; \
+		(_ucNetIdx) < NETWORK_TYPE_BOW_INDEX; \
+		(_ucNetIdx)++)
+
+#define RLM_NET_IS_BOW(_prBssInfo) \
+	((_prBssInfo)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX)
+
+#else
+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx)  RLM_NET_FOR_EACH(_ucNetIdx)
+#define RLM_NET_IS_BOW(_prBssInfo)          (FALSE)
+
+#endif /* end of CFG_ENABLE_BT_OVER_WIFI */
+
+/* The bandwidth modes are not used anymore. They represent if AP
+ * can use 20/40 bandwidth, not all modes. (20110411)
+ */
+#define RLM_AP_IS_BW_40_ALLOWED(_prAdapter, _prBssInfo) \
+	(((_prBssInfo)->eBand == BAND_2G4 && \
+	(_prAdapter)->rWifiVar.rConnSettings.uc2G4BandwidthMode \
+	== CONFIG_BW_20_40M) || \
+	((_prBssInfo)->eBand == BAND_5G && \
+	(_prAdapter)->rWifiVar.rConnSettings.uc5GBandwidthMode \
+	== CONFIG_BW_20_40M))
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter);
+
+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter);
+
+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength);
+
+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength);
+
+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo);
+
+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength);
+
+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+UINT32
+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed,
+		       BOOLEAN fgShortGIDisabled,
+		       UINT_8 u8SupportRxSgi20,
+		       UINT_8 u8SupportRxSgi40,
+		       UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf);
+
+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme);
+
+#if CFG_SUPPORT_DFS		/* Add by Enlai */
+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb);
+
+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE);
+#endif
+
+VOID
+rlmTxRateEnhanceConfig(
+	P_ADAPTER_T	prAdapter
+	);
+
+VOID
+rlmCmd(
+	P_GLUE_INFO_T	prGlueInfo,
+	UINT_8		*prInBuf,
+	UINT_32	u4InBufLen
+	);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#ifndef _lint
+static inline VOID rlmDataTypeCheck(VOID)
+{
+#if CFG_ENABLE_BT_OVER_WIFI
+	DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_AIS_INDEX < NETWORK_TYPE_BOW_INDEX);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_P2P_INDEX < NETWORK_TYPE_BOW_INDEX);
+#endif
+#endif
+
+}
+#endif /* _lint */
+
+#endif /* _RLM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h
new file mode 100644
index 0000000000000..65e907041a28b
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h
@@ -0,0 +1,557 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_domain.h#1
+*/
+
+/*! \file   "rlm_domain.h"
+    \brief
+*/
+
+/*
+** Log: rlm_domain.h
+ *
+ * 09 29 2011 cm.chang
+ * NULL
+ * Change the function prototype of rlmDomainGetChnlList()
+ *
+ * 09 08 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 06 01 2011 cm.chang
+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function
+ * Provide legal channel function based on domain
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 28 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * 1st draft code for RLM module
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
+ *
+ * 01 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Provide query function about full channel list.
+ *
+ * Dec 1 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Declare public rDomainInfo
+ *
+**
+*/
+
+#ifndef _RLM_DOMAIN_H
+#define _RLM_DOMAIN_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define MAX_SUBBAND_NUM     6
+#define MAX_SUBBAND_NUM_5G  8
+
+#define COUNTRY_CODE_NULL               ((UINT_16)0x0)
+
+/* ISO/IEC 3166-1 two-character country codes */
+
+#define COUNTRY_CODE_AD (((UINT_16) 'A' << 8) | (UINT_16) 'D')	/* Andorra                             */
+#define COUNTRY_CODE_AE (((UINT_16) 'A' << 8) | (UINT_16) 'E')	/* UAE                                 */
+#define COUNTRY_CODE_AF (((UINT_16) 'A' << 8) | (UINT_16) 'F')	/* Afghanistan                         */
+#define COUNTRY_CODE_AG (((UINT_16) 'A' << 8) | (UINT_16) 'G')	/* Antigua & Barbuda                   */
+#define COUNTRY_CODE_AI (((UINT_16) 'A' << 8) | (UINT_16) 'I')	/* Anguilla                            */
+#define COUNTRY_CODE_AL (((UINT_16) 'A' << 8) | (UINT_16) 'L')	/* Albania                             */
+#define COUNTRY_CODE_AM (((UINT_16) 'A' << 8) | (UINT_16) 'M')	/* Armenia                             */
+#define COUNTRY_CODE_AN (((UINT_16) 'A' << 8) | (UINT_16) 'N')	/* Netherlands Antilles                */
+#define COUNTRY_CODE_AO (((UINT_16) 'A' << 8) | (UINT_16) 'O')	/* Angola                              */
+#define COUNTRY_CODE_AR (((UINT_16) 'A' << 8) | (UINT_16) 'R')	/* Argentina                           */
+#define COUNTRY_CODE_AS (((UINT_16) 'A' << 8) | (UINT_16) 'S')	/* American Samoa (USA)                */
+#define COUNTRY_CODE_AT (((UINT_16) 'A' << 8) | (UINT_16) 'T')	/* Austria                             */
+#define COUNTRY_CODE_AU (((UINT_16) 'A' << 8) | (UINT_16) 'U')	/* Australia                           */
+#define COUNTRY_CODE_AW (((UINT_16) 'A' << 8) | (UINT_16) 'W')	/* Aruba                               */
+#define COUNTRY_CODE_AZ (((UINT_16) 'A' << 8) | (UINT_16) 'Z')	/* Azerbaijan                          */
+#define COUNTRY_CODE_BA (((UINT_16) 'B' << 8) | (UINT_16) 'A')	/* Bosnia and Herzegovina              */
+#define COUNTRY_CODE_BB (((UINT_16) 'B' << 8) | (UINT_16) 'B')	/* Barbados                            */
+#define COUNTRY_CODE_BD (((UINT_16) 'B' << 8) | (UINT_16) 'D')	/* Bangladesh                          */
+#define COUNTRY_CODE_BE (((UINT_16) 'B' << 8) | (UINT_16) 'E')	/* Belgium                             */
+#define COUNTRY_CODE_BF (((UINT_16) 'B' << 8) | (UINT_16) 'F')	/* Burkina Faso                        */
+#define COUNTRY_CODE_BG (((UINT_16) 'B' << 8) | (UINT_16) 'G')	/* Bulgaria                            */
+#define COUNTRY_CODE_BH (((UINT_16) 'B' << 8) | (UINT_16) 'H')	/* Bahrain                             */
+#define COUNTRY_CODE_BI (((UINT_16) 'B' << 8) | (UINT_16) 'I')	/* Burundi                             */
+#define COUNTRY_CODE_BJ (((UINT_16) 'B' << 8) | (UINT_16) 'J')	/* Benin                               */
+#define COUNTRY_CODE_BM (((UINT_16) 'B' << 8) | (UINT_16) 'M')	/* Bermuda                             */
+#define COUNTRY_CODE_BN (((UINT_16) 'B' << 8) | (UINT_16) 'N')	/* Brunei                              */
+#define COUNTRY_CODE_BO (((UINT_16) 'B' << 8) | (UINT_16) 'O')	/* Bolivia                             */
+#define COUNTRY_CODE_BR (((UINT_16) 'B' << 8) | (UINT_16) 'R')	/* Brazil                              */
+#define COUNTRY_CODE_BS (((UINT_16) 'B' << 8) | (UINT_16) 'S')	/* Bahamas                             */
+#define COUNTRY_CODE_BT (((UINT_16) 'B' << 8) | (UINT_16) 'T')	/* Bhutan                              */
+#define COUNTRY_CODE_BW (((UINT_16) 'B' << 8) | (UINT_16) 'W')	/* Botswana                            */
+#define COUNTRY_CODE_BY (((UINT_16) 'B' << 8) | (UINT_16) 'Y')	/* Belarus                             */
+#define COUNTRY_CODE_BZ (((UINT_16) 'B' << 8) | (UINT_16) 'Z')	/* Belize                              */
+#define COUNTRY_CODE_CA (((UINT_16) 'C' << 8) | (UINT_16) 'A')	/* Canada                              */
+#define COUNTRY_CODE_CD (((UINT_16) 'C' << 8) | (UINT_16) 'D')	/* Congo. Democratic Republic of the   */
+#define COUNTRY_CODE_CF (((UINT_16) 'C' << 8) | (UINT_16) 'F')	/* Central African Republic            */
+#define COUNTRY_CODE_CG (((UINT_16) 'C' << 8) | (UINT_16) 'G')	/* Congo. Republic of the              */
+#define COUNTRY_CODE_CH (((UINT_16) 'C' << 8) | (UINT_16) 'H')	/* Switzerland                         */
+#define COUNTRY_CODE_CI (((UINT_16) 'C' << 8) | (UINT_16) 'I')	/* Cote d'lvoire                       */
+#define COUNTRY_CODE_CK (((UINT_16) 'C' << 8) | (UINT_16) 'K')	/* Cook Island                         */
+#define COUNTRY_CODE_CL (((UINT_16) 'C' << 8) | (UINT_16) 'L')	/* Chile                               */
+#define COUNTRY_CODE_CM (((UINT_16) 'C' << 8) | (UINT_16) 'M')	/* Cameroon                            */
+#define COUNTRY_CODE_CN (((UINT_16) 'C' << 8) | (UINT_16) 'N')	/* China                               */
+#define COUNTRY_CODE_CO (((UINT_16) 'C' << 8) | (UINT_16) 'O')	/* Columbia                            */
+#define COUNTRY_CODE_CR (((UINT_16) 'C' << 8) | (UINT_16) 'R')	/* Costa Rica                          */
+#define COUNTRY_CODE_CU (((UINT_16) 'C' << 8) | (UINT_16) 'U')	/* Cuba                                */
+#define COUNTRY_CODE_CV (((UINT_16) 'C' << 8) | (UINT_16) 'V')	/* Cape Verde                          */
+#define COUNTRY_CODE_CX (((UINT_16) 'C' << 8) | (UINT_16) 'X')	/* "Christmas Island(Australia)        */
+#define COUNTRY_CODE_CY (((UINT_16) 'C' << 8) | (UINT_16) 'Y')	/* Cyprus                              */
+#define COUNTRY_CODE_CZ (((UINT_16) 'C' << 8) | (UINT_16) 'Z')	/* Czech                               */
+#define COUNTRY_CODE_DE (((UINT_16) 'D' << 8) | (UINT_16) 'E')	/* Germany                             */
+#define COUNTRY_CODE_DJ (((UINT_16) 'D' << 8) | (UINT_16) 'J')	/* Djibouti                            */
+#define COUNTRY_CODE_DK (((UINT_16) 'D' << 8) | (UINT_16) 'K')	/* Denmark                             */
+#define COUNTRY_CODE_DM (((UINT_16) 'D' << 8) | (UINT_16) 'M')	/* Dominica                            */
+#define COUNTRY_CODE_DO (((UINT_16) 'D' << 8) | (UINT_16) 'O')	/* Dominican Republic                  */
+#define COUNTRY_CODE_DZ (((UINT_16) 'D' << 8) | (UINT_16) 'Z')	/* Algeria                             */
+#define COUNTRY_CODE_EC (((UINT_16) 'E' << 8) | (UINT_16) 'C')	/* Ecuador                             */
+#define COUNTRY_CODE_EE (((UINT_16) 'E' << 8) | (UINT_16) 'E')	/* Estonia                             */
+#define COUNTRY_CODE_EG (((UINT_16) 'E' << 8) | (UINT_16) 'G')	/* Egypt                               */
+#define COUNTRY_CODE_EH (((UINT_16) 'E' << 8) | (UINT_16) 'H')	/* Western Sahara (Morocco)            */
+#define COUNTRY_CODE_ER (((UINT_16) 'E' << 8) | (UINT_16) 'R')	/* Eritrea                             */
+#define COUNTRY_CODE_ES (((UINT_16) 'E' << 8) | (UINT_16) 'S')	/* Spain                               */
+#define COUNTRY_CODE_ET (((UINT_16) 'E' << 8) | (UINT_16) 'T')	/* Ethiopia                            */
+#define COUNTRY_CODE_EU (((UINT_16) 'E' << 8) | (UINT_16) 'U')	/* Europe                              */
+#define COUNTRY_CODE_FI (((UINT_16) 'F' << 8) | (UINT_16) 'I')	/* Finland                             */
+#define COUNTRY_CODE_FJ (((UINT_16) 'F' << 8) | (UINT_16) 'J')	/* Fiji                                */
+#define COUNTRY_CODE_FK (((UINT_16) 'F' << 8) | (UINT_16) 'K')	/* Falkland Island                     */
+#define COUNTRY_CODE_FM (((UINT_16) 'F' << 8) | (UINT_16) 'M')	/* Micronesia                          */
+#define COUNTRY_CODE_FO (((UINT_16) 'F' << 8) | (UINT_16) 'O')	/* Faroe Island                        */
+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R')	/* France                              */
+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R')	/* Wallis and Futuna (France)          */
+#define COUNTRY_CODE_GA (((UINT_16) 'G' << 8) | (UINT_16) 'A')	/* Gabon                               */
+#define COUNTRY_CODE_GB (((UINT_16) 'G' << 8) | (UINT_16) 'B')	/* United Kingdom                      */
+#define COUNTRY_CODE_GD (((UINT_16) 'G' << 8) | (UINT_16) 'D')	/* Grenada                             */
+#define COUNTRY_CODE_GE (((UINT_16) 'G' << 8) | (UINT_16) 'E')	/* Georgia                             */
+#define COUNTRY_CODE_GF (((UINT_16) 'G' << 8) | (UINT_16) 'F')	/* French Guiana                       */
+#define COUNTRY_CODE_GG (((UINT_16) 'G' << 8) | (UINT_16) 'G')	/* Guernsey                            */
+#define COUNTRY_CODE_GH (((UINT_16) 'G' << 8) | (UINT_16) 'H')	/* Ghana                               */
+#define COUNTRY_CODE_GI (((UINT_16) 'G' << 8) | (UINT_16) 'I')	/* Gibraltar                           */
+#define COUNTRY_CODE_GM (((UINT_16) 'G' << 8) | (UINT_16) 'M')	/* Gambia                              */
+#define COUNTRY_CODE_GN (((UINT_16) 'G' << 8) | (UINT_16) 'N')	/* Guinea                              */
+#define COUNTRY_CODE_GP (((UINT_16) 'G' << 8) | (UINT_16) 'P')	/* Guadeloupe                          */
+#define COUNTRY_CODE_GQ (((UINT_16) 'G' << 8) | (UINT_16) 'Q')	/* Equatorial Guinea                   */
+#define COUNTRY_CODE_GR (((UINT_16) 'G' << 8) | (UINT_16) 'R')	/* Greece                              */
+#define COUNTRY_CODE_GT (((UINT_16) 'G' << 8) | (UINT_16) 'T')	/* Guatemala                           */
+#define COUNTRY_CODE_GU (((UINT_16) 'G' << 8) | (UINT_16) 'U')	/* Guam                                */
+#define COUNTRY_CODE_GW (((UINT_16) 'G' << 8) | (UINT_16) 'W')	/* Guinea-Bissau                       */
+#define COUNTRY_CODE_GY (((UINT_16) 'G' << 8) | (UINT_16) 'Y')	/* Guyana                              */
+#define COUNTRY_CODE_HK (((UINT_16) 'H' << 8) | (UINT_16) 'K')	/* Hong Kong                           */
+#define COUNTRY_CODE_HN (((UINT_16) 'H' << 8) | (UINT_16) 'N')	/* Honduras                            */
+#define COUNTRY_CODE_HR (((UINT_16) 'H' << 8) | (UINT_16) 'R')	/* Croatia                             */
+#define COUNTRY_CODE_HT (((UINT_16) 'H' << 8) | (UINT_16) 'T')	/* Haiti                               */
+#define COUNTRY_CODE_HU (((UINT_16) 'H' << 8) | (UINT_16) 'U')	/* Hungary                             */
+#define COUNTRY_CODE_ID (((UINT_16) 'I' << 8) | (UINT_16) 'D')	/* Indonesia                           */
+#define COUNTRY_CODE_IE (((UINT_16) 'I' << 8) | (UINT_16) 'E')	/* Ireland                             */
+#define COUNTRY_CODE_IL (((UINT_16) 'I' << 8) | (UINT_16) 'L')	/* Israel                              */
+#define COUNTRY_CODE_IM (((UINT_16) 'I' << 8) | (UINT_16) 'M')	/* Isle of Man                         */
+#define COUNTRY_CODE_IN (((UINT_16) 'I' << 8) | (UINT_16) 'N')	/* India                               */
+#define COUNTRY_CODE_IQ (((UINT_16) 'I' << 8) | (UINT_16) 'Q')	/* Iraq                                */
+#define COUNTRY_CODE_IR (((UINT_16) 'I' << 8) | (UINT_16) 'R')	/* Iran                                */
+#define COUNTRY_CODE_IS (((UINT_16) 'I' << 8) | (UINT_16) 'S')	/* Iceland                             */
+#define COUNTRY_CODE_IT (((UINT_16) 'I' << 8) | (UINT_16) 'T')	/* Italy                               */
+#define COUNTRY_CODE_JE (((UINT_16) 'J' << 8) | (UINT_16) 'E')	/* Jersey                              */
+#define COUNTRY_CODE_JM (((UINT_16) 'J' << 8) | (UINT_16) 'M')	/* Jameica                             */
+#define COUNTRY_CODE_JO (((UINT_16) 'J' << 8) | (UINT_16) 'O')	/* Jordan                              */
+#define COUNTRY_CODE_JP (((UINT_16) 'J' << 8) | (UINT_16) 'P')	/* Japan                               */
+#define COUNTRY_CODE_KE (((UINT_16) 'K' << 8) | (UINT_16) 'E')	/* Kenya                               */
+#define COUNTRY_CODE_KG (((UINT_16) 'K' << 8) | (UINT_16) 'G')	/* Kyrgyzstan                          */
+#define COUNTRY_CODE_KH (((UINT_16) 'K' << 8) | (UINT_16) 'H')	/* Cambodia                            */
+#define COUNTRY_CODE_KI (((UINT_16) 'K' << 8) | (UINT_16) 'I')	/* Kiribati                            */
+#define COUNTRY_CODE_KM (((UINT_16) 'K' << 8) | (UINT_16) 'M')	/* Comoros                             */
+#define COUNTRY_CODE_KN (((UINT_16) 'K' << 8) | (UINT_16) 'N')	/* Saint Kitts and Nevis               */
+#define COUNTRY_CODE_KP (((UINT_16) 'K' << 8) | (UINT_16) 'P')	/* North Korea                         */
+#define COUNTRY_CODE_KR (((UINT_16) 'K' << 8) | (UINT_16) 'R')	/* South Korea                         */
+#define COUNTRY_CODE_KW (((UINT_16) 'K' << 8) | (UINT_16) 'W')	/* Kuwait                              */
+#define COUNTRY_CODE_KY (((UINT_16) 'K' << 8) | (UINT_16) 'Y')	/* Cayman Islands                      */
+#define COUNTRY_CODE_KZ (((UINT_16) 'K' << 8) | (UINT_16) 'Z')	/* Kazakhstan                          */
+#define COUNTRY_CODE_LA (((UINT_16) 'L' << 8) | (UINT_16) 'A')	/* Laos                                */
+#define COUNTRY_CODE_LB (((UINT_16) 'L' << 8) | (UINT_16) 'B')	/* Lebanon                             */
+#define COUNTRY_CODE_LC (((UINT_16) 'L' << 8) | (UINT_16) 'C')	/* Saint Lucia                         */
+#define COUNTRY_CODE_LI (((UINT_16) 'L' << 8) | (UINT_16) 'I')	/* Liechtenstein                       */
+#define COUNTRY_CODE_LK (((UINT_16) 'L' << 8) | (UINT_16) 'K')	/* Sri Lanka                           */
+#define COUNTRY_CODE_LR (((UINT_16) 'L' << 8) | (UINT_16) 'R')	/* Liberia                             */
+#define COUNTRY_CODE_LS (((UINT_16) 'L' << 8) | (UINT_16) 'S')	/* Lesotho                             */
+#define COUNTRY_CODE_LT (((UINT_16) 'L' << 8) | (UINT_16) 'T')	/* Lithuania                           */
+#define COUNTRY_CODE_LU (((UINT_16) 'L' << 8) | (UINT_16) 'U')	/* Luxemburg                           */
+#define COUNTRY_CODE_LV (((UINT_16) 'L' << 8) | (UINT_16) 'V')	/* Latvia                              */
+#define COUNTRY_CODE_LY (((UINT_16) 'L' << 8) | (UINT_16) 'Y')	/* Libya                               */
+#define COUNTRY_CODE_MA (((UINT_16) 'M' << 8) | (UINT_16) 'A')	/* Morocco                             */
+#define COUNTRY_CODE_MC (((UINT_16) 'M' << 8) | (UINT_16) 'C')	/* Monaco                              */
+#define COUNTRY_CODE_MD (((UINT_16) 'M' << 8) | (UINT_16) 'D')	/* Moldova                             */
+#define COUNTRY_CODE_ME (((UINT_16) 'M' << 8) | (UINT_16) 'E')	/* Montenegro                          */
+#define COUNTRY_CODE_MF (((UINT_16) 'M' << 8) | (UINT_16) 'F')	/* Saint Martin / Sint Marteen
+								   (Added on window's list)               */
+#define COUNTRY_CODE_MG (((UINT_16) 'M' << 8) | (UINT_16) 'G')	/* Madagascar                          */
+#define COUNTRY_CODE_MH (((UINT_16) 'M' << 8) | (UINT_16) 'H')	/* Marshall Islands                    */
+#define COUNTRY_CODE_MK (((UINT_16) 'M' << 8) | (UINT_16) 'K')	/* Macedonia                           */
+#define COUNTRY_CODE_ML (((UINT_16) 'M' << 8) | (UINT_16) 'L')	/* Mali                                */
+#define COUNTRY_CODE_MM (((UINT_16) 'M' << 8) | (UINT_16) 'M')	/* Myanmar                             */
+#define COUNTRY_CODE_MN (((UINT_16) 'M' << 8) | (UINT_16) 'N')	/* Mongolia                            */
+#define COUNTRY_CODE_MO (((UINT_16) 'M' << 8) | (UINT_16) 'O')	/* Macao                               */
+#define COUNTRY_CODE_MP (((UINT_16) 'M' << 8) | (UINT_16) 'P')	/* Northern Mariana Islands (Rota Island.
+								   Saipan and Tinian Island)              */
+#define COUNTRY_CODE_MQ (((UINT_16) 'M' << 8) | (UINT_16) 'Q')	/* Martinique (France)                 */
+#define COUNTRY_CODE_MR (((UINT_16) 'M' << 8) | (UINT_16) 'R')	/* Mauritania                          */
+#define COUNTRY_CODE_MS (((UINT_16) 'M' << 8) | (UINT_16) 'S')	/* Montserrat (UK)                     */
+#define COUNTRY_CODE_MT (((UINT_16) 'M' << 8) | (UINT_16) 'T')	/* Malta                               */
+#define COUNTRY_CODE_MU (((UINT_16) 'M' << 8) | (UINT_16) 'U')	/* Mauritius                           */
+#define COUNTRY_CODE_MV (((UINT_16) 'M' << 8) | (UINT_16) 'V')	/* Maldives                            */
+#define COUNTRY_CODE_MW (((UINT_16) 'M' << 8) | (UINT_16) 'W')	/* Malawi                              */
+#define COUNTRY_CODE_MX (((UINT_16) 'M' << 8) | (UINT_16) 'X')	/* Mexico                              */
+#define COUNTRY_CODE_MY (((UINT_16) 'M' << 8) | (UINT_16) 'Y')	/* Malaysia                            */
+#define COUNTRY_CODE_MZ (((UINT_16) 'M' << 8) | (UINT_16) 'Z')	/* Mozambique                          */
+#define COUNTRY_CODE_NA (((UINT_16) 'N' << 8) | (UINT_16) 'A')	/* Namibia                             */
+#define COUNTRY_CODE_NC (((UINT_16) 'N' << 8) | (UINT_16) 'C')	/* New Caledonia                       */
+#define COUNTRY_CODE_NE (((UINT_16) 'N' << 8) | (UINT_16) 'E')	/* Niger                               */
+#define COUNTRY_CODE_NF (((UINT_16) 'N' << 8) | (UINT_16) 'F')	/* Norfolk Island                      */
+#define COUNTRY_CODE_NG (((UINT_16) 'N' << 8) | (UINT_16) 'G')	/* Nigeria                             */
+#define COUNTRY_CODE_NI (((UINT_16) 'N' << 8) | (UINT_16) 'I')	/* Nicaragua                           */
+#define COUNTRY_CODE_NL (((UINT_16) 'N' << 8) | (UINT_16) 'L')	/* Netherlands                         */
+#define COUNTRY_CODE_NO (((UINT_16) 'N' << 8) | (UINT_16) 'O')	/* Norway                              */
+#define COUNTRY_CODE_NP (((UINT_16) 'N' << 8) | (UINT_16) 'P')	/* Nepal                               */
+#define COUNTRY_CODE_NR (((UINT_16) 'N' << 8) | (UINT_16) 'R')	/* Nauru                               */
+#define COUNTRY_CODE_NU (((UINT_16) 'N' << 8) | (UINT_16) 'U')	/* Niue                                */
+#define COUNTRY_CODE_NZ (((UINT_16) 'N' << 8) | (UINT_16) 'Z')	/* New Zealand                         */
+#define COUNTRY_CODE_OM (((UINT_16) 'O' << 8) | (UINT_16) 'M')	/* Oman                                */
+#define COUNTRY_CODE_PA (((UINT_16) 'P' << 8) | (UINT_16) 'A')	/* Panama                              */
+#define COUNTRY_CODE_PE (((UINT_16) 'P' << 8) | (UINT_16) 'E')	/* Peru                                */
+#define COUNTRY_CODE_PF (((UINT_16) 'P' << 8) | (UINT_16) 'F')	/* "French Polynesia                   */
+#define COUNTRY_CODE_PG (((UINT_16) 'P' << 8) | (UINT_16) 'G')	/* Papua New Guinea                    */
+#define COUNTRY_CODE_PH (((UINT_16) 'P' << 8) | (UINT_16) 'H')	/* Philippines                         */
+#define COUNTRY_CODE_PK (((UINT_16) 'P' << 8) | (UINT_16) 'K')	/* Pakistan                            */
+#define COUNTRY_CODE_PL (((UINT_16) 'P' << 8) | (UINT_16) 'L')	/* Poland                              */
+#define COUNTRY_CODE_PM (((UINT_16) 'P' << 8) | (UINT_16) 'M')	/* Saint Pierre and Miquelon           */
+#define COUNTRY_CODE_PN (((UINT_16) 'P' << 8) | (UINT_16) 'N')	/* Pitcairn Islands                    */
+#define COUNTRY_CODE_PR (((UINT_16) 'P' << 8) | (UINT_16) 'R')	/* Puerto Rico (USA)                   */
+#define COUNTRY_CODE_PS (((UINT_16) 'P' << 8) | (UINT_16) 'S')	/* Palestinian Authority               */
+#define COUNTRY_CODE_PT (((UINT_16) 'P' << 8) | (UINT_16) 'T')	/* Portugal                            */
+#define COUNTRY_CODE_PW (((UINT_16) 'P' << 8) | (UINT_16) 'W')	/* Palau                               */
+#define COUNTRY_CODE_PY (((UINT_16) 'P' << 8) | (UINT_16) 'Y')	/* Paraguay                            */
+#define COUNTRY_CODE_QA (((UINT_16) 'Q' << 8) | (UINT_16) 'A')	/* Qatar                               */
+#define COUNTRY_CODE_RE (((UINT_16) 'R' << 8) | (UINT_16) 'E')	/* Reunion (France)                    */
+#define COUNTRY_CODE_RKS (((UINT_16) 'R' << 8) | (UINT_16) 'K')	/* Kosvo (Added on window's list)      */
+#define COUNTRY_CODE_RO (((UINT_16) 'R' << 8) | (UINT_16) 'O')	/* Romania                             */
+#define COUNTRY_CODE_RS (((UINT_16) 'R' << 8) | (UINT_16) 'S')	/* Serbia                              */
+#define COUNTRY_CODE_RU (((UINT_16) 'R' << 8) | (UINT_16) 'U')	/* Russia                              */
+#define COUNTRY_CODE_RW (((UINT_16) 'R' << 8) | (UINT_16) 'W')	/* Rwanda                              */
+#define COUNTRY_CODE_SA (((UINT_16) 'S' << 8) | (UINT_16) 'A')	/* Saudi Arabia                        */
+#define COUNTRY_CODE_SB (((UINT_16) 'S' << 8) | (UINT_16) 'B')	/* Solomon Islands                     */
+#define COUNTRY_CODE_SC (((UINT_16) 'S' << 8) | (UINT_16) 'C')	/* Seychelles                          */
+#define COUNTRY_CODE_SD (((UINT_16) 'S' << 8) | (UINT_16) 'D')	/* Sudan                               */
+#define COUNTRY_CODE_SE (((UINT_16) 'S' << 8) | (UINT_16) 'E')	/* Sweden                              */
+#define COUNTRY_CODE_SG (((UINT_16) 'S' << 8) | (UINT_16) 'G')	/* Singapole                           */
+#define COUNTRY_CODE_SI (((UINT_16) 'S' << 8) | (UINT_16) 'I')	/* Slovenia                            */
+#define COUNTRY_CODE_SK (((UINT_16) 'S' << 8) | (UINT_16) 'K')	/* Slovakia                            */
+#define COUNTRY_CODE_SL (((UINT_16) 'S' << 8) | (UINT_16) 'L')	/* Sierra Leone                        */
+#define COUNTRY_CODE_SM (((UINT_16) 'S' << 8) | (UINT_16) 'M')	/* San Marino                          */
+#define COUNTRY_CODE_SN (((UINT_16) 'S' << 8) | (UINT_16) 'N')	/* Senegal                             */
+#define COUNTRY_CODE_SO (((UINT_16) 'S' << 8) | (UINT_16) 'O')	/* Somalia                             */
+#define COUNTRY_CODE_SR (((UINT_16) 'S' << 8) | (UINT_16) 'R')	/* Suriname                            */
+#define COUNTRY_CODE_SS (((UINT_16) 'S' << 8) | (UINT_16) 'S')	/* South_Sudan                         */
+#define COUNTRY_CODE_ST (((UINT_16) 'S' << 8) | (UINT_16) 'T')	/* Sao Tome and Principe               */
+#define COUNTRY_CODE_SV (((UINT_16) 'S' << 8) | (UINT_16) 'V')	/* El Salvador                         */
+#define COUNTRY_CODE_SY (((UINT_16) 'S' << 8) | (UINT_16) 'Y')	/* Syria                               */
+#define COUNTRY_CODE_SZ (((UINT_16) 'S' << 8) | (UINT_16) 'Z')	/* Swaziland                           */
+#define COUNTRY_CODE_TC (((UINT_16) 'T' << 8) | (UINT_16) 'C')	/* Turks and Caicos Islands (UK)       */
+#define COUNTRY_CODE_TD (((UINT_16) 'T' << 8) | (UINT_16) 'D')	/* Chad                                */
+#define COUNTRY_CODE_TF (((UINT_16) 'T' << 8) | (UINT_16) 'F')	/* French Southern and Antarctic Lands */
+#define COUNTRY_CODE_TG (((UINT_16) 'T' << 8) | (UINT_16) 'G')	/* Togo                                */
+#define COUNTRY_CODE_TH (((UINT_16) 'T' << 8) | (UINT_16) 'H')	/* Thailand                            */
+#define COUNTRY_CODE_TJ (((UINT_16) 'T' << 8) | (UINT_16) 'J')	/* Tajikistan                          */
+#define COUNTRY_CODE_TL (((UINT_16) 'T' << 8) | (UINT_16) 'L')	/* East Timor                          */
+#define COUNTRY_CODE_TM (((UINT_16) 'T' << 8) | (UINT_16) 'M')	/* Turkmenistan                        */
+#define COUNTRY_CODE_TN (((UINT_16) 'T' << 8) | (UINT_16) 'N')	/* Tunisia                             */
+#define COUNTRY_CODE_TO (((UINT_16) 'T' << 8) | (UINT_16) 'O')	/* Tonga                               */
+#define COUNTRY_CODE_TR (((UINT_16) 'T' << 8) | (UINT_16) 'R')	/* Turkey                              */
+#define COUNTRY_CODE_TT (((UINT_16) 'T' << 8) | (UINT_16) 'T')	/* Trinidad and Tobago                 */
+#define COUNTRY_CODE_TV (((UINT_16) 'T' << 8) | (UINT_16) 'V')	/* Tuvalu                              */
+#define COUNTRY_CODE_TW (((UINT_16) 'T' << 8) | (UINT_16) 'W')	/* Taiwan                              */
+#define COUNTRY_CODE_TZ (((UINT_16) 'T' << 8) | (UINT_16) 'Z')	/* Tanzania                            */
+#define COUNTRY_CODE_UA (((UINT_16) 'U' << 8) | (UINT_16) 'A')	/* Ukraine                             */
+#define COUNTRY_CODE_UG (((UINT_16) 'U' << 8) | (UINT_16) 'G')	/* Ugnada                              */
+#define COUNTRY_CODE_US (((UINT_16) 'U' << 8) | (UINT_16) 'S')	/* US                                  */
+#define COUNTRY_CODE_UY (((UINT_16) 'U' << 8) | (UINT_16) 'Y')	/* Uruguay                             */
+#define COUNTRY_CODE_UZ (((UINT_16) 'U' << 8) | (UINT_16) 'Z')	/* Uzbekistan                          */
+#define COUNTRY_CODE_VA (((UINT_16) 'V' << 8) | (UINT_16) 'A')	/* Vatican (Holy See)                  */
+#define COUNTRY_CODE_VC (((UINT_16) 'V' << 8) | (UINT_16) 'C')	/* Saint Vincent and the Grenadines    */
+#define COUNTRY_CODE_VE (((UINT_16) 'V' << 8) | (UINT_16) 'E')	/* Venezuela                           */
+#define COUNTRY_CODE_VG (((UINT_16) 'V' << 8) | (UINT_16) 'G')	/* British Virgin Islands              */
+#define COUNTRY_CODE_VI (((UINT_16) 'V' << 8) | (UINT_16) 'I')	/* US Virgin Islands                   */
+#define COUNTRY_CODE_VN (((UINT_16) 'V' << 8) | (UINT_16) 'N')	/* Vietnam                             */
+#define COUNTRY_CODE_VU (((UINT_16) 'V' << 8) | (UINT_16) 'U')	/* Vanuatu                             */
+#define COUNTRY_CODE_WS (((UINT_16) 'W' << 8) | (UINT_16) 'S')	/* Samoa                               */
+#define COUNTRY_CODE_YE (((UINT_16) 'Y' << 8) | (UINT_16) 'E')	/* Yemen                               */
+#define COUNTRY_CODE_YT (((UINT_16) 'Y' << 8) | (UINT_16) 'T')	/* Mayotte (France)                    */
+#define COUNTRY_CODE_ZA (((UINT_16) 'Z' << 8) | (UINT_16) 'A')	/* South Africa                        */
+#define COUNTRY_CODE_ZM (((UINT_16) 'Z' << 8) | (UINT_16) 'M')	/* Zambia                              */
+#define COUNTRY_CODE_ZW (((UINT_16) 'Z' << 8) | (UINT_16) 'W')	/* Zimbabwe                            */
+
+#define COUNTRY_CODE_DF (((UINT_16) 'D' << 8) | (UINT_16) 'F')	/* Default country domain              */
+#define COUNTRY_CODE_UDF (((UINT_16) 'U' << 8) | (UINT_16) 'D')	/* User defined supported channel list
+								   and passive scan channel list       */
+
+#define COUNTRY_CODE_FF (((UINT_16) 'F' << 8) | (UINT_16) 'F')	/* enable open for all channel for Certification */
+#define COUNTRY_CODE_FE (((UINT_16) 'F' << 8) | (UINT_16) 'E')	/* disable open for all channel for Certification */
+
+/* dot11RegDomainsSupportValue */
+#define MIB_REG_DOMAIN_FCC              0x10	/* FCC (US) */
+#define MIB_REG_DOMAIN_IC               0x20	/* IC or DOC (Canada) */
+#define MIB_REG_DOMAIN_ETSI             0x30	/* ETSI (Europe) */
+#define MIB_REG_DOMAIN_SPAIN            0x31	/* Spain */
+#define MIB_REG_DOMAIN_FRANCE           0x32	/* France */
+#define MIB_REG_DOMAIN_JAPAN            0x40	/* MPHPT (Japan) */
+#define MIB_REG_DOMAIN_OTHER            0x00	/* other */
+
+/*2.4G*/
+#define BAND_2G4_LOWER_BOUND 1
+#define BAND_2G4_UPPER_BOUND 14
+/*5G SubBand FCC spec*/
+#define UNII1_LOWER_BOUND    36
+#define UNII1_UPPER_BOUND    48
+#define UNII2A_LOWER_BOUND   52
+#define UNII2A_UPPER_BOUND   64
+#define UNII2C_LOWER_BOUND   100
+#define UNII2C_UPPER_BOUND   144
+#define UNII3_LOWER_BOUND    149
+#define UNII3_UPPER_BOUND    173
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+
+#define POWER_LIMIT_TABLE_NULL			0xFFFF
+#define MAX_TX_POWER					63
+#define MIN_TX_POWER					-64
+#define MAX_CMD_SUPPORT_CHANNEL_NUM	64
+
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+
+typedef enum _ENUM_POWER_LIMIT_T {
+	PWR_LIMIT_CCK,
+	PWR_LIMIT_20M,
+	PWR_LIMIT_40M,
+	PWR_LIMIT_80M,
+	PWR_LIMIT_160M,
+	PWR_LIMIT_NUM
+} ENUM_POWER_LIMIT_T, *P_ENUM_POWER_LIMIT_T;
+
+#endif
+
+typedef enum _ENUM_POWER_LIMIT_SUBBAND_T {
+	POWER_LIMIT_2G4,
+	POWER_LIMIT_UNII1,
+	POWER_LIMIT_UNII2A,
+	POWER_LIMIT_UNII2C,
+	POWER_LIMIT_UNII3,
+	POWER_LIMIT_SUBAND_NUM
+} ENUM_POWER_LIMIT_SUBBAND_T, *P_ENUM_POWER_LIMIT_SUBBAND_T;
+
+/* Define channel offset in unit of 5MHz bandwidth */
+typedef enum _ENUM_CHNL_SPAN_T {
+	CHNL_SPAN_5 = 1,
+	CHNL_SPAN_10 = 2,
+	CHNL_SPAN_20 = 4,
+	CHNL_SPAN_40 = 8
+} ENUM_CHNL_SPAN_T, *P_ENUM_CHNL_SPAN_T;
+
+/* Define BSS operating bandwidth */
+typedef enum _ENUM_CHNL_BW_T {
+	CHNL_BW_20,
+	CHNL_BW_20_40,
+	CHNL_BW_10,
+	CHNL_BW_5
+} ENUM_CHNL_BW_T, *P_ENUM_CHNL_BW_T;
+
+/* In all bands, the first channel will be SCA and the second channel is SCB,
+ * then iteratively.
+ * Note the final channel will not be SCA.
+ */
+typedef struct _DOMAIN_SUBBAND_INFO {
+	/* Note1: regulation class depends on operation bandwidth and RF band.
+	 *  For example: 2.4GHz, 1~13, 20MHz ==> regulation class = 81
+	 *               2.4GHz, 1~13, SCA   ==> regulation class = 83
+	 *               2.4GHz, 1~13, SCB   ==> regulation class = 84
+	 * Note2: TX power limit is not specified here because path loss is unknown
+	 */
+	UINT_8 ucRegClass;	/* Regulation class for 20MHz */
+	UINT_8 ucBand;		/* Type: ENUM_BAND_T */
+	UINT_8 ucChannelSpan;	/* Type: ENUM_CHNL_SPAN_T */
+	UINT_8 ucFirstChannelNum;
+	UINT_8 ucNumChannels;
+	UINT_8 fgDfs;		/* Type: BOOLEAN */
+} DOMAIN_SUBBAND_INFO, *P_DOMAIN_SUBBAND_INFO;
+
+/* Use it as all available channel list for STA */
+typedef struct _DOMAIN_INFO_ENTRY {
+	PUINT_16 pu2CountryGroup;
+	UINT_32 u4CountryNum;
+
+	/* If different attributes, put them into different rSubBands.
+	 * For example, DFS shall be used or not.
+	 */
+	DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM];
+} DOMAIN_INFO_ENTRY, *P_DOMAIN_INFO_ENTRY;
+
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+
+typedef struct _CHANNEL_POWER_LIMIT {
+	UINT_8 ucCentralCh;
+	INT_8 cPwrLimitCCK;
+	INT_8 cPwrLimit20;
+	INT_8 cPwrLimit40;
+	INT_8 cPwrLimit80;
+	INT_8 cPwrLimit160;
+	UINT_8 ucFlag;
+	UINT_8 aucReserved[1];
+} CHANNEL_POWER_LIMIT, *P_CHANNEL_POWER_LIMIT;
+
+typedef struct _COUNTRY_CHANNEL_POWER_LIMIT {
+	UINT_8 aucCountryCode[2];
+	UINT_8 ucCountryFlag;
+	UINT_8 ucChannelNum;
+	UINT_8 aucReserved[4];
+	CHANNEL_POWER_LIMIT rChannelPowerLimit[80];
+} COUNTRY_CHANNEL_POWER_LIMIT, *P_COUNTRY_CHANNEL_POWER_LIMIT;
+
+#define CHANNEL_PWR_LIMIT(_channel, _pwrLimit_cck, _pwrLimit_bw20,	\
+	_pwrLimit_bw40, _pwrLimit_bw80, _pwrLimit_bw160, _ucFlag)	\
+	{                                                  \
+	.ucCentralCh           = (_channel),               \
+	.cPwrLimitCCK          = (_pwrLimit_cck),          \
+	.cPwrLimit20           = (_pwrLimit_bw20),         \
+	.cPwrLimit40           = (_pwrLimit_bw40),         \
+	.cPwrLimit80           = (_pwrLimit_bw80),         \
+	.cPwrLimit160          = (_pwrLimit_bw160),        \
+	.ucFlag                = (_ucFlag),                \
+	.aucReserved           = {0}                       \
+}
+
+typedef struct _COUNTRY_POWER_LIMIT_TABLE_DEFAULT {
+	UINT_8 aucCountryCode[2];
+	/* 0: ch 1 ~14 , 1: ch 36 ~48, 2: ch 52 ~64, 3: ch 100 ~144, 4: ch 149 ~165 */
+	INT_8 aucPwrLimitSubBand[POWER_LIMIT_SUBAND_NUM];
+	/* bit0: cPwrLimit2G4, bit1: cPwrLimitUnii1; bit2: cPwrLimitUnii2A;
+	 * bit3: cPwrLimitUnii2C; bit4: cPwrLimitUnii3; mW: 0, mW\MHz : 1 */
+	UINT_8 ucPwrUnit;
+} COUNTRY_POWER_LIMIT_TABLE_DEFAULT, *P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT;
+
+typedef struct _COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION {
+	UINT_8 aucCountryCode[2];
+	UINT_8 ucCentralCh;
+	INT_8 aucPwrLimit[PWR_LIMIT_NUM];
+} COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION, *P_COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION;
+
+typedef struct _SUBBAND_CHANNEL_T {
+	UINT_8 ucStartCh;
+	UINT_8 ucEndCh;
+	UINT_8 ucInterval;
+	UINT_8 ucReserved;
+} SUBBAND_CHANNEL_T, *P_SUBBAND_CHANNEL_T;
+
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define CAL_CH_OFFSET_80M(_PRIMARY_CH, _CENTRAL_CH) \
+			(((_PRIMARY_CH - _CENTRAL_CH) + 6) >> 2)
+
+#define CAL_CH_OFFSET_160M(_PRIMARY_CH, _CENTRAL_CH) \
+			(((_PRIMARY_CH - _CENTRAL_CH) + 14) >> 2)
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter);
+
+VOID
+rlmDomainGetChnlList(P_ADAPTER_T prAdapter,
+		     ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs,
+		     UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList);
+
+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid);
+
+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid);
+
+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid);
+
+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel);
+
+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf);
+
+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh);
+
+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend);
+
+BOOLEAN rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand,
+				  UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend,
+				  ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2);
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+
+BOOLEAN
+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter,
+			      COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration,
+			      UINT_8 ucPwrLimitNum);
+
+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter);
+
+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode);
+
+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter);
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _RLM_DOMAIN_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h
new file mode 100644
index 0000000000000..7f29dba4ce069
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h
@@ -0,0 +1,150 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_obss.h#1
+*/
+
+/*! \file   "rlm_obss.h"
+    \brief
+*/
+
+/*
+** Log: rlm_obss.h
+ *
+ * 01 24 2011 cm.chang
+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop
+ * ampdu timer when sta_rec is freed
+ * Process received 20/40 coexistence action frame for AP mode
+ *
+ * 01 13 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Refine function when rcv a 20/40M public action frame
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 28 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * 1st draft code for RLM module
+ *
+ * 05 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Process 20/40 coexistence public action frame in AP mode
+ *
+ * 05 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft support for 20/40M bandwidth for AP mode
+ *
+ * 04 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add virtual test for OBSS scan
+ *
+ * 03 30 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support 2.4G OBSS scan
+ *
+ * 02 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support PCO in STA mode
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Use bss info array for concurrent handle
+ *
+ * 01 25 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+*/
+
+#ifndef _RLM_OBSS_H
+#define _RLM_OBSS_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define CHNL_LIST_SZ_2G         14
+#define CHNL_LIST_SZ_5G         14
+
+#define CHNL_LEVEL0             0
+#define CHNL_LEVEL1             1
+#define CHNL_LEVEL2             2
+
+#define AFFECTED_CHNL_OFFSET    5
+
+#define OBSS_SCAN_MIN_INTERVAL  10	/* In unit of sec */
+
+#define PUBLIC_ACTION_MAX_LEN   200	/* In unit of byte */
+
+/* P2P GO only */
+/* Define default OBSS Scan parameters (from MIB in spec.) */
+#define dot11OBSSScanPassiveDwell                   20
+#define dot11OBSSScanActiveDwell                    10
+#define dot11OBSSScanPassiveTotalPerChannel         200
+#define dot11OBSSScanActiveTotalPerChannel          20
+#define dot11BSSWidthTriggerScanInterval            300	/* Unit: sec */
+#define dot11BSSWidthChannelTransitionDelayFactor   5
+#define dot11OBSSScanActivityThreshold              25
+
+#define OBSS_20_40M_TIMEOUT     (dot11BSSWidthTriggerScanInterval + 10)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/* Control MAC PCO function */
+typedef enum _ENUM_SYS_PCO_PHASE_T {
+	SYS_PCO_PHASE_DISABLED = 0,
+	SYS_PCO_PHASE_20M,
+	SYS_PCO_PHASE_40M
+} ENUM_SYS_PCO_PHASE_T, *P_ENUM_SYS_PCO_PHASE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID rlmObssInit(P_ADAPTER_T prAdapter);
+
+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr);
+
+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _RLM_OBSS_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h
new file mode 100644
index 0000000000000..8665e48569bad
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h
@@ -0,0 +1,122 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_protection.h#1
+*/
+
+/*! \file   "rlm_protection.h"
+    \brief
+*/
+
+/*
+** Log: rlm_protection.h
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 28 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * 1st draft code for RLM module
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft code to support protection in AP mode
+ *
+ * 02 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support PCO in STA mode
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Use bss info array for concurrent handle
+ *
+ * 01 25 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+*/
+
+#ifndef _RLM_PROTECTION_H
+#define _RLM_PROTECTION_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_SYS_PROTECT_MODE_T {
+	SYS_PROTECT_MODE_NONE = 0,	/* Mode 0 */
+	SYS_PROTECT_MODE_ERP,	/* Mode 1 */
+	SYS_PROTECT_MODE_NON_HT,	/* Mode 2 */
+	SYS_PROTECT_MODE_20M,	/* Mode 3 */
+
+	SYS_PROTECT_MODE_NUM
+} ENUM_SYS_PROTECT_MODE_T, *P_ENUM_SYS_PROTECT_MODE_T;
+
+/* This definition follows HT Protection field of HT Operation IE */
+typedef enum _ENUM_HT_PROTECT_MODE_T {
+	HT_PROTECT_MODE_NONE = 0,
+	HT_PROTECT_MODE_NON_MEMBER,
+	HT_PROTECT_MODE_20M,
+	HT_PROTECT_MODE_NON_HT,
+
+	HT_PROTECT_MODE_NUM
+} ENUM_HT_PROTECT_MODE_T, *P_ENUM_HT_PROTECT_MODE_T;
+
+typedef enum _ENUM_GF_MODE_T {
+	GF_MODE_NORMAL = 0,
+	GF_MODE_PROTECT,
+	GF_MODE_DISALLOWED,
+
+	GF_MODE_NUM
+} ENUM_GF_MODE_T, *P_ENUM_GF_MODE_T;
+
+typedef enum _ENUM_RIFS_MODE_T {
+	RIFS_MODE_NORMAL = 0,
+	RIFS_MODE_DISALLOWED,
+
+	RIFS_MODE_NUM
+} ENUM_RIFS_MODE_T, *P_ENUM_RIFS_MODE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _RLM_PROTECTION_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h
new file mode 100644
index 0000000000000..d01c6e01e83f5
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h
@@ -0,0 +1,1213 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_txpwr_init.h#1
+*/
+
+/*! \file   "rlm_txpwr_init.h"
+    \brief
+*/
+
+/*
+** Log: rlm_txpwr_init.h
+*/
+
+
+#ifndef _RLM_TXPWR_INIT_H
+#define _RLM_TXPWR_INIT_H
+
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/*Support Tx Power Range : 63~ -64 (unit : 0.5dBm)*/
+
+#define PWR_LIMIT_2G4_IN_MW_MHZ    BIT(0)
+#define PWR_LIMIT_UNII1_IN_MW_MHZ  BIT(1)
+#define PWR_LIMIT_UNII2A_IN_MW_MHZ BIT(2)
+#define PWR_LIMIT_UNII2C_IN_MW_MHZ BIT(3)
+#define PWR_LIMIT_UNII3_IN_MW_MHZ  BIT(4)
+
+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT
+#define CE_FCC_TXPWR_LIMIT_CCK  30  /* 15 dBm */
+#define CE_FCC_TXPWR_LIMIT_OFDM 20  /* 10 dBm */
+#define CE_FCC_TXPWR_LIMIT_HT40 18  /*  9 dBm */
+#endif
+
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+
+COUNTRY_POWER_LIMIT_TABLE_DEFAULT g_rRlmPowerLimitDefault[] = {
+
+	{{'A', 'O'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'B', 'Z'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'B', 'J'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'B', 'T'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'B', 'O'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'B', 'I'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'C', 'M'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'C', 'F'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'T', 'D'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'K', 'M'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'C', 'D'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'C', 'G'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'C', 'I'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'D', 'J'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'G', 'Q'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'E', 'R'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'F', 'J'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'G', 'A'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'G', 'M'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'G', 'N'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'G', 'W'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'R', 'K'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'K', 'G'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'L', 'Y'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'M', 'G'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'M', 'L'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'N', 'R'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'N', 'C'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'T'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'C'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'L'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'B'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'O'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'R'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'Z'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'T', 'J'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'T', 'G'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'T', 'O'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'T', 'M'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'T', 'V'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'V', 'U'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'Y', 'E'}
+	 , {40, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'A', 'S'}
+	 , {60, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'A', 'I'}
+	 , {60, 34, 48, 60, 60}
+	 , 0}
+	,
+	{{'B', 'M'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'C', 'A'}
+	 , {60, 46, 48, 48, 60}
+	 , 0}
+	,
+	{{'K', 'Y'}
+	 , {60, 34, 48, 60, 60}
+	 , 0}
+	,
+	{{'G', 'U'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'F', 'M'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'P', 'R'}
+	 , {60, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'U', 'S'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'V', 'I'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'A', 'R'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'A', 'U'}
+	 , {63, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'A', 'Z'}
+	 , {40, 34, 48, 60, 60}
+	 , 0}
+	,
+	{{'B', 'W'}
+	 , {40, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'K', 'H'}
+	 , {40, 46, 46, 48, 60}
+	 , 0}
+	,
+	{{'C', 'X'}
+	 , {63, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'C', 'O'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'C', 'R'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'E', 'C'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'G', 'D'}
+	 , {40, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'G', 'T'}
+	 , {40, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'H', 'K'}
+	 , {63, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'K', 'I'}
+	 , {63, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'L', 'B'}
+	 , {40, 46, 46, 46, 46}
+	 , 0}
+	,
+	{{'L', 'R'}
+	 , {60, 46, 60, 63, 63}
+	 , 0}
+	,
+	{{'M', 'N'}
+	 , {46, 32, 46, 46, 58}
+	 , 0}
+	,
+	{{'A', 'N'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'N', 'Z'}
+	 , {63, 46, 60, 48, 63}
+	 , 0}
+	,
+	{{'N', 'I'}
+	 , {60, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'P', 'W'}
+	 , {60, 60, 60, 60, 60}
+	 , 0}
+	,
+	{{'P', 'Y'}
+	 , {60, 46, 46, 48, 60}
+	 , 0}
+	,
+	{{'P', 'E'}
+	 , {54, 46, 48, 42, 48}
+	 , 0}
+	,
+	{{'P', 'H'}
+	 , {40, 46, 46, 48, 48}
+	 , 0}
+	,
+	{{'W', 'S'}
+	 , {40, 40, 40, 40, 60}
+	 , 0}
+	,
+	{{'S', 'G'}
+	 , {46, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'L', 'K'}
+	 , {46, 46, 46, 46, 46}
+	 , 0}
+	,
+	{{'T', 'H'}
+	 , {40, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'T', 'T'}
+	 , {60, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'U', 'Y'}
+	 , {63, 46, 46, 46, 46}
+	 , 0}
+	,
+	{{'V', 'N'}
+	 , {46, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'A', 'W'}
+	 , {60, 46, 60, 60, 63}
+	 , 0}
+	,
+	{{'L', 'A'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'S', 'A'}
+	 , {40, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'A', 'E'}
+	 , {40, 46, 46, 60, 46}
+	 , 0}
+	,
+	{{'U', 'G'}
+	 , {40, 46, 46, 48, 60}
+	 , 0}
+	,
+	{{'M', 'M'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'A', 'L'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'D', 'Z'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'A', 'D'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'A', 'T'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'B', 'Y'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'B', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'B', 'A'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'V', 'G'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'B', 'G'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'C', 'V'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'H', 'R'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'C', 'Y'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'C', 'Z'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'D', 'K'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'E', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'E', 'T'}
+	 , {40, 40, 40, 40, 63}
+	 , 0}
+	,
+	{{'F', 'I'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'F', 'R'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'G', 'F'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'P', 'F'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'T', 'F'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'G', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'D', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'G', 'H'}
+	 , {40, 34, 48, 60, 63}
+	 , 0}
+	,
+	{{'G', 'R'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'G', 'P'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'H', 'U'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'I', 'S'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'I', 'Q'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'I', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'I', 'T'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'K', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'L', 'V'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'L', 'S'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'L', 'I'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'L', 'T'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'L', 'U'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'K'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'T'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'Q'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'R'}
+	 , {40, 46, 46, 46, 63}
+	 , 0}
+	,
+	{{'M', 'U'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'Y', 'T'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'D'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'C'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'S'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'N', 'L'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'N', 'O'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'O', 'M'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'P', 'L'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'P', 'T'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'R', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'R', 'O'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'M', 'F'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'S', 'M'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'S', 'N'}
+	 , {40, 40, 40, 60, 63}
+	 , 0}
+	,
+	{{'R', 'S'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'S', 'K'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'S', 'I'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'Z', 'A'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'E', 'S'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'S', 'E'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'C', 'H'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'T', 'R'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'T', 'C'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'G', 'B'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'V', 'A'}
+	 , {40, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'A', 'M'}
+	 , {40, 40, 40, 63, 63}
+	 , 0}
+	,
+	{{'I', 'L'}
+	 , {40, 46, 46, 63, 63}
+	 , 0}
+	,
+	{{'K', 'W'}
+	 , {40, 46, 46, 63, 63}
+	 , 0}
+	,
+	{{'M', 'A'}
+	 , {40, 46, 46, 63, 63}
+	 , 0}
+	,
+	{{'N', 'E'}
+	 , {40, 46, 46, 63, 63}
+	 , 0}
+	,
+	{{'T', 'N'}
+	 , {40, 46, 46, 63, 63}
+	 , 0}
+	,
+	{{'E', 'H'}
+	 , {40, 46, 46, 63, 63}
+	 , 0}
+	,
+	{{'N', 'P'}
+	 , {60, 46, 46, 63, 60}
+	 , 0}
+	,
+	{{'A', 'F'}
+	 , {40, 46, 63, 63, 63}
+	 , 0}
+	,
+	{{'A', 'G'}
+	 , {40, 46, 48, 63, 54}
+	 , 0}
+	,
+	{{'B', 'S'}
+	 , {63, 46, 60, 63, 63}
+	 , 0}
+	,
+	{{'B', 'H'}
+	 , {40, 46, 46, 63, 63}
+	 , 0}
+	,
+	{{'B', 'B'}
+	 , {40, 46, 48, 63, 54}
+	 , 0}
+	,
+	{{'B', 'N'}
+	 , {46, 46, 46, 63, 60}
+	 , 0}
+	,
+	{{'C', 'L'}
+	 , {40, 44, 44, 63, 44}
+	 , 0}
+	,
+	{{'C', 'N'}
+	 , {40, 46, 46, 63, 54}
+	 , 0}
+	,
+	{{'E', 'G'}
+	 , {40, 46, 46, 63, 46}
+	 , 0}
+	,
+	{{'S', 'V'}
+	 , {60, 34, 48, 63, 60}
+	 , 0}
+	,
+	{{'I', 'N'}
+	 , {60, 46, 46, 63, 60}
+	 , 0}
+	,
+	{{'M', 'Y'}
+	 , {54, 60, 60, 63, 60}
+	 , 0}
+	,
+	{{'M', 'V'}
+	 , {40, 46, 46, 63, 40}
+	 , 0}
+	,
+	{{'P', 'A'}
+	 , {60, 34, 48, 63, 60}
+	 , 0}
+	,
+	{{'V', 'E'}
+	 , {60, 46, 46, 63, 60}
+	 , 0}
+	,
+	{{'Z', 'M'}
+	 , {60, 46, 46, 63, 60}
+	 , 0}
+	,
+	{{'J', 'O'}
+	 , {40, 46, 63, 63, 46}
+	 , 0}
+	,
+	{{'P', 'G'}
+	 , {40, 46, 63, 63, 60}
+	 , 0}
+	,
+	{{'B', 'F'}
+	 , {40, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'G', 'Y'}
+	 , {60, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'H', 'T'}
+	 , {40, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'H', 'N'}
+	 , {60, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'J', 'M'}
+	 , {54, 63, 63, 63, 57}
+	 , 0}
+	,
+	{{'M', 'O'}
+	 , {40, 63, 63, 63, 40}
+	 , 0}
+	,
+	{{'M', 'W'}
+	 , {60, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'P', 'K'}
+	 , {40, 63, 63, 63, 40}
+	 , 0}
+	,
+	{{'Q', 'A'}
+	 , {40, 63, 63, 63, 40}
+	 , 0}
+	,
+	{{'R', 'W'}
+	 , {40, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'K', 'N'}
+	 , {40, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'T', 'Z'}
+	 , {40, 63, 63, 63, 40}
+	 , 0}
+	,
+	{{'I', 'D'}
+	 , {46, 63, 63, 63, 60}
+	 , 0}
+	,
+	{{'N', 'G'}
+	 , {40, 63, 46, 63, 60}
+	 , 0}
+	,
+	{{'B', 'D'}
+	 , {40, 46, 46, 60, 28}
+	 , 0}
+	,
+	{{'B', 'R'}
+	 , {52, 46, 46, 60, 60}
+	 , 0}
+	,
+	{{'D', 'M'}
+	 , {60, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'D', 'O'}
+	 , {63, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'F', 'K'}
+	 , {40, 46, 46, 60, 28}
+	 , 0}
+	,
+	{{'K', 'Z'}
+	 , {40, 34, 48, 60, 60}
+	 , 0}
+	,
+	{{'M', 'X'}
+	 , {60, 34, 48, 60, 63}
+	 , 0}
+	,
+	{{'M', 'Z'}
+	 , {40, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'N', 'A'}
+	 , {40, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'R', 'U'}
+	 , {40, 34, 48, 60, 60}
+	 , 0}
+	,
+	{{'L', 'C'}
+	 , {40, 34, 48, 48, 60}
+	 , 0}
+	,
+	{{'V', 'C'}
+	 , {40, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'U', 'A'}
+	 , {40, 46, 46, 46, 48}
+	 , 0}
+	,
+	{{'U', 'Z'}
+	 , {40, 48, 48, 48, 60}
+	 , 0}
+	,
+	{{'Z', 'W'}
+	 , {40, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'M', 'P'}
+	 , {60, 34, 46, 48, 60}
+	 , 0}
+	,
+	{{'T', 'W'}
+	 , {60, 63, 34, 48, 60}
+	 , 0}
+	,
+	{{'C', 'K'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'C', 'U'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'T', 'L'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'F', 'O'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'G', 'I'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'G', 'G'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'I', 'R'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'I', 'M'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'J', 'E'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'K', 'P'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'M', 'H'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'N', 'U'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'N', 'F'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'P', 'S'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'P', 'N'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'P', 'M'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'S'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'D'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'S', 'Y'}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+	,
+	{{'J', 'P'}
+	 , {46, 46, 46, 60, 63}
+	 , 0}
+	,
+	{{'K', 'R'}
+	 , {46, 34, 46, 46, 46}
+	 , PWR_LIMIT_UNII1_IN_MW_MHZ}
+	,
+
+/*Default*/
+	{{0, 0}
+	 , {63, 63, 63, 63, 63}
+	 , 0}
+};
+
+COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION g_rRlmPowerLimitConfiguration[] = {
+
+	{{'A', 'I'}
+	 , 144, {48, 48, 48, 48, 48}
+	 }
+	,
+	{{'A', 'Z'}
+	 , 144, {48, 48, 48, 48, 48}
+	 }
+	,
+	{{'B', 'W'}
+	 , 144, {48, 48, 48, 48, 48}
+	 }
+	,
+	{{'G', 'D'}
+	 , 144, {48, 48, 48, 48, 48}
+	 }
+	,
+	{{'L', 'B'}
+	 , 144, {48, 48, 48, 48, 48}
+	 }
+	,
+	{{'L', 'R'}
+	 , 144, {48, 48, 48, 48, 48}
+	 }
+	,
+	{{'W', 'S'}
+	 , 165, {40, 40, 40, 40, 40}
+	 }
+	,
+	{{'V', 'N'}
+	 , 144, {48, 48, 48, 48, 48}
+	 }
+	,
+	{{'U', 'S'}
+	 , 1, {38, 30, 60, 60, 60}
+	 }
+	,
+	{{'U', 'S'}
+	 , 3, {60, 60, 26, 60, 60}
+	 }
+	,
+	{{'U', 'S'}
+	 , 9, {60, 60, 26, 60, 60}
+	 }
+	,
+	{{'U', 'S'}
+	 , 11, {38, 30, 60, 60, 60}
+	 }
+	,
+	{{'U', 'S'}
+	 , 36, {34, 34, 34, 34, 34}
+	 }
+	,
+	{{'U', 'S'}
+	 , 38, {34, 34, 34, 34, 34}
+	 }
+	,
+	{{'U', 'S'}
+	 , 42, {34, 34, 34, 31, 34}
+	 }
+	,
+	{{'U', 'S'}
+	 , 58, {48, 48, 48, 31, 48}
+	 }
+	,
+	{{'U', 'S'}
+	 , 62, {48, 48, 34, 48, 48}
+	 }
+	,
+	{{'U', 'S'}
+	 , 64, {37, 37, 48, 48, 48}
+	 }
+	,
+	{{'U', 'S'}
+	 , 100, {37, 37, 48, 48, 48}
+	 }
+	,
+	{{'U', 'S'}
+	 , 102, {48, 48, 34, 48, 48}
+	 }
+	,
+	{{'U', 'S'}
+	 , 106, {48, 48, 48, 31, 48}
+	 }
+	,
+	{{'U', 'S'}
+	 , 155, {60, 60, 60, 31, 60}
+	 }
+	,
+	{{'U', 'S'}
+	 , 159, {60, 60, 34, 60, 60}
+	 }
+	,
+	{{'U', 'S'}
+	 , 165, {37, 37, 60, 60, 60}
+	 }
+	,
+
+/*Default*/
+	{{0, 0}
+	 , 165, {63, 63, 63, 63, 63}
+	 }
+};
+
+#if 0
+COUNTRY_CHANNEL_POWER_LIMIT g_rRlmCountryPowerLimitTable[] = {
+	{
+	 {'A', 'O'}
+	 , 0, 0, {0, 0, 0, 0}
+	 ,
+	 {
+	  CHANNEL_PWR_LIMIT(1, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(2, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(3, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(4, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(5, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(6, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(7, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(8, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(9, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(10, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(11, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(12, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(13, 40, 40, 40, 40, 40, 0),
+	  CHANNEL_PWR_LIMIT(14, 40, 40, 40, 40, 40, 0),
+
+	  CHANNEL_PWR_LIMIT(36, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(38, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(40, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(42, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(44, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(46, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(48, 63, 63, 63, 63, 63, 0),
+
+	  CHANNEL_PWR_LIMIT(52, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(54, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(56, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(58, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(60, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(62, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(64, 63, 63, 63, 63, 63, 0),
+
+	  CHANNEL_PWR_LIMIT(100, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(102, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(104, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(106, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(108, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(110, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(112, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(114, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(116, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(118, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(120, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(122, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(124, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(126, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(128, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(130, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(132, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(134, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(136, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(138, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(140, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(142, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(144, 63, 63, 63, 63, 63, 0),
+
+	  CHANNEL_PWR_LIMIT(149, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(151, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(153, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(155, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(157, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(159, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(161, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(163, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(165, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(167, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(169, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(171, 63, 63, 63, 63, 63, 0),
+	  CHANNEL_PWR_LIMIT(173, 63, 63, 63, 63, 63, 0)
+	  }
+	 }
+	,
+	{
+	 /*Used to check the end of country entry */
+	 {0, 0}
+	 , 0, 0, {0, 0, 0, 0}
+	 ,
+	 {
+	  /*Used to check the end of channel power limit */
+	  CHANNEL_PWR_LIMIT(ENDCH, 0, 0, 0, 0, 0, 0)
+	  }
+	 }			/*end of CountryTable */
+};
+#endif
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+#endif /* _RLM_TXPWR_INIT_H */
+
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h
new file mode 100644
index 0000000000000..0df4ec3e08282
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h
@@ -0,0 +1,171 @@
+/*
+** Id:
+*/
+
+/*! \file   "roaming_fsm.h"
+    \brief  This file defines the FSM for Roaming MODULE.
+
+    This file defines the FSM for Roaming MODULE.
+*/
+
+/*
+** Log: roaming_fsm.h
+ *
+ * 08 31 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * remove obsolete code.
+ *
+ * 08 15 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * add swcr in driver reg, 0x9fxx0000, to disable roaming .
+ *
+ * 03 16 2011 tsaiyuan.hsu
+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming
+ * remove obsolete definition and unused variables.
+ *
+ * 02 26 2011 tsaiyuan.hsu
+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support
+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming.
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+*/
+
+#ifndef _ROAMING_FSM_H
+#define _ROAMING_FSM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* Roaming Discovery interval, SCAN result need to be updated */
+#define ROAMING_DISCOVERY_TIMEOUT_SEC               5	/* Seconds. */
+
+/* #define ROAMING_NO_SWING_RCPI_STEP                  5 //rcpi */
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_ROAMING_FAIL_REASON_T {
+	ROAMING_FAIL_REASON_CONNLIMIT = 0,
+	ROAMING_FAIL_REASON_NOCANDIDATE,
+	ROAMING_FAIL_REASON_NUM
+} ENUM_ROAMING_FAIL_REASON_T;
+
+/* events of roaming between driver and firmware */
+typedef enum _ENUM_ROAMING_EVENT_T {
+	ROAMING_EVENT_START = 0,
+	ROAMING_EVENT_DISCOVERY,
+	ROAMING_EVENT_ROAM,
+	ROAMING_EVENT_FAIL,
+	ROAMING_EVENT_ABORT,
+	ROAMING_EVENT_NUM
+} ENUM_ROAMING_EVENT_T;
+
+#define ROAMING_EVENT_REASON_TX_ERR	BIT(0)
+#define ROAMING_EVENT_REASON_RCPI	BIT(1)
+
+typedef struct _ROAMING_PARAM_T {
+	UINT_16 u2Event;
+	UINT_16 u2Data;
+	UINT_16 u2Reason;
+} ROAMING_PARAM_T, *P_ROAMING_PARAM_T;
+
+ /**/ typedef enum _ENUM_ROAMING_STATE_T {
+	ROAMING_STATE_IDLE = 0,
+	ROAMING_STATE_DECISION,
+	ROAMING_STATE_DISCOVERY,
+	ROAMING_STATE_ROAM,
+	ROAMING_STATE_NUM
+} ENUM_ROAMING_STATE_T;
+
+typedef struct _ROAMING_INFO_T {
+	BOOLEAN fgIsEnableRoaming;
+
+	ENUM_ROAMING_STATE_T eCurrentState;
+
+	OS_SYSTIME rRoamingDiscoveryUpdateTime;
+
+#define ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX		2
+	UINT_32 RoamingEntryTimeoutSkipCount;
+
+} ROAMING_INFO_T, *P_ROAMING_INFO_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#if CFG_SUPPORT_ROAMING
+#define IS_ROAMING_ACTIVE(prAdapter) \
+	(prAdapter->rWifiVar.rRoamingInfo.eCurrentState == ROAMING_STATE_ROAM)
+#else
+#define IS_ROAMING_ACTIVE(prAdapter) FALSE
+#endif /* CFG_SUPPORT_ROAMING */
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter);
+
+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter);
+
+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam);
+
+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter);
+
+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState);
+
+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter);
+
+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam);
+
+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter);
+
+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Reason);
+
+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _ROAMING_FSM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h
new file mode 100644
index 0000000000000..20ab14251f65d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h
@@ -0,0 +1,271 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rsn.h#1
+*/
+
+/*! \file   rsn.h
+    \brief  The wpa/rsn related define, macro and structure are described here.
+*/
+
+/*
+** Log: rsn.h
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 06 22 2011 wh.su
+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h
+ * and let the sw structure not align at byte
+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte,
+ * Notice needed update P2P.ko.
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 02 09 2011 wh.su
+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
+ * adding the code for check STA privacy bit at AP mode, .
+ *
+ * 11 05 2010 wh.su
+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value
+ * fixed the.pmkid value mismatch issue
+ *
+ * 10 04 2010 wh.su
+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
+ * add a kal function for set cipher.
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 08 30 2010 wh.su
+ * NULL
+ * remove non-used code.
+ *
+ * 08 19 2010 wh.su
+ * NULL
+ * adding the tx pkt call back handle for countermeasure.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration from MT6620 firmware.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * Fixed the pre-authentication timer not correctly init issue, and modify
+ * the security related callback function prototype.
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the function prototype for generate wap/rsn ie
+ *
+ * Dec 3 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the function input parameter
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding some event function declaration
+ *
+ * Nov 26 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * move the internal data structure for pmkid to rsn.h
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the port control and class error function
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the pmkid candidate
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+**
+*/
+
+#ifndef _RSN_H
+#define _RSN_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* ----- Definitions for Cipher Suite Selectors ----- */
+#define RSN_CIPHER_SUITE_USE_GROUP_KEY  0x00AC0F00
+#define RSN_CIPHER_SUITE_WEP40          0x01AC0F00
+#define RSN_CIPHER_SUITE_TKIP           0x02AC0F00
+#define RSN_CIPHER_SUITE_CCMP           0x04AC0F00
+#define RSN_CIPHER_SUITE_WEP104         0x05AC0F00
+#if CFG_SUPPORT_802_11W
+#define RSN_CIPHER_SUITE_AES_128_CMAC   0x06AC0F00
+#endif
+
+#define WPA_CIPHER_SUITE_NONE           0x00F25000
+#define WPA_CIPHER_SUITE_WEP40          0x01F25000
+#define WPA_CIPHER_SUITE_TKIP           0x02F25000
+#define WPA_CIPHER_SUITE_CCMP           0x04F25000
+#define WPA_CIPHER_SUITE_WEP104         0x05F25000
+
+/* ----- Definitions for Authentication and Key Management Suite Selectors ----- */
+#define RSN_AKM_SUITE_NONE              0x00AC0F00
+#define RSN_AKM_SUITE_802_1X            0x01AC0F00
+#define RSN_AKM_SUITE_PSK               0x02AC0F00
+#if CFG_SUPPORT_802_11W
+#define RSN_AKM_SUITE_802_1X_SHA256     0x05AC0F00
+#define RSN_AKM_SUITE_PSK_SHA256        0x06AC0F00
+#endif
+
+#define WPA_AKM_SUITE_NONE              0x00F25000
+#define WPA_AKM_SUITE_802_1X            0x01F25000
+#define WPA_AKM_SUITE_PSK               0x02F25000
+
+#define ELEM_ID_RSN_LEN_FIXED           20	/* The RSN IE len for associate request */
+
+#define ELEM_ID_WPA_LEN_FIXED           22	/* The RSN IE len for associate request */
+
+#define MASK_RSNIE_CAP_PREAUTH          BIT(0)
+
+#define GET_SELECTOR_TYPE(x)           ((UINT_8)(((x) >> 24) & 0x000000FF))
+#define SET_SELECTOR_TYPE(x, y)         {x = (((x) & 0x00FFFFFF) | (((UINT_32)(y) << 24) & 0xFF000000))}
+
+#define AUTH_CIPHER_CCMP                0x00000008
+
+/* Cihpher suite flags */
+#define CIPHER_FLAG_NONE                        0x00000000
+#define CIPHER_FLAG_WEP40                       0x00000001	/* BIT 1 */
+#define CIPHER_FLAG_TKIP                        0x00000002	/* BIT 2 */
+#define CIPHER_FLAG_CCMP                        0x00000008	/* BIT 4 */
+#define CIPHER_FLAG_WEP104                      0x00000010	/* BIT 5 */
+#define CIPHER_FLAG_WEP128                      0x00000020	/* BIT 6 */
+
+#define WAIT_TIME_IND_PMKID_CANDICATE_SEC       6	/* seconds */
+#define TKIP_COUNTERMEASURE_SEC                 60	/* seconds */
+
+#if CFG_SUPPORT_802_11W
+#define RSN_AUTH_MFP_DISABLED   0	/* MFP disabled */
+#define RSN_AUTH_MFP_OPTIONAL   1	/* MFP optional */
+#define RSN_AUTH_MFP_REQUIRED   2	/* MFP required */
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/* Flags for PMKID Candidate list structure */
+#define EVENT_PMKID_CANDIDATE_PREAUTH_ENABLED   0x01
+
+#define CONTROL_FLAG_UC_MGMT_NO_ENC             BIT(5)
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define RSN_IE(fp)              ((P_RSN_INFO_ELEM_T) fp)
+#define WPA_IE(fp)              ((P_WPA_INFO_ELEM_T) fp)
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo);
+
+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo);
+
+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index);
+
+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index);
+
+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss);
+
+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+BOOLEAN
+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter,
+			    IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion);
+
+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo);
+
+#if CFG_SUPPORT_AAA
+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode);
+#endif
+
+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType);
+
+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc);
+
+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc);
+
+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex);
+
+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter);
+
+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss);
+
+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter);
+
+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm);
+#if CFG_SUPPORT_WPS2
+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+#endif
+
+#if CFG_SUPPORT_802_11W
+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter);
+
+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter);
+
+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter);
+
+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter);
+
+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype);
+#endif
+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _RSN_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h
new file mode 100644
index 0000000000000..c08b2244be6c4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h
@@ -0,0 +1,988 @@
+/*
+** Id: @(#)
+*/
+
+/*! \file   "scan.h"
+    \brief
+
+*/
+
+/*
+** Log: scan.h
+ *
+ * 01 16 2012 cp.wu
+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration
+ * with corresponding network configuration
+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting
+ * preferred band configuration corresponding to network type.
+ *
+ * 08 11 2011 cp.wu
+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
+ * sparse channel detection:
+ * driver: collect sparse channel information with scan-done event
+ *
+ * 07 18 2011 cp.wu
+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID
+ * in a single scanning request
+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID
+ * support as well as uProbeDelay in NDIS 6.x driver model
+ *
+ * 06 27 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings
+ * to work around some tricky AP which use space character as hidden SSID
+ * allow to have a single BSSID with multiple SSID to be presented in scanning result
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 02 09 2011 wh.su
+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module
+ * with structure miss-align pointer issue
+ * always pre-allio WAPI related structure for align p2p module.
+ *
+ * 01 14 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Fix compile error.
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * add interface for RLM to trigger OBSS-SCAN.
+ *
+ * 08 12 2010 yuche.tsai
+ * NULL
+ * Add a functio prototype to find p2p descriptor of a bss descriptor directly.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add function prototype for return channel.
+ * modify data structure for scan specific device ID or TYPE. (Move from P2P Connection Settings to Scan Param)
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Check-in P2P Device Discovery Feature.
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Add a option for channel time extension in scan abort command.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add for P2P Scan Result Parsing & Saving.
+ *
+ * 07 19 2010 yuche.tsai
+ *
+ * Scan status "FIND" is used for P2P FSM find state.
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * SCN module is now able to handle multiple concurrent scanning requests
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * pass band with channel number information as scan parameter
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * remove timer in DRV-SCN.
+ *
+ * 07 09 2010 cp.wu
+ *
+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request
+ * will be directly dropped by returning BUSY
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan uninitialization procedure
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * modify Beacon/ProbeResp to complete parsing,
+ * because host software has looser memory usage restriction
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add P2P related field in SCAN_PARAM_T.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * saa_fsm.c is migrated.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * restore utility function invoking via hem_mbox to direct calls
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h.
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 13 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ *
+ * Add new HW CH macro support
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ *  *  *  *  *  * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Modify scanBuildProbeReqFrameCommonIEs() to support P2P SCAN
+ *
+ * 02 23 2010 wh.su
+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver
+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join.
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 01 07 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ * Simplify the process of Beacon during SCAN and remove redundant variable in PRE_BSS_DESC_T
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding variable for wapi ap
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * remove non-used secuirty variavle
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Refine data structure of BSS_DESC_T and PRE_BSS_DESC_T
+ *
+ * Nov 24 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add eNetType to rScanParam and revise MGMT Handler with Retain Status
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add ucAvailablePhyTypeSet to BSS_DESC_T
+ *
+ * Nov 20 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add aucSrcAddress to SCAN_PARAM_T for P2P's Device Address
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the security related variable
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the security ie filed for scan parsing
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add scanSearchBssDescByPolicy()
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add function declarations of scan_fsm.c
+ *
+ * Oct 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add scan.h to source control
+**
+*/
+
+#ifndef _SCAN_H
+#define _SCAN_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "gl_vendor.h"
+
+/* TDLS test purpose */
+extern BOOLEAN flgTdlsTestExtCapElm;
+extern UINT8 aucTdlsTestExtCapElm[];
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/*! Maximum buffer size of SCAN list */
+#define SCN_MAX_BUFFER_SIZE                 (CFG_MAX_NUM_BSS_LIST * ALIGN_4(sizeof(BSS_DESC_T)))
+
+#define SCN_RM_POLICY_EXCLUDE_CONNECTED     BIT(0)	/* Remove SCAN result except the connected one. */
+#define SCN_RM_POLICY_TIMEOUT               BIT(1)	/* Remove the timeout one */
+#define SCN_RM_POLICY_OLDEST_HIDDEN         BIT(2)	/* Remove the oldest one with hidden ssid */
+#define SCN_RM_POLICY_SMART_WEAKEST         BIT(3)	/* If there are more than half BSS which has the
+							 * same ssid as connection setting, remove the
+							 * weakest one from them
+							 * Else remove the weakest one.
+							 */
+#define SCN_RM_POLICY_ENTIRE                BIT(4)	/* Remove entire SCAN result */
+
+#define SCN_BSS_DESC_SAME_SSID_THRESHOLD    3	/* This is used by POLICY SMART WEAKEST,
+						 * If exceed this value, remove weakest BSS_DESC_T
+						 * with same SSID first in large network.
+						 */
+
+/* the scan time in WFD mode + 2.4G/5G is about 9s so we need to enlarge the value */
+#define SCN_BSS_DESC_REMOVE_TIMEOUT_SEC     15	/* Second. */
+					      /* This is used by POLICY TIMEOUT,
+					       * If exceed this value, remove timeout BSS_DESC_T.
+					       */
+
+#define SCN_PROBE_DELAY_MSEC                0
+
+#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC      5	/* Second. */
+
+#define SCN_NLO_NETWORK_CHANNEL_NUM         (4)
+
+/*----------------------------------------------------------------------------*/
+/* MSG_SCN_SCAN_REQ                                                           */
+/*----------------------------------------------------------------------------*/
+#define SCAN_REQ_SSID_WILDCARD              BIT(0)
+#define SCAN_REQ_SSID_P2P_WILDCARD          BIT(1)
+#define SCAN_REQ_SSID_SPECIFIED             BIT(2)
+
+/*----------------------------------------------------------------------------*/
+/* Support Multiple SSID SCAN                                                 */
+/*----------------------------------------------------------------------------*/
+#define SCN_SSID_MAX_NUM                    CFG_SCAN_SSID_MAX_NUM
+#define SCN_SSID_MATCH_MAX_NUM              CFG_SCAN_SSID_MATCH_MAX_NUM
+
+#define SWC_NUM_BSSID_THRESHOLD_DEFAULT 8
+#define SWC_RSSI_WINDSIZE_DEFAULT 8
+#define LOST_AP_WINDOW 16
+#define MAX_CHANNEL_NUM_PER_BUCKETS 8
+
+#define SCN_BSS_JOIN_FAIL_THRESOLD				4
+#define SCN_BSS_JOIN_FAIL_CNT_RESET_SEC				15
+#define SCN_BSS_JOIN_FAIL_RESET_STEP				2
+
+#if CFG_SUPPORT_BATCH_SCAN
+/*----------------------------------------------------------------------------*/
+/* SCAN_BATCH_REQ                                                             */
+/*----------------------------------------------------------------------------*/
+#define SCAN_BATCH_REQ_START                BIT(0)
+#define SCAN_BATCH_REQ_STOP                 BIT(1)
+#define SCAN_BATCH_REQ_RESULT               BIT(2)
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_SCAN_TYPE_T {
+	SCAN_TYPE_PASSIVE_SCAN = 0,
+	SCAN_TYPE_ACTIVE_SCAN,
+	SCAN_TYPE_NUM
+} ENUM_SCAN_TYPE_T, *P_ENUM_SCAN_TYPE_T;
+
+typedef enum _ENUM_SCAN_STATE_T {
+	SCAN_STATE_IDLE = 0,
+	SCAN_STATE_SCANNING,
+	SCAN_STATE_NUM
+} ENUM_SCAN_STATE_T;
+
+typedef enum _ENUM_SCAN_CHANNEL_T {
+	SCAN_CHANNEL_FULL = 0,
+	SCAN_CHANNEL_2G4,
+	SCAN_CHANNEL_5G,
+	SCAN_CHANNEL_P2P_SOCIAL,
+	SCAN_CHANNEL_SPECIFIED,
+	SCAN_CHANNEL_NUM
+} ENUM_SCAN_CHANNEL, *P_ENUM_SCAN_CHANNEL;
+
+typedef struct _MSG_SCN_FSM_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_32 u4Dummy;
+} MSG_SCN_FSM_T, *P_MSG_SCN_FSM_T;
+
+typedef enum _ENUM_PSCAN_STATE_T {
+	PSCN_IDLE = 1,
+	PSCN_SCANNING,
+	PSCN_RESET,
+	PSCAN_STATE_T_NUM
+} ENUM_PSCAN_STATE_T;
+
+/*----------------------------------------------------------------------------*/
+/* BSS Descriptors                                                            */
+/*----------------------------------------------------------------------------*/
+struct _BSS_DESC_T {
+	LINK_ENTRY_T rLinkEntry;
+
+	UINT_8 aucBSSID[MAC_ADDR_LEN];
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* For IBSS, the SrcAddr is different from BSSID */
+
+	BOOLEAN fgIsConnecting;	/* If we are going to connect to this BSS
+				 * (JOIN or ROAMING to another BSS), don't
+				 * remove this record from BSS List.
+				 */
+	BOOLEAN fgIsConnected;	/* If we have connected to this BSS (NORMAL_TR),
+				 * don't removed this record from BSS list.
+				 */
+
+	BOOLEAN fgIsHiddenSSID;	/* When this flag is TRUE, means the SSID
+				 * of this BSS is not known yet.
+				 */
+	UINT_8 ucSSIDLen;
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];
+
+	OS_SYSTIME rUpdateTime;
+
+	ENUM_BSS_TYPE_T eBSSType;
+
+	UINT_16 u2CapInfo;
+
+	UINT_16 u2BeaconInterval;
+	UINT_16 u2ATIMWindow;
+
+	UINT_16 u2OperationalRateSet;
+	UINT_16 u2BSSBasicRateSet;
+	BOOLEAN fgIsUnknownBssBasicRate;
+
+	BOOLEAN fgIsERPPresent;
+	BOOLEAN fgIsHTPresent;
+
+	UINT_8 ucPhyTypeSet;	/* Available PHY Type Set of this BSS */
+
+	UINT_8 ucChannelNum;
+
+	ENUM_CHNL_EXT_T eSco;	/* Record bandwidth for association process
+				   Some AP will send association resp by 40MHz BW */
+	ENUM_BAND_T eBand;
+
+	UINT_8 ucDTIMPeriod;
+
+	BOOLEAN fgIsLargerTSF;	/* This BSS's TimeStamp is larger than us(TCL == 1 in RX_STATUS_T) */
+
+	UINT_8 ucRCPI;
+
+	UINT_8 ucWmmFlag;	/* A flag to indicate this BSS's WMM capability */
+
+	/*! \brief The srbiter Search State will matched the scan result,
+	   and saved the selected cipher and akm, and report the score,
+	   for arbiter join state, join module will carry this target BSS
+	   to rsn generate ie function, for gen wpa/rsn ie */
+	UINT_32 u4RsnSelectedGroupCipher;
+	UINT_32 u4RsnSelectedPairwiseCipher;
+	UINT_32 u4RsnSelectedAKMSuite;
+
+	UINT_16 u2RsnCap;
+
+	RSN_INFO_T rRSNInfo;
+	RSN_INFO_T rWPAInfo;
+#if 1				/* CFG_SUPPORT_WAPI */
+	WAPI_INFO_T rIEWAPI;
+	BOOLEAN fgIEWAPI;
+#endif
+	BOOLEAN fgIERSN;
+	BOOLEAN fgIEWPA;
+
+	/*! \brief RSN parameters selected for connection */
+	/*! \brief The Select score for final AP selection,
+	   0, no sec, 1,2,3 group cipher is WEP, TKIP, CCMP */
+	UINT_8 ucEncLevel;
+
+#if CFG_ENABLE_WIFI_DIRECT
+	BOOLEAN fgIsP2PPresent;
+	BOOLEAN fgIsP2PReport;	/* TRUE: report to upper layer */
+	P_P2P_DEVICE_DESC_T prP2pDesc;
+
+	UINT_8 aucIntendIfAddr[MAC_ADDR_LEN];	/* For IBSS, the SrcAddr is different from BSSID */
+/* UINT_8 ucDevCapabilityBitmap;  */ /* Device Capability Attribute. (P2P_DEV_CAPABILITY_XXXX) */
+/* UINT_8 ucGroupCapabilityBitmap; */ /* Group Capability Attribute. (P2P_GROUP_CAPABILITY_XXXX) */
+
+	LINK_T rP2pDeviceList;
+
+/* P_LINK_T prP2pDeviceList; */
+
+	/* For
+	 *    1. P2P Capability.
+	 *    2. P2P Device ID. ( in aucSrcAddr[] )
+	 *    3. NOA   (TODO:)
+	 *    4. Extend Listen Timing. (Probe Rsp)  (TODO:)
+	 *    5. P2P Device Info. (Probe Rsp)
+	 *    6. P2P Group Info. (Probe Rsp)
+	 */
+#endif
+
+	BOOLEAN fgIsIEOverflow;	/* The received IE length exceed the maximum IE buffer size */
+	UINT_16 u2RawLength;	/* The byte count of aucRawBuf[] */
+	UINT_16 u2IELength;	/* The byte count of aucIEBuf[] */
+
+	ULARGE_INTEGER u8TimeStamp;	/* Place u8TimeStamp before aucIEBuf[1] to force DW align */
+	UINT_8 aucRawBuf[CFG_RAW_BUFFER_SIZE];
+	UINT_8 aucIEBuf[CFG_IE_BUFFER_SIZE];
+	UINT_8 ucJoinFailureCount;
+	OS_SYSTIME rJoinFailTime;
+};
+
+typedef struct _SCAN_PARAM_T {	/* Used by SCAN FSM */
+	/* Active or Passive */
+	ENUM_SCAN_TYPE_T eScanType;
+
+	/* Network Type */
+	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;
+
+	/* Specified SSID Type */
+	UINT_8 ucSSIDType;
+	UINT_8 ucSSIDNum;
+
+	/* Length of Specified SSID */
+	UINT_8 ucSpecifiedSSIDLen[SCN_SSID_MAX_NUM];
+
+	/* Specified SSID */
+	UINT_8 aucSpecifiedSSID[SCN_SSID_MAX_NUM][ELEM_MAX_LEN_SSID];
+
+#if CFG_ENABLE_WIFI_DIRECT
+	BOOLEAN fgFindSpecificDev;	/* P2P: Discovery Protocol */
+	UINT_8 aucDiscoverDevAddr[MAC_ADDR_LEN];
+	BOOLEAN fgIsDevType;
+	P2P_DEVICE_TYPE_T rDiscoverDevType;
+
+	UINT_16 u2PassiveListenInterval;
+	/* TODO: Find Specific Device Type. */
+#endif				/* CFG_SUPPORT_P2P */
+
+	BOOLEAN fgIsObssScan;
+	BOOLEAN fgIsScanV2;
+
+	/* Run time flags */
+	UINT_16 u2ProbeDelayTime;
+
+	/* channel information */
+	ENUM_SCAN_CHANNEL eScanChannel;
+	UINT_8 ucChannelListNum;
+	RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST];
+
+	/* Feedback information */
+	UINT_8 ucSeqNum;
+
+	/* Information Element */
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+
+} SCAN_PARAM_T, *P_SCAN_PARAM_T;
+
+typedef struct _NLO_PARAM_T {	/* Used by SCAN FSM */
+	SCAN_PARAM_T rScanParam;
+
+	/* NLO */
+	BOOLEAN fgStopAfterIndication;
+	UINT_8 ucFastScanIteration;
+	UINT_16 u2FastScanPeriod;
+	UINT_16 u2SlowScanPeriod;
+
+	/* Match SSID */
+	UINT_8 ucMatchSSIDNum;
+	UINT_8 ucMatchSSIDLen[SCN_SSID_MATCH_MAX_NUM];
+	UINT_8 aucMatchSSID[SCN_SSID_MATCH_MAX_NUM][ELEM_MAX_LEN_SSID];
+
+	UINT_8 aucCipherAlgo[SCN_SSID_MATCH_MAX_NUM];
+	UINT_16 au2AuthAlgo[SCN_SSID_MATCH_MAX_NUM];
+	UINT_8 aucChannelHint[SCN_SSID_MATCH_MAX_NUM][SCN_NLO_NETWORK_CHANNEL_NUM];
+	P_BSS_DESC_T aprPendingBssDescToInd[SCN_SSID_MATCH_MAX_NUM];
+} NLO_PARAM_T, *P_NLO_PARAM_T;
+
+#if 1
+
+typedef struct _GSCN_CHANNEL_INFO_T {
+	UINT_8 ucBand;
+	UINT_8 ucChannel;	/* frequency */
+	UINT_8 ucPassive;	/* 0 => active, 1 => passive scan; ignored for DFS */
+	UINT_8 aucReserved[1];
+
+	UINT_32 u4DwellTimeMs;	/* dwell time hint */
+	/* Add channel class */
+} GSCN_CHANNEL_INFO_T, *P_GSCN_CHANNEL_INFO_T;
+
+typedef struct _GSCAN_CHANNEL_BUCKET_T {
+
+	UINT_16 u2BucketIndex;	/* bucket index, 0 based */
+	UINT_8 ucBucketFreqMultiple;	/* desired period, in millisecond;
+					 * if this is too low, the firmware should choose to generate
+					 * results as fast as it can instead of failing the command */
+	/* report_events semantics -
+	 *  0 => report only when scan history is % full
+	 *  1 => same as 0 + report a scan completion event after scanning this bucket
+	 *  2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL
+	 *  3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to
+	 supplicant as well (optional) . */
+	UINT_8 ucReportFlag;
+	UINT_8 ucNumChannels;
+	UINT_8 aucReserved[3];
+	WIFI_BAND eBand;	/* when UNSPECIFIED, use channel list */
+	GSCN_CHANNEL_INFO_T arChannelList[GSCAN_MAX_CHANNELS];	/* channels to scan; these may include DFS channels */
+} GSCAN_CHANNEL_BUCKET_T, *P_GSCAN_CHANNEL_BUCKET_T;
+
+typedef struct _CMD_GSCN_REQ_T {
+	UINT_8 ucFlags;
+	UINT_8 ucNumScnToCache;
+	UINT_8 aucReserved[2];
+	UINT_32 u4BufferThreshold;
+	UINT_32 u4BasePeriod;	/* base timer period in ms */
+	UINT_32 u4NumBuckets;
+	UINT_32 u4MaxApPerScan;	/* number of APs to store in each scan in the */
+	/* BSSID/RSSI history buffer (keep the highest RSSI APs) */
+
+	GSCAN_CHANNEL_BUCKET_T arChannelBucket[GSCAN_MAX_BUCKETS];
+} CMD_GSCN_REQ_T, *P_CMD_GSCN_REQ_T;
+
+#endif
+
+typedef struct _CMD_GSCN_SCN_COFIG_T {
+	UINT_8 ucNumApPerScn;		/* GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN */
+	UINT_32 u4NumScnToCache;	/* GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE */
+	UINT_32 u4BufferThreshold;	/* GSCAN_ATTRIBUTE_REPORT_THRESHOLD */
+} CMD_GSCN_SCN_COFIG_T, *P_CMD_GSCN_SCN_COFIG_T;
+
+typedef struct _CMD_GET_GSCAN_RESULT {
+	UINT_8 ucVersion;
+	UINT_8 aucReserved[2];
+	UINT_8 ucFlush;
+	UINT_32 u4Num;
+} CMD_GET_GSCAN_RESULT_T, *P_CMD_GET_GSCAN_RESULT_T;
+
+typedef struct _CMD_BATCH_REQ_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucCmd;		/* Start/ Stop */
+	UINT_8 ucMScan;		/* an integer number of scans per batch */
+	UINT_8 ucBestn;		/* an integer number of the max AP to remember per scan */
+	UINT_8 ucRtt;		/* an integer number of highest-strength AP for which we'd like
+				approximate distance reported */
+	UINT_8 ucChannel;	/* channels */
+	UINT_8 ucChannelType;
+	UINT_8 ucChannelListNum;
+	UINT_8 aucReserved[3];
+	UINT_32 u4Scanfreq;	/* an integer number of seconds between scans */
+	CHANNEL_INFO_T arChannelList[32];	/* channels */
+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T;
+
+typedef struct _PSCN_PARAM_T {
+	UINT_8 ucVersion;
+	CMD_NLO_REQ rCurrentCmdNloReq;
+	CMD_BATCH_REQ_T rCurrentCmdBatchReq;
+	CMD_GSCN_REQ_T rCurrentCmdGscnReq;
+	BOOLEAN fgNLOScnEnable;
+	BOOLEAN fgBatchScnEnable;
+	BOOLEAN fgGScnEnable;
+	UINT_32 u4BasePeriod;	/* GSCAN_ATTRIBUTE_BASE_PERIOD */
+} PSCN_PARAM_T, *P_PSCN_PARAM_T;
+
+typedef struct _SCAN_INFO_T {
+	ENUM_SCAN_STATE_T eCurrentState;	/* Store the STATE variable of SCAN FSM */
+
+	OS_SYSTIME rLastScanCompletedTime;
+
+	SCAN_PARAM_T rScanParam;
+	NLO_PARAM_T rNloParam;
+
+	UINT_32 u4NumOfBssDesc;
+
+	UINT_8 aucScanBuffer[SCN_MAX_BUFFER_SIZE];
+
+	LINK_T rBSSDescList;
+
+	LINK_T rFreeBSSDescList;
+
+	LINK_T rPendingMsgList;
+
+	/* Sparse Channel Detection */
+	BOOLEAN fgIsSparseChannelValid;
+	RF_CHANNEL_INFO_T rSparseChannel;
+
+	/* NLO scanning state tracking */
+	BOOLEAN fgNloScanning;
+	BOOLEAN fgPscnOnnning;
+	BOOLEAN fgGScnConfigSet;
+	BOOLEAN fgGScnParamSet;
+	P_PSCN_PARAM_T prPscnParam;
+	ENUM_PSCAN_STATE_T eCurrentPSCNState;
+
+} SCAN_INFO_T, *P_SCAN_INFO_T;
+
+/* Incoming Mailbox Messages */
+typedef struct _MSG_SCN_SCAN_REQ_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetTypeIndex;
+	ENUM_SCAN_TYPE_T eScanType;
+	UINT_8 ucSSIDType;	/* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */
+	UINT_8 ucSSIDLength;
+	UINT_8 aucSSID[PARAM_MAX_LEN_SSID];
+#if CFG_ENABLE_WIFI_DIRECT
+	UINT_16 u2ChannelDwellTime;	/* In TU. 1024us. */
+#endif
+	ENUM_SCAN_CHANNEL eScanChannel;
+	UINT_8 ucChannelListNum;
+	RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST];
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+} MSG_SCN_SCAN_REQ, *P_MSG_SCN_SCAN_REQ;
+
+typedef struct _MSG_SCN_SCAN_REQ_V2_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetTypeIndex;
+	ENUM_SCAN_TYPE_T eScanType;
+	UINT_8 ucSSIDType;	/* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */
+	UINT_8 ucSSIDNum;
+	P_PARAM_SSID_T prSsid;
+	UINT_16 u2ProbeDelay;
+	UINT_16 u2ChannelDwellTime;	/* In TU. 1024us. */
+	ENUM_SCAN_CHANNEL eScanChannel;
+	UINT_8 ucChannelListNum;
+	RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST];
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+} MSG_SCN_SCAN_REQ_V2, *P_MSG_SCN_SCAN_REQ_V2;
+
+typedef struct _MSG_SCN_SCAN_CANCEL_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetTypeIndex;
+#if CFG_ENABLE_WIFI_DIRECT
+	BOOLEAN fgIsChannelExt;
+#endif
+} MSG_SCN_SCAN_CANCEL, *P_MSG_SCN_SCAN_CANCEL;
+
+/* Outgoing Mailbox Messages */
+typedef enum _ENUM_SCAN_STATUS_T {
+	SCAN_STATUS_DONE = 0,
+	SCAN_STATUS_CANCELLED,
+	SCAN_STATUS_FAIL,
+	SCAN_STATUS_BUSY,
+	SCAN_STATUS_NUM
+} ENUM_SCAN_STATUS, *P_ENUM_SCAN_STATUS;
+
+typedef struct _MSG_SCN_SCAN_DONE_T {
+	MSG_HDR_T rMsgHdr;	/* Must be the first member */
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetTypeIndex;
+	ENUM_SCAN_STATUS eScanStatus;
+} MSG_SCN_SCAN_DONE, *P_MSG_SCN_SCAN_DONE;
+
+#if CFG_SUPPORT_AGPS_ASSIST
+typedef enum {
+	AGPS_PHY_A,
+	AGPS_PHY_B,
+	AGPS_PHY_G,
+} AP_PHY_TYPE;
+
+typedef struct _AGPS_AP_INFO_T {
+	UINT_8 aucBSSID[6];
+	INT_16 i2ApRssi;	/* -127..128 */
+	UINT_16 u2Channel;	/* 0..256 */
+	AP_PHY_TYPE ePhyType;
+} AGPS_AP_INFO_T, *P_AGPS_AP_INFO_T;
+
+typedef struct _AGPS_AP_LIST_T {
+	UINT_8 ucNum;
+	AGPS_AP_INFO_T arApInfo[32];
+} AGPS_AP_LIST_T, *P_AGPS_AP_LIST_T;
+#endif
+
+typedef struct _CMD_SET_PSCAN_PARAM {
+	UINT_8 ucVersion;
+	CMD_NLO_REQ rCmdNloReq;
+	CMD_BATCH_REQ_T rCmdBatchReq;
+	CMD_GSCN_REQ_T rCmdGscnReq;
+	BOOLEAN fgNLOScnEnable;
+	BOOLEAN fgBatchScnEnable;
+	BOOLEAN fgGScnEnable;
+	UINT_32 u4BasePeriod;
+} CMD_SET_PSCAN_PARAM, *P_CMD_SET_PSCAN_PARAM;
+
+typedef struct _CMD_SET_PSCAN_ADD_HOTLIST_BSSID {
+	UINT_8 aucMacAddr[6];
+	UINT_8 ucFlags;
+	UINT_8 aucReserved[5];
+} CMD_SET_PSCAN_ADD_HOTLIST_BSSID, *P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID;
+
+typedef struct _CMD_SET_PSCAN_ADD_SWC_BSSID {
+	INT_32 i4RssiLowThreshold;
+	INT_32 i4RssiHighThreshold;
+	UINT_8 aucMacAddr[6];
+	UINT_8 aucReserved[6];
+} CMD_SET_PSCAN_ADD_SWC_BSSID, *P_CMD_SET_PSCAN_ADD_SWC_BSSID;
+
+typedef struct _CMD_SET_PSCAN_MAC_ADDR {
+	UINT_8 ucVersion;
+	UINT_8 ucFlags;
+	UINT_8 aucMacAddr[6];
+	UINT_8 aucReserved[8];
+} CMD_SET_PSCAN_MAC_ADDR, *P_CMD_SET_PSCAN_MAC_ADDR;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines in scan.c                                                         */
+/*----------------------------------------------------------------------------*/
+VOID scnInit(IN P_ADAPTER_T prAdapter);
+
+VOID scnUninit(IN P_ADAPTER_T prAdapter);
+
+/* BSS-DESC Search */
+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]);
+
+P_BSS_DESC_T
+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter,
+				IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid);
+
+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]);
+
+P_BSS_DESC_T
+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter,
+			     IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid);
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]);
+#endif
+
+/* BSS-DESC Search - Alternative */
+P_BSS_DESC_T
+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter,
+				IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]);
+
+P_BSS_DESC_T
+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter,
+					IN ENUM_BSS_TYPE_T eBSSType,
+					IN UINT_8 aucBSSID[],
+					IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid);
+
+/* BSS-DESC Allocation */
+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter);
+
+/* BSS-DESC Removal */
+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy);
+
+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]);
+
+VOID
+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter,
+				  IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+/* BSS-DESC State Change */
+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]);
+
+#if 0
+/* BSS-DESC Insertion */
+P_BSS_DESC_T scanAddToInternalScanResult(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb, IN P_BSS_DESC_T prBssDesc);
+#endif
+
+/* BSS-DESC Insertion - ALTERNATIVE */
+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb);
+
+VOID
+scanBuildProbeReqFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo,
+				IN PUINT_8 pucDesiredSsid, IN UINT_32 u4DesiredSsidLen, IN UINT_16 u2SupportedRateSet);
+
+WLAN_STATUS scanSendProbeReqFrames(IN P_ADAPTER_T prAdapter, IN P_SCAN_PARAM_T prScanParam);
+
+VOID scanUpdateBssDescForSearch(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc);
+
+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb);
+
+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc);
+
+/*----------------------------------------------------------------------------*/
+/* Routines in scan_fsm.c                                                     */
+/*----------------------------------------------------------------------------*/
+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState);
+
+/*----------------------------------------------------------------------------*/
+/* Command Routines                                                           */
+/*----------------------------------------------------------------------------*/
+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter);
+
+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter);
+
+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter);
+
+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* RX Event Handling                                                          */
+/*----------------------------------------------------------------------------*/
+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone);
+
+VOID scnEventNloDone(IN P_ADAPTER_T	 prAdapter,	IN P_EVENT_NLO_DONE_T prNloDone);
+
+/*----------------------------------------------------------------------------*/
+/* Mailbox Message Handling                                                   */
+/*----------------------------------------------------------------------------*/
+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg);
+
+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg);
+
+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex);
+
+/*----------------------------------------------------------------------------*/
+/* Mailbox Message Generation                                                 */
+/*----------------------------------------------------------------------------*/
+VOID
+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter,
+			  IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus);
+
+/*----------------------------------------------------------------------------*/
+/* Query for sparse channel                                                   */
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel);
+
+/*----------------------------------------------------------------------------*/
+/* OID/IOCTL Handling                                                         */
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter,
+		       IN UINT_8 ucSsidNum,
+		       IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval);
+
+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct);
+
+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam);
+
+BOOLEAN scnFsmGSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam);
+
+#if 0
+
+BOOLEAN scnFsmGSCNSetRssiSignificatn(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam);
+#endif
+
+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId);
+
+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr);
+
+#if 1				/* CFG_SUPPORT_GSCN_NONSYNC_BROADCOM */
+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam);
+
+#else
+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_REQ_T prCmdGscnParam);
+
+#endif
+
+BOOLEAN
+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter,
+			 IN P_CMD_NLO_REQ prCmdNloReq,
+			 IN P_CMD_BATCH_REQ_T prCmdBatchReq,
+			 IN P_CMD_GSCN_REQ_T prCmdGscnReq,
+			 IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig,
+			 IN BOOLEAN fgRemoveNLOfromPSCN,
+			 IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN);
+
+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig);
+
+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd);
+
+VOID
+scnPSCNFsm(IN P_ADAPTER_T prAdapter,
+	   ENUM_PSCAN_STATE_T eNextPSCNState,
+	   IN P_CMD_NLO_REQ prCmdNloReq,
+	   IN P_CMD_BATCH_REQ_T prCmdBatchReq,
+	   IN P_CMD_GSCN_REQ_T prCmdGscnReq,
+	   IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig,
+	   IN BOOLEAN fgRemoveNLOfromPSCN,
+	   IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN);
+
+#endif /* _SCAN_H */
+
+#if CFG_SUPPORT_AGPS_ASSIST
+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter);
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h
new file mode 100644
index 0000000000000..c6c468e06c4a5
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h
@@ -0,0 +1,233 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/sec_fsm.h#1
+*/
+
+/*! \file   sec_fsm.h
+    \brief  Declaration of functions and finite state machine for SECURITY Module.
+
+    Function declaration for privacy.c and SEC_STATE for SECURITY FSM.
+*/
+
+/*
+** Log: sec_fsm.h
+ *
+ * 09 29 2010 wh.su
+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 20 2010 wh.su
+ * NULL
+ * adding the eapol callback setting.
+ *
+ * 08 19 2010 wh.su
+ * NULL
+ * adding the tx pkt call back handle for countermeasure.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * modify some code for concurrent network.
+ *
+ * 06 19 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * consdier the concurrent network setting.
+ *
+ * 03 04 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Code refine, and remove non-used code.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * Fixed the pre-authentication timer not correctly init issue, and modify the security
+ * related callback function prototype.
+ *
+ * 03 01 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Refine the variable and parameter for security.
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * fixed the deauth Tx done callback parameter
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the reference function declaration
+ *
+ * Dec 3 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * delete non-used code
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the function prototype
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the function declaration
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the security variable
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+**  \main\maintrunk.MT5921\14 2009-04-06 15:35:47 GMT mtk01088
+**  add the variable to set the disable AP selection for privacy check, for wps open networking.
+**  \main\maintrunk.MT5921\13 2008-11-19 11:46:01 GMT mtk01088
+**  rename some variable with pre-fix to avoid the misunderstanding
+**  \main\maintrunk.MT5921\12 2008-08-28 20:37:11 GMT mtk01088
+**  remove non-used code
+**
+**  \main\maintrunk.MT5921\11 2008-03-18 09:51:52 GMT mtk01088
+**  Add function declaration for timer to indicate pmkid candidate
+**  \main\maintrunk.MT5921\10 2008-02-29 15:12:08 GMT mtk01088
+**  add variable for sw port control
+**  \main\maintrunk.MT5921\9 2008-02-29 12:37:30 GMT mtk01088
+**  rename the security related function declaration
+**  \main\maintrunk.MT5921\8 2007-12-27 13:59:08 GMT mtk01088
+**  adjust the wlan table and sec fsm init timing
+**  \main\maintrunk.MT5921\7 2007-11-20 10:39:49 GMT mtk01088
+**  add function timer for wait EAPoL Error timeout
+**  \main\maintrunk.MT5921\6 2007-11-06 20:39:08 GMT mtk01088
+**  rename the counter measure timer
+**  \main\maintrunk.MT5921\5 2007-11-06 20:14:31 GMT mtk01088
+**  add a abort function
+** Revision 1.5  2007/07/16 02:33:42  MTK01088
+** change the ENUM declaration structure prefix from r to e
+**
+** Revision 1.4  2007/07/09 06:23:10  MTK01088
+** update
+**
+** Revision 1.3  2007/07/04 10:09:04  MTK01088
+** adjust the state for security fsm
+** change function name
+**
+** Revision 1.2  2007/07/03 08:13:22  MTK01088
+** change the sec fsm state
+** add the event for sec fsm
+**
+** Revision 1.1  2007/06/27 06:20:35  MTK01088
+** add the sec fsm header file
+**
+**
+*/
+#ifndef _SEC_FSM_H
+#define _SEC_FSM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/* TKIP CounterMeasure interval for Rejoin to Network. */
+#define COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC        60
+
+/* Timeout to wait the EAPoL Error Report frame Send out. */
+#define EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC       1
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef UINT_32 SEC_STATUS, *P_SEC_STATUS;
+
+#if 0
+/* WPA2 PMKID candicate structure */
+typedef struct _PMKID_CANDICATE_T {
+	UINT_8 aucBssid[MAC_ADDR_LEN];	/* MAC address */
+	UINT_32 u4PreAuthFlags;
+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T;
+#endif
+
+typedef SEC_STATUS(*PFN_SEC_FSM_STATE_HANDLER) (VOID);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define SEC_STATE_TRANSITION_FLAG   fgIsTransition
+#define SEC_NEXT_STATE_VAR          eNextState
+
+#define SEC_STATE_TRANSITION(prAdapter, prSta, eFromState, eToState) \
+	{ secFsmTrans_ ## eFromState ## _to_ ## eToState(prAdapter, prSta); \
+	  SEC_NEXT_STATE_VAR = SEC_STATE_ ## eToState; \
+	  SEC_STATE_TRANSITION_FLAG = (BOOLEAN)TRUE; \
+	}
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*--------------------------------------------------------------*/
+/* Routines to handle the sec check                             */
+/*--------------------------------------------------------------*/
+/***** Routines in sec_fsm.c *****/
+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+VOID secFsmEventInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+VOID
+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm);
+
+VOID
+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta);
+
+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, IN ULONG ulParm);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _SEC_FSM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h
new file mode 100644
index 0000000000000..1c0f9a76e1192
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h
@@ -0,0 +1,368 @@
+/*
+** Id: stats.h#1
+*/
+
+/*! \file stats.h
+    \brief This file includes statistics support.
+*/
+
+/*
+** Log: stats.h
+ *
+ * 07 17 2014 samp.lin
+ * NULL
+ * Initial version.
+ */
+
+/*******************************************************************************
+ *						C O M P I L E R	 F L A G S
+ ********************************************************************************
+ */
+
+/*******************************************************************************
+ *						E X T E R N A L	R E F E R E N C E S
+ ********************************************************************************
+ */
+extern UINT_64 u8DrvOwnStart, u8DrvOwnEnd;
+extern UINT32 u4DrvOwnMax;
+extern BOOLEAN fgIsUnderSuspend;
+
+/*******************************************************************************
+*						C O N S T A N T S
+********************************************************************************
+*/
+
+/* Command to TDLS core module */
+typedef enum _STATS_CMD_CORE_ID {
+	STATS_CORE_CMD_ENV_REQUEST = 0x00
+} STATS_CMD_CORE_ID;
+
+typedef enum _STATS_EVENT_HOST_ID {
+	STATS_HOST_EVENT_ENV_REPORT = 0x00,
+	STATS_HOST_EVENT_RX_DROP
+} STATS_EVENT_HOST_ID;
+
+#define CFG_ARP BIT(0)
+#define CFG_DNS BIT(1)
+#define CFG_TCP BIT(2)
+#define CFG_UDP BIT(3)
+#define CFG_EAPOL BIT(4)
+#define CFG_DHCP BIT(5)
+#define CFG_ICMP BIT(6)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _STATS_CMD_CORE_T {
+
+	UINT32 u4Command;	/* STATS_CMD_CORE_ID */
+
+	UINT8 ucStaRecIdx;
+	UINT8 ucReserved[3];
+
+	UINT32 u4Reserved[4];
+
+#define STATS_CMD_CORE_RESERVED_SIZE					50
+	union {
+		UINT8 Reserved[STATS_CMD_CORE_RESERVED_SIZE];
+	} Content;
+
+} STATS_CMD_CORE_T;
+
+typedef struct _STATS_INFO_ENV_T {
+
+	BOOLEAN fgIsUsed;	/* TRUE: used */
+
+	/* ------------------- TX ------------------- */
+	BOOLEAN fgTxIsRtsUsed;	/* TRUE: we use RTS/CTS currently */
+	BOOLEAN fgTxIsRtsEverUsed;	/* TRUE: we ever use RTS/CTS */
+	BOOLEAN fgTxIsCtsSelfUsed;	/* TRUE: we use CTS-self */
+
+#define STATS_INFO_TX_PARAM_HW_BW40_OFFSET			0
+#define STATS_INFO_TX_PARAM_HW_SHORT_GI20_OFFSET	1
+#define STATS_INFO_TX_PARAM_HW_SHORT_GI40_OFFSET	2
+#define STATS_INFO_TX_PARAM_USE_BW40_OFFSET			3
+#define STATS_INFO_TX_PARAM_USE_SHORT_GI_OFFSET		4
+#define STATS_INFO_TX_PARAM_NO_ACK_OFFSET			5
+	UINT_8 ucTxParam;
+
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucReserved1[2];
+
+	UINT32 u4TxDataCntAll;	/* total tx count from host */
+	UINT32 u4TxDataCntOK;	/* total tx ok count to air */
+	UINT32 u4TxDataCntErr;	/* total tx err count to air */
+
+	/* WLAN_STATUS_BUFFER_RETAINED ~ WLAN_STATUS_PACKET_LIFETIME_ERROR */
+	UINT32 u4TxDataCntErrType[6];	/* total tx err count for different type to air */
+
+	UINT_8 ucTxRate1NonHTMax;
+	UINT_8 ucTxRate1HTMax;
+	UINT32 u4TxRateCntNonHT[16];	/* tx done rate */
+	UINT32 u4TxRateCntHT[16];	/* tx done rate */
+
+	UINT_8 ucTxAggBitmap;	/* TX BA sessions TID0 ~ TID7 */
+	UINT_8 ucTxPeerAggMaxSize;
+
+	/* ------------------- RX ------------------- */
+	BOOLEAN fgRxIsRtsUsed;	/* TRUE: peer uses RTS/CTS currently */
+	BOOLEAN fgRxIsRtsEverUsed;	/* TRUE: peer ever uses RTS/CTS */
+
+	UINT_8 ucRcvRcpi;
+	UINT_8 ucHwChanNum;
+	BOOLEAN fgRxIsShortGI;
+	UINT_8 ucReserved2[1];
+
+	UINT32 u4RxDataCntAll;	/* total rx count from peer */
+	UINT32 u4RxDataCntErr;	/* total rx err count */
+	UINT32 u4RxRateCnt[3][16];	/* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */
+
+	UINT_8 ucRxAggBitmap;	/* RX BA sessions TID0 ~ TID7 */
+	UINT_8 ucRxAggMaxSize;
+
+#define STATS_INFO_PHY_MODE_CCK					0
+#define STATS_INFO_PHY_MODE_OFDM				1
+#define STATS_INFO_PHY_MODE_HT					2
+#define STATS_INFO_PHY_MODE_VHT					3
+	UINT_8 ucBssSupPhyMode;	/* CCK, OFDM, HT, or VHT BSS */
+
+	UINT_8 ucVersion;	/* the version of statistics info environment */
+
+	/* ------------------- Delay ------------------- */
+#define STATS_AIR_DELAY_INT						500	/* 500 byte */
+
+	/* delay in firmware from host to MAC */
+	/* unit: us, for 500B, 1000B, max */
+	UINT32 u4StayIntMaxH2M[3], u4StayIntMinH2M[3], u4StayIntAvgH2M[3];
+
+	/* delay in firmware from MAC to TX done */
+	/* unit: 32us, for 500B, 1000B, max */
+	UINT32 u4AirDelayMax[3], u4AirDelayMin[3], u4AirDelayAvg[3];
+
+	/* delay in firmware from host to TX done */
+	/* unit: us, for 500B, 1000B, max */
+	UINT32 u4StayIntMax[3], u4StayIntMin[3], u4StayIntAvg[3];
+	UINT32 u4StayIntMaxSysTime[3];
+
+	/* delay in firmware from driver to TX done */
+	/* unit: us, for 500B, 1000B, max */
+	UINT32 u4StayIntMaxD2T[3], u4StayIntMinD2T[3], u4StayIntAvgD2T[3];
+
+	/* delay count in firmware from host to TX done */
+	/* u4StayIntByConst: divide 4 fix partitions to count each delay in firmware */
+#define STATS_STAY_INT_CONST					1	/* 1ms */
+#define STATS_STAY_INT_CONST_2					5
+#define STATS_STAY_INT_CONST_3					10
+#define STATS_STAY_INT_CONST_4					15
+#define STATS_STAY_INT_CONST_NUM				4
+	UINT32 u4StayIntByConst[STATS_STAY_INT_CONST_NUM];
+
+	/*
+	   u4StayIntMaxPast: past maximum delay in firmware
+	   u4StayIntCnt[]: divide 4 partitions to count each delay in firmware
+	 */
+#define STATS_STAY_INT_NUM						4
+	UINT32 u4StayIntMaxPast;
+	UINT32 u4StayIntCnt[STATS_STAY_INT_NUM + 1];
+
+	/* delay count in firmware from driver to HIF */
+	/* u4StayIntD2HByConst: divide 4 fix partitions to count each delay in firmware */
+#define STATS_STAY_INT_D2H_CONST				10	/* 10ms */
+#define STATS_STAY_INT_D2H_CONST_2				20
+#define STATS_STAY_INT_D2H_CONST_3				30
+#define STATS_STAY_INT_D2H_CONST_4				40
+#define STATS_STAY_INT_D2H_CONST_NUM			4
+	UINT32 u4StayIntD2HByConst[STATS_STAY_INT_D2H_CONST_NUM];
+
+	/* unit: us, for 500B, 1000B, max */
+	UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3];
+
+	/* ------------------- Others ------------------- */
+	UINT32 u4NumOfChanChange;	/* total channel change count */
+	UINT32 u4NumOfRetryCnt;	/* total TX retry count */
+	UINT32 u4RxFifoFullCnt;	/* counter of the number of the packets which
+				   pass RFCR but are dropped due to FIFO full. */
+	UINT32 u4PsIntMax;	/* maximum time from ps to active */
+	UINT_8 ucNumOfPsChange;	/* peer power save change count */
+	UINT_8 ucReserved3[3];
+
+	UINT32 u4ReportSysTime;	/* firmware system time */
+	UINT32 u4RxDataCntOk;	/* total rx count to hif */
+
+	/* V4 */
+	UINT32 u4RxRateRetryCnt[3][16];	/* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */
+	UINT32 au4ChanIdleCnt[10];	/* past Channel idle count in unit of slot */
+
+	/* V5 */
+	UINT32 u4BtContUseTime;	/* the air time that BT continuous occypy */
+
+	/* V6 */
+	UINT32 u4LastTxOkTime;	/* last time we tx ok to the station */
+
+	/* V7 */
+	UINT_8 ucBtWfCoexGrantCnt[8];	/* [0]:WF Rx Grant Cnt[1]: WF Tx Grant Cnt[2]: WF Grant with Priority1 */
+	/* [4]:BT Rx Grant Cnt[5]: BT Tx Grant Cnt[6]: BT Grant with Priority1 */
+
+	/* V8 */
+	UINT_32 u4RxMacFreeDescCnt[6];
+	UINT_32 u4RxHifFreeDescCnt[6];
+
+	/* V9 */
+#define STATS_MAX_RX_DROP_TYPE			20
+	UINT32 u4NumOfRxDrop[STATS_MAX_RX_DROP_TYPE];
+
+	/* V10 */
+	UINT_32 u4NumOfTxDone;	/* number of all packets (data/man/ctrl) tx done */
+	UINT_32 u4NumOfTxDoneFixRate;	/* number of done rate = 0 */
+	UINT_32 u4NumOfTxDoneErrRate;	/* number of error done rate */
+	UINT_32 u4NumOfNullTxDone;	/* number of null tx done */
+	UINT_32 u4NumOfQoSNullTxDone;	/* number of QoS-null tx done */
+
+	/* V11 */
+	/* delay in firmware from HIF RX to HIF RX Done */
+	/* unit: us, for 500B, 1000B, max */
+	UINT32 u4StayIntMaxHR2HRD[3], u4StayIntMinHR2HRD[3], u4StayIntAvgHR2HRD[3];
+
+	/* V12 */
+	UINT32 u4AirDelayTotal;	/* agg all the air delay */
+
+	/* V13 */
+	UINT32 u4CurrChnlInfo; /* add current channel information */
+
+	UINT_8 ucReserved_rate[4];	/* the field must be the last one */
+} STATS_INFO_ENV_T;
+
+/*******************************************************************************
+*						M A C R O   D E C L A R A T I O N S
+********************************************************************************
+*/
+#if (CFG_SUPPORT_STATISTICS == 1)
+
+#define STATS_ENV_REPORT_DETECT				statsEnvReportDetect
+
+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) \
+{ \
+	(__StaRec__)->u4RxReorderFallAheadCnt++; \
+}
+
+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) \
+{ \
+	(__StaRec__)->u4RxReorderFallBehindCnt++; \
+}
+
+#define STATS_RX_REORDER_HOLE_INC(__StaRec__) \
+{ \
+	(__StaRec__)->u4RxReorderHoleCnt++; \
+}
+
+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) \
+{ \
+	if ((__IsTimeout__) == TRUE) \
+		(__StaRec__)->u4RxReorderHoleTimeoutCnt++; \
+}
+
+#define STATS_RX_ARRIVE_TIME_RECORD(__SwRfb__) \
+{ \
+	(__SwRfb__)->rRxTime = StatsEnvTimeGet(); \
+}
+
+#define STATS_RX_PASS2OS_INC				StatsEnvRxDone
+
+#define STATS_RX_PKT_INFO_DISPLAY			StatsRxPktInfoDisplay
+
+#define STATS_TX_TIME_ARRIVE(__Skb__)										\
+do {														\
+	UINT_64 __SysTime;											\
+	__SysTime = StatsEnvTimeGet(); /* us */									\
+	GLUE_SET_PKT_XTIME(__Skb__, __SysTime);									\
+} while (FALSE)
+
+#define STATS_TX_TIME_TO_HIF				StatsEnvTxTime2Hif
+
+#define STATS_TX_PKT_CALLBACK				StatsTxPktCallBack
+#define STATS_TX_PKT_DONE_INFO_DISPLAY			StatsTxPktDoneInfoDisplay
+
+#define STATS_DRIVER_OWN_RESET() \
+{ \
+	u4DrvOwnMax = 0; \
+}
+#define STATS_DRIVER_OWN_START_RECORD() \
+{ \
+	u8DrvOwnStart = StatsEnvTimeGet(); \
+}
+#define STATS_DRIVER_OWN_END_RECORD() \
+{ \
+	u8DrvOwnEnd = StatsEnvTimeGet(); \
+}
+#define STATS_DRIVER_OWN_STOP()				\
+do {							\
+	UINT32 __Diff;					\
+	__Diff = (UINT32)(u8DrvOwnEnd - u8DrvOwnStart);	\
+	if (__Diff > u4DrvOwnMax)			\
+		u4DrvOwnMax = __Diff;			\
+} while (FALSE)
+
+#else
+
+#define STATS_ENV_REPORT_DETECT(__Adapter__, __StaRecIndex__)
+
+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__)
+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__)
+#define STATS_RX_REORDER_HOLE_INC(__StaRec__)
+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__)
+#define STATS_RX_PASS2OS_INC(__StaRec__, __SwRfb__)
+#define STATS_RX_PKT_INFO_DISPLAY(__Pkt__)
+
+#define STATS_TX_TIME_ARRIVE(__Skb__)
+#define STATS_TX_TIME_TO_HIF(__MsduInfo__, __HwTxHeader__)
+#define STATS_TX_PKT_CALLBACK(__Pkt__, __fgIsNeedAck__)
+#define STATS_TX_PKT_DONE_INFO_DISPLAY(__Adapter__, __Event__)
+
+#define STATS_DRIVER_OWN_RESET()
+#define STATS_DRIVER_OWN_START_RECORD()
+#define STATS_DRIVER_OWN_END_RECORD()
+#define STATS_DRIVER_OWN_STOP()
+#endif /* CFG_SUPPORT_STATISTICS */
+
+/*******************************************************************************
+*						F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*						P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*						P R I V A T E  F U N C T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*						P U B L I C  F U N C T I O N S
+********************************************************************************
+*/
+
+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex);
+
+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb);
+
+UINT_64 StatsEnvTimeGet(VOID);
+
+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader);
+
+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen);
+
+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt);
+
+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo);
+
+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf);
+
+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet);
+
+UINT_16 StatsGetCfgTxDone(VOID);
+
+/* End of stats.h */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h
new file mode 100644
index 0000000000000..50c4b558c2cd5
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h
@@ -0,0 +1,187 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/swcr.h#1
+*/
+
+/*! \file   "swcr.h"
+    \brief
+*/
+
+/*
+ *
+ */
+
+#ifndef _SWCR_H
+#define _SWCR_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "nic_cmd_event.h"
+
+#if 0
+extern SWCR_MAP_ENTRY_T g_arRlmArSwCrMap[];
+#endif
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define SWCR_VAR(x) ((VOID *)&x)
+#define SWCR_FUNC(x)  ((VOID *)x)
+
+#define SWCR_T_FUNC BIT(7)
+
+#define SWCR_L_32 3
+#define SWCR_L_16 2
+#define SWCR_L_8  1
+
+#define SWCR_READ 0
+#define SWCR_WRITE 1
+
+#define SWCR_MAP_NUM(x)  (sizeof(x)/sizeof(x[0]))
+
+#define SWCR_CR_NUM 7
+
+#define SWCR_GET_RW_INDEX(action, rw, index) \
+do { \
+	index = action & 0x7F; \
+	rw = action >> 7; \
+} while (0)
+
+extern UINT_32 g_au4SwCr[];	/*: 0: command other: data */
+
+typedef VOID(*PFN_SWCR_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data);
+typedef VOID(*PFN_CMD_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1);
+
+typedef struct _SWCR_MAP_ENTRY_T {
+	UINT_16 u2Type;
+	PVOID u4Addr;
+} SWCR_MAP_ENTRY_T, *P_SWCR_MAP_ENTRY_T;
+
+typedef struct _SWCR_MOD_MAP_ENTRY_T {
+	UINT_8 ucMapNum;
+	P_SWCR_MAP_ENTRY_T prSwCrMap;
+} SWCR_MOD_MAP_ENTRY_T, *P_SWCR_MOD_MAP_ENTRY_T;
+
+typedef enum _ENUM_SWCR_DBG_TYPE_T {
+	SWCR_DBG_TYPE_ALL = 0,
+	SWCR_DBG_TYPE_TXRX,
+	SWCR_DBG_TYPE_RX_RATES,
+	SWCR_DBG_TYPE_PS,
+	SWCR_DBG_TYPE_NUM
+} ENUM_SWCR_DBG_TYPE_T;
+
+typedef enum _ENUM_SWCR_DBG_ALL_T {
+	SWCR_DBG_ALL_TX_CNT = 0,
+	SWCR_DBG_ALL_TX_BCN_CNT,
+	SWCR_DBG_ALL_TX_FAILED_CNT,
+	SWCR_DBG_ALL_TX_RETRY_CNT,
+	SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT,
+	SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT,
+	SWCR_DBG_ALL_TX_MGNT_DROP_CNT,
+	SWCR_DBG_ALL_TX_ERROR_CNT,
+
+	SWCR_DBG_ALL_RX_CNT,
+	SWCR_DBG_ALL_RX_DROP_CNT,
+	SWCR_DBG_ALL_RX_DUP_DROP_CNT,
+	SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT,
+
+	SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT,
+	SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT,
+
+	SWCR_DBG_ALL_RX_FCSERR_CNT,
+	SWCR_DBG_ALL_RX_FIFOFULL_CNT,
+	SWCR_DBG_ALL_RX_PFDROP_CNT,
+
+	SWCR_DBG_ALL_PWR_PS_POLL_CNT,
+	SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT,
+	SWCR_DBG_ALL_PWR_BCN_IND_CNT,
+	SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT,
+	SWCR_DBG_ALL_PWR_PM_STATE0,
+	SWCR_DBG_ALL_PWR_PM_STATE1,
+	SWCR_DBG_ALL_PWR_CUR_PS_PROF0,
+	SWCR_DBG_ALL_PWR_CUR_PS_PROF1,
+
+	SWCR_DBG_ALL_AR_STA0_RATE,
+	SWCR_DBG_ALL_AR_STA0_BWGI,
+	SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI,
+
+	SWCR_DBG_ALL_ROAMING_ENABLE,
+	SWCR_DBG_ALL_ROAMING_ROAM_CNT,
+	SWCR_DBG_ALL_ROAMING_INT_CNT,
+
+	SWCR_DBG_ALL_BB_RX_MDRDY_CNT,
+	SWCR_DBG_ALL_BB_RX_FCSERR_CNT,
+	SWCR_DBG_ALL_BB_CCK_PD_CNT,
+	SWCR_DBG_ALL_BB_OFDM_PD_CNT,
+	SWCR_DBG_ALL_BB_CCK_SFDERR_CNT,
+	SWCR_DBG_ALL_BB_CCK_SIGERR_CNT,
+	SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT,
+	SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT,
+
+	SWCR_DBG_ALL_NUM
+} ENUM_SWCR_DBG_ALL_T;
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1);
+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1);
+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1);
+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1);
+void testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1);
+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data);
+
+/* Support Debug */
+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl);
+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data);
+
+/* Debug Support */
+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType);
+VOID swCrDebugInit(P_ADAPTER_T prAdapter);
+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout);
+VOID swCrDebugUninit(P_ADAPTER_T prAdapter);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h
new file mode 100644
index 0000000000000..3b6991131d058
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h
@@ -0,0 +1,262 @@
+/*
+** Id: include/tdls.h#1
+*/
+
+/*! \file   "tdls.h"
+    \brief This file contains the internal used in TDLS modules
+	 for MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: tdls.h
+ *
+ * 11 18 2013 vend_samp.lin
+ * NULL
+ * Initial version.
+ *
+ **
+ */
+
+#ifndef _TDLS_H
+#define _TDLS_H
+
+#if (CFG_SUPPORT_TDLS == 1)
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+#define TDLS_CFG_CMD_TEST			1
+#define TDLS_CFG_HT_SUP				1
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev);
+extern BOOLEAN flgTdlsTestExtCapElm;
+extern UINT8 aucTdlsTestExtCapElm[];
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+typedef struct _TDLS_LINK_HIS_OTHERS_T {
+	BOOLEAN fgIsHt;		/* TRUE: HT device */
+
+} TDLS_LINK_HIS_OTHERS_T;
+
+/* command */
+typedef enum _TDLS_CMD_ID {
+	TDLS_CMD_TEST_TX_FRAME = 0x00,
+	TDLS_CMD_TEST_RCV_FRAME = 0x01,
+	TDLS_CMD_TEST_PEER_ADD = 0x02,
+	TDLS_CMD_TEST_PEER_UPDATE = 0x03,
+	TDLS_CMD_TEST_DATA_FRAME = 0x04,
+	TDLS_CMD_TEST_RCV_NULL = 0x05,
+	TDLS_CMD_MIB_UPDATE = 0x06,
+	TDLS_CMD_TEST_SKIP_TX_FAIL = 0x07,
+	TDLS_CMD_UAPSD_CONF = 0x08,
+	TDLS_CMD_CH_SW_CONF = 0x09,
+	TDLS_CMD_TEST_SKIP_KEEP_ALIVE = 0x0a,
+	TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT = 0x0b,
+	TDLS_CMD_TEST_TX_TDLS_FRAME = 0x0c,
+	TDLS_CMD_TEST_PROHIBIT_SET_IN_AP = 0x0d,
+	TDLS_CMD_TEST_SCAN_DISABLE = 0x0e,
+	TDLS_CMD_TEST_DATA_FRAME_CONT = 0x0f,
+	TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP = 0x10,
+	TDLS_CMD_SETUP_CONF = 0x11,
+	TDLS_CMD_INFO = 0x12,
+	TDLS_CMD_TEST_DELAY = 0x13,
+	TDLS_CMD_KEY_INFO = 0x14,
+	TDLS_CMD_TEST_PTI_TX_FAIL = 0x15
+} TDLS_CMD_ID;
+
+typedef enum _TDLS_EVENT_HOST_ID {
+	TDLS_HOST_EVENT_TEAR_DOWN = 0x00,	/* TDLS_EVENT_HOST_SUBID_TEAR_DOWN */
+	TDLS_HOST_EVENT_TX_DONE,
+	TDLS_HOST_EVENT_FME_STATUS,	/* TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME */
+	TDLS_HOST_EVENT_STATISTICS
+} TDLS_EVENT_HOST_ID;
+
+typedef enum _TDLS_EVENT_HOST_SUBID_TEAR_DOWN {
+	TDLS_HOST_EVENT_TD_PTI_TIMEOUT = 0x00,
+	TDLS_HOST_EVENT_TD_AGE_TIMEOUT,
+	TDLS_HOST_EVENT_TD_PTI_SEND_FAIL,
+	TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL,
+	TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX,
+	TDLS_HOST_EVENT_TD_NON_STATE3,
+	TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN
+} TDLS_EVENT_HOST_SUBID_TEAR_DOWN;
+
+typedef enum _TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME {
+	TDLS_HOST_EVENT_SF_BA,
+	TDLS_HOST_EVENT_SF_BA_OK,
+	TDLS_HOST_EVENT_SF_BA_DECLINE,
+	TDLS_HOST_EVENT_SF_BA_PEER,
+	TDLS_HOST_EVENT_SF_BA_RSP_OK,
+	TDLS_HOST_EVENT_SF_BA_RSP_DECLINE
+} TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME;
+
+/* payload specific type in the LLC/SNAP header */
+#define TDLS_FRM_PAYLOAD_TYPE						2
+
+#define TDLS_FRM_CATEGORY							12
+
+typedef enum _TDLS_FRM_ACTION_ID {
+	TDLS_FRM_ACTION_SETUP_REQ = 0x00,
+	TDLS_FRM_ACTION_SETUP_RSP,
+	TDLS_FRM_ACTION_CONFIRM,
+	TDLS_FRM_ACTION_TEARDOWN,
+	TDLS_FRM_ACTION_PTI,
+	TDLS_FRM_ACTION_CHAN_SWITCH_REQ,
+	TDLS_FRM_ACTION_CHAN_SWITCH_RSP,
+	TDLS_FRM_ACTION_PEER_PSM_REQ,
+	TDLS_FRM_ACTION_PEER_PSM_RSP,
+	TDLS_FRM_ACTION_PTI_RSP,	/* 0x09 */
+	TDLS_FRM_ACTION_DISCOVERY_REQ,
+
+	TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT = 0x30,
+
+	TDLS_FRM_DATA_TEST_DATA = 0x80
+} TDLS_FRM_ACTION_ID;
+
+#define TDLS_FRM_ACTION_DISCOVERY_RESPONSE			14
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* 7.3.2.62 Link Identifier element */
+#define ELEM_ID_LINK_IDENTIFIER						101
+#define ELEM_LEN_LINK_IDENTIFIER					18
+
+typedef struct _IE_LINK_IDENTIFIER_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aBSSID[6];
+	UINT_8 aInitiator[6];
+	UINT_8 aResponder[6];
+} __KAL_ATTRIB_PACKED__ IE_LINK_IDENTIFIER_T;
+
+#define TDLS_LINK_IDENTIFIER_IE(__ie__)	((IE_LINK_IDENTIFIER_T *)(__ie__))
+
+/* test command use */
+typedef struct _PARAM_CUSTOM_TDLS_CMD_STRUCT_T {
+
+	UINT_8 ucFmeType;	/* TDLS_FRM_ACTION_ID */
+
+	UINT_8 ucToken;
+	UINT_16 u2Cap;
+
+	/* bit0: TDLS, bit1: Peer U-APSD Buffer, bit2: Channel Switching */
+#define TDLS_EX_CAP_PEER_UAPSD				BIT(0)
+#define TDLS_EX_CAP_CHAN_SWITCH				BIT(1)
+#define TDLS_EX_CAP_TDLS					BIT(2)
+	UINT_8 ucExCap;
+
+	UINT_8 arSupRate[4];
+	UINT_8 arSupChan[4];
+
+	UINT_32 u4Timeout;
+
+#define TDLS_FME_MAC_ADDR_LEN				6
+	UINT_8 arRspAddr[TDLS_FME_MAC_ADDR_LEN];
+	UINT_8 arBssid[TDLS_FME_MAC_ADDR_LEN];
+
+/*
+	Linux Kernel-3.10
+	struct station_parameters {
+		const u8 *supported_rates;
+		struct net_device *vlan;
+		u32 sta_flags_mask, sta_flags_set;
+		u32 sta_modify_mask;
+		int listen_interval;
+		u16 aid;
+		u8 supported_rates_len;
+		u8 plink_action;
+		u8 plink_state;
+		const struct ieee80211_ht_cap *ht_capa;
+		const struct ieee80211_vht_cap *vht_capa;
+		u8 uapsd_queues;
+		u8 max_sp;
+		enum nl80211_mesh_power_mode local_pm;
+		u16 capability;
+		const u8 *ext_capab;
+		u8 ext_capab_len;
+	};
+*/
+	struct ieee80211_ht_cap rHtCapa;
+	struct ieee80211_vht_cap rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */
+	struct station_parameters rPeerInfo;
+
+} PARAM_CUSTOM_TDLS_CMD_STRUCT_T;
+
+typedef struct _TDLS_MGMT_TX_INFO {
+	UINT8 aucPeer[6];
+	UINT8 ucActionCode;
+	UINT8 ucDialogToken;
+	UINT16 u2StatusCode;
+	UINT32 u4SecBufLen;
+	UINT8 aucSecBuf[1000];
+} TDLS_MGMT_TX_INFO;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/* check any TDLS link */
+#define TDLS_IS_NO_LINK_GOING(__GlueInfo__)									\
+	((__GlueInfo__)->rTdlsLink.cLinkCnt == 0)
+
+/* increase TDLS link count */
+#define TDLS_LINK_INCREASE(__GlueInfo__)									\
+	((__GlueInfo__)->rTdlsLink.cLinkCnt++)
+
+/* decrease TDLS link count */
+#define TDLS_LINK_DECREASE(__GlueInfo__) \
+do { \
+	if ((__GlueInfo__)->rTdlsLink.cLinkCnt > 0) \
+		(__GlueInfo__)->rTdlsLink.cLinkCnt--; \
+} while (0)
+
+/* get TDLS link count */
+#define TDLS_LINK_COUNT(__GlueInfo__)										\
+	((__GlueInfo__)->rTdlsLink.cLinkCnt)
+
+/* reset TDLS link count */
+#define TDLS_LINK_COUNT_RESET(__GlueInfo__)									\
+	((__GlueInfo__)->rTdlsLink.cLinkCnt = 0)
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/* Note: these functions are used only in tdls module, not other modules */
+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt);
+
+TDLS_STATUS
+TdlsDataFrameSend(ADAPTER_T *prAdapter,
+		  STA_RECORD_T *prStaRec,
+		  UINT_8 *pPeerMac,
+		  UINT_8 ucActionCode,
+		  UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* CFG_SUPPORT_TDLS */
+
+#endif /* _TDLS_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h
new file mode 100644
index 0000000000000..12c9359f2e8f3
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h
@@ -0,0 +1,104 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wapi.h#1
+*/
+
+/*! \file  wapi.h
+    \brief  The wapi related define, macro and structure are described here.
+*/
+
+/*
+** Log: wapi.h
+ *
+ * 07 20 2010 wh.su
+ *
+ * .
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * Dec 8 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * change the wapi function name and adding the generate wapi ie function
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding some wapi structure define
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+**  \main\maintrunk.MT5921\1 2009-10-09 17:06:29 GMT mtk01088
+**
+*/
+
+#ifndef _WAPI_H
+#define _WAPI_H
+
+#if CFG_SUPPORT_WAPI
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define WAPI_CIPHER_SUITE_WPI           0x01721400	/* WPI_SMS4 */
+#define WAPI_AKM_SUITE_802_1X           0x01721400	/* WAI */
+#define WAPI_AKM_SUITE_PSK              0x02721400	/* WAI_PSK */
+
+#define ELEM_ID_WAPI                    68	/* WAPI IE */
+
+#define WAPI_IE(fp)                     ((P_WAPI_INFO_ELEM_T) fp)
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo);
+
+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss);
+
+/* BOOLEAN */
+/* wapiUpdateTxKeyIdx ( */
+/* IN  P_STA_RECORD_T     prStaRec, */
+/* IN  UINT_8             ucWlanIdx */
+/* ); */
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif
+#endif /* _WAPI_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h
new file mode 100644
index 0000000000000..5dc969f1cc05b
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h
@@ -0,0 +1,87 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wlan_typedef.h#1
+*/
+
+/*! \file   wlan_typedef.h
+    \brief  Declaration of data type and return values of internal protocol stack.
+
+    In this file we declare the data type and return values which will be exported
+    to all MGMT Protocol Stack.
+*/
+
+/*
+** Log: wlan_typedef.h
+*/
+
+#ifndef _WLAN_TYPEDEF_H
+#define _WLAN_TYPEDEF_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Type definition for BSS_INFO_T structure, to describe the attributes used in a
+ * common BSS.
+ */
+typedef struct _BSS_INFO_T BSS_INFO_T, *P_BSS_INFO_T;
+
+typedef BSS_INFO_T AIS_BSS_INFO_T, *P_AIS_BSS_INFO_T;
+typedef BSS_INFO_T P2P_BSS_INFO_T, *P_P2P_BSS_INFO_T;
+typedef BSS_INFO_T BOW_BSS_INFO_T, *P_BOW_BSS_INFO_T;
+
+typedef struct _AIS_SPECIFIC_BSS_INFO_T AIS_SPECIFIC_BSS_INFO_T, *P_AIS_SPECIFIC_BSS_INFO_T;
+typedef struct _P2P_SPECIFIC_BSS_INFO_T P2P_SPECIFIC_BSS_INFO_T, *P_P2P_SPECIFIC_BSS_INFO_T;
+typedef struct _BOW_SPECIFIC_BSS_INFO_T BOW_SPECIFIC_BSS_INFO_T, *P_BOW_SPECIFIC_BSS_INFO_T;
+/* CFG_SUPPORT_WFD */
+typedef struct _WFD_CFG_SETTINGS_T WFD_CFG_SETTINGS_T, *P_WFD_CFG_SETTINGS_T;
+
+typedef struct _WFD_DBG_CFG_SETTINGS_T WFD_DBG_CFG_SETTINGS_T, *P_WFD_DBG_CFG_SETTINGS_T;
+
+/* BSS related structures */
+/* Type definition for BSS_DESC_T structure, to describe parameter sets of a particular BSS */
+typedef struct _BSS_DESC_T BSS_DESC_T, *P_BSS_DESC_T, **PP_BSS_DESC_T;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+typedef struct _HS20_INFO_T HS20_INFO_T, *P_HS20_INFO_T;
+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _WLAN_TYPEDEF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h
new file mode 100644
index 0000000000000..09bc0b5d5151b
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h
@@ -0,0 +1,95 @@
+/*
+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/mgmt/wnm.h#1
+*/
+
+/*! \file  wnm.h
+    \brief This file contains the IEEE 802.11 family related 802.11v network management
+	   for MediaTek 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: wnm.h
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ *
+*/
+
+#ifndef _WNM_H
+#define _WNM_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef struct _TIMINGMSMT_PARAM_T {
+	BOOLEAN fgInitiator;
+	UINT_8 ucTrigger;
+	UINT_8 ucDialogToken;	/* Dialog Token */
+	UINT_8 ucFollowUpDialogToken;	/* Follow Up Dialog Token */
+	UINT_32 u4ToD;		/* Timestamp of Departure [10ns] */
+	UINT_32 u4ToA;		/* Timestamp of Arrival [10ns] */
+} TIMINGMSMT_PARAM_T, *P_TIMINGMSMT_PARAM_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+WLAN_STATUS
+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter,
+			     IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+VOID
+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler);
+
+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA);
+
+#define WNM_UNIT_TEST 1
+
+#if WNM_UNIT_TEST
+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex);
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WNM_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h
new file mode 100644
index 0000000000000..d34f2c9c36a8b
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h
@@ -0,0 +1,1506 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/adapter.h#3
+*/
+
+/*! \file   adapter.h
+    \brief  Definition of internal data structure for driver manipulation.
+
+    In this file we define the internal data structure - ADAPTER_T which stands
+    for MiniPort ADAPTER(From Windows point of view) or stands for Network ADAPTER.
+*/
+
+/*
+** Log: adapter.h
+**
+** 08 31 2012 yuche.tsai
+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have
+** connected to AP previously,one device reboots automatically with KE
+** Fix possible KE when concurrent & disconnect.
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 16 2012 cp.wu
+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration
+ * with corresponding network configuration
+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration
+ * corresponding to network type.
+ *
+ * 12 13 2011 cm.chang
+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer
+ * Add wake lock if timer timeout value is smaller than 5 seconds
+ *
+ * 12 02 2011 yuche.tsai
+ * NULL
+ * Resolve inorder issue under AP mode.
+ *
+ * data frame may TX before assoc response frame.
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Update RSSI for P2P.
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix work thread cancel issue.
+ *
+ * 10 21 2011 eddie.chen
+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout
+ * Add switch to ignore the STA aging timeout.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 20 2011 cm.chang
+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
+ * Remove ERP member in adapter structure
+ *
+ * 09 14 2011 yuche.tsai
+ * NULL
+ * Add P2P IE in assoc response.
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content
+ * check with firmware for valid MAC address.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 08 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Add device discoverability support.
+ * Action frame callback for GO Device Discoverability Req.
+ *
+ * 04 08 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * separate settings of P2P and AIS
+ *
+ * 04 08 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix for sigma
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
+ * Add beacon timeout support for WiFi Direct Network.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue
+ * Make assoc req to append P2P IE if wifi direct is enabled.
+ *
+ * 03 17 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically
+ * continuous memory shortage after system running for a long period
+ * use pre-allocated buffer for storing enhanced interrupt response as well
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce
+ * physically continuous memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 10 2011 yuche.tsai
+ * [WCXRP00000533] [Volunteer Patch][MT6620][Driver] Provide a P2P function API for Legacy WiFi to query AP mode.
+ * Provide an API for Legacy WiFi to query the operation mode..
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
+ * Add code to send beacon and probe response WSC IE at Auto GO.
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as
+ * initial RSSI right after connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid
+ * using a uninitialized MAC-RX RCPI.
+ *
+ * 02 21 2011 terry.wu
+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
+ * Clean P2P scan list while removing P2P.
+ *
+ * 02 17 2011 eddie.chen
+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel
+ * 1) Change GetFrameAction decision when BSS is absent.
+ * 2) Check channel and resource in processing ProbeRequest
+ *
+ * 02 16 2011 cm.chang
+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism
+ * .
+ *
+ * 02 10 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add RX deauthentication & disassociation process under Hot-Spot mode.
+ *
+ * 02 09 2011 wh.su
+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module
+ * with structure miss-align pointer issue
+ * always pre-allio WAPI related structure for align p2p module.
+ *
+ * 02 08 2011 yuche.tsai
+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to
+ * target station for AAA module.
+ * Provide disconnect function for AAA module.
+ *
+ * 02 01 2011 cm.chang
+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
+ * .
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 27 2011 george.huang
+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting
+ * Support CTIA power mode setting.
+ *
+ * 01 27 2011 george.huang
+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability
+ * Support current measure mode, assigned by registry (XP only).
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * Add WMM parameter for broadcast.
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * Add CWMin CWMax for AP to generate IE.
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * report EEPROM used flag via NIC_CAPABILITY
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 27 2010 george.huang
+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB
+ * Support registry option for disable beacon lost detection.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW]
+ * Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * adding fixed rate support for distance test. (from registry setting)
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * code reorganization to improve isolation between GLUE and CORE layers.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 09 27 2010 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
+ * Update BCM/BoW design and settings.
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature
+ * Modify online scan as a run-time adjustable option (for Windows, in registry)
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
+ * use firmware reported mac address right after wlanAdapterStart() as permanent address
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * Add a common IE buffer in P2P INFO structure.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * restore configuration as before.
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * Finish SLT TX/RX & Rate Changing Support.
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Add an intend mode for BSS info.
+ * It is used to let P2P BSS Info to know which OP Mode it is going to become.
+ *
+ * 08 04 2010 george.huang
+ * NULL
+ * handle change PS mode OID/ CMD
+ *
+ * 08 02 2010 cp.wu
+ * NULL
+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver.
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc*
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo
+ * 2) change nicMediaStateChange() API prototype
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add for P2P Scan Result Parsing & Saving.
+ *
+ * 07 19 2010 wh.su
+ *
+ * update for security supporting.
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 19 2010 yuche.tsai
+ *
+ * Remove BSS info which is redonedent in Wifi Var..
+ *
+ * 07 16 2010 yarco.yang
+ *
+ * 1. Support BSS Absence/Presence Event
+ * 2. Support STA change PS mode Event
+ * 3. Support BMC forwarding for AP mode.
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 09 2010 george.huang
+ *
+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 06 29 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * replace g_rQM with Adpater->rQM
+ *
+ * 06 28 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * 1st draft code for RLM module
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * remove duplicate variable for migration.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * modify some code for concurrent network.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add P2P FSM Info in adapter.
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Support CFG_MQM_MIGRATION flag
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration the security related function from firmware.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add P2P related field, additional include p2p_fsm.h if p2p is enabled.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan.c.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add definitions for module migration.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * cnm_timer has been migrated.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * hem_mbox is migrated.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change OID behavior to meet WHQL requirement.
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) do not take timeout mechanism for power mode oids
+ * 2) retrieve network type from connection status
+ * 3) after disassciation, set radio state to off
+ * 4) TCP option over IPv6 is supported
+ *
+ * 05 18 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement Wakeup-on-LAN except firmware integration part
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * reserve field of privacy filter and RTS threshold setting.
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  * are done in adapter layer.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_3_MULTICAST_LIST oid handling
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock
+ *  *  * 2) ensure wlanReleasePendingOid will clear all command queues
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * move ucCmdSeqNum as instance variable
+ *
+ * 01 27 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * .
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  *  * 4. correct some HAL implementation
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  * and result is retrieved by get ATInfo instead
+ *  *  * 2) add 4 counter for recording aggregation statistics
+ *
+ * 12 28 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate redundant variables for connection_state
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-16 18:02:03 GMT mtk02752
+**  add external reference to avoid compilation error
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:40:26 GMT mtk02752
+**  eliminate unused member
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-08 17:36:08 GMT mtk02752
+**  add RF test data members into P_ADAPTER_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:45 GMT mtk01084
+**  update for new HW architecture design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-28 10:29:57 GMT mtk01461
+**  Add read WTSR for SDIO_STATUS_ENHANCE mode
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:37:35 GMT mtk01461
+**  Add prPendingCmdInfoOfOID for temporarily saving the CMD_INFO_T before en-queue to rCmdQueue
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:57:51 GMT mtk01461
+**  Add MGMT Buffer Info
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:34:12 GMT mtk01461
+**  Add SW pre test CFG_HIF_LOOPBACK_PRETEST
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:41:48 GMT mtk01461
+**  Add fgIsWmmAssoc flag for TC assignment
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:51 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:51:52 GMT mtk01426
+**  Add #if CFG_SDIO_RX_ENHANCE related data structure
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:17 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _ADAPTER_H
+#define _ADAPTER_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#if CFG_SUPPORT_HOTSPOT_2_0
+#include "hs20.h"
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _ENHANCE_MODE_DATA_STRUCT_T SDIO_CTRL_T, *P_SDIO_CTRL_T;
+
+typedef struct _WLAN_INFO_T {
+	PARAM_BSSID_EX_T rCurrBssId;
+
+	/* Scan Result */
+	PARAM_BSSID_EX_T arScanResult[CFG_MAX_NUM_BSS_LIST];
+	PUINT_8 apucScanResultIEs[CFG_MAX_NUM_BSS_LIST];
+	UINT_32 u4ScanResultNum;
+
+	/* IE pool for Scanning Result */
+	UINT_8 aucScanIEBuf[CFG_MAX_COMMON_IE_BUF_LEN];
+	UINT_32 u4ScanIEBufferUsage;
+
+	OS_SYSTIME u4SysTime;
+
+	/* connection parameter (for Ad-Hoc) */
+	UINT_16 u2BeaconPeriod;
+	UINT_16 u2AtimWindow;
+
+	PARAM_RATES eDesiredRates;
+	CMD_LINK_ATTRIB eLinkAttr;
+/* CMD_PS_PROFILE_T         ePowerSaveMode; */
+	CMD_PS_PROFILE_T arPowerSaveMode[NETWORK_TYPE_INDEX_NUM];
+
+	/* trigger parameter */
+	ENUM_RSSI_TRIGGER_TYPE eRssiTriggerType;
+	PARAM_RSSI rRssiTriggerValue;
+
+	/* Privacy Filter */
+	ENUM_PARAM_PRIVACY_FILTER_T ePrivacyFilter;
+
+	/* RTS Threshold */
+	PARAM_RTS_THRESHOLD eRtsThreshold;
+
+	/* Network Type */
+	UINT_8 ucNetworkType;
+
+	/* Network Type In Use */
+	UINT_8 ucNetworkTypeInUse;
+
+} WLAN_INFO_T, *P_WLAN_INFO_T;
+
+/* Session for CONNECTION SETTINGS */
+typedef struct _CONNECTION_SETTINGS_T {
+
+	UINT_8 aucMacAddress[MAC_ADDR_LEN];
+
+	UINT_8 ucDelayTimeOfDisconnectEvent;
+
+	BOOLEAN fgIsConnByBssidIssued;
+	UINT_8 aucBSSID[MAC_ADDR_LEN];
+
+	BOOLEAN fgIsConnReqIssued;
+	BOOLEAN fgIsDisconnectedByNonRequest;
+
+	UINT_8 ucSSIDLen;
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];
+
+	ENUM_PARAM_OP_MODE_T eOPMode;
+
+	ENUM_PARAM_CONNECTION_POLICY_T eConnectionPolicy;
+
+	ENUM_PARAM_AD_HOC_MODE_T eAdHocMode;
+
+	ENUM_PARAM_AUTH_MODE_T eAuthMode;
+
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
+
+	BOOLEAN fgIsScanReqIssued;
+
+	/* MIB attributes */
+	UINT_16 u2BeaconPeriod;
+
+	UINT_16 u2RTSThreshold;	/* User desired setting */
+
+	UINT_16 u2DesiredNonHTRateSet;	/* User desired setting */
+
+	UINT_8 ucAdHocChannelNum;	/* For AdHoc */
+
+	ENUM_BAND_T eAdHocBand;	/* For AdHoc */
+
+	UINT_32 u4FreqInKHz;	/* Center frequency */
+
+	/* ATIM windows using for IBSS power saving function */
+	UINT_16 u2AtimWindow;
+
+	/* Features */
+	BOOLEAN fgIsEnableRoaming;
+
+	BOOLEAN fgIsAdHocQoSEnable;
+
+	ENUM_PARAM_PHY_CONFIG_T eDesiredPhyConfig;
+
+	/* Used for AP mode for desired channel and bandwidth */
+	UINT_16 u2CountryCode;
+	UINT_16 u2CountryCodeBakup;
+	UINT_8 uc2G4BandwidthMode;	/* 20/40M or 20M only */
+	UINT_8 uc5GBandwidthMode;	/* 20/40M or 20M only */
+
+	BOOLEAN fgTxShortGIDisabled;
+	BOOLEAN fgRxShortGIDisabled;
+
+#if CFG_SUPPORT_802_11D
+	BOOLEAN fgMultiDomainCapabilityEnabled;
+#endif				/* CFG_SUPPORT_802_11D */
+
+#if 1				/* CFG_SUPPORT_WAPI */
+	BOOLEAN fgWapiMode;
+	UINT_32 u4WapiSelectedGroupCipher;
+	UINT_32 u4WapiSelectedPairwiseCipher;
+	UINT_32 u4WapiSelectedAKMSuite;
+#endif
+
+	/* CR1486, CR1640 */
+	/* for WPS, disable the privacy check for AP selection policy */
+	BOOLEAN fgPrivacyCheckDisable;
+
+	/* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */
+	UINT_8 bmfgApsdEnAc;
+
+	/* for RSN info store, when upper layer set rsn info */
+	RSN_INFO_T rRsnInfo;
+
+} CONNECTION_SETTINGS_T, *P_CONNECTION_SETTINGS_T;
+
+struct _BSS_INFO_T {
+
+	ENUM_PARAM_MEDIA_STATE_T eConnectionState;	/* Connected Flag used in AIS_NORMAL_TR */
+	ENUM_PARAM_MEDIA_STATE_T eConnectionStateIndicated;	/* The Media State that report to HOST */
+
+	ENUM_OP_MODE_T eCurrentOPMode;	/* Current Operation Mode - Infra/IBSS */
+#if CFG_ENABLE_WIFI_DIRECT
+	ENUM_OP_MODE_T eIntendOPMode;
+#endif
+
+	BOOLEAN fgIsNetActive;	/* TRUE if this network has been activated */
+
+	UINT_8 ucNetTypeIndex;	/* ENUM_NETWORK_TYPE_INDEX_T */
+
+	UINT_8 ucReasonOfDisconnect;	/* Used by media state indication */
+
+	UINT_8 ucSSIDLen;	/* Length of SSID */
+
+#if CFG_ENABLE_WIFI_DIRECT
+	ENUM_HIDDEN_SSID_TYPE_T eHiddenSsidType;	/* For Hidden SSID usage. */
+#endif
+
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];	/* SSID used in this BSS */
+
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* The BSSID of the associated BSS */
+
+	UINT_8 aucOwnMacAddr[MAC_ADDR_LEN];	/* Owned MAC Address used in this BSS */
+
+	P_STA_RECORD_T prStaRecOfAP;	/* For Infra Mode, and valid only if
+					 * eConnectionState == MEDIA_STATE_CONNECTED
+					 */
+	LINK_T rStaRecOfClientList;	/* For IBSS/AP Mode, all known STAs in current BSS */
+
+	UINT_16 u2CapInfo;	/* Change Detection */
+
+	UINT_16 u2BeaconInterval;	/* The Beacon Interval of this BSS */
+
+	UINT_16 u2ATIMWindow;	/* For IBSS Mode */
+
+	UINT_16 u2AssocId;	/* For Infra Mode, it is the Assoc ID assigned by AP.
+				 */
+
+	UINT_8 ucDTIMPeriod;	/* For Infra/AP Mode */
+
+	UINT_8 ucDTIMCount;	/* For AP Mode, it is the DTIM value we should carried in
+				 * the Beacon of next TBTT.
+				 */
+
+	UINT_8 ucPhyTypeSet;	/* Available PHY Type Set of this peer
+				 * (This is deduced from received BSS_DESC_T)
+				 */
+
+	UINT_8 ucNonHTBasicPhyType;	/* The Basic PHY Type Index, used to setup Phy Capability */
+
+	UINT_8 ucConfigAdHocAPMode;	/* The configuration of AdHoc/AP Mode. e.g. 11g or 11b */
+
+	UINT_8 ucBeaconTimeoutCount;	/* For Infra/AP Mode, it is a threshold of Beacon Lost Count to
+					   confirm connection was lost */
+
+	BOOLEAN fgHoldSameBssidForIBSS;	/* For IBSS Mode, to keep use same BSSID to extend the life cycle of an IBSS */
+
+	BOOLEAN fgIsBeaconActivated;	/* For AP/IBSS Mode, it is used to indicate that Beacon is sending */
+
+	P_MSDU_INFO_T prBeacon;	/* For AP/IBSS Mode - Beacon Frame */
+
+	BOOLEAN fgIsIBSSMaster;	/* For IBSS Mode - To indicate that we can reply ProbeResp Frame.
+				   In current TBTT interval */
+
+	BOOLEAN fgIsShortPreambleAllowed;	/* From Capability Info. of AssocResp Frame
+						AND of Beacon/ProbeResp Frame */
+	BOOLEAN fgUseShortPreamble;	/* Short Preamble is enabled in current BSS. */
+	BOOLEAN fgUseShortSlotTime;	/* Short Slot Time is enabled in current BSS. */
+
+	UINT_16 u2OperationalRateSet;	/* Operational Rate Set of current BSS */
+	UINT_16 u2BSSBasicRateSet;	/* Basic Rate Set of current BSS */
+
+	UINT_8 ucAllSupportedRatesLen;	/* Used for composing Beacon Frame in AdHoc or AP Mode */
+	UINT_8 aucAllSupportedRates[RATE_NUM];
+
+	UINT_8 ucAssocClientCnt;	/* TODO(Kevin): Number of associated clients */
+
+	BOOLEAN fgIsProtection;
+	BOOLEAN fgIsQBSS;	/* fgIsWmmBSS; *//* For Infra/AP/IBSS Mode, it is used to indicate if we support WMM in
+				 * current BSS. */
+	BOOLEAN fgIsNetAbsent;	/* TRUE: BSS is absent, FALSE: BSS is present */
+
+	UINT_32 u4RsnSelectedGroupCipher;
+	UINT_32 u4RsnSelectedPairwiseCipher;
+	UINT_32 u4RsnSelectedAKMSuite;
+	UINT_16 u2RsnSelectedCapInfo;
+
+    /*------------------------------------------------------------------------*/
+	/* Power Management related information                                   */
+    /*------------------------------------------------------------------------*/
+	PM_PROFILE_SETUP_INFO_T rPmProfSetupInfo;
+
+    /*------------------------------------------------------------------------*/
+	/* WMM/QoS related information                                            */
+    /*------------------------------------------------------------------------*/
+	UINT_8 ucWmmParamSetCount;	/* Used to detect the change of EDCA parameters. For AP mode,
+					the value is used in WMM IE */
+
+	AC_QUE_PARMS_T arACQueParms[WMM_AC_INDEX_NUM];
+
+	UINT_8 aucCWminLog2ForBcast[WMM_AC_INDEX_NUM];	/* For AP mode, broadcast the CWminLog2 */
+	UINT_8 aucCWmaxLog2ForBcast[WMM_AC_INDEX_NUM];	/* For AP mode, broadcast the CWmaxLog2 */
+	AC_QUE_PARMS_T arACQueParmsForBcast[WMM_AC_INDEX_NUM];	/* For AP mode, broadcast the value */
+
+    /*------------------------------------------------------------------------*/
+	/* 802.11n HT operation IE when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) */
+	/* is true. They have the same definition with fields of                  */
+	/* information element (CM)                                               */
+    /*------------------------------------------------------------------------*/
+	ENUM_BAND_T eBand;
+	UINT_8 ucPrimaryChannel;
+	UINT_8 ucHtOpInfo1;
+	UINT_16 u2HtOpInfo2;
+	UINT_16 u2HtOpInfo3;
+
+    /*------------------------------------------------------------------------*/
+	/* Required protection modes (CM)                                         */
+    /*------------------------------------------------------------------------*/
+	BOOLEAN fgErpProtectMode;
+	ENUM_HT_PROTECT_MODE_T eHtProtectMode;
+	ENUM_GF_MODE_T eGfOperationMode;
+	ENUM_RIFS_MODE_T eRifsOperationMode;
+
+	BOOLEAN fgObssErpProtectMode;	/* GO only */
+	ENUM_HT_PROTECT_MODE_T eObssHtProtectMode;	/* GO only */
+	ENUM_GF_MODE_T eObssGfOperationMode;	/* GO only */
+	BOOLEAN fgObssRifsOperationMode;	/* GO only */
+
+    /*------------------------------------------------------------------------*/
+	/* OBSS to decide if 20/40M bandwidth is permitted.                       */
+	/* The first member indicates the following channel list length.          */
+    /*------------------------------------------------------------------------*/
+	BOOLEAN fgAssoc40mBwAllowed;
+	BOOLEAN fg40mBwAllowed;
+	ENUM_CHNL_EXT_T eBssSCO;	/* Real setting for HW
+					 * 20/40M AP mode will always set 40M,
+					 * but its OP IE can be changed.
+					 */
+	UINT_8 auc2G_20mReqChnlList[CHNL_LIST_SZ_2G + 1];
+	UINT_8 auc2G_NonHtChnlList[CHNL_LIST_SZ_2G + 1];
+	UINT_8 auc2G_PriChnlList[CHNL_LIST_SZ_2G + 1];
+	UINT_8 auc2G_SecChnlList[CHNL_LIST_SZ_2G + 1];
+
+	UINT_8 auc5G_20mReqChnlList[CHNL_LIST_SZ_5G + 1];
+	UINT_8 auc5G_NonHtChnlList[CHNL_LIST_SZ_5G + 1];
+	UINT_8 auc5G_PriChnlList[CHNL_LIST_SZ_5G + 1];
+	UINT_8 auc5G_SecChnlList[CHNL_LIST_SZ_5G + 1];
+
+	TIMER_T rObssScanTimer;
+	UINT_16 u2ObssScanInterval;	/* in unit of sec */
+
+	BOOLEAN fgObssActionForcedTo20M;	/* GO only */
+	BOOLEAN fgObssBeaconForcedTo20M;	/* GO only */
+
+    /*------------------------------------------------------------------------*/
+	/* HW Related Fields (Kevin)                                              */
+    /*------------------------------------------------------------------------*/
+	UINT_8 ucHwDefaultFixedRateCode;	/* The default rate code copied to MAC TX Desc */
+	UINT_16 u2HwLPWakeupGuardTimeUsec;
+
+	UINT_8 ucBssFreeQuota;	/* The value is updated from FW  */
+#if CFG_ENABLE_GTK_FRAME_FILTER
+	P_IPV4_NETWORK_ADDRESS_LIST prIpV4NetAddrList;
+#endif
+	UINT_16 u2DeauthReason;
+
+#if (CFG_SUPPORT_TDLS == 1)
+	BOOLEAN fgTdlsIsProhibited;	/* TRUE: AP prohibits TDLS links */
+	BOOLEAN fgTdlsIsChSwProhibited;	/* TRUE: AP prohibits TDLS chan switch */
+#endif				/* CFG_SUPPORT_TDLS */
+};
+
+struct _AIS_SPECIFIC_BSS_INFO_T {
+	UINT_8 ucRoamingAuthTypes;	/* This value indicate the roaming type used in AIS_JOIN */
+
+	BOOLEAN fgIsIBSSActive;
+
+	/*! \brief Global flag to let arbiter stay at standby and not connect to any network */
+	BOOLEAN fgCounterMeasure;
+	UINT_8 ucWEPDefaultKeyID;
+	BOOLEAN fgTransmitKeyExist;	/* Legacy wep Transmit key exist or not */
+
+	/* While Do CounterMeasure procedure, check the EAPoL Error report have send out */
+	BOOLEAN fgCheckEAPoLTxDone;
+
+	UINT_32 u4RsnaLastMICFailTime;
+
+	/* Stored the current bss wpa rsn cap filed, used for roaming policy */
+	/* UINT_16                 u2RsnCap; */
+	TIMER_T rPreauthenticationTimer;
+
+	/* By the flow chart of 802.11i,
+	   wait 60 sec before associating to same AP
+	   or roaming to a new AP
+	   or sending data in IBSS,
+	   keep a timer for handle the 60 sec counterMeasure */
+	TIMER_T rRsnaBlockTrafficTimer;
+	TIMER_T rRsnaEAPoLReportTimeoutTimer;
+
+	/* For Keep the Tx/Rx Mic key for TKIP SW Calculate Mic */
+	/* This is only one for AIS/AP */
+	UINT_8 aucTxMicKey[8];
+	UINT_8 aucRxMicKey[8];
+
+	/* Buffer for WPA2 PMKID */
+	/* The PMKID cache lifetime is expire by media_disconnect_indication */
+	UINT_32 u4PmkidCandicateCount;
+	PMKID_CANDICATE_T arPmkidCandicate[CFG_MAX_PMKID_CACHE];
+	UINT_32 u4PmkidCacheCount;
+	PMKID_ENTRY_T arPmkidCache[CFG_MAX_PMKID_CACHE];
+	BOOLEAN fgIndicatePMKID;
+#if CFG_SUPPORT_802_11W
+	BOOLEAN fgMgmtProtection;
+	UINT_32 u4SaQueryStart;
+	UINT_32 u4SaQueryCount;
+	UINT_8 ucSaQueryTimedOut;
+	PUINT_8 pucSaQueryTransId;
+	TIMER_T rSaQueryTimer;
+	BOOLEAN fgBipKeyInstalled;
+#endif
+};
+
+struct _BOW_SPECIFIC_BSS_INFO_T {
+	UINT_16 u2Reserved;	/* Reserved for Data Type Check */
+};
+
+#if CFG_SLT_SUPPORT
+typedef struct _SLT_INFO_T {
+
+	P_BSS_DESC_T prPseudoBssDesc;
+	UINT_16 u2SiteID;
+	UINT_8 ucChannel2G4;
+	UINT_8 ucChannel5G;
+	BOOLEAN fgIsDUT;
+	UINT_32 u4BeaconReceiveCnt;
+	/* ///////Deprecated///////// */
+	P_STA_RECORD_T prPseudoStaRec;
+} SLT_INFO_T, *P_SLT_INFO_T;
+#endif
+
+/* Major member variables for WiFi FW operation.
+   Variables within this region will be ready for access after WIFI function is enabled.
+*/
+typedef struct _WIFI_VAR_T {
+	BOOLEAN fgIsRadioOff;
+
+	BOOLEAN fgIsEnterD3ReqIssued;
+
+	BOOLEAN fgDebugCmdResp;
+
+	CONNECTION_SETTINGS_T rConnSettings;
+
+	SCAN_INFO_T rScanInfo;
+
+#if CFG_SUPPORT_ROAMING
+	ROAMING_INFO_T rRoamingInfo;
+#endif				/* CFG_SUPPORT_ROAMING */
+
+	AIS_FSM_INFO_T rAisFsmInfo;
+
+	ENUM_PWR_STATE_T aePwrState[NETWORK_TYPE_INDEX_NUM];
+
+	BSS_INFO_T arBssInfo[NETWORK_TYPE_INDEX_NUM];
+
+	AIS_SPECIFIC_BSS_INFO_T rAisSpecificBssInfo;
+
+#if CFG_ENABLE_WIFI_DIRECT
+	P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings;
+
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;
+
+	P_P2P_FSM_INFO_T prP2pFsmInfo;
+#endif				/* CFG_ENABLE_WIFI_DIRECT */
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	BOW_SPECIFIC_BSS_INFO_T rBowSpecificBssInfo;
+	BOW_FSM_INFO_T rBowFsmInfo;
+#endif				/* CFG_ENABLE_BT_OVER_WIFI */
+
+	DEAUTH_INFO_T arDeauthInfo[MAX_DEAUTH_INFO_COUNT];
+
+	/* Current Wi-Fi Settings and Flags */
+	UINT_8 aucPermanentAddress[MAC_ADDR_LEN];
+	UINT_8 aucMacAddress[MAC_ADDR_LEN];
+	UINT_8 aucDeviceAddress[MAC_ADDR_LEN];
+	UINT_8 aucInterfaceAddress[MAC_ADDR_LEN];
+
+	UINT_8 ucAvailablePhyTypeSet;
+
+	ENUM_PHY_TYPE_INDEX_T eNonHTBasicPhyType2G4;	/* Basic Phy Type used by SCN according
+							 * to the set of Available PHY Types
+							 */
+
+	ENUM_PARAM_PREAMBLE_TYPE_T ePreambleType;
+	ENUM_REGISTRY_FIXED_RATE_T eRateSetting;
+
+	BOOLEAN fgIsShortSlotTimeOptionEnable;
+	/* User desired setting, but will honor the capability of AP */
+
+	BOOLEAN fgEnableJoinToHiddenSSID;
+	BOOLEAN fgSupportWZCDisassociation;
+
+	BOOLEAN fgSupportQoS;
+	BOOLEAN fgSupportAmpduTx;
+	BOOLEAN fgSupportAmpduRx;
+	BOOLEAN fgSupportTspec;
+	BOOLEAN fgSupportUAPSD;
+	BOOLEAN fgSupportULPSMP;
+	UINT_8 u8SupportRxSgi20;	/* 0: default 1: enable 2:disble */
+	UINT_8 u8SupportRxSgi40;
+	UINT_8 u8SupportRxGf;
+	UINT_8 u8SupportRxSTBC;
+#if CFG_SUPPORT_CFG_FILE
+	UINT_8 ucApWpsMode;
+	UINT_8 ucCert11nMode;
+#endif
+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT
+	UINT_8 ucCeFccTxPwrLimit;
+	UINT_8 ucCeFccTxPwrLimitCck;
+	UINT_8 ucCeFccTxPwrLimitOfdmHt20;
+	UINT_8 ucCeFccTxPwrLimitHt40;
+#endif
+
+#if CFG_SLT_SUPPORT
+	SLT_INFO_T rSltInfo;
+#endif
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+	HS20_INFO_T rHS20Info;
+#endif
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+	PARAM_GET_CHN_LOAD rChnLoadInfo;
+#endif
+
+} WIFI_VAR_T, *P_WIFI_VAR_T;	/* end of _WIFI_VAR_T */
+
+/* cnm_timer module */
+typedef struct {
+	LINK_T rLinkHead;
+	OS_SYSTIME rNextExpiredSysTime;
+	KAL_WAKE_LOCK_T rWakeLock;
+	BOOLEAN fgWakeLocked;
+} ROOT_TIMER, *P_ROOT_TIMER;
+
+/* FW/DRV/NVRAM version information */
+typedef struct {
+
+	/* NVRAM or Registry */
+	UINT_16 u2Part1CfgOwnVersion;
+	UINT_16 u2Part1CfgPeerVersion;
+	UINT_16 u2Part2CfgOwnVersion;
+	UINT_16 u2Part2CfgPeerVersion;
+
+	/* Firmware */
+	UINT_16 u2FwProductID;
+	UINT_16 u2FwOwnVersion;
+	UINT_16 u2FwPeerVersion;
+
+} WIFI_VER_INFO_T, *P_WIFI_VER_INFO_T;
+
+#if CFG_ENABLE_WIFI_DIRECT
+/*
+* p2p function pointer structure
+*/
+
+typedef struct _P2P_FUNCTION_LINKER {
+	P2P_REMOVE prP2pRemove;
+/* NIC_P2P_MEDIA_STATE_CHANGE                  prNicP2pMediaStateChange; */
+/* SCAN_UPDATE_P2P_DEVICE_DESC                 prScanUpdateP2pDeviceDesc; */
+/* P2P_FSM_RUN_EVENT_RX_PROBE_RESPONSE_FRAME   prP2pFsmRunEventRxProbeResponseFrame; */
+	P2P_GENERATE_P2P_IE prP2pGenerateWSC_IEForBeacon;
+/* P2P_CALCULATE_WSC_IE_LEN_FOR_PROBE_RSP      prP2pCalculateWSC_IELenForProbeRsp; */
+/* P2P_GENERATE_WSC_IE_FOR_PROBE_RSP           prP2pGenerateWSC_IEForProbeRsp; */
+/* SCAN_REMOVE_P2P_BSS_DESC                    prScanRemoveP2pBssDesc; */
+/* P2P_HANDLE_SEC_CHECK_RSP                    prP2pHandleSecCheckRsp; */
+	P2P_NET_REGISTER prP2pNetRegister;
+	P2P_NET_UNREGISTER prP2pNetUnregister;
+	P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocReq;	/* All IEs generated from supplicant. */
+	P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocReq;	/* All IEs generated from supplicant. */
+} P2P_FUNCTION_LINKER, *P_P2P_FUNCTION_LINKER;
+
+#endif
+
+/*
+ *State Machine:
+ *-->STOP: Turn on/off WiFi
+ *-->DISABLE: Screen was off (wlanHandleSystemSuspend)
+ *-->ENABLE: Screen was on (wlanHandleSystemResume)
+ *----->clear DISABLE
+ *-->RUNNING: Screen was on && Tx/Rx was ongoing (wlanHardStartXmit/kalRxIndicatePkts)
+*/
+struct GL_PER_MON_T {
+	TIMER_T rPerfMonTimer;
+	ULONG ulPerfMonFlag;
+	ULONG ulLastTxBytes;
+	ULONG ulLastRxBytes;
+	ULONG ulP2PLastTxBytes;
+	ULONG ulP2PLastRxBytes;
+	/*in bps*/
+	ULONG ulThroughput;
+	/*in ms*/
+	UINT32 u4UpdatePeriod;
+	UINT32 u4TarPerfLevel;
+	UINT32 u4CurrPerfLevel;
+};
+
+/*
+ * Major ADAPTER structure
+ * Major data structure for driver operation
+ */
+struct _ADAPTER_T {
+	UINT_8 ucRevID;
+
+	UINT_16 u2NicOpChnlNum;
+
+	BOOLEAN fgIsEnableWMM;
+	BOOLEAN fgIsWmmAssoc;	/* This flag is used to indicate that WMM is enable in current BSS */
+
+	UINT_32 u4OsPacketFilter;	/* packet filter used by OS */
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	UINT_32 u4CSUMFlags;
+#endif				/* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+	ENUM_BAND_T aePreferBand[NETWORK_TYPE_INDEX_NUM];
+
+	/* ADAPTER flags */
+	UINT_32 u4Flags;
+	UINT_32 u4HwFlags;
+
+	BOOLEAN fgIsRadioOff;
+
+	BOOLEAN fgIsEnterD3ReqIssued;
+
+	UINT_8 aucMacAddress[MAC_ADDR_LEN];
+
+	ENUM_PHY_TYPE_INDEX_T eCurrentPhyType;	/* Current selection basing on the set of Available PHY Types */
+
+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG
+	UINT_32 u4CoalescingBufCachedSize;
+	PUINT_8 pucCoalescingBufCached;
+#endif				/* CFG_COALESCING_BUFFER_SIZE */
+
+	/* Buffer for CMD_INFO_T, Mgt packet and mailbox message */
+	BUF_INFO_T rMgtBufInfo;
+	BUF_INFO_T rMsgBufInfo;
+	PUINT_8 pucMgtBufCached;
+	UINT_32 u4MgtBufCachedSize;
+	UINT_8 aucMsgBuf[MSG_BUFFER_SIZE];
+#if CFG_DBG_MGT_BUF
+	UINT_32 u4MemAllocDynamicCount;	/* Debug only */
+	UINT_32 u4MemFreeDynamicCount;	/* Debug only */
+#endif
+
+	STA_RECORD_T arStaRec[CFG_STA_REC_NUM];
+
+	/* Element for TX PATH */
+	TX_CTRL_T rTxCtrl;
+	QUE_T rFreeCmdList;
+	CMD_INFO_T arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM];
+
+	/* Element for RX PATH */
+	RX_CTRL_T rRxCtrl;
+
+	P_SDIO_CTRL_T prSDIOCtrl;
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	/* Element for MT6620 E1 HIFSYS workaround */
+	BOOLEAN fgIsClockGatingEnabled;
+#endif
+
+	/* Buffer for Authentication Event */
+	/* <Todo> Move to glue layer and refine the kal function */
+	/* Reference to rsnGeneratePmkidIndication function at rsn.c */
+	UINT_8 aucIndicationEventBuffer[(CFG_MAX_PMKID_CACHE * 20) + 8];
+
+	UINT_32 u4IntStatus;
+
+	ENUM_ACPI_STATE_T rAcpiState;
+
+	BOOLEAN fgIsIntEnable;
+	BOOLEAN fgIsIntEnableWithLPOwnSet;
+
+	BOOLEAN fgIsFwOwn;
+	BOOLEAN fgWiFiInSleepyState;
+
+	UINT_32 u4PwrCtrlBlockCnt;
+
+	QUE_T rPendingCmdQueue;
+
+	P_GLUE_INFO_T prGlueInfo;
+
+	UINT_8 ucCmdSeqNum;
+	UINT_8 ucTxSeqNum;
+
+#if 1				/* CFG_SUPPORT_WAPI */
+	BOOLEAN fgUseWapi;
+#endif
+
+	/* RF Test flags */
+	BOOLEAN fgTestMode;
+
+	/* WLAN Info for DRIVER_CORE OID query */
+	WLAN_INFO_T rWlanInfo;
+
+#if CFG_ENABLE_WIFI_DIRECT
+	BOOLEAN fgIsP2PRegistered;
+	ENUM_NET_REG_STATE_T rP2PNetRegState;
+	BOOLEAN fgIsWlanLaunched;
+	P_P2P_INFO_T prP2pInfo;
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+	OS_SYSTIME rP2pLinkQualityUpdateTime;
+	BOOLEAN fgIsP2pLinkQualityValid;
+	EVENT_LINK_QUALITY rP2pLinkQuality;
+#endif
+
+	/* FSM Timer */
+	TIMER_T rP2pFsmTimeoutTimer;
+#endif
+
+	/* Online Scan Option */
+	BOOLEAN fgEnOnlineScan;
+
+	/* Online Scan Option */
+	BOOLEAN fgDisBcnLostDetection;
+
+	/* MAC address */
+	PARAM_MAC_ADDRESS rMyMacAddr;
+
+	/* Wake-up Event for WOL */
+	UINT_32 u4WakeupEventEnable;
+
+	/* Event Buffering */
+	EVENT_STATISTICS rStatStruct;
+	OS_SYSTIME rStatUpdateTime;
+	BOOLEAN fgIsStatValid;
+
+	EVENT_LINK_QUALITY rLinkQuality;
+	OS_SYSTIME rLinkQualityUpdateTime;
+	BOOLEAN fgIsLinkQualityValid;
+	OS_SYSTIME rLinkRateUpdateTime;
+	BOOLEAN fgIsLinkRateValid;
+
+	/* WIFI_VAR_T */
+	WIFI_VAR_T rWifiVar;
+
+	/* MTK WLAN NIC driver IEEE 802.11 MIB */
+	IEEE_802_11_MIB_T rMib;
+
+	/* Mailboxs for inter-module communication */
+	MBOX_T arMbox[MBOX_ID_TOTAL_NUM];
+
+	/* Timers for OID Pending Handling */
+	TIMER_T rOidTimeoutTimer;
+
+	TIMER_T rReturnIndicatedRfbListTimer;
+
+	/* Root Timer for cnm_timer module */
+	ROOT_TIMER rRootTimer;
+
+	/* RLM maintenance */
+	ENUM_CHNL_EXT_T eRfSco;
+	ENUM_SYS_PROTECT_MODE_T eSysProtectMode;
+	ENUM_GF_MODE_T eSysHtGfMode;
+	ENUM_RIFS_MODE_T eSysTxRifsMode;
+	ENUM_SYS_PCO_PHASE_T eSysPcoPhase;
+
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+
+	/* QM */
+	QUE_MGT_T rQM;
+
+	CNM_INFO_T rCnmInfo;
+
+	UINT_32 u4PowerMode;
+
+	UINT_32 u4CtiaPowerMode;
+	BOOLEAN fgEnCtiaPowerMode;
+
+	UINT_32 fgEnArpFilter;
+
+	UINT_32 u4UapsdAcBmp;
+
+	UINT_32 u4MaxSpLen;
+
+	UINT_32 u4PsCurrentMeasureEn;
+
+	/* Version Information */
+	WIFI_VER_INFO_T rVerInfo;
+
+	/* 5GHz support (from F/W) */
+	BOOLEAN fgIsHw5GBandDisabled;
+	BOOLEAN fgEnable5GBand;
+	BOOLEAN fgIsEepromUsed;
+	BOOLEAN fgIsEfuseValid;
+	BOOLEAN fgIsEmbbededMacAddrValid;
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+	BOOLEAN fgIsPowerLimitTableValid;
+#endif
+
+	/* Packet Forwarding Tracking */
+	INT_32 i4PendingFwdFrameCount;
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+	UINT_8 ucRddStatus;
+#endif
+
+	BOOLEAN fgDisStaAgingTimeoutDetection;
+#if CFG_SUPPORT_CFG_FILE
+	P_WLAN_CFG_T prWlanCfg;
+	WLAN_CFG_T rWlanCfg;
+#endif
+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT
+	KAL_WAKE_LOCK_T rApWakeLock;
+#endif
+	UINT_32 u4FwCompileFlag0;
+	UINT_32 u4FwCompileFlag1;
+	KAL_WAKE_LOCK_T rTxThreadWakeLock;
+	KAL_WAKE_LOCK_T rAhbIsrWakeLock;
+
+#if CFG_SUPPORT_ROAMING_ENC
+	BOOLEAN fgIsRoamingEncEnabled;
+#endif				/* CFG_SUPPORT_ROAMING_ENC */
+
+#if (CFG_SUPPORT_TDLS == 1)
+	BOOLEAN fgTdlsIsSup;
+#endif				/* CFG_SUPPORT_TDLS */
+
+	UINT_8 ucScanTime;
+
+#if CFG_SUPPORT_DBG_POWERMODE
+	BOOLEAN fgEnDbgPowerMode;	/*  dbg privilege power mode, always keep in active */
+#endif
+
+	UINT_32 u4AirDelayTotal;	/*  dbg privilege power mode, always keep in active */
+	ULONG	ulSuspendFlag;
+	struct GL_PER_MON_T rPerMonitor;
+};				/* end of _ADAPTER_T */
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define SUSPEND_FLAG_FOR_WAKEUP_REASON	(0)
+#define SUSPEND_FLAG_CLEAR_WHEN_RESUME	(1)
+
+/*----------------------------------------------------------------------------*/
+/* Macros for BSS_INFO_T - Flag of Net Active                                 */
+/*----------------------------------------------------------------------------*/
+#define IS_NET_ACTIVE(_prAdapter, _NetTypeIndex) \
+		(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive)
+#define IS_BSS_ACTIVE(_prBssInfo)     ((_prBssInfo)->fgIsNetActive)
+
+#define IS_AIS_ACTIVE(_prAdapter)     IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_AIS_INDEX)
+#define IS_P2P_ACTIVE(_prAdapter)     IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_P2P_INDEX)
+#define IS_BOW_ACTIVE(_prAdapter)     IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_BOW_INDEX)
+
+#define SET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \
+	{_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = TRUE; }
+
+#define UNSET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \
+	{_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = FALSE; }
+
+#define BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \
+		{   UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; \
+		    P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \
+		    \
+		    _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \
+		    _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \
+		    _prBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; \
+		    _prBssInfo->fgIsNetActive = FALSE; \
+		    _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \
+		    _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \
+		    COPY_MAC_ADDR(_prBssInfo->aucBSSID, _aucZeroMacAddr); \
+		    LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \
+		    _prBssInfo->fgIsBeaconActivated = FALSE; \
+		    _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \
+		    _prBssInfo->fgIsNetAbsent = FALSE; \
+		}
+
+#if CFG_ENABLE_BT_OVER_WIFI
+#define BOW_BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \
+		{  \
+		    P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \
+		    \
+		    _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \
+		    _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \
+		    _prBssInfo->eCurrentOPMode = OP_MODE_BOW; \
+		    _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \
+		    _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \
+		    LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \
+		    _prBssInfo->fgIsBeaconActivated = TRUE; \
+		    _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \
+		    _prBssInfo->fgIsNetAbsent = FALSE; \
+		}
+#endif
+
+#define PERF_MON_DISABLE_BIT_OFF    (0)
+#define PERF_MON_STOP_BIT_OFF       (1)
+#define PERF_MON_RUNNING_BIT_OFF    (2)
+
+#define THROUGHPUT_L1_THRESHOLD		(20*1024*1024)
+#define THROUGHPUT_L2_THRESHOLD		(60*1024*1024)
+#define THROUGHPUT_L3_THRESHOLD		(135*1024*1024)
+
+/*----------------------------------------------------------------------------*/
+/* Macros for Power State                                                     */
+/*----------------------------------------------------------------------------*/
+#define SET_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \
+	{_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_IDLE; }
+
+#define SET_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \
+	{_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_ACTIVE; }
+
+#define SET_NET_PWR_STATE_PS(_prAdapter, _NetTypeIndex) \
+	{_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_PS; }
+
+#define IS_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \
+	(_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_ACTIVE)
+
+#define IS_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \
+	(_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_IDLE)
+
+#define IS_SCN_PWR_STATE_ACTIVE(_prAdapter) \
+	(_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_ACTIVE)
+
+#define IS_SCN_PWR_STATE_IDLE(_prAdapter) \
+	(_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_IDLE)
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _ADAPTER_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h
new file mode 100644
index 0000000000000..6c4c1b76622b2
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h
@@ -0,0 +1,322 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/bow.h#1
+*/
+
+/*
+** Log: bow.h
+ *
+ * 01 16 2012 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support BOW for 5GHz band.
+ *
+ * 05 25 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Add BoW Cancel Scan Request and Turn On deactive network function.
+ *
+ * 05 22 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Submit missing BoW header files.
+ *
+ * 03 27 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support multiple physical link.
+ *
+ * 03 06 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Sync BOW Driver to latest person development branch version..
+ *
+ * 02 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix kernel API change issue.
+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is
+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock);
+ * After ALPS 2.3, kfifo_alloc() is changed to
+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask);
+ *
+ * 02 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update BOW structure.
+ *
+ * 02 09 2011 cp.wu
+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3
+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031
+ * with BOW and P2P enabled as default
+ *
+ * 02 08 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in.
+ * Update BOW get MAC status, remove returning event for AIS network type.
+ *
+ * 01 11 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add Activity Report definition.
+ *
+ * 10 18 2010 chinghwa.yu
+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size
+ * Fix wrong BoW event size.
+ *
+ * 07 15 2010 cp.wu
+ *
+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * 1) all BT physical handles shares the same RSSI/Link Quality.
+ * 2) simplify BT command composing
+ *
+ * 04 28 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change prefix for data structure used to communicate with 802.11 PAL
+ * to avoid ambiguous naming with firmware interface
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * basic implementation for EVENT_BT_OVER_WIFI
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 09 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * sync. with design document for interface change.
+ *
+ * 04 02 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * Wi-Fi driver no longer needs to implement 802.11 PAL, thus replaced by wrapping command/event definitions
+ *
+ * 03 16 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * correct typo.
+ *
+ * 03 16 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * update for all command/event needed to be supported by 802.11 PAL.
+ *
+ * 03 16 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * build up basic data structure and definitions to support BT-over-WiFi
+ *
+*/
+
+#ifndef _BOW_H_
+#define _BOW_H_
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define BOWDEVNAME          "bow0"
+
+#define MAX_BOW_NUMBER_OF_CHANNEL_2G4            14
+#define MAX_BOW_NUMBER_OF_CHANNEL_5G              4
+/* (MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) */
+#define MAX_BOW_NUMBER_OF_CHANNEL                    18
+
+#define MAX_ACTIVITY_REPORT                                    2
+#define MAX_ACTIVITY_REPROT_TIME                          660
+
+#define ACTIVITY_REPORT_STATUS_SUCCESS              0
+#define ACTIVITY_REPORT_STATUS_FAILURE               1
+#define ACTIVITY_REPORT_STATUS_TIME_INVALID     2
+#define ACTIVITY_REPORT_STATUS_OTHERS                3
+
+#define ACTIVITY_REPORT_SCHEDULE_UNKNOWN        0	/* Does not know the schedule of the interference */
+#define ACTIVITY_REPORT_SCHEDULE_KNOWN             1
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _BT_OVER_WIFI_COMMAND_HEADER_T {
+	UINT_8 ucCommandId;
+	UINT_8 ucSeqNumber;
+	UINT_16 u2PayloadLength;
+} AMPC_COMMAND_HEADER_T, *P_AMPC_COMMAND_HEADER_T;
+
+typedef struct _BT_OVER_WIFI_COMMAND {
+	AMPC_COMMAND_HEADER_T rHeader;
+	UINT_8 aucPayload[0];
+} AMPC_COMMAND, *P_AMPC_COMMAND;
+
+typedef struct _BT_OVER_WIFI_EVENT_HEADER_T {
+	UINT_8 ucEventId;
+	UINT_8 ucSeqNumber;
+	UINT_16 u2PayloadLength;
+} AMPC_EVENT_HEADER_T, *P_AMPC_EVENT_HEADER_T;
+
+typedef struct _BT_OVER_WIFI_EVENT {
+	AMPC_EVENT_HEADER_T rHeader;
+	UINT_8 aucPayload[0];
+} AMPC_EVENT, *P_AMPC_EVENT;
+
+typedef struct _CHANNEL_DESC_T {
+	UINT_8 ucChannelBand;
+	UINT_8 ucChannelNum;
+} CHANNEL_DESC, P_CHANNEL_DESC;
+
+/* Command Structures */
+typedef struct _BOW_SETUP_CONNECTION {
+/* Fixed to 2.4G */
+	UINT_8 ucChannelNum;
+	UINT_8 ucReserved1;
+	UINT_8 aucPeerAddress[6];
+	UINT_16 u2BeaconInterval;
+	UINT_8 ucTimeoutDiscovery;
+	UINT_8 ucTimeoutInactivity;
+	UINT_8 ucRole;
+	UINT_8 ucPAL_Capabilities;
+	INT_8 cMaxTxPower;
+	UINT_8 ucReserved2;
+
+/* Pending, for future BOW 5G supporting. */
+/*    UINT_8          aucPeerAddress[6];
+    UINT_16         u2BeaconInterval;
+    UINT_8          ucTimeoutDiscovery;
+    UINT_8          ucTimeoutInactivity;
+    UINT_8          ucRole;
+    UINT_8          ucPAL_Capabilities;
+    INT_8           cMaxTxPower;
+    UINT_8          ucChannelListNum;
+    CHANNEL_DESC    arChannelList[1];
+*/
+} BOW_SETUP_CONNECTION, *P_BOW_SETUP_CONNECTION;
+
+typedef struct _BOW_DESTROY_CONNECTION {
+	UINT_8 aucPeerAddress[6];
+	UINT_8 aucReserved[2];
+} BOW_DESTROY_CONNECTION, *P_BOW_DESTROY_CONNECTION;
+
+typedef struct _BOW_SET_PTK {
+	UINT_8 aucPeerAddress[6];
+	UINT_8 aucReserved[2];
+	UINT_8 aucTemporalKey[16];
+} BOW_SET_PTK, *P_BOW_SET_PTK;
+
+typedef struct _BOW_READ_RSSI {
+	UINT_8 aucPeerAddress[6];
+	UINT_8 aucReserved[2];
+} BOW_READ_RSSI, *P_BOW_READ_RSSI;
+
+typedef struct _BOW_READ_LINK_QUALITY {
+	UINT_8 aucPeerAddress[6];
+	UINT_8 aucReserved[2];
+} BOW_READ_LINK_QUALITY, *P_BOW_READ_LINK_QUALITY;
+
+typedef struct _BOW_SHORT_RANGE_MODE {
+	UINT_8 aucPeerAddress[6];
+	INT_8 cTxPower;
+	UINT_8 ucReserved;
+} BOW_SHORT_RANGE_MODE, *P_BOW_SHORT_RANGE_MODE;
+
+/* Event Structures */
+typedef struct _BOW_COMMAND_STATUS {
+	UINT_8 ucStatus;
+	UINT_8 ucReserved[3];
+} BOW_COMMAND_STATUS, *P_BOW_COMMAND_STATUS;
+
+typedef struct _BOW_MAC_STATUS {
+	UINT_8 aucMacAddr[6];
+	UINT_8 ucAvailability;
+	UINT_8 ucNumOfChannel;
+	CHANNEL_DESC arChannelList[MAX_BOW_NUMBER_OF_CHANNEL];
+} BOW_MAC_STATUS, *P_BOW_MAC_STATUS;
+
+typedef struct _BOW_LINK_CONNECTED {
+	CHANNEL_DESC rChannel;
+	UINT_8 aucReserved;
+	UINT_8 aucPeerAddress[6];
+} BOW_LINK_CONNECTED, *P_BOW_LINK_CONNECTED;
+
+typedef struct _BOW_LINK_DISCONNECTED {
+	UINT_8 ucReason;
+	UINT_8 aucReserved;
+	UINT_8 aucPeerAddress[6];
+} BOW_LINK_DISCONNECTED, *P_BOW_LINK_DISCONNECTED;
+
+typedef struct _BOW_RSSI {
+	INT_8 cRssi;
+	UINT_8 aucReserved[3];
+} BOW_RSSI, *P_BOW_RSSI;
+
+typedef struct _BOW_LINK_QUALITY {
+	UINT_8 ucLinkQuality;
+	UINT_8 aucReserved[3];
+} BOW_LINK_QUALITY, *P_BOW_LINK_QUALITY;
+
+typedef enum _ENUM_BOW_CMD_ID_T {
+	BOW_CMD_ID_GET_MAC_STATUS = 1,
+	BOW_CMD_ID_SETUP_CONNECTION,
+	BOW_CMD_ID_DESTROY_CONNECTION,
+	BOW_CMD_ID_SET_PTK,
+	BOW_CMD_ID_READ_RSSI,
+	BOW_CMD_ID_READ_LINK_QUALITY,
+	BOW_CMD_ID_SHORT_RANGE_MODE,
+	BOW_CMD_ID_GET_CHANNEL_LIST,
+} ENUM_BOW_CMD_ID_T, *P_ENUM_BOW_CMD_ID_T;
+
+typedef enum _ENUM_BOW_EVENT_ID_T {
+	BOW_EVENT_ID_COMMAND_STATUS = 1,
+	BOW_EVENT_ID_MAC_STATUS,
+	BOW_EVENT_ID_LINK_CONNECTED,
+	BOW_EVENT_ID_LINK_DISCONNECTED,
+	BOW_EVENT_ID_RSSI,
+	BOW_EVENT_ID_LINK_QUALITY,
+	BOW_EVENT_ID_CHANNEL_LIST,
+	BOW_EVENT_ID_CHANNEL_SELECTED,
+} ENUM_BOW_EVENT_ID_T, *P_ENUM_BOW_EVENT_ID_T;
+
+typedef enum _ENUM_BOW_DEVICE_STATE {
+	BOW_DEVICE_STATE_DISCONNECTED = 0,
+	BOW_DEVICE_STATE_DISCONNECTING,
+	BOW_DEVICE_STATE_ACQUIRING_CHANNEL,
+	BOW_DEVICE_STATE_STARTING,
+	BOW_DEVICE_STATE_SCANNING,
+	BOW_DEVICE_STATE_CONNECTING,
+	BOW_DEVICE_STATE_CONNECTED,
+	BOW_DEVICE_STATE_NUM
+} ENUM_BOW_DEVICE_STATE, *P_ENUM_BOW_DEVICE_STATE;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+#endif /*_BOW_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h
new file mode 100644
index 0000000000000..c1ecb303b877f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h
@@ -0,0 +1,150 @@
+/*
+** Id:
+*/
+
+/*! \file   "cmd_buf.h"
+    \brief  In this file we define the structure for Command Packet.
+
+		In this file we define the structure for Command Packet and the control unit
+    of MGMT Memory Pool.
+*/
+
+/*
+** Log: cmd_buf.h
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by
+ * ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 13 2010 cp.wu
+ *
+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow
+ * under concurrent network operation
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Enable change log
+*/
+
+#ifndef _CMD_BUF_H
+#define _CMD_BUF_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _COMMAND_TYPE {
+	COMMAND_TYPE_GENERAL_IOCTL,
+	COMMAND_TYPE_NETWORK_IOCTL,
+	COMMAND_TYPE_SECURITY_FRAME,
+	COMMAND_TYPE_MANAGEMENT_FRAME,
+	COMMAND_TYPE_NUM
+} COMMAND_TYPE, *P_COMMAND_TYPE;
+
+typedef VOID(*PFN_CMD_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+typedef VOID(*PFN_CMD_TIMEOUT_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+struct _CMD_INFO_T {
+	QUE_ENTRY_T rQueEntry;
+
+	COMMAND_TYPE eCmdType;
+
+	UINT_16 u2InfoBufLen;	/* This is actual CMD buffer length */
+	PUINT_8 pucInfoBuffer;	/* May pointer to structure in prAdapter */
+	P_NATIVE_PACKET prPacket;	/* only valid when it's a security frame */
+
+	ENUM_NETWORK_TYPE_INDEX_T eNetworkType;
+	UINT_8 ucStaRecIndex;	/* only valid when it's a security frame */
+
+	PFN_CMD_DONE_HANDLER pfCmdDoneHandler;
+	PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler;
+
+	BOOLEAN fgIsOid;	/* Used to check if we need indicate */
+
+	UINT_8 ucCID;
+	BOOLEAN fgSetQuery;
+	BOOLEAN fgNeedResp;
+	BOOLEAN fgDriverDomainMCR;	/* Access Driver Domain MCR, for CMD_ID_ACCESS_REG only */
+	UINT_8 ucCmdSeqNum;
+	UINT_32 u4SetInfoLen;	/* Indicate how many byte we read for Set OID */
+
+	/* information indicating by OID/ioctl */
+	PVOID pvInformationBuffer;
+	UINT_32 u4InformationBufferLength;
+
+	/* private data */
+	UINT_32 u4PrivateData;
+};
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter);
+
+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length);
+
+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+/*----------------------------------------------------------------------------*/
+/* Routines for CMDs                                                          */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter,
+		    UINT_8 ucCID,
+		    BOOLEAN fgSetQuery,
+		    BOOLEAN fgNeedResp,
+		    BOOLEAN fgIsOid,
+		    PFN_CMD_DONE_HANDLER pfCmdDoneHandler,
+		    PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler,
+		    UINT_32 u4SetQueryInfoLen,
+		    PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen);
+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName);
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _CMD_BUF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h
new file mode 100644
index 0000000000000..0fdb9dcadeeff
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h
@@ -0,0 +1,618 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hal.h#1
+*/
+
+/*! \file   "hal.h"
+    \brief  The declaration of hal functions
+
+    N/A
+*/
+
+/*
+** Log: hal.h
+ *
+ * 04 01 2011 tsaiyuan.hsu
+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues
+ * fix the klocwork issues, 57500, 57501, 57502 and 57503.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability improvement
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 11 08 2010 cp.wu
+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart()
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change zero-padding for TX port access to HAL.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  *  *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  *  *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  *  *  * 4. correct some HAL implementation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-16 18:02:26 GMT mtk02752
+**  include precomp.h
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:16 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 13:54:15 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-11 10:36:01 GMT mtk01084
+**  modify HAL functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-09 22:56:28 GMT mtk01084
+**  modify HW access routines
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:50:09 GMT mtk01084
+**  add new macro HAL_TX_PORT_WR
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:08:10 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:50 GMT mtk01084
+**  update for new HW architecture design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-05-18 14:28:10 GMT mtk01084
+**  fix issue in HAL_DRIVER_OWN_BY_SDIO_CMD52()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-11 17:26:33 GMT mtk01084
+**  modify the bit definition to check driver own status
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:30:22 GMT mtk01461
+**  Fix typo
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:50:34 GMT mtk01461
+**  Redefine HAL_PORT_RD/WR macro for SW pre test
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-24 09:46:49 GMT mtk01084
+**  fix LINT error
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 16:53:38 GMT mtk01084
+**  add HAL_DRIVER_OWN_BY_SDIO_CMD52()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:53:13 GMT mtk01426
+**  Fixed lint warn
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:20 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _HAL_H
+#define _HAL_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/* Macros for flag operations for the Adapter structure */
+#define HAL_SET_FLAG(_M, _F)             ((_M)->u4HwFlags |= (_F))
+#define HAL_CLEAR_FLAG(_M, _F)           ((_M)->u4HwFlags &= ~(_F))
+#define HAL_TEST_FLAG(_M, _F)            ((_M)->u4HwFlags & (_F))
+#define HAL_TEST_FLAGS(_M, _F)           (((_M)->u4HwFlags & (_F)) == (_F))
+
+#if defined(_HIF_SDIO)
+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \
+do { \
+	if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \
+		if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+			ASSERT(0); \
+		} \
+		if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) == FALSE) {\
+			HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \
+			fgIsBusAccessFailed = TRUE; \
+			/* DBGLOG(HAL, ERROR, ("HAL_MCR_RD access fail! 0x%x: 0x%x\n", */ \
+				/* (UINT32)_u4Offset, (UINT32)*_pu4Value)); */ \
+		} \
+	} else { \
+		/* DBGLOG(HAL, WARN, ("ignore HAL_MCR_RD access! 0x%x\n", (UINT32)_u4Offset)); */ \
+	} \
+} while (0)
+
+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \
+do { \
+	if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \
+		if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+			ASSERT(0); \
+		} \
+		if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) == FALSE) {\
+			HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \
+			fgIsBusAccessFailed = TRUE; \
+			/* DBGLOG(HAL, ERROR, ("HAL_MCR_WR access fail! 0x%x: 0x%x\n", */ \
+				/* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \
+		} \
+	} else { \
+		/* DBGLOG(HAL, WARN, ("ignore HAL_MCR_WR access! 0x%x: 0x%x\n", */ \
+				/* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \
+	} \
+} while (0)
+
+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+{ \
+	/*fgResult = FALSE; */\
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \
+		if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+			== FALSE) {\
+			HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \
+			fgIsBusAccessFailed = TRUE; \
+			DBGLOG(HAL, ERROR, "HAL_PORT_RD access fail! 0x%x\n", _u4Port); \
+			} \
+		else { \
+			/*fgResult = TRUE;*/ } \
+	} else { \
+		DBGLOG(HAL, WARN, "ignore HAL_PORT_RD access! 0x%x\n", _u4Port); \
+	} \
+}
+
+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+{ \
+	/*fgResult = FALSE; */\
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \
+		if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+			== FALSE) {\
+			HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \
+			fgIsBusAccessFailed = TRUE; \
+			DBGLOG(HAL, ERROR, "HAL_PORT_WR access fail! 0x%x\n", _u4Port); \
+		} \
+		else { \
+		/*fgResult = TRUE;*/ } \
+	} else { \
+		DBGLOG(HAL, WARN, "ignore HAL_PORT_WR access! 0x%x\n", _u4Port); \
+	} \
+}
+
+#if 0				/* only for SDIO */
+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \
+{ \
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \
+		if (kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf) == FALSE) {\
+			HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \
+			fgIsBusAccessFailed = TRUE; \
+			DBGLOG(HAL, ERROR, "HAL_BYTE_WR access fail! 0x%x\n", _u4Port); \
+		} \
+		else { \
+			/* Todo:: Nothing*/ \
+		} \
+	} \
+	else { \
+		DBGLOG(HAL, WARN, "ignore HAL_BYTE_WR access! 0x%x\n", _u4Port); \
+	} \
+}
+#endif
+
+#define HAL_DRIVER_OWN_BY_SDIO_CMD52(_prAdapter, _pfgDriverIsOwnReady) \
+{ \
+	UINT_8 ucBuf = BIT(1); \
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \
+		if (kalDevReadAfterWriteWithSdioCmd52(_prAdapter->prGlueInfo, MCR_WHLPCR_BYTE1, &ucBuf, 1) \
+			== FALSE) {\
+			HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \
+			fgIsBusAccessFailed = TRUE; \
+			DBGLOG(HAL, ERROR, "kalDevReadAfterWriteWithSdioCmd52 access fail!\n"); \
+		} \
+	else { \
+		*_pfgDriverIsOwnReady = (ucBuf & BIT(0)) ? TRUE : FALSE; \
+		} \
+	} else { \
+		DBGLOG(HAL, WARN, "ignore HAL_DRIVER_OWN_BY_SDIO_CMD52 access!\n"); \
+	} \
+}
+
+#else /* #if defined(_HIF_SDIO) */
+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \
+{ \
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) \
+		== FALSE) \
+		fgIsBusAccessFailed = TRUE; \
+}
+
+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \
+{ \
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) \
+		== FALSE) \
+		fgIsBusAccessFailed = TRUE; \
+}
+
+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+{ \
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+		== FALSE) \
+		fgIsBusAccessFailed = TRUE; \
+}
+
+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+{ \
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+	if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \
+		== FALSE) \
+		fgIsBusAccessFailed = TRUE; \
+}
+
+#if 0				/* only for SDIO */
+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \
+{ \
+	if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \
+		ASSERT(0); \
+	} \
+kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf); \
+}
+#endif
+
+#endif /* #if defined(_HIF_SDIO) */
+
+#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \
+{ \
+	ASSERT(u4PortId < 2); \
+	HAL_PORT_RD(prAdapter, \
+			((u4PortId == 0) ? MCR_WRDR0 : MCR_WRDR1), \
+			u4Len, \
+			pvBuf, \
+			_u4ValidBufSize/*temp!!*//*4Kbyte*/); \
+}
+
+#define HAL_WRITE_TX_PORT(_prAdapter, _ucTxPortIdx, _u4Len, _pucBuf, _u4ValidBufSize) \
+{ \
+	ASSERT(_ucTxPortIdx < 2); \
+	if ((_u4ValidBufSize - _u4Len) >= sizeof(UINT_32)) { \
+		/* fill with single dword of zero as TX-aggregation termination */ \
+		*(PUINT_32) (&((_pucBuf)[ALIGN_4(_u4Len)])) = 0; \
+	} \
+	HAL_PORT_WR(_prAdapter, \
+			(_ucTxPortIdx == 0) ? MCR_WTDR0 : MCR_WTDR1, \
+			_u4Len, \
+			_pucBuf, \
+			_u4ValidBufSize/*temp!!*//*4KByte*/); \
+}
+
+/* The macro to read the given MCR several times to check if the wait
+   condition come true. */
+#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, _waitCondition, _waitDelay, _waitCount, _status) \
+{ \
+	UINT_32 count; \
+	(_status) = FALSE; \
+	for (count = 0; count < (_waitCount); count++) { \
+		HAL_MCR_RD((_pAdapter), (_offset), (_pReadValue)); \
+		if ((_waitCondition)) { \
+			(_status) = TRUE; \
+			break; \
+		} \
+		kalUdelay((_waitDelay)); \
+	} \
+}
+
+/* The macro to write 1 to a R/S bit and read it several times to check if the
+   command is done */
+#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, _busyMask, _waitDelay, _waitCount, _status) \
+{ \
+	UINT_32 u4Temp; \
+	UINT_32 u4Count = _waitCount; \
+	(_status) = FALSE; \
+	HAL_MCR_WR((_pAdapter), (_offset), (_writeValue)); \
+	do { \
+		kalUdelay((_waitDelay)); \
+		HAL_MCR_RD((_pAdapter), (_offset), &u4Temp); \
+		if (!(u4Temp & (_busyMask))) { \
+			(_status) = TRUE; \
+			break; \
+		} \
+		u4Count--; \
+	} while (u4Count); \
+}
+
+#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \
+{ \
+	UINT_32 u4Value; \
+	HAL_MCR_RD(_prAdapter, \
+			MCR_WCIR, \
+			&u4Value); \
+	*pu2ChipId = (UINT_16)(u4Value & WCIR_CHIP_ID); \
+	*pu2Version = (UINT_16)(u4Value & WCIR_REVISION_ID) >> 16; \
+}
+
+#define HAL_WAIT_WIFI_FUNC_READY(_prAdapter) \
+{ \
+	UINT_32 u4Value; \
+	UINT_32 i; \
+	for (i = 0; i < 100; i++) { \
+		HAL_MCR_RD(_prAdapter, \
+			MCR_WCIR, \
+			&u4Value); \
+		if (u4Value & WCIR_WLAN_READY) { \
+			break; \
+		} \
+	NdisMSleep(10); \
+	} \
+}
+
+#define HAL_INTR_DISABLE(_prAdapter) \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHLPCR, \
+			WHLPCR_INT_EN_CLR)
+
+#define HAL_INTR_ENABLE(_prAdapter) \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHLPCR, \
+			WHLPCR_INT_EN_SET)
+
+#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHLPCR, \
+			(WHLPCR_INT_EN_SET | WHLPCR_FW_OWN_REQ_SET))
+
+#define HAL_LP_OWN_SET(_prAdapter) \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHLPCR, \
+			WHLPCR_FW_OWN_REQ_SET)
+
+#define HAL_LP_OWN_CLR_OK(_prAdapter, _pfgResult) \
+{ \
+	UINT_32 i; \
+	UINT_32 u4RegValue; \
+	UINT_32 u4LoopCnt = 2048 / 8; \
+	*_pfgResult = TRUE; \
+	/* Software get LP ownership */ \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHLPCR, \
+			WHLPCR_FW_OWN_REQ_CLR) \
+	for (i = 0; i < u4LoopCnt; i++) { \
+		HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \
+		if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \
+			break; \
+		} \
+		else { \
+			kalUdelay(8); \
+		} \
+	} \
+	if (i == u4LoopCnt) { \
+		*_pfgResult = FALSE; \
+		/*ERRORLOG(("LP cannot be own back (%ld)", u4LoopCnt));*/ \
+		/* check the time of LP instructions need to perform from Sleep to On */ \
+		/*ASSERT(0); */ \
+	} \
+}
+
+#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) \
+{ \
+	HAL_MCR_RD(_prAdapter, \
+			MCR_WASR, \
+			pu4AbnormalReason); \
+}
+
+#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) \
+{ \
+	UINT_32 u4Value; \
+	HAL_MCR_RD(_prAdapter, \
+			MCR_WHCR, \
+			&u4Value); \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHCR, \
+			u4Value & ~WHCR_RX_ENHANCE_MODE_EN); \
+}
+
+#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) \
+{ \
+	UINT_32 u4Value; \
+	HAL_MCR_RD(_prAdapter, \
+			MCR_WHCR, \
+			&u4Value); \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHCR, \
+			u4Value | WHCR_RX_ENHANCE_MODE_EN); \
+}
+
+#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) \
+{ \
+	UINT_32 u4Value, ucNum; \
+	ucNum = ((_ucNumOfRxLen >= 16) ? 0 : _ucNumOfRxLen); \
+	u4Value = 0; \
+	HAL_MCR_RD(_prAdapter, \
+			MCR_WHCR, \
+			&u4Value); \
+	u4Value &= ~WHCR_MAX_HIF_RX_LEN_NUM; \
+	u4Value |= ((((UINT_32)ucNum) << 4) & WHCR_MAX_HIF_RX_LEN_NUM); \
+	HAL_MCR_WR(_prAdapter, \
+			MCR_WHCR, \
+			u4Value); \
+}
+
+#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) \
+{ \
+	UINT_32 u4Value; \
+	HAL_MCR_RD(prAdapter, \
+			MCR_WHCR, \
+			&u4Value); \
+	HAL_MCR_WR(prAdapter, \
+			MCR_WHCR, \
+			u4Value & ~WHCR_W_INT_CLR_CTRL); \
+	prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = TRUE;\
+}
+
+#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) \
+{ \
+	UINT_32 u4Value; \
+	HAL_MCR_RD(prAdapter, \
+			MCR_WHCR, \
+			&u4Value); \
+	HAL_MCR_WR(prAdapter, \
+			MCR_WHCR, \
+			u4Value | WHCR_W_INT_CLR_CTRL); \
+	prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = FALSE;\
+}
+
+/* Note: enhance mode structure may also carried inside the buffer,
+	 if the length of the buffer is long enough */
+#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) \
+	HAL_PORT_RD(prAdapter, \
+			MCR_WHISR, \
+			length, \
+			pvBuf, \
+			length)
+
+#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, aucTxReleaseCount) \
+{ \
+	PUINT_32 pu4Value = (PUINT_32)aucTxReleaseCount; \
+	HAL_MCR_RD(_prAdapter, \
+			MCR_WTSR0, \
+			&pu4Value[0]); \
+	HAL_MCR_RD(_prAdapter, \
+			MCR_WTSR1, \
+			&pu4Value[1]); \
+}
+
+#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) \
+{ \
+	UINT_32 u4Value; \
+	u4Value = 0; \
+	HAL_MCR_RD(prAdapter, \
+			MCR_WRPLR, \
+			&u4Value); \
+	*pu2Rx0Len = (UINT_16)u4Value; \
+	*pu2Rx1Len = (UINT_16)(u4Value >> 16); \
+}
+
+#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, u2Len, pu4Status) \
+{ \
+	PUINT_32 pu4Buf = (PUINT_32)pvBuf; \
+	*pu4Status = pu4Buf[0]; \
+}
+
+#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4BufOut, u4LenBufOut) \
+{ \
+	PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \
+	ASSERT(u4LenBufOut >= 8); \
+	pu4BufOut[0] = pu4Buf[1]; \
+	pu4BufOut[1] = pu4Buf[2]; \
+}
+
+#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) \
+{ \
+	PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \
+	ASSERT((sizeof(au2Rx0Len) / sizeof(UINT_16)) >= 16); \
+	ASSERT((sizeof(au2Rx1Len) / sizeof(UINT_16)) >= 16); \
+	*pu2Rx0Num = (UINT_16)pu4Buf[3]; \
+	*pu2Rx1Num = (UINT_16)(pu4Buf[3] >> 16); \
+	kalMemCopy(au2Rx0Len, &pu4Buf[4], 8); \
+	kalMemCopy(au2Rx1Len, &pu4Buf[12], 8); \
+}
+
+#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4Mailbox0, pu4Mailbox1) \
+{ \
+	PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \
+	*pu4Mailbox0 = (UINT_16)pu4Buf[21]; \
+	*pu4Mailbox1 = (UINT_16)pu4Buf[22]; \
+}
+
+#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \
+	((u4IntrStatus & WHISR_TX_DONE_INT) ? TRUE : FALSE)
+
+#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \
+	((u4IntrStatus & (WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)) ? TRUE : FALSE)
+
+#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) \
+	((u4IntrStatus & WHISR_ABNORMAL_INT) ? TRUE : FALSE)
+
+#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) \
+	((u4IntrStatus & WHISR_FW_OWN_BACK_INT) ? TRUE : FALSE)
+
+#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) \
+{ \
+	ASSERT(u4MboxId < 2); \
+	HAL_MCR_WR(prAdapter, \
+			((u4MboxId == 0) ? MCR_H2DSM0R : MCR_H2DSM1R), \
+			u4Data); \
+}
+
+#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) \
+{ \
+	ASSERT(u4MboxId < 2); \
+	HAL_MCR_RD(prAdapter, \
+			((u4MboxId == 0) ? MCR_D2HRM0R : MCR_D2HRM1R), \
+			pu4Data); \
+}
+
+#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \
+{ \
+	UINT_32 u4Value; \
+	HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);\
+	HAL_MCR_WR(prAdapter, MCR_WHCR, \
+			(fgEnableReadClear) ? \
+			(u4Value | WHCR_W_MAILBOX_RD_CLR_EN) : \
+			(u4Value & ~WHCR_W_MAILBOX_RD_CLR_EN)); \
+	prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\
+}
+
+#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear)
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _HAL_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h
new file mode 100644
index 0000000000000..b9aa154b097ef
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h
@@ -0,0 +1,220 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_rx.h#1
+*/
+
+/*! \file   "hif_rx.h"
+    \brief  Provide HIF RX Header Information between F/W and Driver
+
+    N/A
+*/
+
+/*
+** Log: hif_rx.h
+ *
+ * 09 01 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 07 16 2010 yarco.yang
+ *
+ * 1. Support BSS Absence/Presence Event
+ * 2. Support STA change PS mode Event
+ * 3. Support BMC forwarding for AP mode.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * follow-ups for HIF_RX_HEADER_T update:
+ * 1) add TCL
+ * 2) add RCPI
+ * 3) add ChannelNumber
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add necessary changes to driver data paths.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:44:00 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-09 13:59:20 GMT MTK02468
+**  Added HIF_RX_HDR parsing macros
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 19:54:54 GMT mtk02752
+**  adopt HIF_RX_HEADER_T in new data path
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-29 19:51:19 GMT mtk01084
+**  modify FW/ driver interface
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:33:58 GMT mtk01461
+**  Add define of HW_APPENED_LEN
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:51:02 GMT mtk01461
+**  Rename ENUM_HIF_RX_PKT_TYPE_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 12:05:03 GMT mtk01426
+**  Remove __KAL_ATTRIB_PACKED__ and add hifDataTypeCheck()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:18:52 GMT mtk01426
+**  Add comment to HIF_RX_HEADER_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:23 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _HIF_RX_H
+#define _HIF_RX_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/*! HIF_RX_HEADER_T */
+/* DW 0, Byte 1 */
+#define HIF_RX_HDR_PACKET_TYPE_MASK      BITS(0, 1)
+#define HIF_RX_HDR_SEC_MODE_MASK		 BITS(2, 5)
+#define HIF_RX_HDR_SEC_MODE_OFFSET		 2
+
+/* DW 1, Byte 0 */
+#define HIF_RX_HDR_HEADER_LEN            BITS(2, 7)
+#define HIF_RX_HDR_HEADER_LEN_OFFSET     2
+#define HIF_RX_HDR_HEADER_OFFSET_MASK    BITS(0, 1)
+
+/* DW 1, Byte 1 */
+#define HIF_RX_HDR_80211_HEADER_FORMAT   BIT(0)
+#define HIF_RX_HDR_DO_REORDER            BIT(1)
+#define HIF_RX_HDR_PAL                   BIT(2)
+#define HIF_RX_HDR_TCL                   BIT(3)
+#define HIF_RX_HDR_NETWORK_IDX_MASK      BITS(4, 7)
+#define HIF_RX_HDR_NETWORK_IDX_OFFSET    4
+
+/* DW 1, Byte 2, 3 */
+#define HIF_RX_HDR_SEQ_NO_MASK           BITS(0, 11)
+#define HIF_RX_HDR_TID_MASK              BITS(12, 14)
+#define HIF_RX_HDR_TID_OFFSET            12
+#define HIF_RX_HDR_BAR_FRAME             BIT(15)
+
+#define HIF_RX_HDR_FLAG_AMP_WDS             BIT(0)
+#define HIF_RX_HDR_FLAG_802_11_FORMAT       BIT(1)
+#define HIF_RX_HDR_FLAG_BAR_FRAME           BIT(2)
+#define HIF_RX_HDR_FLAG_DO_REORDERING       BIT(3)
+#define HIF_RX_HDR_FLAG_CTRL_WARPPER_FRAME  BIT(4)
+
+#define HIF_RX_HW_APPENDED_LEN              4
+
+/* For DW 2, Byte 3 - ucHwChannelNum */
+#define HW_CHNL_NUM_MAX_2G4                 14
+#define HW_CHNL_NUM_MAX_4G_5G               (255 - HW_CHNL_NUM_MAX_2G4)
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef struct _HIF_RX_HEADER_T {
+	UINT_16 u2PacketLen;
+	UINT_16 u2PacketType;
+	UINT_8 ucHerderLenOffset;
+	UINT_8 uc80211_Reorder_PAL_TCL;
+	UINT_16 u2SeqNoTid;
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucRcpi;
+	UINT_8 ucHwChannelNum;
+	UINT_8 ucReserved;
+} HIF_RX_HEADER_T, *P_HIF_RX_HEADER_T;
+
+typedef enum _ENUM_HIF_RX_PKT_TYPE_T {
+	HIF_RX_PKT_TYPE_DATA = 0,
+	HIF_RX_PKT_TYPE_EVENT,
+	HIF_RX_PKT_TYPE_TX_LOOPBACK,
+	HIF_RX_PKT_TYPE_MANAGEMENT,
+	HIF_RX_PKT_TYPE_NUM
+} ENUM_HIF_RX_PKT_TYPE_T, *P_ENUM_HIF_RX_PKT_TYPE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define HIF_RX_HDR_SIZE        sizeof(HIF_RX_HEADER_T)
+
+#define HIF_RX_HDR_GET_80211_FLAG(_prHifRxHdr) \
+	(((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_80211_HEADER_FORMAT) ? TRUE : FALSE))
+#define HIF_RX_HDR_GET_REORDER_FLAG(_prHifRxHdr) \
+	(((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_DO_REORDER) ? TRUE : FALSE))
+#define HIF_RX_HDR_GET_PAL_FLAG(_prHifRxHdr) \
+	(((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_PAL) ? TRUE : FALSE))
+#define HIF_RX_HDR_GET_TCL_FLAG(_prHifRxHdr) \
+	(((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_TCL) ? TRUE : FALSE))
+#define HIF_RX_HDR_GET_NETWORK_IDX(_prHifRxHdr) \
+	((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_NETWORK_IDX_MASK)\
+	>> HIF_RX_HDR_NETWORK_IDX_OFFSET)
+
+#define HIF_RX_HDR_GET_SEC_MODE(_prHifRxHdr) \
+		((((_prHifRxHdr)->u2PacketType) & HIF_RX_HDR_SEC_MODE_MASK) >> HIF_RX_HDR_SEC_MODE_OFFSET)
+
+#define HIF_RX_HDR_GET_TID(_prHifRxHdr) \
+	((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_TID_MASK)\
+	>> HIF_RX_HDR_TID_OFFSET)
+#define HIF_RX_HDR_GET_SN(_prHifRxHdr) \
+	(((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_SEQ_NO_MASK)
+#define HIF_RX_HDR_GET_BAR_FLAG(_prHifRxHdr) \
+	(((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_BAR_FRAME) ? TRUE : FALSE))
+
+#define HIF_RX_HDR_GET_CHNL_NUM(_prHifRxHdr) \
+	((((_prHifRxHdr)->ucHwChannelNum) > HW_CHNL_NUM_MAX_4G_5G) ? \
+	(((_prHifRxHdr)->ucHwChannelNum) - HW_CHNL_NUM_MAX_4G_5G) : \
+	((_prHifRxHdr)->ucHwChannelNum))
+
+/* To do: support more bands other than 2.4G and 5G */
+#define HIF_RX_HDR_GET_RF_BAND(_prHifRxHdr) \
+	((((_prHifRxHdr)->ucHwChannelNum) <= HW_CHNL_NUM_MAX_2G4) ? \
+	BAND_2G4 : BAND_5G)
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static inline VOID hifDataTypeCheck(VOID);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/* Kevin: we don't have to call following function to inspect the data structure.
+ * It will check automatically while at compile time.
+ * We'll need this for porting driver to different RTOS.
+ */
+static inline VOID hifDataTypeCheck(VOID)
+{
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_RX_HEADER_T) == 12);
+
+}
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h
new file mode 100644
index 0000000000000..17252f2c7760c
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h
@@ -0,0 +1,214 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_tx.h#1
+*/
+
+/*
+** Log: hif_tx.h
+ *
+ * 10 07 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * add firmware download for MT5931.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * fill extra information for revised HIF_TX_HEADER.
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate
+ * 2) add  packet type for indicating management frames
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code clean: removing unused variables and structure definitions
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  *  * 2. follow MSDN defined behavior when associates to another AP
+ *  *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 01 13 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled the Burst_End Indication mechanism
+ *
+ * 01 13 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:40 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-24 19:55:11 GMT mtk02752
+**  adopt HIF_TX_HEADER_T in new data path
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-23 17:54:13 GMT mtk02752
+**  CMD_HDR_SIZE = (sizeof(WIFI_CMD_T)) to follow up CM's CMD/EVENT documentation
+**
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-17 22:41:10 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-17 17:34:07 GMT mtk02752
+**  remove HIF_TX_BUFF_COUNT_TC0 (move to nic_tx.h)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-17 12:14:12 GMT mtk02752
+**  add initial value for HIF_TX_BUFF_COUNT_TC5
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-13 13:54:18 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-04 14:11:14 GMT mtk01084
+**  modify SW TX data format
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-29 19:51:53 GMT mtk01084
+**  modify FW/ driver interface
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-20 12:22:46 GMT mtk01461
+**  Add SeqNum field to CMD Header
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:40:52 GMT mtk01461
+**  Update the Log Sign
+*/
+
+#ifndef _HIF_TX_H
+#define _HIF_TX_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* Maximum buffer size for individual HIF TCQ Buffer */
+#define HIF_TX_BUFF_MAX_SIZE                1552	/* Reserved field was not included */
+
+/* Maximum buffer count for individual HIF TCQ */
+#define HIF_TX_BUFF_COUNT_TC0               3
+#define HIF_TX_BUFF_COUNT_TC1               3
+#define HIF_TX_BUFF_COUNT_TC2               3
+#define HIF_TX_BUFF_COUNT_TC3               3
+#define HIF_TX_BUFF_COUNT_TC4               2
+
+#define TX_HDR_SIZE                         sizeof(HIF_TX_HEADER_T)
+
+#define CMD_HDR_SIZE                        sizeof(WIFI_CMD_T)
+
+#define CMD_PKT_SIZE_FOR_IMAGE              2048	/* !< 2048 Bytes CMD payload buffer */
+
+/*! NIC_HIF_TX_HEADER_T */
+/* DW 0, Byte 0,1 */
+#define HIF_TX_HDR_TX_BYTE_COUNT_MASK       BITS(0, 11)
+#define HIF_TX_HDR_USER_PRIORITY_OFFSET     12
+
+/* DW 0, Byte 2 */
+#define HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK   BITS(0, 7)
+
+/* DW 0, Byte 3 */
+#define HIF_TX_HDR_IP_CSUM                  BIT(0)
+#define HIF_TX_HDR_TCP_CSUM                 BIT(1)
+#define HIF_TX_HDR_RESOURCE_MASK            BITS(2, 5)
+#define HIF_TX_HDR_RESOURCE_OFFSET     2
+#define HIF_TX_HDR_PACKET_TYPE_MASK         BITS(6, 7)
+#define HIF_TX_HDR_PACKET_TYPE_OFFSET       6
+
+/* DW 1, Byte 0 */
+#define HIF_TX_HDR_WLAN_HEADER_LEN_MASK     BITS(0, 5)
+
+/* DW 1, Byte 1 */
+#define HIF_TX_HDR_FORMAT_ID_MASK               BITS(0, 2)
+#define HIF_TX_HDR_NETWORK_TYPE_MASK            BITS(4, 5)
+#define HIF_TX_HDR_NETWORK_TYPE_OFFSET          4
+#define HIF_TX_HDR_FLAG_1X_FRAME_MASK           BIT(6)
+#define HIF_TX_HDR_FLAG_1X_FRAME_OFFSET         6
+#define HIF_TX_HDR_FLAG_802_11_FORMAT_MASK      BIT(7)
+#define HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET    7
+
+/* DW2, Byte 3 */
+#define HIF_TX_HDR_PS_FORWARDING_TYPE_MASK  BITS(0, 1)
+#define HIF_TX_HDR_PS_SESSION_ID_MASK       BITS(2, 4)
+#define HIF_TX_HDR_PS_SESSION_ID_OFFSET     2
+#define HIF_TX_HDR_BURST_END_MASK           BIT(5)
+#define HIF_TX_HDR_BURST_END_OFFSET         5
+
+/* DW3, Byte 1 */
+#define HIF_TX_HDR_NEED_ACK                 BIT(0)
+#define HIF_TX_HDR_BIP                      BIT(1)
+#define HIF_TX_HDR_BASIC_RATE               BIT(2)
+#define HIF_TX_HDR_NEED_TX_DONE_STATUS      BIT(3)
+#define HIF_TX_HDR_RTS                      BIT(4)
+
+/*******************************************************************************
+*                         D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _HIF_HW_TX_HEADER_T {
+	UINT_16 u2TxByteCount;
+	UINT_8 ucEtherTypeOffset;
+	UINT_8 ucCSflags;
+	UINT_8 aucBuffer[0];
+} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T;
+
+typedef struct _HIF_TX_HEADER_T {
+	UINT_16 u2TxByteCount_UserPriority;
+	UINT_8 ucEtherTypeOffset;
+	UINT_8 ucResource_PktType_CSflags;
+	UINT_8 ucWlanHeaderLength;
+	UINT_8 ucPktFormtId_Flags;
+	UINT_16 u2LLH;		/* for BOW */
+	UINT_16 u2SeqNo;	/* for BOW */
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucForwardingType_SessionID_Reserved;
+	UINT_8 ucPacketSeqNo;
+	UINT_8 ucAck_BIP_BasicRate;
+	UINT_8 aucReserved[2];
+} HIF_TX_HEADER_T, *P_HIF_TX_HEADER_T;
+
+typedef enum _ENUM_HIF_TX_PKT_TYPE_T {
+	HIF_TX_PKT_TYPE_DATA = 0,
+	HIF_TX_PKT_TYPE_CMD,
+	HIF_TX_PKT_TYPE_HIF_LOOPBACK,
+	HIF_TX_PKT_TYPE_MANAGEMENT,
+	HIF_TX_PKT_TYPE_NUM
+} ENUM_HIF_TX_PKT_TYPE_T, *P_ENUM_HIF_TX_PKT_TYPE_T;
+
+typedef enum _ENUM_HIF_OOB_CTRL_PKT_TYPE_T {
+	HIF_OOB_CTRL_PKT_TYPE_LOOPBACK = 1,
+	HIF_OOB_CTRL_PKT_TYP_NUM
+} ENUM_HIF_OOB_CTRL_PKT_TYPE_T, *P_ENUM_HIF_OOB_CTRL_PKT_TYPE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define TFCB_FRAME_PAD_TO_DW(u2Length)      ALIGN_4(u2Length)
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/* Kevin: we don't have to call following function to inspect the data structure.
+ * It will check automatically while at compile time.
+ */
+static inline VOID hif_txDataTypeCheck(VOID);
+
+static inline VOID hif_txDataTypeCheck(VOID)
+{
+	DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_TX_HEADER_T) == 16);
+
+}
+
+#endif /*_HIF_TX_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h
new file mode 100644
index 0000000000000..ff38d30c3cf2f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h
@@ -0,0 +1,2323 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/mac.h#1
+*/
+
+/*! \file   "mac.h"
+    \brief  Brief description.
+
+    Detail description.
+*/
+
+/*
+** Log: mac.h
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 06 22 2011 wh.su
+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h
+ * and let the sw structure not align at byte
+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte,
+ * Notice needed update P2P.ko.
+ *
+ * 05 06 2011 wh.su
+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send
+ * the wrong beacon make driver got incorrect support rate set
+ * Add the length check before access the ie length filed.
+ *
+ * 05 06 2011 wh.su
+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send
+ * the wrong beacon make driver got incorrect support rate set
+ * adding the length check before processing next ie..
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 08 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Add device discover ability support.
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Some action frame define is not belong to P2P.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Add some service discovery MAC define, phase I.
+ *
+ * 12 13 2010 cp.wu
+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
+ * create branch for Wi-Fi driver v1.1
+ *
+ * 12 13 2010 cp.wu
+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork
+ * suppress warning reported by Klockwork.
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration
+ * revert to previous revision. (this file is not necessary to be changed)
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * 1. Add P2P MAC define.
+ * 2. Add scan device found event
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add WFA specific OUI.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add P2P IE ID & Vendor OUI TYPE for P2P.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge MAC.h.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 01 13 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Added OFFSET_BAR_SSC_SN
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:00:24 GMT MTK02468
+**  Added offsets and masks for the BA Parameter Set filed
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:26 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _MAC_H
+#define _MAC_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* 3  --------------- Constants for Ethernet/802.11 MAC --------------- */
+/* MAC Address */
+#define MAC_ADDR_LEN                            6
+
+#define MAC_ADDR_LOCAL_ADMIN                    BIT(1)
+
+#define ETH_P_IPV4                              0x0800
+#define ETH_P_IPX                               0x8137	/* Novell IPX */
+#define ETH_P_AARP                              0x80F3	/* AppleTalk Address Resolution Protocol (AARP) */
+#define ETH_P_IPV6                              0x86DD
+
+#define IP_VERSION_4                            4
+#define IP_VERSION_6                            6
+
+#define IP_PROTOCOL_TCP                         6
+#define IP_PROTOCOL_UDP                         17
+
+#define IPV4_HDR_IP_IDENTIFICATION_OFFSET       4
+#define IPV4_HDR_IP_PROTOCOL_OFFSET             9
+#define IPV4_HDR_IP_CSUM_OFFSET                 10
+#define IPV4_HDR_IP_SRC_ADDR_OFFSET             12
+#define IPV4_HDR_IP_DST_ADDR_OFFSET             16
+
+#define IPV6_HDR_IP_PROTOCOL_OFFSET             6
+#define IPV6_HDR_IP_SRC_ADDR_OFFSET             8
+#define IPV6_HDR_IP_DST_ADDR_OFFSET             24
+#define IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET    32
+#define IPV6_HDR_IP_DST_ADDR_MAC_LOW_OFFSET     37
+#define IPV6_PROTOCOL_ICMPV6                    0x3A
+#define IPV6_ADDR_LEN	                        16
+#define IPV6_HDR_LEN                            40
+
+#define ARP_OPERATION_OFFSET                    6
+#define ARP_SNEDER_MAC_OFFSET                   8
+#define ARP_SENDER_IP_OFFSET                    14
+#define ARP_TARGET_MAC_OFFSET                   18
+#define ARP_TARGET_IP_OFFSET                    24
+#define ARP_OPERATION_REQUEST                   0x0001
+#define ARP_OPERATION_RESPONSE                  0x0002
+
+#define ICMPV6_TYPE_OFFSET                      0
+#define ICMPV6_FLAG_OFFSET                      4
+#define ICMPV6_TARGET_ADDR_OFFSET				8
+#define ICMPV6_TARGET_LL_ADDR_TYPE_OFFSET		24
+#define ICMPV6_TARGET_LL_ADDR_LEN_OFFSET		25
+#define ICMPV6_TARGET_LL_ADDR_TA_OFFSET			26
+
+#define ICMPV6_FLAG_ROUTER_BIT                  BIT(7)
+#define ICMPV6_FLAG_SOLICITED_BIT               BIT(6)
+#define ICMPV6_FLAG_OVERWRITE_BIT               BIT(5)
+#define ICMPV6_TYPE_NEIGHBOR_SOLICITATION       0x87
+#define ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT      0x88
+
+#define TCP_HDR_TCP_CSUM_OFFSET                 16
+#define UDP_HDR_UDP_CSUM_OFFSET                 6
+
+#define LLC_LEN                                 8	/* LLC(3) + SNAP(3) + EtherType(2) */
+
+#define NULL_MAC_ADDR                           {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+#define BC_MAC_ADDR                             {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
+
+/* Ethernet Frame Field Size, in byte */
+#define ETHER_HEADER_LEN                        14
+#define ETHER_TYPE_LEN                          2
+#define ETHER_MIN_PKT_SZ                        60
+#define ETHER_MAX_PKT_SZ                        1514
+
+/* IEEE 802.11 WLAN Frame Field Size, in byte */
+#define WLAN_MAC_HEADER_LEN                     24	/* Address 4 excluded */
+#define WLAN_MAC_HEADER_A4_LEN                  30	/* Address 4 included */
+#define WLAN_MAC_HEADER_QOS_LEN                 26	/* QoS Control included */
+#define WLAN_MAC_HEADER_QOS_HTC_LEN             30	/* QoS Control and HTC included */
+#define WLAN_MAC_HEADER_A4_QOS_LEN              32	/* Address 4 and QoS Control included */
+#define WLAN_MAC_HEADER_A4_QOS_HTC_LEN          36	/* Address 4, QoS Control and HTC included */
+#define WLAN_MAC_MGMT_HEADER_LEN                24	/* Address 4 excluded */
+#define WLAN_MAC_MGMT_HEADER_HTC_LEN            28	/* HTC included */
+
+#define QOS_CTRL_LEN                            2
+#define HT_CTRL_LEN                             4
+
+#define WLAN_MAC_CTS_ACK_LEN         (WLAN_MAC_CTS_ACK_FRAME_HEADER_LEN + FCS_LEN)
+
+/* 6.2.1.1.2 Semantics of the service primitive */
+#define MSDU_MAX_LENGTH                         2304
+
+/* 7.1.3.3.3 Broadcast BSSID */
+#define BC_BSSID                                BC_MAC_ADDR
+
+/* 7.1.3.7 FCS field */
+#define FCS_LEN                                 4
+
+/* 7.3.1.6 Listen Interval field */
+#define DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD  2	/* In unit of AP's DTIM interval, */
+#define DEFAULT_LISTEN_INTERVAL                 10
+
+/* 7.3.2.1 Broadcast(Wildcard) SSID */
+#define BC_SSID                                 ""
+#define BC_SSID_LEN                             0
+
+/* 7.3.2.2 Data Rate Value */
+#define RATE_1M                                 2	/* 1M in unit of 500kb/s */
+#define RATE_2M                                 4	/* 2M */
+#define RATE_5_5M                               11	/* 5.5M */
+#define RATE_11M                                22	/* 11M */
+#define RATE_22M                                44	/* 22M */
+#define RATE_33M                                66	/* 33M */
+#define RATE_6M                                 12	/* 6M */
+#define RATE_9M                                 18	/* 9M */
+#define RATE_12M                                24	/* 12M */
+#define RATE_18M                                36	/* 18M */
+#define RATE_24M                                48	/* 24M */
+#define RATE_36M                                72	/* 36M */
+#define RATE_48M                                96	/* 48M */
+#define RATE_54M                                108	/* 54M */
+/* 7.3.2.14 BSS membership selector */
+#define RATE_HT_PHY                             127	/* BSS Selector - Clause 20. HT PHY */
+#define RATE_MASK                               BITS(0, 6)	/* mask bits for the rate */
+#define RATE_BASIC_BIT                          BIT(7)	/* mask bit for the rate belonging to the BSSBasicRateSet */
+
+/* 8.3.2.2 TKIP MPDU formats */
+#define TKIP_MIC_LEN                            8
+
+/* 9.2.10 DIFS */
+#define DIFS                                    2	/* 2 x aSlotTime */
+
+/* 11.3 STA Authentication and Association */
+#define STA_STATE_1                             0	/* Accept Class 1 frames */
+#define STA_STATE_2                             1	/* Accept Class 1 & 2 frames */
+#define STA_STATE_3                             2	/* Accept Class 1,2 & 3 frames */
+
+/* 15.4.8.5 802.11k RCPI-dBm mapping*/
+#define NDBM_LOW_BOUND_FOR_RCPI                 110
+#define RCPI_LOW_BOUND                          0
+#define RCPI_HIGH_BOUND                         220
+#define RCPI_MEASUREMENT_NOT_AVAILABLE          255
+
+/* PHY characteristics */
+/* 17.4.4/18.3.3/19.8.4 Slot Time (aSlotTime) */
+#define SLOT_TIME_LONG                          20	/* Long Slot Time */
+#define SLOT_TIME_SHORT                         9	/* Short Slot Time */
+
+#define SLOT_TIME_HR_DSSS                       SLOT_TIME_LONG	/* 802.11b aSlotTime */
+#define SLOT_TIME_OFDM                          SLOT_TIME_SHORT	/* 802.11a aSlotTime(20M Spacing) */
+#define SLOT_TIME_OFDM_10M_SPACING              13	/* 802.11a aSlotTime(10M Spacing) */
+#define SLOT_TIME_ERP_LONG                      SLOT_TIME_LONG	/* 802.11g aSlotTime(Long) */
+#define SLOT_TIME_ERP_SHORT                     SLOT_TIME_SHORT	/* 802.11g aSlotTime(Short) */
+
+/* 17.4.4/18.3.3/19.8.4 Contention Window (aCWmin & aCWmax) */
+#define CWMIN_OFDM                              15	/* 802.11a aCWmin */
+#define CWMAX_OFDM                              1023	/* 802.11a aCWmax */
+
+#define CWMIN_HR_DSSS                           31	/* 802.11b aCWmin */
+#define CWMAX_HR_DSSS                           1023	/* 802.11b aCWmax */
+
+#define CWMIN_ERP_0                             31	/* 802.11g aCWmin(0) - for only have 1/2/5/11Mbps Rates */
+#define CWMIN_ERP_1                             15	/* 802.11g aCWmin(1) */
+#define CWMAX_ERP                               1023	/* 802.11g aCWmax */
+
+/* Short Inter-Frame Space (aSIFSTime) */
+/* 15.3.3 802.11b aSIFSTime */
+#define SIFS_TIME_HR_DSSS                       10
+/* 17.4.4 802.11a aSIFSTime */
+#define SIFS_TIME_OFDM                          16
+/* 19.8.4 802.11g aSIFSTime */
+#define SIFS_TIME_ERP                           10
+
+/* 15.4.6.2 Number of operating channels */
+#define CH_1                                    0x1
+#define CH_2                                    0x2
+#define CH_3                                    0x3
+#define CH_4                                    0x4
+#define CH_5                                    0x5
+#define CH_6                                    0x6
+#define CH_7                                    0x7
+#define CH_8                                    0x8
+#define CH_9                                    0x9
+#define CH_10                                   0xa
+#define CH_11                                   0xb
+#define CH_12                                   0xc
+#define CH_13                                   0xd
+#define CH_14                                   0xe
+
+#define MAXIMUM_OPERATION_CHANNEL_LIST          46
+
+/* 3  --------------- IEEE 802.11 PICS --------------- */
+/* Annex D - dot11OperationEntry 2 */
+#define DOT11_RTS_THRESHOLD_MIN                 0
+#define DOT11_RTS_THRESHOLD_MAX                 2347	/* from Windows DDK */
+/* #define DOT11_RTS_THRESHOLD_MAX                 3000 // from Annex D */
+
+#define DOT11_RTS_THRESHOLD_DEFAULT             \
+	    DOT11_RTS_THRESHOLD_MAX
+
+/* Annex D - dot11OperationEntry 5 */
+#define DOT11_FRAGMENTATION_THRESHOLD_MIN       256
+#define DOT11_FRAGMENTATION_THRESHOLD_MAX       2346	/* from Windows DDK */
+/* #define DOT11_FRAGMENTATION_THRESHOLD_MAX       3000 // from Annex D */
+
+#define DOT11_FRAGMENTATION_THRESHOLD_DEFAULT   \
+	    DOT11_FRAGMENTATION_THRESHOLD_MAX
+
+/* Annex D - dot11OperationEntry 6 */
+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MIN     1
+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MAX     0xFFFFffff
+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_DEFAULT 4095	/* 802.11 define 512 */
+						     /* MT5921 only aceept N <= 4095 */
+
+/* Annex D - dot11OperationEntry 7 */
+#define DOT11_RECEIVE_LIFETIME_TU_MIN           1
+#define DOT11_RECEIVE_LIFETIME_TU_MAX           0xFFFFffff
+#define DOT11_RECEIVE_LIFETIME_TU_DEFAULT       4096	/* 802.11 define 512 */
+
+/* Annex D - dot11StationConfigEntry 12 */
+#define DOT11_BEACON_PERIOD_MIN                 1	/* TU. */
+#define DOT11_BEACON_PERIOD_MAX                 0xffff	/* TU. */
+#define DOT11_BEACON_PERIOD_DEFAULT             100	/* TU. */
+
+/* Annex D - dot11StationConfigEntry 13 */
+#define DOT11_DTIM_PERIOD_MIN                   1	/* TU. */
+#define DOT11_DTIM_PERIOD_MAX                   255	/* TU. */
+#define DOT11_DTIM_PERIOD_DEFAULT               1	/* TU. */
+
+/* Annex D - dot11RegDomainsSupportValue */
+#define REGULATION_DOMAIN_FCC                   0x10	/* FCC (US) */
+#define REGULATION_DOMAIN_IC                    0x20	/* IC or DOC (Canada) */
+#define REGULATION_DOMAIN_ETSI                  0x30	/* ETSI (Europe) */
+#define REGULATION_DOMAIN_SPAIN                 0x31	/* Spain */
+#define REGULATION_DOMAIN_FRANCE                0x32	/* France */
+#define REGULATION_DOMAIN_JAPAN                 0x40	/* MKK (Japan) */
+#define REGULATION_DOMAIN_CHINA                 0x50	/* China */
+#define REGULATION_DOMAIN_OTHER                 0x00	/* Other */
+
+/* 3  --------------- IEEE 802.11 MAC header fields --------------- */
+/* 7.1.3.1 Masks for the subfields in the Frame Control field */
+#define MASK_FC_PROTOCOL_VER                    BITS(0, 1)
+#define MASK_FC_TYPE                            BITS(2, 3)
+#define MASK_FC_SUBTYPE                         BITS(4, 7)
+#define MASK_FC_SUBTYPE_QOS_DATA                BIT(7)
+#define MASK_FC_TO_DS                           BIT(8)
+#define MASK_FC_FROM_DS                         BIT(9)
+#define MASK_FC_MORE_FRAG                       BIT(10)
+#define MASK_FC_RETRY                           BIT(11)
+#define MASK_FC_PWR_MGT                         BIT(12)
+#define MASK_FC_MORE_DATA                       BIT(13)
+#define MASK_FC_PROTECTED_FRAME                 BIT(14)
+#define MASK_FC_ORDER                           BIT(15)
+
+#define MASK_FRAME_TYPE                         (MASK_FC_TYPE | MASK_FC_SUBTYPE)
+#define MASK_TO_DS_FROM_DS                      (MASK_FC_TO_DS | MASK_FC_FROM_DS)
+
+#define MAX_NUM_OF_FC_SUBTYPES                  16
+#define OFFSET_OF_FC_SUBTYPE                    4
+
+/* 7.1.3.1.2 MAC frame types and subtypes */
+#define MAC_FRAME_TYPE_MGT                      0
+#define MAC_FRAME_TYPE_CTRL                     BIT(2)
+#define MAC_FRAME_TYPE_DATA                     BIT(3)
+#define MAC_FRAME_TYPE_QOS_DATA                 (MAC_FRAME_TYPE_DATA | MASK_FC_SUBTYPE_QOS_DATA)
+
+#define MAC_FRAME_ASSOC_REQ                     (MAC_FRAME_TYPE_MGT | 0x0000)
+#define MAC_FRAME_ASSOC_RSP                     (MAC_FRAME_TYPE_MGT | 0x0010)
+#define MAC_FRAME_REASSOC_REQ                   (MAC_FRAME_TYPE_MGT | 0x0020)
+#define MAC_FRAME_REASSOC_RSP                   (MAC_FRAME_TYPE_MGT | 0x0030)
+#define MAC_FRAME_PROBE_REQ                     (MAC_FRAME_TYPE_MGT | 0x0040)
+#define MAC_FRAME_PROBE_RSP                     (MAC_FRAME_TYPE_MGT | 0x0050)
+#define MAC_FRAME_BEACON                        (MAC_FRAME_TYPE_MGT | 0x0080)
+#define MAC_FRAME_ATIM                          (MAC_FRAME_TYPE_MGT | 0x0090)
+#define MAC_FRAME_DISASSOC                      (MAC_FRAME_TYPE_MGT | 0x00A0)
+#define MAC_FRAME_AUTH                          (MAC_FRAME_TYPE_MGT | 0x00B0)
+#define MAC_FRAME_DEAUTH                        (MAC_FRAME_TYPE_MGT | 0x00C0)
+#define MAC_FRAME_ACTION                        (MAC_FRAME_TYPE_MGT | 0x00D0)
+#define MAC_FRAME_ACTION_NO_ACK                 (MAC_FRAME_TYPE_MGT | 0x00E0)
+
+#define MAC_FRAME_CONTRL_WRAPPER                (MAC_FRAME_TYPE_CTRL | 0x0070)
+#define MAC_FRAME_BLOCK_ACK_REQ                 (MAC_FRAME_TYPE_CTRL | 0x0080)
+#define MAC_FRAME_BLOCK_ACK                     (MAC_FRAME_TYPE_CTRL | 0x0090)
+#define MAC_FRAME_PS_POLL                       (MAC_FRAME_TYPE_CTRL | 0x00A0)
+#define MAC_FRAME_RTS                           (MAC_FRAME_TYPE_CTRL | 0x00B0)
+#define MAC_FRAME_CTS                           (MAC_FRAME_TYPE_CTRL | 0x00C0)
+#define MAC_FRAME_ACK                           (MAC_FRAME_TYPE_CTRL | 0x00D0)
+#define MAC_FRAME_CF_END                        (MAC_FRAME_TYPE_CTRL | 0x00E0)
+#define MAC_FRAME_CF_END_CF_ACK                 (MAC_FRAME_TYPE_CTRL | 0x00F0)
+
+#define MAC_FRAME_DATA                          (MAC_FRAME_TYPE_DATA | 0x0000)
+#define MAC_FRAME_DATA_CF_ACK                   (MAC_FRAME_TYPE_DATA | 0x0010)
+#define MAC_FRAME_DATA_CF_POLL                  (MAC_FRAME_TYPE_DATA | 0x0020)
+#define MAC_FRAME_DATA_CF_ACK_CF_POLL           (MAC_FRAME_TYPE_DATA | 0x0030)
+#define MAC_FRAME_NULL                          (MAC_FRAME_TYPE_DATA | 0x0040)
+#define MAC_FRAME_CF_ACK                        (MAC_FRAME_TYPE_DATA | 0x0050)
+#define MAC_FRAME_CF_POLL                       (MAC_FRAME_TYPE_DATA | 0x0060)
+#define MAC_FRAME_CF_ACK_CF_POLL                (MAC_FRAME_TYPE_DATA | 0x0070)
+#define MAC_FRAME_QOS_DATA                      (MAC_FRAME_TYPE_DATA | 0x0080)
+#define MAC_FRAME_QOS_DATA_CF_ACK               (MAC_FRAME_TYPE_DATA | 0x0090)
+#define MAC_FRAME_QOS_DATA_CF_POLL              (MAC_FRAME_TYPE_DATA | 0x00A0)
+#define MAC_FRAME_QOS_DATA_CF_ACK_CF_POLL       (MAC_FRAME_TYPE_DATA | 0x00B0)
+#define MAC_FRAME_QOS_NULL                      (MAC_FRAME_TYPE_DATA | 0x00C0)
+#define MAC_FRAME_QOS_CF_POLL                   (MAC_FRAME_TYPE_DATA | 0x00E0)
+#define MAC_FRAME_QOS_CF_ACK_CF_POLL            (MAC_FRAME_TYPE_DATA | 0x00F0)
+
+/* 7.1.3.2 Mask for the AID value in the Duration/ID field */
+#define MASK_DI_DURATION                        BITS(0, 14)
+#define MASK_DI_AID                             BITS(0, 13)
+#define MASK_DI_AID_MSB                         BITS(14, 15)
+#define MASK_DI_CFP_FIXED_VALUE                 BIT(15)
+
+/* 7.1.3.4 Masks for the subfields in the Sequence Control field */
+#define MASK_SC_SEQ_NUM                         BITS(4, 15)
+#define MASK_SC_SEQ_NUM_OFFSET                  4
+#define MASK_SC_FRAG_NUM                        BITS(0, 3)
+#define INVALID_SEQ_CTRL_NUM                    0x000F	/* According to 6.2.1.1.2
+							 * FRAG_NUM won't equal to 15
+							 */
+
+/* 7.1.3.5 QoS Control field */
+#define TID_NUM                                 16
+#define TID_MASK                                BITS(0, 3)
+#define EOSP                                    BIT(4)
+#define ACK_POLICY                              BITS(5, 6)
+#define A_MSDU_PRESENT                          BIT(7)
+
+#define MASK_QC_TID                  BITS(0, 3)
+#define MASK_QC_EOSP                 BIT(4)
+#define MASK_QC_EOSP_OFFSET          4
+#define MASK_QC_ACK_POLICY           BITS(5, 6)
+#define MASK_QC_ACK_POLICY_OFFSET    5
+#define MASK_QC_A_MSDU_PRESENT       BIT(7)
+
+/* 7.1.3.5a HT Control field */
+#define HT_CTRL_LINK_ADAPTATION_CTRL            BITS(0, 15)
+#define HT_CTRL_CALIBRATION_POSITION            BITS(16, 17)
+#define HT_CTRL_CALIBRATION_SEQUENCE            BITS(18, 19)
+#define HT_CTRL_CSI_STEERING                    BITS(22, 23)
+#define HT_CTRL_NDP_ANNOUNCEMENT                BIT(24)
+#define HT_CTRL_AC_CONSTRAINT                   BIT(30)
+#define HT_CTRL_RDG_MORE_PPDU                   BIT(31)
+
+#define LINK_ADAPTATION_CTRL_TRQ                BIT(1)
+#define LINK_ADAPTATION_CTRL_MAI_MRQ            BIT(2)
+#define LINK_ADAPTATION_CTRL_MAI_MSI            BITS(3, 5)
+#define LINK_ADAPTATION_CTRL_MFSI               BITS(6, 8)
+#define LINK_ADAPTATION_CTRL_MFB_ASELC_CMD      BITS(9, 11)
+#define LINK_ADAPTATION_CTRL_MFB_ASELC_DATA     BITS(12, 15)
+
+/* 7.1.3.5.3 Ack Policy subfield*/
+#define ACK_POLICY_NORMAL_ACK_IMPLICIT_BA_REQ 0
+#define ACK_POLICY_NO_ACK 1
+#define ACK_POLICY_NO_EXPLICIT_ACK_PSMP_ACK 2
+#define ACK_POLICY_BA 3
+
+/* 7.1.3.7 FCS field */
+#define FCS_LEN                                 4
+
+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */
+#define PSPOLL_FRAME_LEN                        16	/* w/o FCS */
+
+/* 7.2.7.1 BAR */
+#define OFFSET_BAR_SSC_SN                       4
+
+/* 8.3.2.2 TKIP MPDU formats */
+#define TKIP_MIC_LEN                            8
+
+/* 2009.11.30 mtk02468: Moved these definitions to the right place */
+#if 0
+/* Block Ack Parameter Set field */
+#define BA_PARM_BA_POLICY                       BIT(1)
+#define BA_PARM_TID                             BITS(2, 5)
+#define BA_PARM_BUFFER_SIZE                     BITS(6, 15)
+#endif
+
+#define BA_POLICY_IMMEDIATE                     BIT(1)
+
+/* Block Ack Starting Sequence Control field */
+#define BA_START_SEQ_CTL_FRAG_NUM               BITS(0, 3)
+#define BA_START_SEQ_CTL_SSN                    BITS(4, 15)
+
+/* BAR Control field */
+#define BAR_CONTROL_NO_ACK_POLICY               BIT(0)
+#define BAR_CONTROL_MULTI_TID                   BIT(1)
+#define BAR_CONTROL_COMPRESSED_BA               BIT(2)
+#define BAR_CONTROL_TID_INFO                    BITS(12, 15)
+#define BAR_CONTROL_TID_INFO_OFFSET             12
+
+/* TID Value */
+#define BAR_INFO_TID_VALUE                      BITS(12, 15)
+
+#define BAR_COMPRESSED_VARIANT_FRAME_LEN        (16 + 4)
+
+/* 3  --------------- IEEE 802.11 frame body fields --------------- */
+/* 3 Management frame body components (I): Fixed Fields. */
+/* 7.3.1.1 Authentication Algorithm Number field */
+#define AUTH_ALGORITHM_NUM_FIELD_LEN                2
+
+#define AUTH_ALGORITHM_NUM_OPEN_SYSTEM              0	/* Open System */
+#define AUTH_ALGORITHM_NUM_SHARED_KEY               1	/* Shared Key */
+#define AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION      2	/* Fast BSS Transition */
+
+/* 7.3.1.2 Authentication Transaction Sequence Number field */
+#define AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN      2
+#define AUTH_TRANSACTION_SEQ_1                      1
+#define AUTH_TRANSACTION_SEQ_2                      2
+#define AUTH_TRANSACTION_SEQ_3                      3
+#define AUTH_TRANSACTION_SEQ_4                      4
+
+/* 7.3.1.3 Beacon Interval field */
+#define BEACON_INTERVAL_FIELD_LEN                   2
+
+/* 7.3.1.4 Capability Information field */
+#define CAP_INFO_FIELD_LEN                          2
+#define CAP_INFO_ESS                                BIT(0)
+#define CAP_INFO_IBSS                               BIT(1)
+#define CAP_INFO_BSS_TYPE                           (CAP_INFO_ESS | CAP_INFO_IBSS)
+#define CAP_INFO_CF_POLLABLE                        BIT(2)
+#define CAP_INFO_CF_POLL_REQ                        BIT(3)
+#define CAP_INFO_CF                                 (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ)
+#define CAP_INFO_PRIVACY                            BIT(4)
+#define CAP_INFO_SHORT_PREAMBLE                     BIT(5)
+#define CAP_INFO_PBCC                               BIT(6)
+#define CAP_INFO_CH_AGILITY                         BIT(7)
+#define CAP_INFO_SPEC_MGT                           BIT(8)
+#define CAP_INFO_QOS                                BIT(9)
+#define CAP_INFO_SHORT_SLOT_TIME                    BIT(10)
+#define CAP_INFO_APSD                               BIT(11)
+#define CAP_INFO_RESERVED                           BIT(12)
+#define CAP_INFO_DSSS_OFDM                          BIT(13)
+#define CAP_INFO_DELAYED_BLOCK_ACK                  BIT(14)
+#define CAP_INFO_IMM_BLOCK_ACK                      BIT(15)
+/* STA usage of CF-Pollable and CF-Poll Request subfields */
+/* STA: not CF-Pollable */
+#define CAP_CF_STA_NOT_POLLABLE                     0x0000
+/* STA: CF-Pollable, not requesting on the CF-Polling list */
+#define CAP_CF_STA_NOT_ON_LIST                      CAP_INFO_CF_POLL_REQ
+/* STA: CF-Pollable, requesting on the CF-Polling list */
+#define CAP_CF_STA_ON_LIST                          CAP_INFO_CF_POLLABLE
+/* STA: CF-Pollable, requesting never to be polled */
+#define CAP_CF_STA_NEVER_POLLED                     (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ)
+
+/* AP usage of CF-Pollable and CF-Poll Request subfields */
+/* AP: No point coordinator (PC) */
+#define CAP_CF_AP_NO_PC                             0x0000
+/* AP: PC at AP for delivery only (no polling) */
+#define CAP_CF_AP_DELIVERY_ONLY                     CAP_INFO_CF_POLL_REQ
+/* AP: PC at AP for delivery and polling */
+#define CAP_CF_AP_DELIVERY_POLLING                  CAP_INFO_CF_POLLABLE
+
+/* 7.3.1.5 Current AP Address field */
+#define CURR_AP_ADDR_FIELD_LEN                      MAC_ADDR_LEN
+
+/* 7.3.1.6 Listen Interval field */
+#define LISTEN_INTERVAL_FIELD_LEN                   2
+
+/* 7.3.1.7 Reason Code field */
+#define REASON_CODE_FIELD_LEN                       2
+
+#define REASON_CODE_RESERVED                        0	/* Reseved */
+#define REASON_CODE_UNSPECIFIED                     1	/* Unspecified reason */
+#define REASON_CODE_PREV_AUTH_INVALID               2	/* Previous auth no longer valid */
+#define REASON_CODE_DEAUTH_LEAVING_BSS              3	/* Deauth because sending STA is leaving BSS */
+#define REASON_CODE_DISASSOC_INACTIVITY             4	/* Disassoc due to inactivity */
+#define REASON_CODE_DISASSOC_AP_OVERLOAD            5	/* Disassoc because AP is unable to handle all assoc STAs */
+#define REASON_CODE_CLASS_2_ERR                     6	/* Class 2 frame rx from nonauth STA */
+#define REASON_CODE_CLASS_3_ERR                     7	/* Class 3 frame rx from nonassoc STA */
+#define REASON_CODE_DISASSOC_LEAVING_BSS            8	/* Disassoc because sending STA is leaving BSS */
+#define REASON_CODE_ASSOC_BEFORE_AUTH               9	/* STA requesting (re)assoc is not auth with responding STA */
+#define REASON_CODE_DISASSOC_PWR_CAP_UNACCEPTABLE   10	/* Disassoc because the info in Power Capability is
+							unacceptable */
+#define REASON_CODE_DISASSOC_SUP_CHS_UNACCEPTABLE   11	/* Disassoc because the info in Supported Channels is
+							unacceptable */
+#define REASON_CODE_INVALID_INFO_ELEM               13	/* Invalid information element */
+#define REASON_CODE_MIC_FAILURE                     14	/* MIC failure */
+#define REASON_CODE_4_WAY_HANDSHAKE_TIMEOUT         15	/* 4-way handshake timeout */
+#define REASON_CODE_GROUP_KEY_UPDATE_TIMEOUT        16	/* Group key update timeout */
+#define REASON_CODE_DIFFERENT_INFO_ELEM             17	/* Info element in 4-way handshake different from
+							(Re-)associate request/Probe response/Beacon */
+#define REASON_CODE_MULTICAST_CIPHER_NOT_VALID      18	/* Multicast Cipher is not valid */
+#define REASON_CODE_UNICAST_CIPHER_NOT_VALID        19	/* Unicast Cipher is not valid */
+#define REASON_CODE_AKMP_NOT_VALID                  20	/* AKMP is not valid */
+#define REASON_CODE_UNSUPPORTED_RSNE_VERSION        21	/* Unsupported RSNE version */
+#define REASON_CODE_INVALID_RSNE_CAPABILITIES       22	/* Invalid RSNE Capabilities */
+#define REASON_CODE_IEEE_802_1X_AUTH_FAILED         23	/* IEEE 802.1X Authentication failed */
+#define REASON_CODE_CIPHER_REJECT_SEC_POLICY        24	/* Cipher suite rejected because of the security policy */
+#define REASON_CODE_DISASSOC_UNSPECIFIED_QOS        32	/* Disassoc for unspecified, QoS-related reason */
+#define REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH      33	/* Disassoc because QAP lacks sufficient bandwidth
+							for this QSTA */
+#define REASON_CODE_DISASSOC_ACK_LOST_POOR_CHANNEL  34	/* Disassoc because of too many ACKs lost for AP transmissions
+							and/or poor channel conditions */
+#define REASON_CODE_DISASSOC_TX_OUTSIDE_TXOP_LIMIT  35	/* Disassoc because QSTA is transmitting outside the limits of
+							its TXOPs */
+#define REASON_CODE_PEER_WHILE_LEAVING              36	/* QSTA is leaving the QBSS or resetting */
+#define REASON_CODE_PEER_REFUSE_DLP                 37	/* Peer does not want to use this mechanism */
+#define REASON_CODE_PEER_SETUP_REQUIRED             38	/* Frames received but a setup is reqired */
+#define REASON_CODE_PEER_TIME_OUT                   39	/* Time out */
+#define REASON_CODE_PEER_CIPHER_UNSUPPORTED         45	/* Peer does not support the requested cipher suite */
+#define REASON_CODE_BEACON_TIMEOUT			100	/* for beacon timeout, defined by mediatek */
+#define REASON_CODE_BSS_SECURITY_CHANGE			101	/* for BSS security change, defined by mediatek */
+/* 7.3.1.8 AID field */
+#define AID_FIELD_LEN                               2
+#define AID_MASK                                    BITS(0, 13)
+#define AID_MSB                                     BITS(14, 15)
+#define AID_MIN_VALUE                               1
+#define AID_MAX_VALUE                               2007
+
+/* 7.3.1.9 Status Code field */
+#define STATUS_CODE_FIELD_LEN                       2
+
+#define STATUS_CODE_RESERVED                        0	/* Reserved - Used by TX Auth */
+#define STATUS_CODE_SUCCESSFUL                      0	/* Successful */
+#define STATUS_CODE_UNSPECIFIED_FAILURE             1	/* Unspecified failure */
+#define STATUS_CODE_CAP_NOT_SUPPORTED               10	/* Cannot support all requested cap in the Cap Info field */
+#define STATUS_CODE_REASSOC_DENIED_WITHOUT_ASSOC    11	/* Reassoc denied due to inability to confirm that
+							assoc exists */
+#define STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD   12	/* Assoc denied due to reason outside the scope of this std. */
+#define STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED    13	/* Responding STA does not support the specified
+							auth algorithm */
+#define STATUS_CODE_AUTH_OUT_OF_SEQ                 14	/* Rx an auth frame with auth transaction seq num
+							out of expected seq */
+#define STATUS_CODE_AUTH_REJECTED_CHAL_FAIL         15	/* Auth rejected because of challenge failure */
+#define STATUS_CODE_AUTH_REJECTED_TIMEOUT           16	/* Auth rejected due to timeout waiting for next frame
+							in sequence */
+#define STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD        17	/* Assoc denied because AP is unable to handle additional
+							assoc STAs */
+#define STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED 18	/* Assoc denied due to requesting STA not supporting
+							all of basic rates */
+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_PREAMBLE  19	/* Assoc denied due to requesting STA not supporting short
+							preamble */
+#define STATUS_CODE_ASSOC_DENIED_NO_PBCC            20	/* Assoc denied due to requesting STA not supporting PBCC */
+#define STATUS_CODE_ASSOC_DENIED_NO_CH_AGILITY      21	/* Assoc denied due to requesting STA not supporting channel
+							agility */
+#define STATUS_CODE_ASSOC_REJECTED_NO_SPEC_MGT      22	/* Assoc rejected because Spectrum Mgt capability is required */
+#define STATUS_CODE_ASSOC_REJECTED_PWR_CAP          23	/* Assoc rejected because the info in Power Capability
+							is unacceptable */
+#define STATUS_CODE_ASSOC_REJECTED_SUP_CHS          24	/* Assoc rejected because the info in Supported Channels
+							is unacceptable */
+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25	/* Assoc denied due to requesting STA not supporting
+							short slot time */
+#define STATUS_CODE_ASSOC_DENIED_NO_DSSS_OFDM       26	/* Assoc denied due to requesting STA not supporting
+							DSSS-OFDM */
+#if CFG_SUPPORT_802_11W
+#define STATUS_CODE_ASSOC_REJECTED_TEMPORARILY      30	/*  IEEE 802.11w, Assoc denied due to the SA query */
+#define STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31	/* IEEE 802.11w, Assoc denied due to the MFP select
+								policy */
+#endif
+#define STATUS_CODE_UNSPECIFIED_QOS_FAILURE         32	/* Unspecified, QoS-related failure */
+#define STATUS_CODE_ASSOC_DENIED_BANDWIDTH          33	/* Assoc denied due to insufficient bandwidth to handle another
+							QSTA */
+#define STATUS_CODE_ASSOC_DENIED_POOR_CHANNEL       34	/* Assoc denied due to excessive frame loss rates and/or poor
+							channel conditions */
+#define STATUS_CODE_ASSOC_DENIED_NO_QOS_FACILITY    35	/* Assoc denied due to requesting STA not supporting QoS
+							facility */
+#define STATUS_CODE_REQ_DECLINED                    37	/* Request has been declined */
+#define STATUS_CODE_REQ_INVALID_PARAMETER_VALUE     38	/* Request has not been successful as one or more parameters
+							have invalid values */
+#define STATUS_CODE_REQ_NOT_HONORED_TSPEC           39	/* TS not created because request cannot be honored.
+							Suggested TSPEC provided. */
+#define STATUS_CODE_INVALID_INFO_ELEMENT            40	/* Invalid information element */
+#define STATUS_CODE_INVALID_GROUP_CIPHER            41	/* Invalid group cipher */
+#define STATUS_CODE_INVALID_PAIRWISE_CIPHER         42	/* Invalid pairwise cipher */
+#define STATUS_CODE_INVALID_AKMP                    43	/* Invalid AKMP */
+#define STATUS_CODE_UNSUPPORTED_RSN_IE_VERSION      44	/* Unsupported RSN information element version */
+#define STATUS_CODE_INVALID_RSN_IE_CAP              45	/* Invalid RSN information element capabilities */
+#define STATUS_CODE_CIPHER_SUITE_REJECTED           46	/* Cipher suite rejected because of security policy */
+#define STATUS_CODE_REQ_NOT_HONORED_TS_DELAY        47	/* TS not created because request cannot be honored.
+							Attempt to create a TS later. */
+#define STATUS_CODE_DIRECT_LINK_NOT_ALLOWED         48	/* Direct Link is not allowed in the BSS by policy */
+#define STATUS_CODE_DESTINATION_STA_NOT_PRESENT     49	/* Destination STA is not present within this QBSS */
+#define STATUS_CODE_DESTINATION_STA_NOT_QSTA        50	/* Destination STA is not a QSTA */
+#define STATUS_CODE_ASSOC_DENIED_LARGE_LIS_INTERVAL 51	/* Association denied because the ListenInterval is too large */
+
+/* proprietary definition of reserved field of Status Code */
+#define STATUS_CODE_JOIN_FAILURE                    0xFFF0	/* Join failure */
+#define STATUS_CODE_JOIN_TIMEOUT                    0xFFF1	/* Join timeout */
+#define STATUS_CODE_AUTH_TIMEOUT                    0xFFF2	/* Authentication timeout */
+#define STATUS_CODE_ASSOC_TIMEOUT                   0xFFF3	/* (Re)Association timeout */
+#define STATUS_CODE_CCX_CCKM_REASSOC_FAILURE        0xFFF4	/* CCX CCKM reassociation failure */
+
+/* 7.3.1.10 Timestamp field */
+#define TIMESTAMP_FIELD_LEN                         8
+
+/* 7.3.1.11 Category of Action field */
+#define CATEGORY_SPEC_MGT                           0
+#define CATEGORY_QOS_ACTION                         1	/* QoS action */
+#define CATEGORY_DLS_ACTION                         2	/* Direct Link Protocol (DLP) action */
+#define CATEGORY_BLOCK_ACK_ACTION                   3	/* Block ack action */
+#define CATEGORY_PUBLIC_ACTION                      4	/* Public action */
+#define CATEGORY_RM_ACTION                          5	/* Radio measurement action */
+#define CATEGORY_HT_ACTION                          7
+#if CFG_SUPPORT_802_11W
+#define CATEGORY_SA_QUERT_ACTION                    8
+#endif
+#define CATEGORY_WNM_ACTION                         10	/* 802.11v Wireless Network Management */
+#define CATEGORY_UNPROTECTED_WNM_ACTION             11	/* 802.11v Wireless Network Management */
+#define CATEGORY_WME_MGT_NOTIFICATION               17	/* WME management notification */
+#define CATEGORY_VENDOR_SPECIFIC_ACTION             127
+
+/* 7.3.1.14 Block Ack Parameter Set field */
+#define BA_PARAM_SET_ACK_POLICY_MASK                BIT(1)
+#define BA_PARAM_SET_ACK_POLICY_MASK_OFFSET         1
+#define BA_PARAM_SET_TID_MASK                       BITS(2, 5)
+#define BA_PARAM_SET_TID_MASK_OFFSET                2
+#define BA_PARAM_SET_BUFFER_SIZE_MASK               BITS(6, 15)
+#define BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET        6
+
+#define BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA        1
+#define BA_PARAM_SET_ACK_POLICY_DELAYED_BA          0
+
+/* 3 Management frame body components (II): Information Elements. */
+/* 7.3.2 Element IDs of information elements */
+#define ELEM_HDR_LEN                                2
+
+#define ELEM_ID_SSID                                0	/* SSID */
+#define ELEM_ID_SUP_RATES                           1	/* Supported rates */
+#define ELEM_ID_FH_PARAM_SET                        2	/* FH parameter set */
+#define ELEM_ID_DS_PARAM_SET                        3	/* DS parameter set */
+#define ELEM_ID_CF_PARAM_SET                        4	/* CF parameter set */
+#define ELEM_ID_TIM                                 5	/* TIM */
+#define ELEM_ID_IBSS_PARAM_SET                      6	/* IBSS parameter set */
+#define ELEM_ID_COUNTRY_INFO                        7	/* Country information */
+#define ELEM_ID_HOPPING_PATTERN_PARAM               8	/* Hopping pattern parameters */
+#define ELEM_ID_HOPPING_PATTERN_TABLE               9	/* Hopping pattern table */
+#define ELEM_ID_REQUEST                             10	/* Request */
+#define ELEM_ID_BSS_LOAD                            11	/* BSS load */
+#define ELEM_ID_EDCA_PARAM_SET                      12	/* EDCA parameter set */
+#define ELEM_ID_TSPEC                               13	/* Traffic specification (TSPEC) */
+#define ELEM_ID_TCLAS                               14	/* Traffic classification (TCLAS) */
+#define ELEM_ID_SCHEDULE                            15	/* Schedule */
+#define ELEM_ID_CHALLENGE_TEXT                      16	/* Challenge text */
+
+#define ELEM_ID_PWR_CONSTRAINT                      32	/* Power constraint */
+#define ELEM_ID_PWR_CAP                             33	/* Power capability */
+#define ELEM_ID_TPC_REQ                             34	/* TPC request */
+#define ELEM_ID_TPC_REPORT                          35	/* TPC report */
+#define ELEM_ID_SUP_CHS                             36	/* Supported channels */
+#define ELEM_ID_CH_SW_ANNOUNCEMENT                  37	/* Channel switch announcement */
+#define ELEM_ID_MEASUREMENT_REQ                     38	/* Measurement request */
+#define ELEM_ID_MEASUREMENT_REPORT                  39	/* Measurement report */
+#define ELEM_ID_QUIET                               40	/* Quiet */
+#define ELEM_ID_IBSS_DFS                            41	/* IBSS DFS */
+#define ELEM_ID_ERP_INFO                            42	/* ERP information */
+#define ELEM_ID_TS_DELAY                            43	/* TS delay */
+#define ELEM_ID_TCLAS_PROCESSING                    44	/* TCLAS processing */
+#define ELEM_ID_HT_CAP                              45	/* HT Capabilities subelement */
+#define ELEM_ID_QOS_CAP                             46	/* QoS capability */
+#define ELEM_ID_RSN                                 48	/* RSN IE */
+#define ELEM_ID_EXTENDED_SUP_RATES                  50	/* Extended supported rates */
+#define ELEM_ID_TIMEOUT_INTERVAL                    56	/* 802.11w SA Timeout interval */
+#define ELEM_ID_SUP_OPERATING_CLASS					59	/* Supported Operating Classes */
+#define ELEM_ID_HT_OP                               61	/* HT Operation */
+#define ELEM_ID_SCO                                 62	/* Secondary Channel Offset */
+#define ELEM_ID_RRM_ENABLED_CAP                     70	/* Radio Resource Management Enabled Capabilities */
+#define ELEM_ID_20_40_BSS_COEXISTENCE               72	/* 20/40 BSS Coexistence */
+#define ELEM_ID_20_40_INTOLERANT_CHNL_REPORT        73	/* 20/40 BSS Intolerant Channel Report */
+#define ELEM_ID_OBSS_SCAN_PARAMS                    74	/* Overlapping BSS Scan Parameters */
+#define ELEM_ID_INTERWORKING                        107	/* Interworking with External Network */
+#define ELEM_ID_ADVERTISEMENT_PROTOCOL              108	/* Advertisement Protocol */
+#define ELEM_ID_ROAMING_CONSORTIUM                  111	/* Roaming Consortium */
+#define ELEM_ID_EXTENDED_CAP                        127	/* Extended capabilities */
+
+#define ELEM_ID_VENDOR                              221	/* Vendor specific IE */
+#define ELEM_ID_WPA                                 ELEM_ID_VENDOR	/* WPA IE */
+#define ELEM_ID_WMM                                 ELEM_ID_VENDOR	/* WMM IE */
+#define ELEM_ID_P2P                                   ELEM_ID_VENDOR	/* WiFi Direct */
+#define ELEM_ID_WFD                                   ELEM_ID_VENDOR	/* WiFi Direct */
+#define ELEM_ID_WSC                                 ELEM_ID_VENDOR	/* WSC IE */
+
+#define ELEM_ID_RESERVED                            255	/* Reserved */
+
+/* 7.3.2.1 SSID element */
+#define ELEM_MAX_LEN_SSID                           32
+
+/* 7.3.2.2 Supported Rates */
+#define ELEM_MAX_LEN_SUP_RATES                      8
+
+/* 7.3.2.4 DS Parameter Set */
+#define ELEM_MAX_LEN_DS_PARAMETER_SET               1
+
+/* 7.3.2.5 CF Parameter Set */
+#define ELEM_CF_PARM_LEN                            8
+
+/* 7.3.2.6 TIM */
+#define ELEM_MIX_LEN_TIM                            4
+#define ELEM_MAX_LEN_TIM                            254
+
+/* 7.3.2.7 IBSS Parameter Set element */
+#define ELEM_MAX_LEN_IBSS_PARAMETER_SET             2
+
+/* 7.3.2.8 Challenge Text element */
+#define ELEM_MIN_LEN_CHALLENGE_TEXT                 1
+#define ELEM_MAX_LEN_CHALLENGE_TEXT                 253
+
+/* 7.3.2.9 Country Information element */
+/* Country IE should contain at least 3-bytes country code string and one subband triplet. */
+#define ELEM_MIN_LEN_COUNTRY_INFO                   6
+
+#define ELEM_ID_COUNTRY_INFO_TRIPLET_LEN_FIXED              3
+#define ELEM_ID_COUNTRY_INFO_SUBBAND_TRIPLET_LEN_FIXED      3
+#define ELEM_ID_COUNTRY_INFO_REGULATORY_TRIPLET_LEN_FIXED   3
+
+/* 7.3.2.13 ERP Information element */
+#define ELEM_MAX_LEN_ERP                            1
+/* -- bits in the ERP Information element */
+#define ERP_INFO_NON_ERP_PRESENT                    BIT(0)	/* NonERP_Present bit */
+#define ERP_INFO_USE_PROTECTION                     BIT(1)	/* Use_Protection bit */
+#define ERP_INFO_BARKER_PREAMBLE_MODE               BIT(2)	/* Barker_Preamble_Mode bit */
+
+/* 7.3.2.14 Extended Supported Rates */
+#define ELEM_MAX_LEN_EXTENDED_SUP_RATES             255
+
+#if CFG_SUPPORT_DFS
+/* 7.3.2.19 Supported Channels element */
+#define ELEM_MAX_LEN_SUPPORTED_CHANNELS            7
+#endif
+
+/* 7.3.2.21 Measurement Request element */
+#define ELEM_RM_TYPE_BASIC_REQ                      0
+#define ELEM_RM_TYPE_CCA_REQ                        1
+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REQ              2
+#define ELEM_RM_TYPE_CHNL_LOAD_REQ                  3
+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REQ            4
+#define ELEM_RM_TYPE_BEACON_REQ                     5
+#define ELEM_RM_TYPE_FRAME_REQ                      6
+#define ELEM_RM_TYPE_STA_STATISTICS_REQ             7
+#define ELEM_RM_TYPE_LCI_REQ                        8
+#define ELEM_RM_TYPE_TS_REQ                         9
+#define ELEM_RM_TYPE_MEASURE_PAUSE_REQ              255
+
+/* 7.3.2.22 Measurement Report element */
+#define ELEM_RM_TYPE_BASIC_REPORT                   0
+#define ELEM_RM_TYPE_CCA_REPORT                     1
+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REPORT           2
+#define ELEM_RM_TYPE_CHNL_LOAD_REPORT               3
+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REPORT         4
+#define ELEM_RM_TYPE_BEACON_REPORT                  5
+#define ELEM_RM_TYPE_FRAME_REPORT                   6
+#define ELEM_RM_TYPE_STA_STATISTICS_REPORT          7
+#define ELEM_RM_TYPE_LCI_REPORT                     8
+#define ELEM_RM_TYPE_TS_REPORT                      9
+/*Auto Channel Selection*/
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+#define ELEM_RM_TYPE_ACS_CHN						1
+#define ELEM_RM_TYPE_LTE_CHN						2
+#endif
+
+/* 7.3.2.25 RSN information element */
+#define ELEM_MAX_LEN_WPA                            34	/* one pairwise, one AKM suite, one PMKID */
+#define ELEM_MAX_LEN_RSN                            38	/* one pairwise, one AKM suite, one PMKID */
+#define ELEM_MAX_LEN_WAPI                           38	/* one pairwise, one AKM suite, one BKID */
+#define ELEM_MAX_LEN_WSC                            200	/* one pairwise, one AKM suite, one BKID */
+
+#if CFG_SUPPORT_802_11W
+#define ELEM_WPA_CAP_MFPR                           BIT(6)
+#define ELEM_WPA_CAP_MFPC                           BIT(7)
+#endif
+
+/* 7.3.2.27 Extended Capabilities information element */
+#define ELEM_EXT_CAP_20_40_COEXIST_SUPPORT          BIT(0)
+#define ELEM_EXT_CAP_PSMP_CAP                       BIT(4)
+#define ELEM_EXT_CAP_SERVICE_INTERVAL_GRANULARITY   BIT(5)
+#define ELEM_EXT_CAP_SCHEDULE_PSMP                  BIT(6)
+
+#define ELEM_EXT_CAP_BSS_TRANSITION_BIT             19
+#define ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT             27
+#define ELEM_EXT_CAP_INTERWORKING_BIT               31
+#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT           46
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+#define ELEM_MAX_LEN_EXT_CAP                        (6)
+#else
+#define ELEM_MAX_LEN_EXT_CAP                        (3 - ELEM_HDR_LEN)
+#endif
+
+/* 7.3.2.30 TSPEC element */
+#define TS_INFO_TRAFFIC_TYPE_MASK                   BIT(0)	/* WMM: 0 (Asynchronous TS of low-duty cycles) */
+#define TS_INFO_TID_OFFSET                          1
+#define TS_INFO_TID_MASK                            BITS(1, 4)
+#define TS_INFO_DIRECTION_OFFSET                    5
+#define TS_INFO_DIRECTION_MASK                      BITS(5, 6)
+#define TS_INFO_ACCESS_POLICY_OFFSET                7
+#define TS_INFO_ACCESS_POLICY_MASK                  BITS(7, 8)
+#define TS_INFO_AGGREGATION_MASK                    BIT(9)	/* WMM: 0 */
+#define TS_INFO_APSD_MASK                           BIT(10)
+#define TS_INFO_UP_OFFSET                           11
+#define TS_INFO_UP_MASK                             BITS(11, 13)
+#define TS_INFO_ACK_POLICY_OFFSET                   14
+#define TS_INFO_ACK_POLICY_MASK                     BITS(14, 15)
+#define TS_INFO_SCHEDULE_MASK                       16
+
+/* 7.3.2.56 HT capabilities element */
+#define ELEM_MAX_LEN_HT_CAP                         (28 - ELEM_HDR_LEN)	/* sizeof(IE_HT_CAP_T)-2 */
+
+/* 7.3.2.56.2 HT capabilities Info field */
+#define HT_CAP_INFO_LDPC_CAP                        BIT(0)
+#define HT_CAP_INFO_SUP_CHNL_WIDTH                  BIT(1)
+#define HT_CAP_INFO_SM_POWER_SAVE                   BITS(2, 3)
+#define HT_CAP_INFO_HT_GF                           BIT(4)
+#define HT_CAP_INFO_SHORT_GI_20M                    BIT(5)
+#define HT_CAP_INFO_SHORT_GI_40M                    BIT(6)
+#define HT_CAP_INFO_TX_STBC                         BIT(7)
+#define HT_CAP_INFO_RX_STBC                         BITS(8, 9)
+#define HT_CAP_INFO_HT_DELAYED_BA                   BIT(10)
+#define HT_CAP_INFO_MAX_AMSDU_LEN                   BIT(11)
+#define HT_CAP_INFO_DSSS_CCK_IN_40M                 BIT(12)
+#define HT_CAP_INFO_40M_INTOLERANT                  BIT(14)
+#define HT_CAP_INFO_LSIG_TXOP_SUPPORT               BIT(15)
+
+#define HT_CAP_INFO_RX_STBC_NO_SUPPORTED            0
+#define HT_CAP_INFO_RX_STBC_1_SS                    BIT(8)
+#define HT_CAP_INFO_RX_STBC_2_SS                    BIT(9)
+#define HT_CAP_INFO_RX_STBC_3_SS                    HT_CAP_INFO_RX_STBC
+
+/* 7.3.2.56.3 A-MPDU Parameters field */
+#define AMPDU_PARAM_MAX_AMPDU_LEN_EXP               BITS(0, 1)
+#define AMPDU_PARAM_MIN_START_SPACING               BITS(2, 4)
+
+#define AMPDU_PARAM_MAX_AMPDU_LEN_8K                0
+#define AMPDU_PARAM_MAX_AMPDU_LEN_16K               BIT(0)
+#define AMPDU_PARAM_MAX_AMPDU_LEN_32K               BIT(1)
+#define AMPDU_PARAM_MAX_AMPDU_LEN_64K               BITS(0, 1)
+
+#define AMPDU_PARAM_MSS_NO_RESTRICIT                0
+#define AMPDU_PARAM_MSS_1_4_US                      BIT(2)
+#define AMPDU_PARAM_MSS_1_2_US                      BIT(3)
+#define AMPDU_PARAM_MSS_1_US                        BITS(2, 3)
+#define AMPDU_PARAM_MSS_2_US                        BIT(4)
+#define AMPDU_PARAM_MSS_4_US                        (BIT(4) | BIT(2))
+#define AMPDU_PARAM_MSS_8_US                        (BIT(4) | BIT(3))
+#define AMPDU_PARAM_MSS_16_US                       BITS(2, 4)
+
+/* 7.3.2.56.4 Supported MCS Set field (TX rate: octects 12~15) */
+#define SUP_MCS_TX_SET_DEFINED                      BIT(0)
+#define SUP_MCS_TX_RX_SET_NOT_EQUAL                 BIT(1)
+#define SUP_MCS_TX_MAX_NUM_SS                       BITS(2, 3)
+#define SUP_MCS_TX_UNEQUAL_MODULATION               BIT(4)
+
+#define SUP_MCS_TX_MAX_NUM_1_SS                     0
+#define SUP_MCS_TX_MAX_NUM_2_SS                     BIT(2)
+#define SUP_MCS_TX_MAX_NUM_3_SS                     BIT(3)
+#define SUP_MCS_TX_MAX_NUM_4_SS                     BITS(2, 3)
+
+#define SUP_MCS_RX_BITMASK_OCTET_NUM                10
+#define SUP_MCS_RX_DEFAULT_HIGHEST_RATE             0	/* Not specify */
+
+/* 7.3.2.56.5 HT Extended Capabilities field */
+#define HT_EXT_CAP_PCO                              BIT(0)
+#define HT_EXT_CAP_PCO_TRANSITION_TIME              BITS(1, 2)
+#define HT_EXT_CAP_MCS_FEEDBACK                     BITS(8, 9)
+#define HT_EXT_CAP_HTC_SUPPORT                      BIT(10)
+#define HT_EXT_CAP_RD_RESPONDER                     BIT(11)
+
+#define HT_EXT_CAP_PCO_TRANS_TIME_NONE              0
+#define HT_EXT_CAP_PCO_TRANS_TIME_400US             BIT(1)
+#define HT_EXT_CAP_PCO_TRANS_TIME_1_5MS             BIT(2)
+#define HT_EXT_CAP_PCO_TRANS_TIME_5MS               BITS(1, 2)
+
+#define HT_EXT_CAP_MCS_FEEDBACK_NO_FB               0
+#define HT_EXT_CAP_MCS_FEEDBACK_UNSOLICITED         BIT(9)
+#define HT_EXT_CAP_MCS_FEEDBACK_BOTH                BITS(8, 9)
+
+/* 7.3.2.56.6 Transmit Beamforming Capabilities field */
+
+/* 7.3.2.56.7 Antenna Selection Capability field */
+#define ASEL_CAP_CAPABLE                            BIT(0)
+#define ASEL_CAP_CSI_FB_BY_TX_ASEL_CAPABLE          BIT(1)
+#define ASEL_CAP_ANT_INDICES_FB_BY_TX_ASEL_CAPABLE  BIT(2)
+#define ASEL_CAP_EXPLICIT_CSI_FB_CAPABLE            BIT(3)
+#define ASEL_CAP_ANT_INDICES_CAPABLE                BIT(4)
+#define ASEL_CAP_RX_ASEL_CAPABLE                    BIT(5)
+#define ASEL_CAP_TX_SOUNDING_CAPABLE                BIT(6)
+
+/* 7.3.2.57 HT Operation element */
+#define ELEM_MAX_LEN_HT_OP                          (24 - ELEM_HDR_LEN)	/* sizeof(IE_HT_OP_T)-2 */
+
+#define HT_OP_INFO1_SCO                             BITS(0, 1)
+#define HT_OP_INFO1_STA_CHNL_WIDTH                  BIT(2)
+#define HT_OP_INFO1_RIFS_MODE                       BIT(3)
+
+#define HT_OP_INFO2_HT_PROTECTION                   BITS(0, 1)
+#define HT_OP_INFO2_NON_GF_HT_STA_PRESENT           BIT(2)
+#define HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT         BIT(4)
+
+#define HT_OP_INFO3_DUAL_BEACON                     BIT(6)
+#define HT_OP_INFO3_DUAL_CTS_PROTECTION             BIT(7)
+#define HT_OP_INFO3_STBC_BEACON                     BIT(8)
+#define HT_OP_INFO3_LSIG_TXOP_FULL_SUPPORT          BIT(9)
+#define HT_OP_INFO3_PCO_ACTIVE                      BIT(10)
+#define HT_OP_INFO3_PCO_PHASE                       BIT(11)
+
+/* 7.3.2.59 OBSS Scan Parameter element */
+#define ELEM_MAX_LEN_OBSS_SCAN                      (16 - ELEM_HDR_LEN)
+
+/* 7.3.2.60 20/40 BSS Coexistence element */
+#define ELEM_MAX_LEN_20_40_BSS_COEXIST              (3 - ELEM_HDR_LEN)
+
+#define BSS_COEXIST_INFO_REQ                        BIT(0)
+#define BSS_COEXIST_40M_INTOLERANT                  BIT(1)
+#define BSS_COEXIST_20M_REQ                         BIT(2)
+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ         BIT(3)
+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_GRANT       BIT(4)
+
+/* 802.11u 7.3.2.92 Interworking IE */
+#define ELEM_MAX_LEN_INTERWORKING                   (11 - ELEM_HDR_LEN)
+
+/* 802.11u 7.3.2.93 Advertisement Protocol IE */
+#define ELEM_MAX_LEN_ADV_PROTOCOL                   (4 - ELEM_HDR_LEN)
+
+/* 802.11u 7.3.2.96 Roaming Consortium IE */
+#define ELEM_MAX_LEN_ROAMING_CONSORTIUM             (19 - ELEM_HDR_LEN)
+
+#define IW_IE_LENGTH_ANO                            1
+#define IW_IE_LENGTH_ANO_VENUE                      3
+#define IW_IE_LENGTH_ANO_HESSID                     7
+#define IW_IE_LENGTH_ANO_VENUE_HESSID               9
+
+/* 3 Management frame body components (III): 7.4 Action frame format details. */
+/* 7.4.1 Spectrum Measurement Action frame details */
+#define ACTION_MEASUREMENT_REQ                      0	/* Spectrum measurement request */
+#define ACTION_MEASUREMENT_REPORT                   1	/* Spectrum measurement report */
+#define ACTION_TPC_REQ                              2	/* TPC request */
+#define ACTION_TPC_REPORT                           3	/* TPC report */
+#define ACTION_CHNL_SWITCH                          4	/* Channel Switch Announcement */
+
+/* 7.4.2 QoS Action frame details */
+#define ACTION_ADDTS_REQ                            0	/* ADDTS request */
+#define ACTION_ADDTS_RSP                            1	/* ADDTS response */
+#define ACTION_DELTS                                2	/* DELTS */
+#define ACTION_SCHEDULE                             3	/* Schedule */
+
+#define ACTION_ADDTS_REQ_FRAME_LEN                  (24+3+63)	/* WMM TSPEC IE: 63 */
+#define ACTION_ADDTS_RSP_FRAME_LEN                  (24+4+63)	/* WMM Status Code: 1; WMM TSPEC IE: 63 */
+
+/* 7.4.3 DLS Action frame details */
+#define ACTION_DLS_REQ                              0	/* DLS request */
+#define ACTION_DLS_RSP                              1	/* DLS response */
+#define ACTION_DLS_TEARDOWN                         2	/* DLS teardown */
+
+/* 7.4.4 Block ack  Action frame details */
+#define ACTION_ADDBA_REQ                            0	/* ADDBA request */
+#define ACTION_ADDBA_RSP                            1	/* ADDBA response */
+#define ACTION_DELBA                                2	/* DELBA */
+
+#define ACTION_ADDBA_REQ_FRAME_LEN                  (24+9)
+#define ACTION_ADDBA_RSP_FRAME_LEN                  (24+9)
+
+#define ACTION_DELBA_INITIATOR_MASK                 BIT(11)
+#define ACTION_DELBA_TID_MASK                       BITS(12, 15)
+#define ACTION_DELBA_TID_OFFSET                     12
+#define ACTION_DELBA_FRAME_LEN                      (24+6)
+
+/* 7.4.6 Radio Measurement Action frame details */
+#define ACTION_RM_REQ                               0	/* Radio measurement request */
+#define ACTION_RM_REPORT                            1	/* Radio measurement report */
+#define ACTION_LM_REQ                               2	/* Link measurement request */
+#define ACTION_LM_REPORT                            3	/* Link measurement report */
+#define ACTION_NEIGHBOR_REPORT_REQ                  4	/* Neighbor report request */
+#define ACTION_NEIGHBOR_REPORT_RSP                  5	/* Neighbor report response */
+
+/* 7.4.7 Public Action frame details */
+#define ACTION_PUBLIC_20_40_COEXIST                 0	/* 20/40 BSS coexistence */
+
+#if CFG_SUPPORT_802_11W
+/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */
+#define ACTION_SA_QUERY_REQUEST                     0
+#define ACTION_SA_QUERY_RESPONSE                    1
+
+#define ACTION_SA_QUERY_TR_ID_LEN                   2
+
+/* Timeout Interval Type */
+#define ACTION_SA_TIMEOUT_REASSOC_DEADLINE          1
+#define ACTION_SA_TIMEOUT_KEY_LIFETIME              2
+#define ACTION_SA_TIMEOUT_ASSOC_COMEBACK            3
+#endif
+
+/* 7.4.10.1 HT action frame details */
+#define ACTION_HT_NOTIFY_CHANNEL_WIDTH              0	/* Notify Channel Width */
+#define ACTION_HT_SM_POWER_SAVE                     1	/* SM Power Save */
+#define ACTION_HT_PSMP                              2	/* PSMP */
+#define ACTION_HT_SET_PCO_PHASE                     3	/* Set PCO Phase */
+#define ACTION_HT_CSI                               4	/* CSI */
+#define ACTION_HT_NON_COMPRESSED_BEAMFORM           5	/* Non-compressed Beamforming */
+#define ACTION_HT_COMPRESSED_BEAMFORM               6	/* Compressed Beamforming */
+#define ACTION_HT_ANT_SEL_INDICES_FB                7	/* Antenna Selection Indices Feedback */
+
+/* 802.11v Wireless Network Management */
+#define ACTION_WNM_TIMING_MEASUREMENT_REQUEST       27
+
+#define ACTION_UNPROTECTED_WNM_TIM                  0
+#define ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT   1
+
+#define ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN      12
+
+/* 3  --------------- WFA  frame body fields --------------- */
+#define VENDOR_OUI_WFA                              { 0x00, 0x50, 0xF2 }
+#define VENDOR_OUI_WFA_SPECIFIC                     { 0x50, 0x6F, 0x9A }
+#define VENDOR_OUI_TYPE_WPA                         1
+#define VENDOR_OUI_TYPE_WMM                         2
+#define VENDOR_OUI_TYPE_WPS                         4
+#define VENDOR_OUI_TYPE_P2P                         9
+#define VENDOR_OUI_TYPE_WFD                         10
+#define VENDOR_OUI_TYPE_HS20                        16
+
+#define VENDOR_OUI_TYPE_LEN                         4	/* Length of OUI and Type */
+
+/* VERSION(2 octets for WPA) / SUBTYPE(1 octet)-VERSION(1 octet) fields for WMM in WFA IE */
+#define VERSION_WPA                                 0x0001	/* Little Endian Format */
+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_INFO         0x0100
+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_PARAM        0x0101
+
+/* SUBTYPE(1 octet) for WMM */
+#define VENDOR_OUI_SUBTYPE_WMM_INFO                 0x00	/* WMM Spec version 1.1 */
+#define VENDOR_OUI_SUBTYPE_WMM_PARAM                0x01
+#define VENDOR_OUI_SUBTYPE_WMM_TSPEC                0x02
+
+/* VERSION(1 octet) for WMM */
+#define VERSION_WMM                                 0x01	/* WMM Spec version 1.1 */
+
+/* WMM-2.1.6 QoS Control Field */
+#define WMM_QC_UP_MASK                              BITS(0, 2)
+#define WMM_QC_EOSP                                 BIT(4)
+#define WMM_QC_ACK_POLICY_MASK                      BITS(5, 6)
+#define WMM_QC_ACK_POLICY_OFFSET                    5
+#define WMM_QC_ACK_POLICY_ACKNOWLEDGE               0
+#define WMM_QC_ACK_POLICY_NOT_ACKNOWLEDGE           (1 << WMM_QC_ACK_POLICY_OFFSET)
+
+/* WMM-2.2.1 WMM Information Element */
+#define ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE           6
+
+/* HOTSPOT 2.0 Indication IE*/
+#define ELEM_MAX_LEN_HS20_INDICATION                5
+#define ELEM_MIN_LEN_HS20_INDICATION                4
+
+/* Hotspot Configuration*/
+#define ELEM_HS_CONFIG_DGAF_DISABLED_MASK           BIT(0)	/* Downstream Group-Addressed Forwarding */
+
+/* 3 Control frame body */
+/* 7.2.1.7 BlockAckReq */
+#define CTRL_BAR_BAR_CONTROL_OFFSET                 16
+#define CTRL_BAR_BAR_INFORMATION_OFFSET             18
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE)
+#pragma pack(1)
+#endif
+
+typedef struct _LLC_SNAP_HEADER_T {
+	UINT_8 ucDSAP;
+	UINT_8 ucSSAP;
+	UINT_8 ucControl;
+	UINT_8 aucCode[3];
+	UINT_16 u2Type;
+} __KAL_ATTRIB_PACKED__ LLC_SNAP_HEADER_T, *P_LLC_SNAP_HEADER_T;
+
+/* 3 MAC Header. */
+/* Ethernet Frame Header */
+typedef struct _ETH_FRAME_HEADER_T {
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];
+	UINT_16 u2TypeLen;
+} __KAL_ATTRIB_PACKED__ ETH_FRAME_HEADER_T, *P_ETH_FRAME_HEADER_T;
+
+/* Ethernet Frame Structure */
+typedef struct _ETH_FRAME_T {
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];
+	UINT_16 u2TypeLen;
+	UINT_8 aucData[1];
+} __KAL_ATTRIB_PACKED__ ETH_FRAME_T, *P_ETH_FRAME_T;
+
+/* IEEE 802.11 WLAN Frame Structure */
+/* WLAN MAC Header (without Address 4 and QoS Control fields) */
+typedef struct _WLAN_MAC_HEADER_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2DurationID;
+	UINT_8 aucAddr1[MAC_ADDR_LEN];
+	UINT_8 aucAddr2[MAC_ADDR_LEN];
+	UINT_8 aucAddr3[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_T, *P_WLAN_MAC_HEADER_T;
+
+/* WLAN MAC Header (QoS Control fields included) */
+typedef struct _WLAN_MAC_HEADER_QOS_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2DurationID;
+	UINT_8 aucAddr1[MAC_ADDR_LEN];
+	UINT_8 aucAddr2[MAC_ADDR_LEN];
+	UINT_8 aucAddr3[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+	UINT_16 u2QosCtrl;
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_QOS_T, *P_WLAN_MAC_HEADER_QOS_T;
+
+/* WLAN MAC Header (HT Control fields included) */
+typedef struct _WLAN_MAC_HEADER_HT_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2DurationID;
+	UINT_8 aucAddr1[MAC_ADDR_LEN];
+	UINT_8 aucAddr2[MAC_ADDR_LEN];
+	UINT_8 aucAddr3[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+	UINT_16 u2QosCtrl;
+	UINT_32 u4HtCtrl;
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_HT_T, *P_WLAN_MAC_HEADER_HT_T;
+
+/* WLAN MAC Header (Address 4 included) */
+typedef struct _WLAN_MAC_HEADER_A4_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2DurationID;
+	UINT_8 aucAddr1[MAC_ADDR_LEN];
+	UINT_8 aucAddr2[MAC_ADDR_LEN];
+	UINT_8 aucAddr3[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+	UINT_8 aucAddr4[MAC_ADDR_LEN];
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_T, *P_WLAN_MAC_HEADER_A4_T;
+
+/* WLAN MAC Header (Address 4 and QoS Control fields included) */
+typedef struct _WLAN_MAC_HEADER_A4_QOS_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2DurationID;
+	UINT_8 aucAddr1[MAC_ADDR_LEN];
+	UINT_8 aucAddr2[MAC_ADDR_LEN];
+	UINT_8 aucAddr3[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+	UINT_8 aucAddr4[MAC_ADDR_LEN];
+	UINT_16 u2QosCtrl;
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_QOS_T, *P_WLAN_MAC_HEADER_A4_QOS_T;
+
+typedef struct _WLAN_MAC_HEADER_A4_HT_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2DurationID;
+	UINT_8 aucAddr1[MAC_ADDR_LEN];
+	UINT_8 aucAddr2[MAC_ADDR_LEN];
+	UINT_8 aucAddr3[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+	UINT_8 aucAddr4[MAC_ADDR_LEN];
+	UINT_16 u2QosCtrl;
+	UINT_32 u4HtCtrl;
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_HT_T, *P_WLAN_MAC_HEADER_A4_HT_T;
+
+/* 7.2.3 WLAN MAC Header for Management Frame - MMPDU */
+typedef struct _WLAN_MAC_MGMT_HEADER_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2Duration;
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];
+	UINT_8 aucBSSID[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_T, *P_WLAN_MAC_MGMT_HEADER_T;
+
+/* WLAN MAC Header for Management Frame (HT Control fields included) */
+typedef struct _WLAN_MAC_MGMT_HEADER_HT_T {
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2DurationID;
+	UINT_8 aucAddr1[MAC_ADDR_LEN];
+	UINT_8 aucAddr2[MAC_ADDR_LEN];
+	UINT_8 aucAddr3[MAC_ADDR_LEN];
+	UINT_16 u2SeqCtrl;
+	UINT_32 u4HtCtrl;
+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_HT_T, *P_WLAN_MAC_MGMT_HEADER_HT_T;
+
+/* 3 WLAN CONTROL Frame */
+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */
+typedef struct _CTRL_PSPOLL_FRAME_T {
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2AID;		/* AID */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_8 aucTA[MAC_ADDR_LEN];	/* TA */
+} __KAL_ATTRIB_PACKED__ CTRL_PSPOLL_FRAME_T, *P_CTRL_PSPOLL_FRAME_T;
+
+/* BAR */
+typedef struct _CTRL_BAR_FRAME_T {
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* RA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* TA */
+	UINT_16 u2BarControl;
+	UINT_8 aucBarInfo[2];	/* Variable size */
+} __KAL_ATTRIB_PACKED__ CTRL_BAR_FRAME_T, *P_CTRL_BAR_FRAME_T;
+
+/* 3 WLAN Management Frame. */
+/* 7.2.3.1 WLAN Management Frame - Beacon Frame */
+typedef struct _WLAN_BEACON_FRAME_T {
+	/* Beacon header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Beacon frame body */
+	UINT_32 au4Timestamp[2];	/* Timestamp */
+	UINT_16 u2BeaconInterval;	/* Beacon Interval */
+	UINT_16 u2CapInfo;	/* Capability */
+	UINT_8 aucInfoElem[1];	/* Various IEs, start from SSID */
+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_T, *P_WLAN_BEACON_FRAME_T;
+
+typedef struct _WLAN_BEACON_FRAME_BODY_T {
+	/* Beacon frame body */
+	UINT_32 au4Timestamp[2];	/* Timestamp */
+	UINT_16 u2BeaconInterval;	/* Beacon Interval */
+	UINT_16 u2CapInfo;	/* Capability */
+	UINT_8 aucInfoElem[1];	/* Various IEs, start from SSID */
+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_BODY_T, *P_WLAN_BEACON_FRAME_BODY_T;
+
+/* 7.2.3.3 WLAN Management Frame - Disassociation Frame */
+typedef struct _WLAN_DISASSOC_FRAME_T {
+	/* Authentication MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Disassociation frame body */
+	UINT_16 u2ReasonCode;	/* Reason code */
+	UINT_8 aucInfoElem[1];	/* Various IEs, possible no. */
+} __KAL_ATTRIB_PACKED__ WLAN_DISASSOC_FRAME_T, *P_WLAN_DISASSOC_FRAME_T;
+
+/* 7.2.3.4 WLAN Management Frame - Association Request frame */
+typedef struct _WLAN_ASSOC_REQ_FRAME_T {
+	/* Association Request MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Association Request frame body */
+	UINT_16 u2CapInfo;	/* Capability information */
+	UINT_16 u2ListenInterval;	/* Listen interval */
+	UINT_8 aucInfoElem[1];	/* Information elements, include WPA IE */
+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_REQ_FRAME_T, *P_WLAN_ASSOC_REQ_FRAME_T;
+
+/* 7.2.3.5 WLAN Management Frame - Association Response frame */
+typedef struct _WLAN_ASSOC_RSP_FRAME_T {
+	/* Association Response MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Association Response frame body */
+	UINT_16 u2CapInfo;	/* Capability information */
+	UINT_16 u2StatusCode;	/* Status code */
+	UINT_16 u2AssocId;	/* Association ID */
+	UINT_8 aucInfoElem[1];	/* Information elements, such as
+				   supported rates, and etc. */
+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_RSP_FRAME_T, *P_WLAN_ASSOC_RSP_FRAME_T;
+
+/* 7.2.3.6 WLAN Management Frame - Reassociation Request frame */
+typedef struct _WLAN_REASSOC_REQ_FRAME_T {
+	/* Reassociation Request MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Reassociation Request frame body */
+	UINT_16 u2CapInfo;	/* Capability information */
+	UINT_16 u2ListenInterval;	/* Listen interval */
+	UINT_8 aucCurrentAPAddr[MAC_ADDR_LEN];	/* Current AP address */
+	UINT_8 aucInfoElem[1];	/* Information elements, include WPA IE */
+} __KAL_ATTRIB_PACKED__ WLAN_REASSOC_REQ_FRAME_T, *P_WLAN_REASSOC_REQ_FRAME_T;
+
+/* 7.2.3.7 WLAN Management Frame - Reassociation Response frame
+   (the same as Association Response frame) */
+typedef WLAN_ASSOC_RSP_FRAME_T WLAN_REASSOC_RSP_FRAME_T, *P_WLAN_REASSOC_RSP_FRAME_T;
+
+/* 7.2.3.9 WLAN Management Frame - Probe Response Frame */
+typedef WLAN_BEACON_FRAME_T WLAN_PROBE_RSP_FRAME_T, *P_WLAN_PROBE_RSP_FRAME_T;
+
+/* 7.2.3.10 WLAN Management Frame - Authentication Frame */
+typedef struct _WLAN_AUTH_FRAME_T {
+	/* Authentication MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Authentication frame body */
+	UINT_16 u2AuthAlgNum;	/* Authentication algorithm number */
+	UINT_16 u2AuthTransSeqNo;	/* Authentication transaction sequence number */
+	UINT_16 u2StatusCode;	/* Status code */
+	UINT_8 aucInfoElem[1];	/* Various IEs for Fast BSS Transition */
+} __KAL_ATTRIB_PACKED__ WLAN_AUTH_FRAME_T, *P_WLAN_AUTH_FRAME_T;
+
+/* 7.2.3.11 WLAN Management Frame - Deauthentication Frame */
+typedef struct _WLAN_DEAUTH_FRAME_T {
+	/* Authentication MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Deauthentication frame body */
+	UINT_16 u2ReasonCode;	/* Reason code */
+	UINT_8 aucInfoElem[1];	/* Various IEs, possible no. */
+} __KAL_ATTRIB_PACKED__ WLAN_DEAUTH_FRAME_T, *P_WLAN_DEAUTH_FRAME_T;
+
+/* 3 Information Elements. */
+/* 7.3.2 Generic element format */
+typedef struct _IE_HDR_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucInfo[1];
+} __KAL_ATTRIB_PACKED__ IE_HDR_T, *P_IE_HDR_T;
+
+/* 7.3.2.1 SSID element */
+typedef struct _IE_SSID_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];
+} __KAL_ATTRIB_PACKED__ IE_SSID_T, *P_IE_SSID_T;
+
+/* 7.3.2.2 Supported Rates element */
+typedef struct _IE_SUPPORTED_RATE_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucSupportedRates[ELEM_MAX_LEN_SUP_RATES];
+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_RATE_T, *P_IE_SUPPORTED_RATE_T;
+
+/* 7.3.2.4 DS Parameter Set element */
+typedef struct _IE_DS_PARAM_SET_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucCurrChnl;
+} __KAL_ATTRIB_PACKED__ IE_DS_PARAM_SET_T, *P_IE_DS_PARAM_SET_T;
+
+/* 7.3.2.5 CF Parameter Set element */
+typedef struct _IE_CF_PARAM_SET_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucCFPCount;
+	UINT_8 ucCFPPeriod;
+	UINT_16 u2CFPMaxDur;
+	UINT_16 u2DurRemaining;
+} __KAL_ATTRIB_PACKED__ IE_CF_PARAM_SET_T, *P_IE_CF_PARAM_SET_T;
+
+/* 7.3.2.6 TIM */
+typedef struct _IE_TIM_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucDTIMCount;
+	UINT_8 ucDTIMPeriod;
+	UINT_8 ucBitmapControl;
+	UINT_8 aucPartialVirtualMap[1];
+} __KAL_ATTRIB_PACKED__ IE_TIM_T, *P_IE_TIM_T;
+
+/* 7.3.2.7 IBSS Parameter Set element */
+typedef struct _IE_IBSS_PARAM_SET_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_16 u2ATIMWindow;
+} __KAL_ATTRIB_PACKED__ IE_IBSS_PARAM_SET_T, *P_IE_IBSS_PARAM_SET_T;
+
+/* 7.3.2.8 Challenge Text element */
+typedef struct _IE_CHALLENGE_TEXT_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucChallengeText[ELEM_MAX_LEN_CHALLENGE_TEXT];
+} __KAL_ATTRIB_PACKED__ IE_CHALLENGE_TEXT_T, *P_IE_CHALLENGE_TEXT_T;
+
+/* 7.3.2.9 Country information element */
+#if CFG_SUPPORT_802_11D
+/*! \brief COUNTRY_INFO_TRIPLET is defined for the COUNTRY_INFO_ELEM structure. */
+typedef struct _COUNTRY_INFO_TRIPLET_T {
+	UINT_8 ucParam1;	/*!< If param1 >= 201, this triplet is referred to as
+				   Regulatory Triplet in 802_11J. */
+	UINT_8 ucParam2;
+	UINT_8 ucParam3;
+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_TRIPLET_T, *P_COUNTRY_INFO_TRIPLET_T;
+
+typedef struct _COUNTRY_INFO_SUBBAND_TRIPLET_T {
+	UINT_8 ucFirstChnlNum;	/*!< First Channel Number */
+	UINT_8 ucNumOfChnl;	/*!< Number of Channels */
+	INT_8 cMaxTxPwrLv;	/*!< Maximum Transmit Power Level */
+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_SUBBAND_TRIPLET_T, *P_COUNTRY_INFO_SUBBAND_TRIPLET_T;
+
+typedef struct _COUNTRY_INFO_REGULATORY_TRIPLET_T {
+	UINT_8 ucRegExtId;	/*!< Regulatory Extension Identifier, should
+				   be greater than or equal to 201 */
+	UINT_8 ucRegClass;	/*!< Regulatory Class */
+	UINT_8 ucCoverageClass;	/*!< Coverage Class, unsigned 1-octet value 0~31
+				   , 32~255 reserved */
+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_REGULATORY_TRIPLET_T, *P_COUNTRY_INFO_REGULATORY_TRIPLET_T;
+
+typedef struct _IE_COUNTRY_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucCountryStr[3];
+	COUNTRY_INFO_SUBBAND_TRIPLET_T arCountryStr[1];
+} __KAL_ATTRIB_PACKED__ IE_COUNTRY_T, *P_IE_COUNTRY_T;
+#endif /* CFG_SUPPORT_802_11D */
+
+/* 7.3.2.13 ERP element */
+typedef struct _IE_ERP_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucERP;
+} __KAL_ATTRIB_PACKED__ IE_ERP_T, *P_IE_ERP_T;
+
+/* 7.3.2.14 Extended Supported Rates element */
+typedef struct _IE_EXT_SUPPORTED_RATE_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucExtSupportedRates[ELEM_MAX_LEN_EXTENDED_SUP_RATES];
+} __KAL_ATTRIB_PACKED__ IE_EXT_SUPPORTED_RATE_T, *P_IE_EXT_SUPPORTED_RATE_T;
+
+/* 7.3.2.15 Power Constraint element */
+typedef struct _IE_POWER_CONSTRAINT_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucLocalPowerConstraint;	/* Unit: dBm */
+} __KAL_ATTRIB_PACKED__ IE_POWER_CONSTRAINT_T, *P_IE_POWER_CONSTRAINT_T;
+
+/* 7.3.2.16 Power Capability element */
+typedef struct _IE_POWER_CAP_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	INT_8 cMinTxPowerCap;	/* Unit: dBm */
+	INT_8 cMaxTxPowerCap;	/* Unit: dBm */
+} __KAL_ATTRIB_PACKED__ IE_POWER_CAP_T, *P_IE_POWER_CAP_T;
+
+/* 7.3.2.17 TPC request element */
+typedef struct _IE_TPC_REQ_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+} __KAL_ATTRIB_PACKED__ IE_TPC_REQ_T, *P_IE_TPC_REQ_T;
+
+/* 7.3.2.18 TPC report element */
+typedef struct _IE_TPC_REPORT_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	INT_8 cTxPower;		/* Unit: dBm */
+	INT_8 cLinkMargin;	/* Unit: dB */
+} __KAL_ATTRIB_PACKED__ IE_TPC_REPORT_T, *P_IE_TPC_REPORT_T;
+
+#if CFG_SUPPORT_DFS		/* Add by Enlai */
+/* 7.3.2.19 Supported Channels element*/
+typedef struct _IE_SUPPORTED_CHANNELS_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucChannelNum[ELEM_MAX_LEN_SUPPORTED_CHANNELS * 2];
+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_CHANNELS_T, *P_IE_SUPPORTED_CHANNELS_T;
+
+/* 7.3.2.20 Channel Switch Announcement element*/
+typedef struct _IE_CHANNEL_SWITCH_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucChannelSwitchMode;
+	UINT_8 ucNewChannelNum;
+	UINT_8 ucChannelSwitchCount;
+} __KAL_ATTRIB_PACKED__ IE_CHANNEL_SWITCH_T, *P_IE_CHANNEL_SWITCH_T;
+#endif
+
+/* 7.3.2.21 Measurement Request element */
+typedef struct _IE_MEASUREMENT_REQ_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucToken;
+	UINT_8 ucRequestMode;
+	UINT_8 ucMeasurementType;
+	UINT_8 aucRequestFields[1];
+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REQ_T, *P_IE_MEASUREMENT_REQ_T;
+
+typedef struct _SM_BASIC_REQ_T {
+	UINT_8 ucChannel;
+	UINT_32 au4StartTime[2];
+	UINT_16 u2Duration;
+} __KAL_ATTRIB_PACKED__ SM_BASIC_REQ_T, *P_SM_BASIC_REQ_T;
+
+/* SM_COMMON_REQ_T is not specified in Spec. Use it as common structure of SM */
+typedef SM_BASIC_REQ_T SM_REQ_COMMON_T, *P_SM_REQ_COMMON_T;
+typedef SM_BASIC_REQ_T SM_CCA_REQ_T, *P_SM_CCA_REQ_T;
+typedef SM_BASIC_REQ_T SM_RPI_HISTOGRAM_REQ_T, *P_SM_RPI_HISTOGRAM_REQ_T;
+
+typedef struct _RM_CHNL_LOAD_REQ_T {
+	UINT_8 ucRegulatoryClass;
+	UINT_8 ucChannel;
+	UINT_16 u2RandomInterval;
+	UINT_16 u2Duration;
+	UINT_8 aucSubElements[1];
+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REQ_T, *P_RM_CHNL_LOAD_REQ_T;
+
+typedef RM_CHNL_LOAD_REQ_T RM_NOISE_HISTOGRAM_REQ_T, *P_RM_NOISE_HISTOGRAM_REQ_T;
+
+typedef struct _RM_BCN_REQ_T {
+	UINT_8 ucRegulatoryClass;
+	UINT_8 ucChannel;
+	UINT_16 u2RandomInterval;
+	UINT_16 u2Duration;
+	UINT_8 ucMeasurementMode;
+	UINT_8 aucBssid[6];
+	UINT_8 aucSubElements[1];
+} __KAL_ATTRIB_PACKED__ RM_BCN_REQ_T, *P_RM_BCN_REQ_T;
+
+typedef struct _RM_FRAME_REQ_T {
+	UINT_8 ucRegulatoryClass;
+	UINT_8 ucChannel;
+	UINT_16 u2RandomInterval;
+	UINT_16 u2Duration;
+	UINT_8 ucFrameReqType;
+	UINT_8 aucMacAddr[6];
+	UINT_8 aucSubElements[1];
+} __KAL_ATTRIB_PACKED__ RM_FRAME_REQ_T, *P_RM_FRAME_REQ_T;
+
+typedef struct _RM_STA_STATS_REQ_T {
+	UINT_8 aucPeerMacAddr[6];
+	UINT_16 u2RandomInterval;
+	UINT_16 u2Duration;
+	UINT_8 ucGroupID;
+	UINT_8 aucSubElements[1];
+} __KAL_ATTRIB_PACKED__ RM_STA_STATS_REQ_T, *P_RM_STA_STATS_REQ_T;
+
+typedef struct _RM_LCI_REQ_T {
+	UINT_8 ucLocationSubject;
+	UINT_8 ucLatitudeResolution;
+	UINT_8 ucLongitudeResolution;
+	UINT_8 ucAltitudeResolution;
+	UINT_8 aucSubElements[1];
+} __KAL_ATTRIB_PACKED__ RM_LCI_REQ_T, *P_RM_LCI_REQ_T;
+
+typedef struct _RM_TS_MEASURE_REQ_T {
+	UINT_16 u2RandomInterval;
+	UINT_16 u2Duration;
+	UINT_8 aucPeerStaAddr[6];
+	UINT_8 ucTrafficID;
+	UINT_8 ucBin0Range;
+	UINT_8 aucSubElements[1];
+} __KAL_ATTRIB_PACKED__ RM_TS_MEASURE_REQ_T, *P_RM_TS_MEASURE_REQ_T;
+
+typedef struct _RM_MEASURE_PAUSE_REQ_T {
+	UINT_16 u2PauseTime;
+	UINT_8 aucSubElements[1];
+} __KAL_ATTRIB_PACKED__ RM_MEASURE_PAUSE_REQ_T, *P_RM_MEASURE_PAUSE_REQ_T;
+
+/* 7.3.2.22 Measurement Report element */
+typedef struct _IE_MEASUREMENT_REPORT_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucToken;
+	UINT_8 ucReportMode;
+	UINT_8 ucMeasurementType;
+	UINT_8 aucReportFields[1];
+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REPORT_T, *P_IE_MEASUREMENT_REPORT_T;
+
+typedef struct _SM_BASIC_REPORT_T {
+	UINT_8 ucChannel;
+	UINT_32 u4StartTime[2];
+	UINT_16 u2Duration;
+	UINT_8 ucMap;
+} __KAL_ATTRIB_PACKED__ SM_BASIC_REPORT_T, *P_SM_BASIC_REPORT_T;
+
+typedef struct _SM_CCA_REPORT_T {
+	UINT_8 ucChannel;
+	UINT_32 u4StartTime[2];
+	UINT_16 u2Duration;
+	UINT_8 ucCcaBusyFraction;
+} __KAL_ATTRIB_PACKED__ SM_CCA_REPORT_T, *P_SM_CCA_REPORT_T;
+
+typedef struct _SM_RPI_REPORT_T {
+	UINT_8 ucChannel;
+	UINT_32 u4StartTime[2];
+	UINT_16 u2Duration;
+	UINT_8 aucRPI[8];
+} __KAL_ATTRIB_PACKED__ SM_RPI_REPORT_T, *P_SM_RPI_REPORT_T;
+
+typedef struct _RM_CHNL_LOAD_REPORT_T {
+	UINT_8 ucRegulatoryClass;
+	UINT_8 ucChannel;
+	UINT_32 u4StartTime[2];
+	UINT_16 u2Duration;
+	UINT_8 ucChnlLoad;
+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REPORT_T, *P_RM_CHNL_LOAD_REPORT_T;
+
+typedef struct _RM_IPI_REPORT_T {
+	UINT_8 ucRegulatoryClass;
+	UINT_8 ucChannel;
+	UINT_32 u4StartTime[2];
+	UINT_16 u2Duration;
+	UINT_8 ucAntennaId;
+	INT_8 cANPI;
+	UINT_8 aucIPI[11];
+} __KAL_ATTRIB_PACKED__ RM_IPI_REPORT_T, *P_RM_IPI_REPORT_T;
+
+/* 7.3.2.23 Quiet element */
+typedef struct _IE_QUIET_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucCount;
+	UINT_8 ucPeriod;
+	UINT_16 u2Duration;
+	UINT_16 u2Offset;
+} __KAL_ATTRIB_PACKED__ IE_QUIET_T, *P_IE_QUIET_T;
+
+/* 7.3.2.27 Extended Capabilities element */
+typedef struct _IE_EXT_CAP_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucCapabilities[5];
+} __KAL_ATTRIB_PACKED__ IE_EXT_CAP_T, *P_EXT_CAP_T;
+
+/* 7.3.2.27 hs20 Extended Capabilities element */
+typedef struct _IE_HS20_EXT_CAP_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucCapabilities[6];
+} __KAL_ATTRIB_PACKED__ IE_HS20_EXT_CAP_T, *P_HS20_EXT_CAP_T;
+
+
+/* 7.3.2.27 Extended Capabilities element */
+typedef struct _IE_RRM_ENABLED_CAP_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucCap[5];
+} __KAL_ATTRIB_PACKED__ IE_RRM_ENABLED_CAP_T, *P_IE_RRM_ENABLED_CAP_T;
+
+/* 7.3.2.51 Timeout Interval element (TIE) */
+typedef struct _IE_TIMEOUT_INTERVAL_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+#define IE_TIMEOUT_INTERVAL_TYPE_RESERVED			0
+#define IE_TIMEOUT_INTERVAL_TYPE_REASSOC			1
+#define IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME		2
+#define IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK		3
+	UINT_8 ucType;
+	UINT_32 u4Value;
+} __KAL_ATTRIB_PACKED__ IE_TIMEOUT_INTERVAL_T;
+
+/* 7.3.2.56 HT Capabilities element */
+typedef struct _SUP_MCS_SET_FIELD {
+	UINT_8 aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM];
+	UINT_16 u2RxHighestSupportedRate;
+	UINT_32 u4TxRateInfo;
+} __KAL_ATTRIB_PACKED__ SUP_MCS_SET_FIELD, *P_SUP_MCS_SET_FIELD;
+
+typedef struct _IE_HT_CAP_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_16 u2HtCapInfo;
+	UINT_8 ucAmpduParam;
+	SUP_MCS_SET_FIELD rSupMcsSet;
+	UINT_16 u2HtExtendedCap;
+	UINT_32 u4TxBeamformingCap;
+	UINT_8 ucAselCap;
+} __KAL_ATTRIB_PACKED__ IE_HT_CAP_T, *P_IE_HT_CAP_T;
+
+/* 7.3.2.57 HT Operation element */
+typedef struct _IE_HT_OP_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucPrimaryChannel;
+	UINT_8 ucInfo1;
+	UINT_16 u2Info2;
+	UINT_16 u2Info3;
+	UINT_8 aucBasicMcsSet[16];
+} __KAL_ATTRIB_PACKED__ IE_HT_OP_T, *P_IE_HT_OP_T;
+
+/* 7.3.2.25 RSN Information element format */
+typedef struct _RSN_INFO_ELEM_T {
+	UCHAR ucElemId;
+	UCHAR ucLength;
+	UINT_16 u2Version;
+	UINT_32 u4GroupKeyCipherSuite;
+	UINT_16 u2PairwiseKeyCipherSuiteCount;
+	UCHAR aucPairwiseKeyCipherSuite1[4];
+} __KAL_ATTRIB_PACKED__ RSN_INFO_ELEM_T, *P_RSN_INFO_ELEM_T;
+
+/* 7.3.2.26 WPA Information element format */
+typedef struct _WPA_INFO_ELEM_T {
+	UCHAR ucElemId;
+	UCHAR ucLength;
+	UCHAR aucOui[3];
+	UCHAR ucOuiType;
+	UINT_16 u2Version;
+	UINT_32 u4GroupKeyCipherSuite;
+	UINT_16 u2PairwiseKeyCipherSuiteCount;
+	UCHAR aucPairwiseKeyCipherSuite1[4];
+} __KAL_ATTRIB_PACKED__ WPA_INFO_ELEM_T, *P_WPA_INFO_ELEM_T;
+
+/* 7.3.2.58 20/40 BSS Intolerant Channel Report element */
+typedef struct _IE_INTOLERANT_CHNL_REPORT_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucRegulatoryClass;
+	UINT_8 aucChannelList[1];
+} __KAL_ATTRIB_PACKED__ IE_INTOLERANT_CHNL_REPORT_T, *P_IE_INTOLERANT_CHNL_REPORT_T;
+
+/* 7.3.2.59 OBSS Scan Parameters element */
+typedef struct _IE_OBSS_SCAN_PARAM_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_16 u2ScanPassiveDwell;
+	UINT_16 u2ScanActiveDwell;
+	UINT_16 u2TriggerScanInterval;
+	UINT_16 u2ScanPassiveTotalPerChnl;
+	UINT_16 u2ScanActiveTotalPerChnl;
+	UINT_16 u2WidthTransDelayFactor;
+	UINT_16 u2ScanActivityThres;
+} __KAL_ATTRIB_PACKED__ IE_OBSS_SCAN_PARAM_T, *P_IE_OBSS_SCAN_PARAM_T;
+
+/* 7.3.2.60 20/40 BSS Coexistence element */
+typedef struct _IE_20_40_COEXIST_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucData;
+} __KAL_ATTRIB_PACKED__ IE_20_40_COEXIST_T, *P_IE_20_40_COEXIST_T;
+
+/* 7.3.2.60 20/40 BSS Coexistence element */
+typedef struct _IE_SUP_OPERATING_CLASS_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 ucCur;
+	UINT_8 ucSup[255];
+} __KAL_ATTRIB_PACKED__ IE_SUP_OPERATING_CLASS_T, *P_IE_SUP_OPERATING_CLASS_T;
+
+/* 3 7.4 Action Frame. */
+/* 7.4 Action frame format */
+typedef struct _WLAN_ACTION_FRAME {
+	/* Action MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Action frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucActionDetails[1];	/* Action details */
+} __KAL_ATTRIB_PACKED__ WLAN_ACTION_FRAME, *P_WLAN_ACTION_FRAME;
+
+/* 7.4.1.1 Spectrum Measurement Request frame format */
+typedef struct _ACTION_SM_REQ_FRAME {
+	/* ADDTS Request MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* ADDTS Request frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token */
+	UINT_8 aucInfoElem[1];	/* Information elements  */
+} __KAL_ATTRIB_PACKED__ ACTION_SM_REQ_FRAME, *P_ACTION_SM_REQ_FRAME;
+
+/* 7.4.1.2 Spectrum Measurement Report frame format */
+typedef ACTION_SM_REQ_FRAME ACTION_SM_REPORT_FRAME, *P_ACTION_SM_REPORT_FRAME;
+
+/* 7.4.1.5 Channel Switch Announcement frame format */
+typedef struct _ACTION_CHANNEL_SWITCH_FRAME {
+	/* ADDTS Request MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* ADDTS Request frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 aucInfoElem[5];	/* Information elements  */
+} __KAL_ATTRIB_PACKED__ _ACTION_CHANNEL_SWITCH_FRAME, *P_ACTION_CHANNEL_SWITCH_FRAME;
+
+/* 7.4.2.1 ADDTS Request frame format */
+typedef struct _ACTION_ADDTS_REQ_FRAME {
+	/* ADDTS Request MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* ADDTS Request frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token */
+	UINT_8 aucInfoElem[1];	/* Information elements, such as
+				   TS Delay, and etc. */
+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_REQ_FRAME, *P_ACTION_ADDTS_REQ_FRAME;
+
+/* 7.4.2.2 ADDTS Response frame format */
+typedef struct _ACTION_ADDTS_RSP_FRAME {
+	/* ADDTS Response MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* ADDTS Response frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token */
+	UINT_8 ucStatusCode;	/* WMM Status Code is of one byte */
+	UINT_8 aucInfoElem[1];	/* Information elements, such as
+				   TS Delay, and etc. */
+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_RSP_FRAME, *P_ACTION_ADDTS_RSP_FRAME;
+
+/* 7.4.2.3 DELTS frame format */
+typedef struct _ACTION_DELTS_FRAME {
+	/* DELTS MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* DELTS frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 aucTsInfo[3];	/* TS Info */
+} __KAL_ATTRIB_PACKED__ ACTION_DELTS_FRAME, *P_ACTION_DELTS_FRAME;
+
+/* 7.4.4.1 ADDBA Request frame format */
+typedef struct _ACTION_ADDBA_REQ_FRAME_T {
+	/* Action MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Action frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token chosen by the sender */
+	UINT_8 aucBAParameterSet[2];	/* BA policy, TID, buffer size */
+	UINT_8 aucBATimeoutValue[2];
+	UINT_8 aucBAStartSeqCtrl[2];	/* SSN */
+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_FRAME_T, *P_ACTION_ADDBA_REQ_FRAME_T;
+
+typedef struct _ACTION_ADDBA_REQ_BODY_T {
+	UINT_16 u2BAParameterSet;	/* BA policy, TID, buffer size */
+	UINT_16 u2BATimeoutValue;
+	UINT_16 u2BAStartSeqCtrl;	/* SSN */
+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_BODY_T, *P_ACTION_ADDBA_REQ_BODY_T;
+
+/* 7.4.4.2 ADDBA Response frame format */
+typedef struct _ACTION_ADDBA_RSP_FRAME_T {
+	/* Action MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Action frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token chosen by the sender */
+	UINT_8 aucStatusCode[2];
+	UINT_8 aucBAParameterSet[2];	/* BA policy, TID, buffer size */
+	UINT_8 aucBATimeoutValue[2];
+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_FRAME_T, *P_ACTION_ADDBA_RSP_FRAME_T;
+
+typedef struct _ACTION_ADDBA_RSP_BODY_T {
+	UINT_16 u2StatusCode;
+	UINT_16 u2BAParameterSet;	/* BA policy, TID, buffer size */
+	UINT_16 u2BATimeoutValue;
+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_BODY_T, *P_ACTION_ADDBA_RSP_BODY_T;
+
+/* 7.4.4.3 DELBA frame format */
+typedef struct _ACTION_DELBA_FRAME_T {
+	/* Action MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2DurationID;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Action frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_16 u2DelBaParameterSet;	/* Bit 11 Initiator, Bits 12-15 TID */
+	UINT_16 u2ReasonCode;	/* 7.3.1.7 */
+} __KAL_ATTRIB_PACKED__ ACTION_DELBA_FRAME_T, *P_ACTION_DELBA_FRAME_T;
+
+/* 7.4.6.1 Radio Measurement Request frame format */
+typedef struct _ACTION_RM_REQ_FRAME {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Radio Measurement Request frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token */
+	UINT_16 u2Repetitions;	/* Number of repetitions */
+	UINT_8 aucInfoElem[1];	/* Measurement Request elements, such as
+				   channel load request, and etc. */
+} __KAL_ATTRIB_PACKED__ ACTION_RM_REQ_FRAME, *P_ACTION_RM_REQ_FRAME;
+
+/* 7.4.6.2 Radio Measurement Report frame format */
+typedef struct _ACTION_RM_REPORT_FRAME {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Radio Measurement Report frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token */
+	UINT_8 aucInfoElem[1];	/* Measurement Report elements, such as
+				   channel load report, and etc. */
+} __KAL_ATTRIB_PACKED__ ACTION_RM_REPORT_FRAME, *P_ACTION_RM_REPORT_FRAME;
+
+/* 7.4.7.1a 20/40 BSS Coexistence Management frame format */
+typedef struct _ACTION_20_40_COEXIST_FRAME {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* BSS Coexistence Management frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+
+	IE_20_40_COEXIST_T rBssCoexist;	/* 20/40 BSS coexistence element */
+	IE_INTOLERANT_CHNL_REPORT_T rChnlReport;	/* Intolerant channel report */
+
+} __KAL_ATTRIB_PACKED__ ACTION_20_40_COEXIST_FRAME, *P_ACTION_20_40_COEXIST_FRAME;
+
+#if CFG_SUPPORT_802_11W
+/* 7.4.9 SA Query Management frame format */
+typedef struct _ACTION_SA_QUERY_FRAME {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* BSS Coexistence Management frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+
+	UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN];	/* Transaction id */
+
+} __KAL_ATTRIB_PACKED__ ACTION_SA_QUERY_FRAME, *P_ACTION_SA_QUERY_FRAME;
+#endif
+
+/* 7.4.10 Notify Channel Width Management frame format */
+typedef struct _ACTION_NOTIFY_CHNL_WIDTH_FRAME {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* BSS Coexistence Management frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucChannelWidth;	/* Channel Width */
+} __KAL_ATTRIB_PACKED__ ACTION_NOTIFY_CHNL_WIDTH_FRAME, *P_ACTION_NOTIFY_CHNL_WIDTH_FRAME;
+
+/* 802.11v Wireless Network Management: Timing Measurement Request */
+typedef struct _ACTION_WNM_TIMING_MEAS_REQ_FRAME {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Timing Measurement Request Management frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucTrigger;	/* Trigger */
+} __KAL_ATTRIB_PACKED__ ACTION_WNM_TIMING_MEAS_REQ_FRAME, *P_ACTION_WNM_TIMING_MEAS_REQ_FRAME;
+
+/* 802.11v Wireless Network Management: Timing Measurement */
+typedef struct _ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* Timing Measurement Management frame body */
+	UINT_8 ucCategory;	/* Category */
+	UINT_8 ucAction;	/* Action Value */
+	UINT_8 ucDialogToken;	/* Dialog Token */
+	UINT_8 ucFollowUpDialogToken;	/* Follow Up Dialog Token */
+	UINT_32 u4ToD;		/* Timestamp of Departure [10ns] */
+	UINT_32 u4ToA;		/* Timestamp of Arrival [10ns] */
+	UINT_8 ucMaxToDErr;	/* Maximum of ToD Error [10ns] */
+	UINT_8 ucMaxToAErr;	/* Maximum of ToA Error [10ns] */
+} __KAL_ATTRIB_PACKED__ ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME, *P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME;
+
+/* 3 Information Elements from WFA. */
+typedef struct _IE_WFA_T {
+	UINT_8 ucId;
+	UINT_8 ucLength;
+	UINT_8 aucOui[3];
+	UINT_8 ucOuiType;
+	UINT_8 aucOuiSubTypeVersion[2];
+	/*!< Please be noted. WPA defines a 16 bit field version
+	   instead of one subtype field and one version field */
+} __KAL_ATTRIB_PACKED__ IE_WFA_T, *P_IE_WFA_T;
+
+/* HS20 3.1 - HS 2.0 Indication Information Element */
+typedef struct _IE_HS20_INDICATION_T {
+	UINT_8 ucId;		/* Element ID */
+	UINT_8 ucLength;	/* Length */
+	UINT_8 aucOui[3];	/* OUI */
+	UINT_8 ucType;		/* Type */
+	UINT_8 ucHotspotConfig;	/* Hotspot Configuration */
+} __KAL_ATTRIB_PACKED__ IE_HS20_INDICATION_T, *P_IE_HS20_INDICATION_T;
+
+/* WAPI Information element format */
+typedef struct _WAPI_INFO_ELEM_T {
+	UCHAR ucElemId;
+	UCHAR ucLength;
+	UINT_16 u2Version;
+	UINT_16 u2AuthKeyMgtSuiteCount;
+	UCHAR aucAuthKeyMgtSuite1[4];
+} __KAL_ATTRIB_PACKED__ WAPI_INFO_ELEM_T, *P_WAPI_INFO_ELEM_T;
+
+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE)
+#pragma pack()
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/* Convert the ECWmin(max) to CWmin(max) */
+#define ECW_TO_CW(_ECW)         ((1 << (_ECW)) - 1)
+
+/* Convert the RCPI to dBm */
+#define RCPI_TO_dBm(_rcpi)                          \
+	((PARAM_RSSI)(((_rcpi) > RCPI_HIGH_BOUND ? RCPI_HIGH_BOUND : (_rcpi)) >> 1) - NDBM_LOW_BOUND_FOR_RCPI)
+
+/* Convert the dBm to RCPI */
+#define dBm_TO_RCPI(_dbm)                           \
+	(RCPI)(((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) > RCPI_HIGH_BOUND) ? RCPI_HIGH_BOUND : \
+	((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) < RCPI_LOW_BOUND ? RCPI_LOW_BOUND : \
+	(((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1)))
+
+/* Convert an unsigned char pointer to an information element pointer */
+#define IE_ID(fp)               (((P_IE_HDR_T) fp)->ucId)
+#define IE_LEN(fp)              (((P_IE_HDR_T) fp)->ucLength)
+#define IE_SIZE(fp)             (ELEM_HDR_LEN + IE_LEN(fp))
+
+#define SSID_IE(fp)             ((P_IE_SSID_T) fp)
+
+#define SUP_RATES_IE(fp)        ((P_IE_SUPPORTED_RATE_T) fp)
+
+#define DS_PARAM_IE(fp)         ((P_IE_DS_PARAM_SET_T) fp)
+
+#define TIM_IE(fp)              ((P_IE_TIM_T) fp)
+
+#define IBSS_PARAM_IE(fp)       ((P_IE_IBSS_PARAM_SET_T) fp)
+
+#define ERP_INFO_IE(fp)         ((P_IE_ERP_T) fp)
+
+#define EXT_SUP_RATES_IE(fp)    ((P_IE_EXT_SUPPORTED_RATE_T) fp)
+
+#define WFA_IE(fp)              ((P_IE_WFA_T) fp)
+
+#if CFG_SUPPORT_802_11D
+#define COUNTRY_IE(fp)          ((P_IE_COUNTRY_T) fp)
+#endif
+
+#define EXT_CAP_IE(fp)          ((P_EXT_CAP_T) fp)
+
+#define HT_CAP_IE(fp)           ((P_IE_HT_CAP_T) fp)
+
+#define HT_OP_IE(fp)            ((P_IE_HT_OP_T) fp)
+
+#define OBSS_SCAN_PARAM_IE(fp)  ((P_IE_OBSS_SCAN_PARAM_T) fp)
+
+#define BSS_20_40_COEXIST_IE(fp) ((P_IE_20_40_COEXIST_T) fp)
+
+#define SUP_OPERATING_CLASS_IE(fp) ((P_IE_SUP_OPERATING_CLASS_T) fp)
+
+#define QUIET_IE(fp)            ((P_IE_QUIET_T) fp)
+
+#if CFG_SUPPORT_DFS		/* Add by Enlai */
+#define SUPPORTED_CHANNELS_IE(fp) ((P_IE_SUPPORTED_CHANNELS_T)fp)
+#endif
+
+#define TIMEOUT_INTERVAL_IE(fp)	((IE_TIMEOUT_INTERVAL_T *)fp)
+
+/* The macro to check if the MAC address is B/MCAST Address */
+#define IS_BMCAST_MAC_ADDR(_pucDestAddr)            \
+	((BOOLEAN) (((PUINT_8)(_pucDestAddr))[0] & BIT(0)))
+
+/* The macro to check if the MAC address is UCAST Address */
+#define IS_UCAST_MAC_ADDR(_pucDestAddr)             \
+	((BOOLEAN) !(((PUINT_8)(_pucDestAddr))[0] & BIT(0)))
+
+/* The macro to copy the MAC address */
+#define COPY_MAC_ADDR(_pucDestAddr, _pucSrcAddr)    \
+	kalMemCopy(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)
+
+/* The macro to check if two MAC addresses are equal */
+#define EQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr)   \
+	(!kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN))
+
+/* The macro to check if two MAC addresses are not equal */
+#define UNEQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \
+	(kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN))
+
+/* The macro to check whether two SSIDs are equal */
+#define EQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \
+	((ucSsidLen1 <= ELEM_MAX_LEN_SSID) && \
+	(ucSsidLen2 <= ELEM_MAX_LEN_SSID) && \
+	((ucSsidLen1) == (ucSsidLen2)) && \
+	!kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1))
+
+/* The macro to check whether two SSIDs are equal */
+#define UNEQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \
+	((ucSsidLen1 > ELEM_MAX_LEN_SSID) || \
+	(ucSsidLen2 > ELEM_MAX_LEN_SSID) || \
+	((ucSsidLen1) != (ucSsidLen2)) || \
+	kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1))
+
+/* The macro to copy the SSID, the length of pucDestSsid should have at least 32 bytes */
+#define COPY_SSID(pucDestSsid, ucDestSsidLen, pucSrcSsid, ucSrcSsidLen) \
+	do { \
+		ucDestSsidLen = ucSrcSsidLen; \
+		if (ucSrcSsidLen) { \
+			ASSERT(ucSrcSsidLen <= ELEM_MAX_LEN_SSID); \
+			kalMemCopy(pucDestSsid, \
+					pucSrcSsid, \
+					((ucSrcSsidLen > ELEM_MAX_LEN_SSID) ? ELEM_MAX_LEN_SSID : ucSrcSsidLen)); \
+			} \
+	} while (FALSE)
+
+/* The macro to copy the IE */
+#define COPY_IE(pucDestIE, pucSrcIE) \
+	do { \
+		kalMemCopy((PUINT_8)pucDestIE, \
+		(PUINT_8)pucSrcIE,\
+		IE_SIZE(pucSrcIE)); \
+	} while (FALSE)
+
+#define IE_FOR_EACH(_pucIEsBuf, _u2IEsBufLen, _u2Offset) \
+	for ((_u2Offset) = 0;\
+		((((_u2Offset) + 2) <= (_u2IEsBufLen)) && (((_u2Offset) + IE_SIZE(_pucIEsBuf)) <= (_u2IEsBufLen))); \
+		(_u2Offset) += IE_SIZE(_pucIEsBuf), (_pucIEsBuf) += IE_SIZE(_pucIEsBuf))
+
+#define SET_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \
+			do { \
+				if ((_ucBit) < ((_ucFieldLength) * 8)) { \
+					PUINT_8 aucExtCap = (PUINT_8)(_aucField); \
+					((aucExtCap)[(_ucBit) / 8]) |= BIT((_ucBit) % 8); \
+				} \
+			} while (FALSE)
+
+#define TEST_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \
+			((((_ucFieldLength) * 8) > (_ucBit)) && (((_aucField)[(_ucBit) / 8]) & BIT((_ucBit) % 8)))
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _MAC_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h
new file mode 100644
index 0000000000000..583923aed0100
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h
@@ -0,0 +1,272 @@
+/*
+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/nic/mtreg.h#2
+*/
+
+/*! \file   "mtreg.h"
+    \brief  The common register definition of mt5931
+
+    N/A
+*/
+
+/*
+** Log: mtreg.h
+ *
+ * 01 28 2013 samp.lin
+ * [WCXRP00000851] [MT6582 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6582-specific definitions.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628-specific definitions.
+ *
+ * 07 13 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add initial version for MT6628 driver support.
+ *
+*/
+
+#ifndef _MTREG_H
+#define _MTREG_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/* 1 MT6628 MCR Definition */
+
+/* 2 Host Interface */
+
+/* 4 CHIP ID Register */
+#define MCR_WCIR                            0x0000
+
+/* 4 HIF Low Power Control  Register */
+#define MCR_WHLPCR                          0x0004
+
+/* 4 Control  Status Register */
+#define MCR_WSDIOCSR                        0x0008
+#define MCR_WSPICSR                         0x0008
+
+/* 4 HIF Control Register */
+#define MCR_WHCR                            0x000C
+
+/* 4 HIF Interrupt Status  Register */
+#define MCR_WHISR                           0x0010
+
+/* 4 HIF Interrupt Enable  Register */
+#define MCR_WHIER                           0x0014
+
+/* 4 Abnormal Status Register */
+#define MCR_WASR                            0x0018
+
+/* 4 WLAN Software Interrupt Control Register */
+#define MCR_WSICR                           0x001C
+
+/* 4 WLAN TX Status Register */
+#define MCR_WTSR0                           0x0020
+
+/* 4 WLAN TX Status Register */
+#define MCR_WTSR1                           0x0024
+
+/* 4 WLAN TX Data Register 0 */
+#define MCR_WTDR0                           0x0028
+
+/* 4 WLAN TX Data Register 1 */
+#define MCR_WTDR1                           0x002C
+
+/* 4 WLAN RX Data Register 0 */
+#define MCR_WRDR0                           0x0030
+
+/* 4 WLAN RX Data Register 1 */
+#define MCR_WRDR1                           0x0034
+
+/* 4 Host to Device Send Mailbox 0 Register */
+#define MCR_H2DSM0R                         0x0038
+
+/* 4 Host to Device Send Mailbox 1 Register */
+#define MCR_H2DSM1R                         0x003c
+
+/* 4 Device to Host Receive Mailbox 0 Register */
+#define MCR_D2HRM0R                         0x0040
+
+/* 4 Device to Host Receive Mailbox 1 Register */
+#define MCR_D2HRM1R                         0x0044
+
+/* 4 Device to Host Receive Mailbox 2 Register */
+#define MCR_D2HRM2R                         0x0048
+
+/* 4 WLAN RX Packet Length Register */
+#define MCR_WRPLR                           0x0050
+
+/* 4 HSIF Transaction Count Register */
+#define MCR_HSTCR                           0x0058
+
+/* #if CFG_SDIO_INTR_ENHANCE */
+typedef struct _ENHANCE_MODE_DATA_STRUCT_T {
+	UINT_32 u4WHISR;
+	union {
+		struct {
+			UINT_8 ucTQ0Cnt;
+			UINT_8 ucTQ1Cnt;
+			UINT_8 ucTQ2Cnt;
+			UINT_8 ucTQ3Cnt;
+			UINT_8 ucTQ4Cnt;
+			UINT_8 ucTQ5Cnt;
+			UINT_16 u2Rsrv;
+		} u;
+		UINT_32 au4WTSR[2];
+	} rTxInfo;
+	union {
+		struct {
+			UINT_16 u2NumValidRx0Len;
+			UINT_16 u2NumValidRx1Len;
+			UINT_16 au2Rx0Len[16];
+			UINT_16 au2Rx1Len[16];
+		} u;
+		UINT_32 au4RxStatusRaw[17];
+	} rRxInfo;
+	UINT_32 u4RcvMailbox0;
+	UINT_32 u4RcvMailbox1;
+} ENHANCE_MODE_DATA_STRUCT_T, *P_ENHANCE_MODE_DATA_STRUCT_T;
+/* #endif */ /* ENHANCE_MODE_DATA_STRUCT_T */
+
+/* 2 Definition in each register */
+/* 3 WCIR 0x0000 */
+#define WCIR_WLAN_READY                  BIT(21)
+#define WCIR_POR_INDICATOR               BIT(20)
+#define WCIR_REVISION_ID                 BITS(16, 19)
+#define WCIR_CHIP_ID                     BITS(0, 15)
+
+#define MTK_CHIP_REV_72                  0x00006572
+#define MTK_CHIP_REV_82                  0x00006582
+#define MTK_CHIP_REV_92                  0x00006592
+#define MTK_CHIP_MP_REVERSION_ID         0x0
+
+/* 3 WHLPCR 0x0004 */
+#define WHLPCR_FW_OWN_REQ_CLR            BIT(9)
+#define WHLPCR_FW_OWN_REQ_SET            BIT(8)
+#define WHLPCR_IS_DRIVER_OWN             BIT(8)
+#define WHLPCR_INT_EN_CLR                BIT(1)
+#define WHLPCR_INT_EN_SET                BIT(0)
+
+/* 3 WSDIOCSR 0x0008 */
+#define WSDIOCSR_SDIO_RE_INIT_EN         BIT(0)
+
+/* 3 WSPICSR 0x0008 */
+#define WCSR_SPI_MODE_SEL                BITS(3, 4)
+#define WCSR_SPI_ENDIAN_BIG              BIT(2)
+#define WCSR_SPI_INT_OUT_MODE            BIT(1)
+#define WCSR_SPI_DATA_OUT_MODE           BIT(0)
+
+/* 3 WHCR 0x000C */
+#define WHCR_RX_ENHANCE_MODE_EN         BIT(16)
+#define WHCR_MAX_HIF_RX_LEN_NUM         BITS(4, 7)
+#define WHCR_W_MAILBOX_RD_CLR_EN        BIT(2)
+#define WHCR_W_INT_CLR_CTRL             BIT(1)
+#define WHCR_MCU_DBG_EN                 BIT(0)
+#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM  4
+
+/* 3 WHISR 0x0010 */
+#define WHISR_D2H_SW_INT                BITS(8, 31)
+#define WHISR_D2H_SW_ASSERT_INFO_INT    BIT(31)
+#define WHISR_FW_OWN_BACK_INT           BIT(4)
+#define WHISR_ABNORMAL_INT              BIT(3)
+#define WHISR_RX1_DONE_INT              BIT(2)
+#define WHISR_RX0_DONE_INT              BIT(1)
+#define WHISR_TX_DONE_INT               BIT(0)
+
+/* 3 WHIER 0x0014 */
+#define WHIER_D2H_SW_INT                BITS(8, 31)
+#define WHIER_FW_OWN_BACK_INT_EN        BIT(4)
+#define WHIER_ABNORMAL_INT_EN           BIT(3)
+#define WHIER_RX1_DONE_INT_EN           BIT(2)
+#define WHIER_RX0_DONE_INT_EN           BIT(1)
+#define WHIER_TX_DONE_INT_EN            BIT(0)
+#define WHIER_DEFAULT                   (WHIER_RX0_DONE_INT_EN    | \
+					 WHIER_RX1_DONE_INT_EN    | \
+					 WHIER_TX_DONE_INT_EN     | \
+					 WHIER_ABNORMAL_INT_EN    | \
+					 WHIER_D2H_SW_INT           \
+					 )
+
+/* 3 WASR 0x0018 */
+#define WASR_FW_OWN_INVALID_ACCESS      BIT(4)
+#define WASR_RX1_UNDER_FLOW             BIT(3)
+#define WASR_RX0_UNDER_FLOW             BIT(2)
+#define WASR_TX1_OVER_FLOW              BIT(1)
+#define WASR_TX0_OVER_FLOW              BIT(0)
+
+/* 3 WSICR 0x001C */
+#define WSICR_H2D_SW_INT_SET            BITS(16, 31)
+
+/* 3 WRPLR 0x0050 */
+#define WRPLR_RX1_PACKET_LENGTH         BITS(16, 31)
+#define WRPLR_RX0_PACKET_LENGTH         BITS(0, 15)
+
+/* 3 HSTCR 0x0058 */
+#define HSTCR_AFF_BURST_LEN			    BITS(24, 25)
+#define HSTCR_AFF_BURST_LEN_OFFSET      24
+#define HSTCR_TRANS_TARGET			    BITS(20, 22)
+#define HSTCR_TRANS_TARGET_OFFSET	    20
+#define HSTCR_HSIF_TRANS_CNT		    BITS(2, 19)
+#define HSTCR_HSIF_TRANS_CNT_OFFSET     2
+
+/* HSTCR_TRANS_TARGET */
+typedef enum _eTransTarget {
+	TRANS_TARGET_TXD0 = 0,
+	TRANS_TARGET_TXD1,
+	TRANS_TARGET_RXD0,
+	TRANS_TARGET_RXD1,
+	TRANS_TARGET_WHISR,
+	NUM_TRANS_TARGET
+} E_TRANS_TARGET_T;
+
+typedef enum _E_AFF_BURST_LEN {
+	BURST_1_DW = 0,
+	BURST_4_DW,
+	BURST_8_DW,
+	BURST_RSV,
+	NUM_AFF_BURST_LEN
+} E_AFF_BURST_LEN;
+
+#endif /* _MTREG_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h
new file mode 100644
index 0000000000000..c059b707aee84
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h
@@ -0,0 +1,498 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic.h#1
+*/
+
+/*! \file   "nic.h"
+    \brief  The declaration of nic functions
+
+    Detail description.
+*/
+
+/*
+** Log: nic.h
+ *
+ * 11 01 2011 chinglan.wang
+ * NULL
+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP.
+ * If disconnect the AP and flush all the data frame in the TX queue, WPS
+ * cannot do the 4-way handshake to connect to the AP..
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 05 11 2011 cp.wu
+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke.
+ *
+ * 04 11 2011 yuche.tsai
+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue.
+ * Fix kernel panic issue when MMPDU of P2P is pending in driver.
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right
+ * after connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
+ *
+ * 02 01 2011 cm.chang
+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
+ * .
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW]
+ * Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 26 2010 eddie.chen
+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB
+ * Add auto rate parameter in registry.
+ *
+ * 10 12 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * add HT (802.11n) fixed rate support.
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * adding fixed rate support for distance test. (from registry setting)
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced
+ * by ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test
+ * with AIS associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * HIFSYS Clock Source Workaround
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * Centralize mgmt/system service procedures into independent calls.
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo
+ * 2) change nicMediaStateChange() API prototype
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 06 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Update arguments for nicUpdateBeaconIETemplate()
+ *
+ * 07 06 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * STA-REC is maintained by CNM only.
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) ignore RSN checking when RSN is not turned on.
+ * 2) set STA-REC deactivation callback as NULL
+ * 3) add variable initialization API based on PHY configuration
+ *
+ * 06 30 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * sync. with CMD/EVENT document ver0.07.
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) sync to. CMD/EVENT document v0.03
+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
+ * 3) send command packet to indicate FW-PM after
+ *     a) 1st beacon is received after AIS has connected to an AP
+ *     b) IBSS-ALONE has been created
+ *     c) IBSS-MERGE has occurred
+ *
+ * 06 25 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Create beacon update path, with expose bssUpdateBeaconContent()
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implement TX_DONE callback path.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 04 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) surpress compiler warning
+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add channel frequency <-> number conversion
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ *  *  *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
+ *
+ * 03 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * always process TX interrupt first then RX interrupt.
+ *
+ * 02 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add checksum offloading support.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-10-13 21:58:58 GMT mtk01084
+**  update for new HW architecture design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-24 21:12:55 GMT mtk01104
+**  Add function prototype nicRestoreSpiDefMode()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:54 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:32 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _NIC_H
+#define _NIC_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+struct _REG_ENTRY_T {
+	UINT_32 u4Offset;
+	UINT_32 u4Value;
+};
+
+struct _TABLE_ENTRY_T {
+	P_REG_ENTRY_T pu4TablePtr;
+	UINT_16 u2Size;
+};
+
+/*! INT status to event map */
+typedef struct _INT_EVENT_MAP_T {
+	UINT_32 u4Int;
+	UINT_32 u4Event;
+} INT_EVENT_MAP_T, *P_INT_EVENT_MAP_T;
+
+enum ENUM_INT_EVENT_T {
+	INT_EVENT_ABNORMAL,
+	INT_EVENT_SW_INT,
+	INT_EVENT_TX,
+	INT_EVENT_RX,
+	INT_EVENT_NUM
+};
+
+typedef enum _ENUM_IE_UPD_METHOD_T {
+	IE_UPD_METHOD_UPDATE_RANDOM,
+	IE_UPD_METHOD_UPDATE_ALL,
+	IE_UPD_METHOD_DELETE_ALL,
+} ENUM_IE_UPD_METHOD_T, *P_ENUM_IE_UPD_METHOD_T;
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+extern BOOLEAN fgIsResetting;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines in nic.c                                                          */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter);
+
+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter);
+
+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter);
+
+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus);
+
+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter);
+
+VOID nicMCRInit(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter);
+
+#if CFG_SDIO_INTR_ENHANCE
+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter);
+
+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus);
+#endif
+
+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter);
+
+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt);
+
+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter);
+
+#if defined(_HIF_SPI)
+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter);
+#endif
+
+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter);
+
+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter);
+
+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data);
+
+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data);
+
+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap);
+
+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum);
+
+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum);
+
+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx);
+
+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType);
+
+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter);
+
+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter);
+
+/* Media State Change */
+WLAN_STATUS
+nicMediaStateChange(IN P_ADAPTER_T prAdapter,
+		    IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus);
+
+/* Utility function for channel number conversion */
+UINT_32 nicChannelNum2Freq(IN UINT_32 u4ChannelNum);
+
+UINT_32 nicFreq2ChannelNum(IN UINT_32 u4FreqInKHz);
+
+/* firmware command wrapper */
+    /* NETWORK (WIFISYS) */
+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+    /* BSS-INFO */
+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+    /* BSS-INFO Indication (PM) */
+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+    /* Beacon Template Update */
+WLAN_STATUS
+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter,
+			  IN ENUM_IE_UPD_METHOD_T eIeUpdMethod,
+			  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+			  IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen);
+
+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam);
+
+/*----------------------------------------------------------------------------*/
+/* Calibration Control                                                        */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam);
+
+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset);
+
+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult);
+
+/*----------------------------------------------------------------------------*/
+/* PHY configuration                                                          */
+/*----------------------------------------------------------------------------*/
+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* MGMT and System Service Control                                            */
+/*----------------------------------------------------------------------------*/
+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter);
+
+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter);
+
+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter);
+
+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo);
+
+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS
+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter,
+			  ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent);
+
+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent);
+/*----------------------------------------------------------------------------*/
+/* Scan Result Processing                                                     */
+/*----------------------------------------------------------------------------*/
+VOID
+nicAddScanResult(IN P_ADAPTER_T prAdapter,
+		 IN PARAM_MAC_ADDRESS rMacAddr,
+		 IN P_PARAM_SSID_T prSsid,
+		 IN UINT_32 u4Privacy,
+		 IN PARAM_RSSI rRssi,
+		 IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType,
+		 IN P_PARAM_802_11_CONFIG_T prConfiguration,
+		 IN ENUM_PARAM_OP_MODE_T eOpMode,
+		 IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf);
+
+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx);
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+/*----------------------------------------------------------------------------*/
+/* Workaround Control                                                         */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter);
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* Fixed Rate Hacking                                                         */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+nicUpdateRateParams(IN P_ADAPTER_T prAdapter,
+		    IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting,
+		    IN PUINT_8 pucDesiredPhyTypeSet,
+		    IN PUINT_16 pu2DesiredNonHTRateSet,
+		    IN PUINT_16 pu2BSSBasicRateSet,
+		    IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 u2HtCapInfo);
+
+/*----------------------------------------------------------------------------*/
+/* Write registers                                                            */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value);
+
+/*----------------------------------------------------------------------------*/
+/* Update auto rate                                                           */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter,
+		    IN UINT_32 u4ArSysParam0,
+		    IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3);
+
+/*----------------------------------------------------------------------------*/
+/* Enable/Disable Roaming                                                     */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming);
+
+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* Link Quality Updating                                                      */
+/*----------------------------------------------------------------------------*/
+VOID
+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter,
+		     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality);
+
+VOID
+nicUpdateRSSI(IN P_ADAPTER_T prAdapter,
+	      IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality);
+
+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed);
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam);
+#endif
+
+#endif /* _NIC_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h
new file mode 100644
index 0000000000000..86e2c84b07ffa
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h
@@ -0,0 +1,420 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_rx.h#1
+*/
+
+/*! \file   "nic_rx.h"
+    \brief  The declaration of the nic rx functions
+
+*/
+
+/*
+** Log: nic_rx.h
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 05 05 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * add delay after whole-chip resetting for MT5931 E1 ASIC.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 01 24 2011 cm.chang
+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode
+ * and stop ampdu timer when sta_rec is freed
+ * Process received 20/40 coexistence action frame for AP mode
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * Change prototype of API of adding P2P device to scan result.
+ * Additional IE buffer is saved.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Modify data structure for P2P Scan result.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * newly added P2P API should be declared in header file.
+ *
+ * 07 30 2010 cp.wu
+ * NULL
+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * saa_fsm.c is migrated.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * remove driver-land statistics.
+ *
+ * 03 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
+ *  *
+ *
+ * 03 11 2010 cp.wu
+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING
+ *
+ * 03 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code clean: removing unused variables and structure definitions
+ *
+ * 02 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement host-side firmware download logic
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
+ *  * 2) firmware image length is now retrieved via NdisFileOpen
+ *  * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
+ *  * 4) nicRxWaitResponse() revised
+ *  * 5) another set of TQ counter default value is added for fw-download state
+ *  * 6) Wi-Fi load address is now retrieved from registry too
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  *  * and result is retrieved by get ATInfo instead
+ *  *  *  * 2) add 4 counter for recording aggregation statistics
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:49:09 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 14:02:37 GMT MTK02468
+**  Added ucStaRecIdx in SW_RFB_T and HALF_SEQ_NO_COUNT definition (to replace HALF_SEQ_NO_CNOUT)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-27 11:07:54 GMT mtk02752
+**  add flush for reset
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 18:18:09 GMT mtk02752
+**  modify nicRxAddScanResult()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-24 22:42:22 GMT mtk02752
+**  add nicRxAddScanResult() to prepare to handle SCAN_RESULT event
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-24 19:57:06 GMT mtk02752
+**  adopt P_HIF_RX_HEADER_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 21:43:04 GMT mtk02752
+**  correct ENUM_RX_PKT_DESTINATION_T definitions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 15:28:25 GMT mtk02752
+**  add ucQueuedPacketNum for indicating how many packet are queued by RX reordering buffer/forwarding path
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 15:05:01 GMT mtk02752
+**  add eTC for SW_RFB_T and structure RX_MAILBOX
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 21:16:57 GMT mtk02752
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-13 16:59:30 GMT mtk02752
+**  add handler for event packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-13 13:45:50 GMT mtk02752
+**  add port param for nicRxEnhanceReadBuffer()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-11 10:12:31 GMT mtk02752
+**  nicSDIOReadIntStatus() always read sizeof(ENHANCE_MODE_DATA_STRUCT_T) for int response,
+**  thus the number should be set to 0(:=16) instead of 10
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-29 19:53:32 GMT mtk01084
+**  modify structure naming
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-23 16:08:23 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:01 GMT mtk01084
+**  update for new HW architecture design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-20 12:23:33 GMT mtk01461
+**  Add u4MaxEventBufferLen parameter to nicRxWaitResponse()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-18 21:00:48 GMT mtk01426
+**  Update SDIO_MAXIMUM_RX_STATUS value
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:36:15 GMT mtk01461
+**  Remove unused define - SDIO_MAXIMUM_TX_STATUS
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:17 GMT mtk01461
+**  Add function for HIF_LOOPBACK_PRE_TEST
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:56:19 GMT mtk01426
+**  Add to support CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:19:56 GMT mtk01426
+**  Add nicRxWaitResponse function proto type
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:35 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _NIC_RX_H
+#define _NIC_RX_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+extern P_SW_RFB_T g_arGscnResultsTempBuffer[];
+extern UINT_8 g_GscanResultsTempBufferIndex;
+extern UINT_8 g_arGscanResultsIndicateNumber[];
+extern UINT_8 g_GetResultsBufferedCnt;
+extern UINT_8 g_GetResultsCmdCnt;
+extern void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb);
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define MAX_SEQ_NO                  4095
+#define MAX_SEQ_NO_COUNT            4096
+#define HALF_SEQ_NO_CNOUT           2048
+
+#define HALF_SEQ_NO_COUNT           2048
+
+#define MT6620_FIXED_WIN_SIZE         64
+#define CFG_RX_MAX_BA_ENTRY            4
+#define CFG_RX_MAX_BA_TID_NUM          8
+
+#define RX_STATUS_FLAG_MORE_PACKET    BIT(30)
+#define RX_STATUS_CHKSUM_MASK         BITS(0, 10)
+
+#define RX_RFB_LEN_FIELD_LEN        4
+#define RX_HEADER_OFFSET            2
+
+#define RX_RETURN_INDICATED_RFB_TIMEOUT_SEC      3
+
+#if defined(_HIF_SDIO) && defined(WINDOWS_DDK)
+/*! On XP, maximum Tx+Rx Statue <= 64-4(HISR)*/
+#define SDIO_MAXIMUM_RX_LEN_NUM              0	/*!< 0~15 (0: un-limited) */
+#else
+#define SDIO_MAXIMUM_RX_LEN_NUM              0	/*!< 0~15 (0: un-limited) */
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_RX_STATISTIC_COUNTER_T {
+	RX_MPDU_TOTAL_COUNT = 0,
+	RX_SIZE_ERR_DROP_COUNT,
+
+	RX_DATA_INDICATION_COUNT,
+	RX_DATA_RETURNED_COUNT,
+	RX_DATA_RETAINED_COUNT,
+
+	RX_DROP_TOTAL_COUNT,
+	RX_TYPE_ERR_DROP_COUNT,
+	RX_CLASS_ERR_DROP_COUNT,
+	RX_DST_NULL_DROP_COUNT,
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60
+	RX_CSUM_TCP_FAILED_COUNT,
+	RX_CSUM_UDP_FAILED_COUNT,
+	RX_CSUM_IP_FAILED_COUNT,
+	RX_CSUM_TCP_SUCCESS_COUNT,
+	RX_CSUM_UDP_SUCCESS_COUNT,
+	RX_CSUM_IP_SUCCESS_COUNT,
+	RX_CSUM_UNKNOWN_L4_PKT_COUNT,
+	RX_CSUM_UNKNOWN_L3_PKT_COUNT,
+	RX_IP_V6_PKT_CCOUNT,
+#endif
+	RX_STATISTIC_COUNTER_NUM
+} ENUM_RX_STATISTIC_COUNTER_T;
+
+typedef enum _ENUM_RX_PKT_DESTINATION_T {
+	RX_PKT_DESTINATION_HOST,	/* to OS */
+	RX_PKT_DESTINATION_FORWARD,	/* to TX queue for forward, AP mode */
+	RX_PKT_DESTINATION_HOST_WITH_FORWARD,	/* to both TX and OS, AP mode broadcast packet */
+	RX_PKT_DESTINATION_NULL,	/* packet to be freed */
+	RX_PKT_DESTINATION_NUM
+} ENUM_RX_PKT_DESTINATION_T;
+
+struct _SW_RFB_T {
+	QUE_ENTRY_T rQueEntry;
+	PVOID pvPacket;		/*!< ptr to rx Packet Descriptor */
+	PUINT_8 pucRecvBuff;	/*!< ptr to receive data buffer */
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	UINT_32 u4HifRxHdrFlag;
+	PVOID pvHeader;
+	UINT_16 u2PacketLen;
+	UINT_16 u2HeaderLen;
+	UINT_16 u2SSN;
+	UINT_8 ucTid;
+	UINT_8 ucWlanIdx;
+	UINT_8 ucPacketType;
+	UINT_8 ucStaRecIdx;
+
+	ENUM_CSUM_RESULT_T aeCSUM[CSUM_TYPE_NUM];
+	ENUM_RX_PKT_DESTINATION_T eDst;
+	ENUM_TRAFFIC_CLASS_INDEX_T eTC;	/* only valid when eDst == FORWARD */
+
+	UINT_64 rRxTime;
+};
+
+/*! RX configuration type structure */
+typedef struct _RX_CTRL_T {
+	UINT_32 u4RxCachedSize;
+	PUINT_8 pucRxCached;
+	QUE_T rFreeSwRfbList;
+	QUE_T rReceivedRfbList;
+	QUE_T rIndicatedRfbList;
+
+#if CFG_SDIO_RX_AGG
+	PUINT_8 pucRxCoalescingBufPtr;
+#endif
+
+	PVOID apvIndPacket[CFG_RX_MAX_PKT_NUM];
+	PVOID apvRetainedPacket[CFG_RX_MAX_PKT_NUM];
+
+	UINT_8 ucNumIndPacket;
+	UINT_8 ucNumRetainedPacket;
+	UINT_64 au8Statistics[RX_STATISTIC_COUNTER_NUM];	/*!< RX Counters */
+
+#if CFG_HIF_STATISTICS
+	UINT_32 u4TotalRxAccessNum;
+	UINT_32 u4TotalRxPacketNum;
+#endif
+
+#if CFG_HIF_RX_STARVATION_WARNING
+	UINT_32 u4QueuedCnt;
+	UINT_32 u4DequeuedCnt;
+#endif
+
+#if CFG_RX_PKTS_DUMP
+	UINT_32 u4RxPktsDumpTypeMask;
+#endif
+
+} RX_CTRL_T, *P_RX_CTRL_T;
+
+typedef struct _RX_MAILBOX_T {
+	UINT_32 u4RxMailbox[2];	/* for Device-to-Host Mailbox */
+} RX_MAILBOX_T, *P_RX_MAILBOX_T;
+
+typedef WLAN_STATUS(*PROCESS_RX_MGT_FUNCTION) (P_ADAPTER_T, P_SW_RFB_T);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define RX_INC_CNT(prRxCtrl, eCounter)              \
+	{((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]++; }
+
+#define RX_ADD_CNT(prRxCtrl, eCounter, u8Amount)    \
+	{((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter] += (UINT_64)u8Amount; }
+
+#define RX_GET_CNT(prRxCtrl, eCounter)              \
+	(((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter])
+
+#define RX_RESET_ALL_CNTS(prRxCtrl)                 \
+	{kalMemZero(&prRxCtrl->au8Statistics[0], sizeof(prRxCtrl->au8Statistics)); }
+
+#define RX_STATUS_TEST_MORE_FLAG(flag) \
+	((BOOLEAN)((flag & RX_STATUS_FLAG_MORE_PACKET) ? TRUE : FALSE))
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter);
+
+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter);
+
+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter);
+
+#if !CFG_SDIO_INTR_ENHANCE
+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb);
+
+#else
+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS
+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter,
+		       IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb);
+#endif /* CFG_SDIO_INTR_ENHANCE */
+
+#if CFG_SDIO_RX_AGG
+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter);
+#endif
+
+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb);
+
+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb);
+
+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter);
+
+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb);
+
+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb);
+
+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb);
+
+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb);
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus);
+
+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]);
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count);
+
+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter);
+
+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count);
+
+WLAN_STATUS
+nicRxWaitResponse(IN P_ADAPTER_T prAdapter,
+		  IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length);
+
+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter);
+
+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+#endif /* _NIC_RX_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h
new file mode 100644
index 0000000000000..e516468fcb16a
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h
@@ -0,0 +1,642 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1
+*/
+
+/*! \file   nic_tx.h
+    \brief  Functions that provide TX operation in NIC's point of view.
+
+    This file provides TX functions which are responsible for both Hardware and
+    Software Resource Management and keep their Synchronization.
+
+*/
+
+/*
+** Log: nic_tx.h
+ *
+ * 11 18 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add log counter for tx
+ *
+ * 11 10 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add TX_DONE status detail information.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628-specific definitions.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing
+ * frame dropping cases for TC4 path
+ * 1. add nicTxGetResource() API for QM to make decisions.
+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability improvement
+ *
+ * 02 16 2011 cp.wu
+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking
+ * available count and modify behavior
+ * 1. add new API: nicTxGetFreeCmdCount()
+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 12 15 2010 yuche.tsai
+ * NULL
+ * Update SLT Descriptor number configure in driver.
+ *
+ * 11 16 2010 yarco.yang
+ * [WCXRP00000177] [MT5931 F/W] Performance tuning for 1st connection
+ * Update TX buffer count
+ *
+ * 11 03 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * 1) use 8 buffers for MT5931 which is equipped with less memory
+ * 2) modify MT5931 debug level to TRACE when download is successful
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion
+ * 2. shorten polling count for shorter response time
+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * code reorganization to improve isolation between GLUE and CORE layers.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * API added: nicTxPendingPackets(), for simplifying porting layer
+ *
+ * 07 26 2010 cp.wu
+ *
+ * change TC4 initial value from 2 to 4.
+ *
+ * 07 13 2010 cp.wu
+ *
+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under
+ *    concurrent network operation
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 06 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Add MGMT Packet type for HIF_TX_HEADER
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * integrate .
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * refine TX-DONE callback.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * TX descriptors are now allocated once for reducing allocation overhead
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * specify correct value for management frames.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate
+ * 2) add  packet type for indicating management frames
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add necessary changes to driver data paths.
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wlan_def.h.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * remove driver-land statistics.
+ *
+ * 03 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
+ *  *  *
+ *
+ * 03 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code clean: removing unused variables and structure definitions
+ *
+ * 03 02 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Redistributed the initial TC resources for normal operation
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add mutex to avoid multiple access to qmTxQueue simultaneously.
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add new API: wlanProcessQueuedPackets()
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
+ *  *  * 2) firmware image length is now retrieved via NdisFileOpen
+ *  *  * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
+ *  *  * 4) nicRxWaitResponse() revised
+ *  *  * 5) another set of TQ counter default value is added for fw-download state
+ *  *  * 6) Wi-Fi load address is now retrieved from registry too
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  *  *  * 2. follow MSDN defined behavior when associates to another AP
+ *  *  *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  *  *  *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  *  *  *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  *  *  *  * 4. correct some HAL implementation
+ *
+ * 01 13 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled the Burst_End Indication mechanism
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  *  *  * and result is retrieved by get ATInfo instead
+ *  *  *  *  * 2) add 4 counter for recording aggregation statistics
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:53:28 GMT mtk02752
+**  remove unused API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-27 11:08:00 GMT mtk02752
+**  add flush for reset
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-24 19:56:49 GMT mtk02752
+**  remove redundant eTC
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 22:01:08 GMT mtk02468
+**  Added MSDU_INFO fields for composing HIF TX header
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:51 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:35:05 GMT mtk02752
+**  + nicTxMsduInfoList() for sending MsduInfoList
+**  + NIC_TX_BUFF_COUNT_TC[0~5]
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-17 11:07:00 GMT mtk02752
+**  add nicTxAdjustTcq() API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 22:28:30 GMT mtk02752
+**  move aucFreeBufferCount/aucMaxNumOfBuffer into another structure
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 21:44:50 GMT mtk02752
+**  + nicTxReturnMsduInfo()
+**  + nicTxFillMsduInfo()
+**  + rFreeMsduInfoList field in TX_CTRL
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-16 18:00:43 GMT mtk02752
+**  use P_PACKET_INFO_T for prPacket to avoid inventing another new structure for packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-16 15:28:49 GMT mtk02752
+**  add ucQueuedPacketNum for indicating how many packets are queued by per STA/AC queue
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-16 10:52:01 GMT mtk02752
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-14 23:39:24 GMT mtk02752
+**  interface structure redefine
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-13 21:17:03 GMT mtk02752
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-29 19:53:10 GMT mtk01084
+**  remove strange code by Frog
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:04 GMT mtk01084
+**  update for new HW architecture design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-02 13:53:03 GMT mtk01725
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:36:50 GMT mtk01461
+**  Add declaration of nicTxReleaseResource()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:58:39 GMT mtk01461
+**  Move CMD_INFO_T related define and function to cmd_buf.h
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:53 GMT mtk01461
+**  Add function for SDIO_TX_ENHANCE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:33:27 GMT mtk01461
+**  Define constants for TX PATH and add nicTxPollingResource
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:32 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:38 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _NIC_TX_H
+#define _NIC_TX_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define NIC_TX_RESOURCE_POLLING_TIMEOUT     256
+#define NIC_TX_RESOURCE_POLLING_DELAY_MSEC  50
+
+/* Maximum buffer count for individual HIF TCQ */
+
+#if defined(MT6620)
+#if CFG_SLT_SUPPORT
+    /* 20101215 mtk01725 Redistributed the initial TC resources for SLT operation */
+#define NIC_TX_BUFF_COUNT_TC0       0	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC1       16	/* First connection: 32 */
+#define NIC_TX_BUFF_COUNT_TC2       0	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC3       0	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC4       4	/* First connection: 2 */
+#define NIC_TX_BUFF_COUNT_TC5       0	/* First connection: 0 */
+#else
+    /* 20100302 mtk02468 Redistributed the initial TC resources for normal operation */
+#define NIC_TX_BUFF_COUNT_TC0       6	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC1       8	/* First connection: 32 */
+#define NIC_TX_BUFF_COUNT_TC2       8	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC3       8	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC4       4	/* First connection: 2 */
+#define NIC_TX_BUFF_COUNT_TC5       2	/* First connection: 0 */
+#endif
+#elif defined(MT6628)
+#if (CFG_SRAM_SIZE_OPTION == 0)
+#define NIC_TX_BUFF_COUNT_TC0       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC1       20	/* First connection: 32 */
+#define NIC_TX_BUFF_COUNT_TC2       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC3       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC4       4	/* First connection: 2 */
+#define NIC_TX_BUFF_COUNT_TC5       1	/* First connection: 0 */
+#elif (CFG_SRAM_SIZE_OPTION == 1)
+#define NIC_TX_BUFF_COUNT_TC0       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC1       36	/* First connection: 32 */
+#define NIC_TX_BUFF_COUNT_TC2       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC3       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC4       4	/* First connection: 2 */
+#define NIC_TX_BUFF_COUNT_TC5       1	/* First connection: 0 */
+#elif (CFG_SRAM_SIZE_OPTION == 2)
+#define NIC_TX_BUFF_COUNT_TC0       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC1       48	/* First connection: 32 */
+#define NIC_TX_BUFF_COUNT_TC2       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC3       1	/* First connection: 0 */
+#define NIC_TX_BUFF_COUNT_TC4       4	/* First connection: 2 */
+#define NIC_TX_BUFF_COUNT_TC5       1	/* First connection: 0 */
+#else
+#error "> Set TX_BUFF_COUNT_TC error!"
+#endif
+#endif
+
+#define NIC_TX_BUFF_SUM                     (NIC_TX_BUFF_COUNT_TC0 + \
+					    NIC_TX_BUFF_COUNT_TC1 + \
+					    NIC_TX_BUFF_COUNT_TC2 + \
+					    NIC_TX_BUFF_COUNT_TC3 + \
+					    NIC_TX_BUFF_COUNT_TC4 + \
+					    NIC_TX_BUFF_COUNT_TC5)
+#if CFG_ENABLE_FW_DOWNLOAD
+
+#define NIC_TX_INIT_BUFF_COUNT_TC0               8
+#define NIC_TX_INIT_BUFF_COUNT_TC1               0
+#define NIC_TX_INIT_BUFF_COUNT_TC2               0
+#define NIC_TX_INIT_BUFF_COUNT_TC3               0
+#define NIC_TX_INIT_BUFF_COUNT_TC4               0
+#define NIC_TX_INIT_BUFF_COUNT_TC5               0
+
+#define NIC_TX_INIT_BUFF_SUM                    (NIC_TX_INIT_BUFF_COUNT_TC0 + \
+						    NIC_TX_INIT_BUFF_COUNT_TC1 + \
+						    NIC_TX_INIT_BUFF_COUNT_TC2 + \
+						    NIC_TX_INIT_BUFF_COUNT_TC3 + \
+						    NIC_TX_INIT_BUFF_COUNT_TC4 + \
+						    NIC_TX_INIT_BUFF_COUNT_TC5)
+
+#endif
+
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+#define NIC_TX_TIME_THRESHOLD                       100	/* in unit of ms */
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* 3 Session for TX QUEUES */
+/* The definition in this ENUM is used to categorize packet's Traffic Class according
+ * to the their TID(User Priority).
+ * In order to achieve QoS goal, a particular TC should not block the process of
+ * another packet with different TC.
+ * In current design we will have 5 categories(TCs) of SW resource.
+ */
+typedef enum _ENUM_TRAFFIC_CLASS_INDEX_T {
+	TC0_INDEX = 0,		/* HIF TX0: AC0 packets */
+	TC1_INDEX,		/* HIF TX0: AC1 packets & non-QoS packets */
+	TC2_INDEX,		/* HIF TX0: AC2 packets */
+	TC3_INDEX,		/* HIF TX0: AC3 packets */
+	TC4_INDEX,		/* HIF TX1: Command packets or 802.1x packets */
+	TC5_INDEX,		/* HIF TX0: BMCAST packets */
+	TC_NUM			/* Maximum number of Traffic Classes. */
+} ENUM_TRAFFIC_CLASS_INDEX_T;
+
+typedef enum _ENUM_TX_STATISTIC_COUNTER_T {
+	TX_MPDU_TOTAL_COUNT = 0,
+	TX_INACTIVE_BSS_DROP,
+	TX_INACTIVE_STA_DROP,
+	TX_FORWARD_OVERFLOW_DROP,
+	TX_AP_BORADCAST_DROP,
+	TX_STATISTIC_COUNTER_NUM
+} ENUM_TX_STATISTIC_COUNTER_T;
+
+typedef struct _TX_TCQ_STATUS_T {
+	UINT_8 aucFreeBufferCount[TC_NUM];
+	UINT_8 aucMaxNumOfBuffer[TC_NUM];
+} TX_TCQ_STATUS_T, *P_TX_TCQ_STATUS_T;
+
+typedef struct _TX_TCQ_ADJUST_T {
+	INT_8 acVariation[TC_NUM];
+} TX_TCQ_ADJUST_T, *P_TX_TCQ_ADJUST_T;
+
+typedef struct _TX_CTRL_T {
+	UINT_32 u4TxCachedSize;
+	PUINT_8 pucTxCached;
+
+/* Elements below is classified according to TC (Traffic Class) value. */
+
+	TX_TCQ_STATUS_T rTc;
+
+	PUINT_8 pucTxCoalescingBufPtr;
+
+	QUE_T rFreeMsduInfoList;
+
+	/* Management Frame Tracking */
+	/* number of management frames to be sent */
+	INT_32 i4TxMgmtPendingNum;
+
+	/* to tracking management frames need TX done callback */
+	QUE_T rTxMgmtTxingQueue;
+
+#if CFG_HIF_STATISTICS
+	UINT_32 u4TotalTxAccessNum;
+	UINT_32 u4TotalTxPacketNum;
+#endif
+	UINT_32 au4Statistics[TX_STATISTIC_COUNTER_NUM];
+
+	/* Number to track forwarding frames */
+	INT_32 i4PendingFwdFrameCount;
+
+} TX_CTRL_T, *P_TX_CTRL_T;
+
+typedef enum _ENUM_TX_PACKET_SRC_T {
+	TX_PACKET_OS,
+	TX_PACKET_OS_OID,
+	TX_PACKET_FORWARDING,
+	TX_PACKET_MGMT,
+	TX_PACKET_NUM
+} ENUM_TX_PACKET_SRC_T;
+
+typedef enum _ENUM_HIF_TX_PACKET_TYPE_T {
+	HIF_TX_PACKET_TYPE_DATA = 0,
+	HIF_TX_PACKET_TYPE_COMMAND,
+	HIF_TX_PACKET_TYPE_HIF_LB,
+	HIF_TX_PACKET_TYPE_MGMT
+} ENUM_HIF_TX_PACKET_TYPE_T, *P_ENUM_HIF_TX_PACKET_TYPE_T;
+
+typedef enum _ENUM_TX_RESULT_CODE_T {
+	TX_RESULT_SUCCESS = 0,
+	TX_RESULT_LIFE_TIMEOUT,
+	TX_RESULT_RTS_ERROR,
+	TX_RESULT_MPDU_ERROR,
+	TX_RESULT_AGING_TIMEOUT,
+	TX_RESULT_FLUSHED,
+	TX_RESULT_DROPPED_IN_DRIVER = 32,
+	TX_RESULT_NUM
+} ENUM_TX_RESULT_CODE_T, *P_ENUM_TX_RESULT_CODE_T;
+
+struct _WLAN_CFG_ENTRY_T {
+	UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX];
+	UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX];
+	WLAN_CFG_SET_CB pfSetCb;
+	PVOID pPrivate;
+	UINT_32 u4Flags;
+};
+
+struct _WLAN_CFG_T {
+	UINT_32 u4WlanCfgEntryNumMax;
+	UINT_32 u4WlanCfgKeyLenMax;
+	UINT_32 u4WlanCfgValueLenMax;
+	WLAN_CFG_ENTRY_T arWlanCfgBuf[WLAN_CFG_ENTRY_NUM_MAX];
+};
+
+/* TX Call Back Function  */
+typedef WLAN_STATUS(*PFN_TX_DONE_HANDLER) (IN P_ADAPTER_T prAdapter,
+					   IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+typedef struct _PKT_PROFILE_T {
+	BOOLEAN fgIsValid;
+#if CFG_PRINT_RTP_PROFILE
+	BOOLEAN fgIsPrinted;
+	UINT_16 u2IpSn;
+	UINT_16 u2RtpSn;
+	UINT_8 ucTcxFreeCount;
+#endif
+	OS_SYSTIME rHardXmitArrivalTimestamp;
+	OS_SYSTIME rEnqueueTimestamp;
+	OS_SYSTIME rDequeueTimestamp;
+	OS_SYSTIME rHifTxDoneTimestamp;
+} PKT_PROFILE_T, *P_PKT_PROFILE_T;
+#endif
+
+/* TX transactions could be divided into 4 kinds:
+ *
+ * 1) 802.1X / Bluetooth-over-Wi-Fi Security Frames
+ *    [CMD_INFO_T] - [prPacket] - in skb or NDIS_PACKET form
+ *
+ * 2) MMPDU
+ *    [CMD_INFO_T] - [prPacket] - [MSDU_INFO_T] - [prPacket] - direct buffer for frame body
+ *
+ * 3) Command Packets
+ *    [CMD_INFO_T] - [pucInfoBuffer] - direct buffer for content of command packet
+ *
+ * 4) Normal data frame
+ *    [MSDU_INFO_T] - [prPacket] - in skb or NDIS_PACKET form
+ */
+
+/* PS_FORWARDING_TYPE_NON_PS means that the receiving STA is in Active Mode
+*   from the perspective of host driver (maybe not synchronized with FW --> SN is needed)
+*/
+
+struct _MSDU_INFO_T {
+	QUE_ENTRY_T rQueEntry;
+	P_NATIVE_PACKET prPacket;
+
+	ENUM_TX_PACKET_SRC_T eSrc;	/* specify OS/FORWARD packet */
+	UINT_8 ucUserPriority;
+
+	/* For composing HIF TX header */
+	UINT_8 ucTC;		/* Traffic Class: 0~4 (HIF TX0), 5 (HIF TX1) */
+	UINT_8 ucPacketType;	/* 0: Data, 1: Command, 2: HIF Loopback 3: Management Frame */
+	UINT_8 ucStaRecIndex;
+	UINT_8 ucNetworkType;	/* See ENUM_NETWORK_TYPE_T */
+	UINT_8 ucFormatID;	/* 0: MAUI, Linux, Windows NDIS 5.1 */
+	BOOLEAN fgIs802_1x;	/* TRUE: 802.1x frame */
+	BOOLEAN fgIs802_11;	/* TRUE: 802.11 header is present */
+	UINT_16 u2PalLLH;	/* PAL Logical Link Header (for BOW network) */
+	UINT_16 u2AclSN;	/* ACL Sequence Number (for BOW network) */
+	UINT_8 ucPsForwardingType;	/* See ENUM_PS_FORWARDING_TYPE_T */
+	UINT_8 ucPsSessionID;	/* PS Session ID specified by the FW for the STA */
+	BOOLEAN fgIsBurstEnd;	/* TRUE means this is the last packet of the burst for (STA, TID) */
+	BOOLEAN fgIsBIP;	/* Management Frame Protection */
+	BOOLEAN fgIsBasicRate;	/* Force Basic Rate Transmission */
+
+	/* flattened from PACKET_INFO_T */
+	UINT_8 ucMacHeaderLength;
+	UINT_8 ucLlcLength;	/* w/o EtherType */
+	UINT_16 u2FrameLength;
+	UINT_8 aucEthDestAddr[MAC_ADDR_LEN];	/* Ethernet Destination Address */
+
+	/* for TX done tracking */
+	UINT_8 ucTxSeqNum;
+	PFN_TX_DONE_HANDLER pfTxDoneHandler;
+	BOOLEAN fgNeedTxDoneStatus;
+
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+	PKT_PROFILE_T rPktProfile;
+#endif
+	COMMAND_TYPE eCmdType;
+	UINT_8 ucCID;
+	UINT_32 u4InqueTime;
+};
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define TX_INC_CNT(prTxCtrl, eCounter)              \
+	{((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]++; }
+
+#define TX_ADD_CNT(prTxCtrl, eCounter, u8Amount)    \
+	{((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter] += (UINT_32)u8Amount; }
+
+#define TX_GET_CNT(prTxCtrl, eCounter)              \
+	(((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter])
+
+#define TX_RESET_ALL_CNTS(prTxCtrl)                 \
+	{kalMemZero(&prTxCtrl->au4Statistics[0], sizeof(prTxCtrl->au4Statistics)); }
+
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+#define PRINT_PKT_PROFILE(_pkt_profile, _note) \
+{ \
+	if (!(_pkt_profile)->fgIsPrinted) { \
+		DBGLOG(TX, TRACE, "X[%u] E[%u] D[%u] HD[%u] B[%d] RTP[%d] %s\n", \
+		(UINT_32)((_pkt_profile)->rHardXmitArrivalTimestamp), \
+		(UINT_32)((_pkt_profile)->rEnqueueTimestamp), \
+		(UINT_32)((_pkt_profile)->rDequeueTimestamp), \
+		(UINT_32)((_pkt_profile)->rHifTxDoneTimestamp), \
+		(UINT_8)((_pkt_profile)->ucTcxFreeCount), \
+		(UINT_16)((_pkt_profile)->u2RtpSn), \
+		(_note)); \
+		(_pkt_profile)->fgIsPrinted = TRUE; \
+	} \
+}
+
+#define CHK_PROFILES_DELTA(_pkt1, _pkt2, _delta) \
+	   (CHECK_FOR_TIMEOUT((_pkt1)->rHardXmitArrivalTimestamp, (_pkt2)->rHardXmitArrivalTimestamp, (_delta)) || \
+	    CHECK_FOR_TIMEOUT((_pkt1)->rEnqueueTimestamp, (_pkt2)->rEnqueueTimestamp, (_delta)) || \
+	    CHECK_FOR_TIMEOUT((_pkt1)->rDequeueTimestamp, (_pkt2)->rDequeueTimestamp, (_delta)) || \
+	    CHECK_FOR_TIMEOUT((_pkt1)->rHifTxDoneTimestamp, (_pkt2)->rHifTxDoneTimestamp, (_delta)))
+
+#define CHK_PROFILE_DELTA(_pkt, _delta) \
+	   (CHECK_FOR_TIMEOUT((_pkt)->rEnqueueTimestamp, (_pkt)->rHardXmitArrivalTimestamp, (_delta)) || \
+	    CHECK_FOR_TIMEOUT((_pkt)->rDequeueTimestamp, (_pkt)->rEnqueueTimestamp, (_delta)) || \
+	    CHECK_FOR_TIMEOUT((_pkt)->rHifTxDoneTimestamp, (_pkt)->rDequeueTimestamp, (_delta)))
+#endif
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt);
+
+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC);
+
+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_8 *aucTxRlsCnt);
+
+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter);
+
+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC);
+
+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead);
+
+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue);
+
+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC);
+
+VOID nicTxRelease(IN P_ADAPTER_T prAdapter);
+
+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter);
+
+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead);
+
+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead);
+
+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prNdisPacket);
+
+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter);
+
+#if CFG_ENABLE_FW_DOWNLOAD
+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC);
+
+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter);
+#endif
+
+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _NIC_TX_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h
new file mode 100644
index 0000000000000..d518aaf10eb56
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h
@@ -0,0 +1,192 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p.h#3
+*/
+
+/*
+** Log: p2p.h
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Add the code to support disconnect p2p group
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * [Wi-Fi Direct] add framework for driver hooks
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * p2p interface revised to be sync. with HAL
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 18 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add parameter to control:
+ * 1) auto group owner
+ * 2) P2P-PS parameter (CTWindow, NoA descriptors)
+ *
+ * 05 18 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * correct WPS Device Password ID definition.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement get scan result.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic handling framework for wireless extension ioctls.
+ *
+ * 05 14 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * p2p ioctls revised.
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement basic wi-fi direct framework
+ *
+ * 05 07 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic framework for implementating P2P driver hook.
+ *
+ *
+*/
+
+#ifndef _P2P_H
+#define _P2P_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/* refer to 'Config Methods' in WPS */
+#define WPS_CONFIG_USBA                 0x0001
+#define WPS_CONFIG_ETHERNET             0x0002
+#define WPS_CONFIG_LABEL                0x0004
+#define WPS_CONFIG_DISPLAY              0x0008
+#define WPS_CONFIG_EXT_NFC              0x0010
+#define WPS_CONFIG_INT_NFC              0x0020
+#define WPS_CONFIG_NFC                  0x0040
+#define WPS_CONFIG_PBC                  0x0080
+#define WPS_CONFIG_KEYPAD               0x0100
+
+/* refer to 'Device Password ID' in WPS */
+#define WPS_DEV_PASSWORD_ID_PIN         0x0000
+#define WPS_DEV_PASSWORD_ID_USER        0x0001
+#define WPS_DEV_PASSWORD_ID_MACHINE     0x0002
+#define WPS_DEV_PASSWORD_ID_REKEY       0x0003
+#define WPS_DEV_PASSWORD_ID_PUSHBUTTON  0x0004
+#define WPS_DEV_PASSWORD_ID_REGISTRAR   0x0005
+
+#define P2P_DEVICE_TYPE_NUM         2
+#define P2P_DEVICE_NAME_LENGTH      32
+#define P2P_NETWORK_NUM             8
+#define P2P_MEMBER_NUM              8
+
+#define P2P_WILDCARD_SSID           "DIRECT-"
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+struct _P2P_INFO_T {
+	UINT_32 u4DeviceNum;
+	EVENT_P2P_DEV_DISCOVER_RESULT_T arP2pDiscoverResult[CFG_MAX_NUM_BSS_LIST];
+	PUINT_8 pucCurrIePtr;
+	UINT_8 aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN];	/* A common pool for IE of all scan results. */
+};
+
+typedef enum {
+	ENUM_P2P_PEER_GROUP,
+	ENUM_P2P_PEER_DEVICE,
+	ENUM_P2P_PEER_NUM
+} ENUM_P2P_PEER_TYPE, *P_ENUM_P2P_PEER_TYPE;
+
+typedef struct _P2P_DEVICE_INFO {
+	UINT_8 aucDevAddr[PARAM_MAC_ADDR_LEN];
+	UINT_8 aucIfAddr[PARAM_MAC_ADDR_LEN];
+	UINT_8 ucDevCapabilityBitmap;
+	INT_32 i4ConfigMethod;
+	UINT_8 aucPrimaryDeviceType[8];
+	UINT_8 aucSecondaryDeviceType[8];
+	UINT_8 aucDeviceName[P2P_DEVICE_NAME_LENGTH];
+} P2P_DEVICE_INFO, *P_P2P_DEVICE_INFO;
+
+typedef struct _P2P_GROUP_INFO {
+	PARAM_SSID_T rGroupID;
+	P2P_DEVICE_INFO rGroupOwnerInfo;
+	UINT_8 ucMemberNum;
+	P2P_DEVICE_INFO arMemberInfo[P2P_MEMBER_NUM];
+} P2P_GROUP_INFO, *P_P2P_GROUP_INFO;
+
+typedef struct _P2P_NETWORK_INFO {
+	ENUM_P2P_PEER_TYPE eNodeType;
+
+	union {
+		P2P_GROUP_INFO rGroupInfo;
+		P2P_DEVICE_INFO rDeviceInfo;
+	} node;
+
+} P2P_NETWORK_INFO, *P_P2P_NETWORK_INFO;
+
+typedef struct _P2P_NETWORK_LIST {
+	UINT_8 ucNetworkNum;
+	P2P_NETWORK_INFO rP2PNetworkInfo[P2P_NETWORK_NUM];
+} P2P_NETWORK_LIST, *P_P2P_NETWORK_LIST;
+
+typedef struct _P2P_DISCONNECT_INFO {
+	UINT_8 ucRole;
+	UINT_8 ucRsv[3];
+} P2P_DISCONNECT_INFO, *P_P2P_DISCONNECT_INFO;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+#endif /*_P2P_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h
new file mode 100644
index 0000000000000..7f7a92584c7ce
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h
@@ -0,0 +1,83 @@
+/*
+** Id:
+*/
+
+/*! \file   "p2p_cmd_buf.h"
+    \brief  In this file we define the structure for Command Packet.
+
+		In this file we define the structure for Command Packet and the control unit
+    of MGMT Memory Pool.
+*/
+
+/*
+** Log: p2p_cmd_buf.h
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 12 22 2010 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface
+ * for supporting Wi-Fi Direct Service Discovery
+ * 1. header file restructure for more clear module isolation
+ * 2. add function interface definition for implementing Service Discovery callbacks
+*/
+
+#ifndef _P2P_CMD_BUF_H
+#define _P2P_CMD_BUF_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*--------------------------------------------------------------*/
+/* Firmware Command Packer                                      */
+/*--------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter,
+			  UINT_8 ucCID,
+			  BOOLEAN fgSetQuery,
+			  BOOLEAN fgNeedResp,
+			  BOOLEAN fgIsOid,
+			  PFN_CMD_DONE_HANDLER pfCmdDoneHandler,
+			  PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler,
+			  UINT_32 u4SetQueryInfoLen,
+			  PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen);
+
+#endif /* _P2P_CMD_BUF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h
new file mode 100644
index 0000000000000..76115dabe1a1d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h
@@ -0,0 +1,207 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_mac.h#2
+*/
+
+/*! \file   "p2p_mac.h"
+    \brief  Brief description.
+
+    Detail description.
+*/
+
+#ifndef _P2P_MAC_H
+#define _P2P_MAC_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define ACTION_PUBLIC_WIFI_DIRECT                   9
+#define ACTION_GAS_INITIAL_REQUEST                 10
+#define ACTION_GAS_INITIAL_RESPONSE               11
+#define ACTION_GAS_COMEBACK_REQUEST           12
+#define ACTION_GAS_COMEBACK_RESPONSE         13
+
+/* P2P 4.2.8.1 - P2P Public Action Frame Type. */
+#define P2P_PUBLIC_ACTION_GO_NEGO_REQ               0
+#define P2P_PUBLIC_ACTION_GO_NEGO_RSP               1
+#define P2P_PUBLIC_ACTION_GO_NEGO_CFM               2
+#define P2P_PUBLIC_ACTION_INVITATION_REQ            3
+#define P2P_PUBLIC_ACTION_INVITATION_RSP            4
+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_REQ          5
+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_RSP          6
+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_REQ        7
+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_RSP        8
+
+/* P2P 4.2.9.1 - P2P Action Frame Type */
+#define P2P_ACTION_NOTICE_OF_ABSENCE                0
+#define P2P_ACTION_P2P_PRESENCE_REQ                 1
+#define P2P_ACTION_P2P_PRESENCE_RSP                 2
+#define P2P_ACTION_GO_DISCOVER_REQ                  3
+
+#define P2P_PUBLIC_ACTION_FRAME_LEN                (WLAN_MAC_MGMT_HEADER_LEN+8)
+#define P2P_ACTION_FRAME_LEN                       (WLAN_MAC_MGMT_HEADER_LEN+7)
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/* P2P 4.2.8.2 P2P Public Action Frame Format */
+typedef struct _P2P_PUBLIC_ACTION_FRAME_T {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* P2P Public Action Frame Body */
+	UINT_8 ucCategory;	/* Category, 0x04 */
+	UINT_8 ucAction;	/* Action Value, 0x09 */
+	UINT_8 aucOui[3];	/* 0x50, 0x6F, 0x9A */
+	UINT_8 ucOuiType;	/* 0x09 */
+	UINT_8 ucOuiSubtype;	/* GO Nego Req/Rsp/Cfm, P2P Invittion Req/Rsp, Device Discoverability Req/Rsp */
+	UINT_8 ucDialogToken;	/* Dialog Token. */
+	UINT_8 aucInfoElem[1];	/* P2P IE, WSC IE. */
+} __KAL_ATTRIB_PACKED__ P2P_PUBLIC_ACTION_FRAME_T, *P_P2P_PUBLIC_ACTION_FRAME_T;
+
+/* P2P 4.2.9.1 -  General Action Frame Format. */
+typedef struct _P2P_ACTION_FRAME_T {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* P2P Action Frame Body */
+	UINT_8 ucCategory;	/* 0x7F */
+	UINT_8 aucOui[3];	/* 0x50, 0x6F, 0x9A */
+	UINT_8 ucOuiType;	/* 0x09 */
+	UINT_8 ucOuiSubtype;	/*  */
+	UINT_8 ucDialogToken;
+	UINT_8 aucInfoElem[1];
+} __KAL_ATTRIB_PACKED__ P2P_ACTION_FRAME_T, *P_P2P_ACTION_FRAME_T;
+
+/* P2P C.1 GAS Public Action Initial Request Frame Format */
+typedef struct _GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* P2P Public Action Frame Body */
+	UINT_8 ucCategory;	/* Category, 0x04 */
+	UINT_8 ucAction;	/* Action Value, 0x09 */
+	UINT_8 ucDialogToken;	/* Dialog Token. */
+	UINT_8 aucInfoElem[1];	/* Advertisement IE. */
+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T;
+
+/* P2P C.2 GAS Public Action Initial Response Frame Format */
+typedef struct _GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* P2P Public Action Frame Body */
+	UINT_8 ucCategory;	/* Category, 0x04 */
+	UINT_8 ucAction;	/* Action Value, 0x09 */
+	UINT_8 ucDialogToken;	/* Dialog Token. */
+	UINT_16 u2StatusCode;	/* Initial Response. */
+	UINT_16 u2ComebackDelay;	/* Initial Response. *//* In unit of TU. */
+	UINT_8 aucInfoElem[1];	/* Advertisement IE. */
+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T;
+
+/* P2P C.3-1 GAS Public Action Comeback Request Frame Format */
+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* P2P Public Action Frame Body */
+	UINT_8 ucCategory;	/* Category, 0x04 */
+	UINT_8 ucAction;	/* Action Value, 0x09 */
+	UINT_8 ucDialogToken;	/* Dialog Token. */
+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T;
+
+/* P2P C.3-2 GAS Public Action Comeback Response Frame Format */
+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T {
+	/* MAC header */
+	UINT_16 u2FrameCtrl;	/* Frame Control */
+	UINT_16 u2Duration;	/* Duration */
+	UINT_8 aucDestAddr[MAC_ADDR_LEN];	/* DA */
+	UINT_8 aucSrcAddr[MAC_ADDR_LEN];	/* SA */
+	UINT_8 aucBSSID[MAC_ADDR_LEN];	/* BSSID */
+	UINT_16 u2SeqCtrl;	/* Sequence Control */
+	/* P2P Public Action Frame Body */
+	UINT_8 ucCategory;	/* Category, 0x04 */
+	UINT_8 ucAction;	/* Action Value, 0x09 */
+	UINT_8 ucDialogToken;	/* Dialog Token. */
+	UINT_16 u2StatusCode;	/* Comeback Response. */
+	UINT_8 ucFragmentID;	/*Comeback Response. */
+	UINT_16 u2ComebackDelay;	/* Comeback Response. */
+	UINT_8 aucInfoElem[1];	/* Advertisement IE. */
+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T;
+
+typedef struct _P2P_SD_VENDER_SPECIFIC_CONTENT_T {
+	/* Service Discovery Vendor-specific Content. */
+	UINT_8 ucOuiSubtype;	/* 0x09 */
+	UINT_16 u2ServiceUpdateIndicator;
+	UINT_8 aucServiceTLV[1];
+} __KAL_ATTRIB_PACKED__ P2P_SD_VENDER_SPECIFIC_CONTENT_T, *P_P2P_SD_VENDER_SPECIFIC_CONTENT_T;
+
+typedef struct _P2P_SERVICE_REQUEST_TLV_T {
+	UINT_16 u2Length;
+	UINT_8 ucServiceProtocolType;
+	UINT_8 ucServiceTransID;
+	UINT_8 aucQueryData[1];
+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_REQUEST_TLV_T, *P_P2P_SERVICE_REQUEST_TLV_T;
+
+typedef struct _P2P_SERVICE_RESPONSE_TLV_T {
+	UINT_16 u2Length;
+	UINT_8 ucServiceProtocolType;
+	UINT_8 ucServiceTransID;
+	UINT_8 ucStatusCode;
+	UINT_8 aucResponseData[1];
+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_RESPONSE_TLV_T, *P_P2P_SERVICE_RESPONSE_TLV_T;
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h
new file mode 100644
index 0000000000000..0a87bd457a926
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h
@@ -0,0 +1,62 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic.h#1
+*/
+
+/*! \file   "p2p_nic.h"
+    \brief  The declaration of nic functions
+
+    Detail description.
+*/
+
+#ifndef _P2P_NIC_H
+#define _P2P_NIC_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+VOID
+nicP2pMediaStateChange(IN P_ADAPTER_T prAdapter,
+		       IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus);
+
+VOID
+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter,
+		  IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h
new file mode 100644
index 0000000000000..cea77414ce357
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h
@@ -0,0 +1,70 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic_cmd_event.h#1
+*/
+
+/*! \file   p2p_nic_cmd_event.h
+    \brief
+*/
+
+#ifndef _P2P_NIC_CMD_EVENT_H
+#define _P2P_NIC_CMD_EVENT_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+typedef struct _EVENT_P2P_DEV_DISCOVER_RESULT_T {
+/* UINT_8                          aucCommunicateAddr[MAC_ADDR_LEN];  // Deprecated. */
+	UINT_8 aucDeviceAddr[MAC_ADDR_LEN];	/* Device Address. */
+	UINT_8 aucInterfaceAddr[MAC_ADDR_LEN];	/* Device Address. */
+	UINT_8 ucDeviceCapabilityBitmap;
+	UINT_8 ucGroupCapabilityBitmap;
+	UINT_16 u2ConfigMethod;	/* Configure Method. */
+	P2P_DEVICE_TYPE_T rPriDevType;
+	UINT_8 ucSecDevTypeNum;
+	P2P_DEVICE_TYPE_T arSecDevType[2];
+	UINT_16 u2NameLength;
+	UINT_8 aucName[32];
+	PUINT_8 pucIeBuf;
+	UINT_16 u2IELength;
+	UINT_8 aucBSSID[MAC_ADDR_LEN];
+	/* TODO: Service Information or PasswordID valid? */
+} EVENT_P2P_DEV_DISCOVER_RESULT_T, *P_EVENT_P2P_DEV_DISCOVER_RESULT_T;
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h
new file mode 100644
index 0000000000000..dbfb90d94ee4c
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h
@@ -0,0 +1,971 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/que_mgt.h#1
+*/
+
+/*! \file   "que_mgt.h"
+    \brief  TX/RX queues management header file
+
+    The main tasks of queue management include TC-based HIF TX flow control,
+    adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save
+    forwarding control, RX packet reordering, and RX BA agreement management.
+*/
+
+/*
+** Log: que_mgt.h
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628-specific definitions.
+ *
+ * 07 26 2011 eddie.chen
+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter
+ * API for query the RX reorder queued packets counter.
+ *
+ * 06 14 2011 eddie.chen
+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931
+ * Change the parameter for WMM pass.
+ *
+ * 05 31 2011 eddie.chen
+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931
+ * Fix the QM quota in MT5931.
+ *
+ * 05 09 2011 eddie.chen
+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
+ * Check free number before copying broadcast packet.
+ *
+ * 04 14 2011 eddie.chen
+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
+ * Check the SW RFB free. Fix the compile warning..
+ *
+ * 04 08 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix for sigma
+ *
+ * 03 28 2011 eddie.chen
+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW
+ * Fix wmm parameters in beacon for BOW.
+ *
+ * 03 15 2011 eddie.chen
+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter
+ * Add sw debug counter for QM.
+ *
+ * 02 17 2011 eddie.chen
+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel
+ * 1) Change GetFrameAction decision when BSS is absent.
+ * 2) Check channel and resource in processing ProbeRequest
+ *
+ * 01 12 2011 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * 1) Check Bss if support QoS before adding WMMIE
+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 12 23 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * 1. update WMM IE parsing, with ASSOC REQ handling
+ * 2. extend U-APSD parameter passing from driver to FW
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T
+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 08 04 2010 yarco.yang
+ * NULL
+ * Add TX_AMPDU and ADDBA_REJECT command
+ *
+ * 07 22 2010 george.huang
+ *
+ * Update fgIsQoS information in BSS INFO by CMD
+ *
+ * 07 16 2010 yarco.yang
+ *
+ * 1. Support BSS Absence/Presence Event
+ * 2. Support STA change PS mode Event
+ * 3. Support BMC forwarding for AP mode.
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 13 2010 yarco.yang
+ *
+ * [WPD00003849]
+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing
+ *
+ * 07 09 2010 yarco.yang
+ *
+ * [MT6620 and MT5931] SW Migration: Add ADDBA support
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 29 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * replace g_rQM with Adpater->rQM
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add API in que_mgt to retrieve sta-rec index for security frames.
+ *
+ * 06 23 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Merge g_arStaRec[] into adapter->arStaRec[]
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Support CFG_MQM_MIGRATION flag
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 30 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled adaptive TC resource control
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 19 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * By default enabling dynamic STA_REC activation and decactivation
+ *
+ * 03 17 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST)
+ *
+ * 03 11 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Fixed buffer leak when processing BAR frames
+ *
+ * 02 25 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled multi-STA TX path with fairness
+ *
+ * 02 24 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled dynamically activating and deactivating STA_RECs
+ *
+ * 02 24 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Added code for dynamic activating and deactivating STA_RECs.
+ *
+ * 01 13 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled the Burst_End Indication mechanism
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:04:53 GMT MTK02468
+**  Added RX buffer reordering function prototypes
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-02 22:08:44 GMT MTK02468
+**  Added macro QM_INIT_STA_REC for initialize a STA_REC
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 21:58:43 GMT mtk02468
+**  Initial version
+**
+*/
+
+#ifndef _QUE_MGT_H
+#define _QUE_MGT_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/* Queue Manager Features */
+/* 1: Indicate the last TX packet to the FW for each burst */
+#define QM_BURST_END_INFO_ENABLED       1
+/* 1: To fairly share TX resource among active STAs */
+#define QM_FORWARDING_FAIRNESS          1
+/* 1: To adaptively adjust resource for each TC */
+#define QM_ADAPTIVE_TC_RESOURCE_CTRL    1
+/* 1: To print TC resource adjustment results */
+#define QM_PRINT_TC_RESOURCE_CTRL       0
+/* 1: If pkt with SSN is missing, auto advance the RX reordering window */
+#define QM_RX_WIN_SSN_AUTO_ADVANCING    1
+/* 1: Indicate the packets falling behind to OS before the frame with SSN is received */
+#define QM_RX_INIT_FALL_BEHIND_PASS     1
+/* 1: Count times of TC resource empty happened */
+#define QM_TC_RESOURCE_EMPTY_COUNTER    1
+/* Parameters */
+
+/*
+	In TDLS or AP mode, peer maybe enter "sleep mode".
+
+	If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode,
+	we need to wait 60 * u4TimeToAdjustTcResource = 180 packets
+	u4TimeToAdjustTcResource = 3,
+	then we will adjust TC resouce for VI or VO.
+
+	But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7,
+	we will to wait about 12 seconds to collect 180 packets.
+	but the test time is only 20 seconds.
+*/
+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN  60	/* p: Update queue lengths when p TX packets are enqueued */
+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN 5
+
+#define QM_INIT_TIME_TO_ADJUST_TC_RSC   3	/* s: Adjust the TC resource every s updates of queue lengths  */
+#define QM_QUE_LEN_MOVING_AVE_FACTOR    3	/* Factor for Que Len averaging */
+
+#define QM_MIN_RESERVED_TC0_RESOURCE    1
+#define QM_MIN_RESERVED_TC1_RESOURCE    1
+#define QM_MIN_RESERVED_TC2_RESOURCE    1
+#define QM_MIN_RESERVED_TC3_RESOURCE    1
+#define QM_MIN_RESERVED_TC4_RESOURCE    2	/* Resource for TC4 is not adjustable */
+#define QM_MIN_RESERVED_TC5_RESOURCE    1
+
+#if defined(MT6620)
+
+#define QM_GUARANTEED_TC0_RESOURCE      4
+#define QM_GUARANTEED_TC1_RESOURCE      4
+#define QM_GUARANTEED_TC2_RESOURCE      9
+#define QM_GUARANTEED_TC3_RESOURCE      11
+#define QM_GUARANTEED_TC4_RESOURCE      2	/* Resource for TC4 is not adjustable */
+#define QM_GUARANTEED_TC5_RESOURCE      4
+
+#elif defined(MT6628)
+
+#define QM_GUARANTEED_TC0_RESOURCE      4
+#define QM_GUARANTEED_TC1_RESOURCE      4
+#define QM_GUARANTEED_TC2_RESOURCE      6
+#define QM_GUARANTEED_TC3_RESOURCE      6
+#define QM_GUARANTEED_TC4_RESOURCE      2	/* Resource for TC4 is not adjustable */
+#define QM_GUARANTEED_TC5_RESOURCE      4
+
+#else
+#error
+#endif
+
+#define QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY    0
+
+#define QM_TOTAL_TC_RESOURCE            (\
+	NIC_TX_BUFF_COUNT_TC0 + NIC_TX_BUFF_COUNT_TC1 +\
+	NIC_TX_BUFF_COUNT_TC2 + NIC_TX_BUFF_COUNT_TC3 +\
+	NIC_TX_BUFF_COUNT_TC5)
+#define QM_AVERAGE_TC_RESOURCE          6
+
+/* Note: QM_INITIAL_RESIDUAL_TC_RESOURCE shall not be less than 0 */
+/* for 6628: QM_TOTAL_TC_RESOURCE = 28, RESIDUAL = 4 4 6 6 2 4 = 26 */
+#define QM_INITIAL_RESIDUAL_TC_RESOURCE  (QM_TOTAL_TC_RESOURCE - \
+					 (QM_GUARANTEED_TC0_RESOURCE +\
+					  QM_GUARANTEED_TC1_RESOURCE +\
+					  QM_GUARANTEED_TC2_RESOURCE +\
+					  QM_GUARANTEED_TC3_RESOURCE +\
+					  QM_GUARANTEED_TC5_RESOURCE \
+					  ))
+
+/* Hard-coded network type for Phase 3: NETWORK_TYPE_AIS/P2P/BOW */
+#define QM_OPERATING_NETWORK_TYPE   NETWORK_TYPE_AIS
+
+#define QM_TEST_MODE                        0
+#define QM_TEST_TRIGGER_TX_COUNT            50
+#define QM_TEST_STA_REC_DETERMINATION       0
+#define QM_TEST_STA_REC_DEACTIVATION        0
+#define QM_TEST_FAIR_FORWARDING             0
+
+#define QM_DEBUG_COUNTER                    0
+
+/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */
+/* Per-Type Queues: [0] BMCAST */
+#define NUM_OF_PER_STA_TX_QUEUES    5
+#define NUM_OF_PER_TYPE_TX_QUEUES   1
+
+/* These two constants are also used for FW to verify the STA_REC index */
+#define STA_REC_INDEX_BMCAST        0xFF
+#define STA_REC_INDEX_NOT_FOUND     0xFE
+
+/* TX Queue Index */
+#define TX_QUEUE_INDEX_BMCAST       0
+#define TX_QUEUE_INDEX_NO_STA_REC   0
+#define TX_QUEUE_INDEX_AC0          0
+#define TX_QUEUE_INDEX_AC1          1
+#define TX_QUEUE_INDEX_AC2          2
+#define TX_QUEUE_INDEX_AC3          3
+#define TX_QUEUE_INDEX_802_1X       4
+#define TX_QUEUE_INDEX_NON_QOS      1
+
+/* 1 WMM-related */
+/* WMM FLAGS */
+#define WMM_FLAG_SUPPORT_WMM                BIT(0)
+#define WMM_FLAG_SUPPORT_WMMSA              BIT(1)
+#define WMM_FLAG_AC_PARAM_PRESENT           BIT(2)
+#define WMM_FLAG_SUPPORT_UAPSD              BIT(3)
+
+/* WMM Admission Control Mandatory FLAGS */
+#define ACM_FLAG_ADM_NOT_REQUIRED           0
+#define ACM_FLAG_ADM_GRANTED                BIT(0)
+#define ACM_FLAG_ADM_REQUIRED               BIT(1)
+
+/* WMM Power Saving FLAGS */
+#define AC_FLAG_TRIGGER_ENABLED             BIT(1)
+#define AC_FLAG_DELIVERY_ENABLED            BIT(2)
+
+/* WMM-2.2.1 WMM Information Element */
+#define ELEM_MAX_LEN_WMM_INFO               7
+
+/* WMM-2.2.2 WMM Parameter Element */
+#define ELEM_MAX_LEN_WMM_PARAM              24
+
+/* WMM-2.2.1 WMM QoS Info field */
+#define WMM_QOS_INFO_PARAM_SET_CNT          BITS(0, 3)	/* Sent by AP */
+#define WMM_QOS_INFO_UAPSD                  BIT(7)
+
+#define WMM_QOS_INFO_VO_UAPSD               BIT(0)	/* Sent by non-AP STA */
+#define WMM_QOS_INFO_VI_UAPSD               BIT(1)
+#define WMM_QOS_INFO_BK_UAPSD               BIT(2)
+#define WMM_QOS_INFO_BE_UAPSD               BIT(3)
+#define WMM_QOS_INFO_MAX_SP_LEN_MASK        BITS(5, 6)
+#define WMM_QOS_INFO_MAX_SP_ALL             0
+#define WMM_QOS_INFO_MAX_SP_2               BIT(5)
+#define WMM_QOS_INFO_MAX_SP_4               BIT(6)
+#define WMM_QOS_INFO_MAX_SP_6               BITS(5, 6)
+
+/* -- definitions for Max SP length field */
+#define WMM_MAX_SP_LENGTH_ALL               0
+#define WMM_MAX_SP_LENGTH_2                 2
+#define WMM_MAX_SP_LENGTH_4                 4
+#define WMM_MAX_SP_LENGTH_6                 6
+
+/* WMM-2.2.2 WMM ACI/AIFSN field */
+/* -- subfields in the ACI/AIFSN field */
+#define WMM_ACIAIFSN_AIFSN                  BITS(0, 3)
+#define WMM_ACIAIFSN_ACM                    BIT(4)
+#define WMM_ACIAIFSN_ACI                    BITS(5, 6)
+#define WMM_ACIAIFSN_ACI_OFFSET             5
+
+/* -- definitions for ACI field */
+#define WMM_ACI_AC_BE                       0
+#define WMM_ACI_AC_BK                       BIT(5)
+#define WMM_ACI_AC_VI                       BIT(6)
+#define WMM_ACI_AC_VO                       BITS(5, 6)
+
+#define WMM_ACI(_AC)                        (_AC << WMM_ACIAIFSN_ACI_OFFSET)
+
+/* -- definitions for ECWmin/ECWmax field */
+#define WMM_ECW_WMIN_MASK                   BITS(0, 3)
+#define WMM_ECW_WMAX_MASK                   BITS(4, 7)
+#define WMM_ECW_WMAX_OFFSET                 4
+
+#define TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME              0	/* Unit: 64 us */
+
+#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS      (1000)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+enum {
+	QM_DBG_CNT_00 = 0,
+	QM_DBG_CNT_01,
+	QM_DBG_CNT_02,
+	QM_DBG_CNT_03,
+	QM_DBG_CNT_04,
+	QM_DBG_CNT_05,
+	QM_DBG_CNT_06,
+	QM_DBG_CNT_07,
+	QM_DBG_CNT_08,
+	QM_DBG_CNT_09,
+	QM_DBG_CNT_10,
+	QM_DBG_CNT_11,
+	QM_DBG_CNT_12,
+	QM_DBG_CNT_13,
+	QM_DBG_CNT_14,
+	QM_DBG_CNT_15,
+	QM_DBG_CNT_16,
+	QM_DBG_CNT_17,
+	QM_DBG_CNT_18,
+	QM_DBG_CNT_19,
+	QM_DBG_CNT_20,
+	QM_DBG_CNT_21,
+	QM_DBG_CNT_22,
+	QM_DBG_CNT_23,
+	QM_DBG_CNT_24,
+	QM_DBG_CNT_25,
+	QM_DBG_CNT_26,
+	QM_DBG_CNT_27,
+	QM_DBG_CNT_28,
+	QM_DBG_CNT_29,
+	QM_DBG_CNT_30,
+	QM_DBG_CNT_31,
+	QM_DBG_CNT_NUM
+};
+
+/* Used for MAC TX */
+typedef enum _ENUM_MAC_TX_QUEUE_INDEX_T {
+	MAC_TX_QUEUE_AC0_INDEX = 0,
+	MAC_TX_QUEUE_AC1_INDEX,
+	MAC_TX_QUEUE_AC2_INDEX,
+	MAC_TX_QUEUE_AC3_INDEX,
+	MAC_TX_QUEUE_AC4_INDEX,
+	MAC_TX_QUEUE_AC5_INDEX,
+	MAC_TX_QUEUE_AC6_INDEX,
+	MAC_TX_QUEUE_BCN_INDEX,
+	MAC_TX_QUEUE_BMC_INDEX,
+	MAC_TX_QUEUE_NUM
+} ENUM_MAC_TX_QUEUE_INDEX_T;
+
+typedef struct _RX_BA_ENTRY_T {
+	BOOLEAN fgIsValid;
+	QUE_T rReOrderQue;
+	UINT_16 u2WinStart;
+	UINT_16 u2WinEnd;
+	UINT_16 u2WinSize;
+
+	/* For identifying the RX BA agreement */
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucTid;
+
+	BOOLEAN fgIsWaitingForPktWithSsn;
+
+	/* UINT_8                  ucTxBufferSize; */
+	/* BOOL                    fgIsAcConstrain; */
+	/* BOOL                    fgIsBaEnabled; */
+} RX_BA_ENTRY_T, *P_RX_BA_ENTRY_T;
+
+/* The mailbox message (could be used for Host-To-Device or Device-To-Host Mailbox) */
+typedef struct _MAILBOX_MSG_T {
+	UINT_32 u4Msg[2];	/* [0]: D2HRM0R or H2DRM0R, [1]: D2HRM1R or H2DRM1R */
+} MAILBOX_MSG_T, *P_MAILBOX_MSG_T;
+
+/* Used for adaptively adjusting TC resources */
+typedef struct _TC_RESOURCE_CTRL_T {
+	/* TC0, TC1, TC2, TC3, TC5 */
+	UINT_32 au4AverageQueLen[TC_NUM - 1];
+} TC_RESOURCE_CTRL_T, *P_TC_RESOURCE_CTRL_T;
+
+typedef struct _QUE_MGT_T {	/* Queue Management Control Info */
+
+	/* Per-Type Queues: [0] BMCAST or UNKNOWN-STA packets */
+	QUE_T arTxQueue[NUM_OF_PER_TYPE_TX_QUEUES];
+
+#if 0
+	/* For TX Scheduling */
+	UINT_8 arRemainingTxOppt[NUM_OF_PER_STA_TX_QUEUES];
+	UINT_8 arCurrentTxStaIndex[NUM_OF_PER_STA_TX_QUEUES];
+
+#endif
+
+	/* Reordering Queue Parameters */
+	RX_BA_ENTRY_T arRxBaTable[CFG_NUM_OF_RX_BA_AGREEMENTS];
+
+	/* Current number of activated RX BA agreements <= CFG_NUM_OF_RX_BA_AGREEMENTS */
+	UINT_8 ucRxBaCount;
+
+#if QM_TEST_MODE
+	UINT_32 u4PktCount;
+	P_ADAPTER_T prAdapter;
+
+#if QM_TEST_FAIR_FORWARDING
+	UINT_32 u4CurrentStaRecIndexToEnqueue;
+#endif
+
+#endif
+
+#if QM_FORWARDING_FAIRNESS
+	/* The current TX count for a STA with respect to a TC index */
+	UINT_32 au4ForwardCount[NUM_OF_PER_STA_TX_QUEUES];
+
+	/* The current serving STA with respect to a TC index */
+	UINT_32 au4HeadStaRecIndex[NUM_OF_PER_STA_TX_QUEUES];
+#endif
+
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+	UINT_32 au4AverageQueLen[TC_NUM];
+	UINT_32 au4CurrentTcResource[TC_NUM];
+	UINT_32 au4MinReservedTcResource[TC_NUM];	/* The minimum amount of resource no matter busy or idle */
+	UINT_32 au4GuaranteedTcResource[TC_NUM];	/* The minimum amount of resource when extremely busy */
+
+	UINT_32 u4TimeToAdjustTcResource;
+	UINT_32 u4TimeToUpdateQueLen;
+	UINT_32 u4TxNumOfVi, u4TxNumOfVo;	/* number of VI/VO packets */
+
+	/* Set to TRUE if the last TC adjustment has not been completely applied (i.e., waiting more TX-Done events
+	   to align the TC quotas to the TC resource assignment) */
+	BOOLEAN fgTcResourcePostAnnealing;
+
+#endif
+
+#if QM_DEBUG_COUNTER
+	UINT_32 au4QmDebugCounters[QM_DBG_CNT_NUM];
+#endif
+#if QM_TC_RESOURCE_EMPTY_COUNTER
+	UINT_32 au4QmTcResourceEmptyCounter[NET_TYPE_NUM][TC_NUM];
+	UINT_32 au4QmTcResourceBackCounter[TC_NUM];
+	UINT_32 au4DequeueNoTcResourceCounter[TC_NUM];
+
+	UINT_32 au4ResourceUsedCounter[TC_NUM];
+
+	UINT_32 au4ResourceWantedCounter[TC_NUM];
+
+	UINT_32 u4EnqeueuCounter;
+	UINT_32 u4DequeueCounter;
+#endif
+} QUE_MGT_T, *P_QUE_MGT_T;
+
+typedef struct _EVENT_RX_ADDBA_T {
+	/* Event header */
+	UINT_16 u2Length;
+	UINT_16 u2Reserved1;	/* Must be filled with 0x0001 (EVENT Packet) */
+	UINT_8 ucEID;
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved2[2];
+
+	/* Fields not present in the received ADDBA_REQ */
+	UINT_8 ucStaRecIdx;
+
+	/* Fields that are present in the received ADDBA_REQ */
+	UINT_8 ucDialogToken;	/* Dialog Token chosen by the sender */
+	UINT_16 u2BAParameterSet;	/* BA policy, TID, buffer size */
+	UINT_16 u2BATimeoutValue;
+	UINT_16 u2BAStartSeqCtrl;	/* SSN */
+
+} EVENT_RX_ADDBA_T, *P_EVENT_RX_ADDBA_T;
+
+typedef struct _EVENT_RX_DELBA_T {
+	/* Event header */
+	UINT_16 u2Length;
+	UINT_16 u2Reserved1;	/* Must be filled with 0x0001 (EVENT Packet) */
+	UINT_8 ucEID;
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved2[2];
+
+	/* Fields not present in the received ADDBA_REQ */
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucTid;
+} EVENT_RX_DELBA_T, *P_EVENT_RX_DELBA_T;
+
+typedef struct _EVENT_BSS_ABSENCE_PRESENCE_T {
+	/* Event header */
+	UINT_16 u2Length;
+	UINT_16 u2Reserved1;	/* Must be filled with 0x0001 (EVENT Packet) */
+	UINT_8 ucEID;
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved2[2];
+
+	/* Event Body */
+	UINT_8 ucNetTypeIdx;
+	BOOLEAN fgIsAbsent;
+	UINT_8 ucBssFreeQuota;
+	UINT_8 aucReserved[1];
+} EVENT_BSS_ABSENCE_PRESENCE_T, *P_EVENT_BSS_ABSENCE_PRESENCE_T;
+
+typedef struct _EVENT_STA_CHANGE_PS_MODE_T {
+	/* Event header */
+	UINT_16 u2Length;
+	UINT_16 u2Reserved1;	/* Must be filled with 0x0001 (EVENT Packet) */
+	UINT_8 ucEID;
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved2[2];
+
+	/* Event Body */
+	UINT_8 ucStaRecIdx;
+	BOOLEAN fgIsInPs;
+	UINT_8 ucUpdateMode;
+	UINT_8 ucFreeQuota;
+} EVENT_STA_CHANGE_PS_MODE_T, *P_EVENT_STA_CHANGE_PS_MODE_T;
+
+/* The free quota is used by PS only now */
+/* The event may be used by per STA flow conttrol in general */
+typedef struct _EVENT_STA_UPDATE_FREE_QUOTA_T {
+	/* Event header */
+	UINT_16 u2Length;
+	UINT_16 u2Reserved1;	/* Must be filled with 0x0001 (EVENT Packet) */
+	UINT_8 ucEID;
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved2[2];
+
+	/* Event Body */
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucUpdateMode;
+	UINT_8 ucFreeQuota;
+	UINT_8 aucReserved[1];
+} EVENT_STA_UPDATE_FREE_QUOTA_T, *P_EVENT_STA_UPDATE_FREE_QUOTA_T;
+
+/* WMM-2.2.1 WMM Information Element */
+typedef struct _IE_WMM_INFO_T {
+	UINT_8 ucId;		/* Element ID */
+	UINT_8 ucLength;	/* Length */
+	UINT_8 aucOui[3];	/* OUI */
+	UINT_8 ucOuiType;	/* OUI Type */
+	UINT_8 ucOuiSubtype;	/* OUI Subtype */
+	UINT_8 ucVersion;	/* Version */
+	UINT_8 ucQosInfo;	/* QoS Info field */
+	UINT_8 ucDummy[3];	/* Dummy for pack */
+} IE_WMM_INFO_T, *P_IE_WMM_INFO_T;
+
+/* WMM-2.2.2 WMM Parameter Element */
+typedef struct _IE_WMM_PARAM_T {
+	UINT_8 ucId;		/* Element ID */
+	UINT_8 ucLength;	/* Length */
+
+	/* IE Body */
+	UINT_8 aucOui[3];	/* OUI */
+	UINT_8 ucOuiType;	/* OUI Type */
+	UINT_8 ucOuiSubtype;	/* OUI Subtype */
+	UINT_8 ucVersion;	/* Version */
+
+	/* WMM IE Body */
+	UINT_8 ucQosInfo;	/* QoS Info field */
+	UINT_8 ucReserved;
+
+	/* AC Parameters */
+	UINT_8 ucAciAifsn_BE;
+	UINT_8 ucEcw_BE;
+	UINT_8 aucTxopLimit_BE[2];
+
+	UINT_8 ucAciAifsn_BG;
+	UINT_8 ucEcw_BG;
+	UINT_8 aucTxopLimit_BG[2];
+
+	UINT_8 ucAciAifsn_VI;
+	UINT_8 ucEcw_VI;
+	UINT_8 aucTxopLimit_VI[2];
+
+	UINT_8 ucAciAifsn_VO;
+	UINT_8 ucEcw_VO;
+	UINT_8 aucTxopLimit_VO[2];
+
+} IE_WMM_PARAM_T, *P_IE_WMM_PARAM_T;
+
+typedef struct _IE_WMM_TSPEC_T {
+	UINT_8 ucId;		/* Element ID */
+	UINT_8 ucLength;	/* Length */
+	UINT_8 aucOui[3];	/* OUI */
+	UINT_8 ucOuiType;	/* OUI Type */
+	UINT_8 ucOuiSubtype;	/* OUI Subtype */
+	UINT_8 ucVersion;	/* Version */
+	/* WMM TSPEC body */
+	UINT_8 aucTsInfo[3];	/* TS Info */
+	UINT_8 aucTspecBodyPart[1];	/* Note: Utilize PARAM_QOS_TSPEC to fill (memory copy) */
+} IE_WMM_TSPEC_T, *P_IE_WMM_TSPEC_T;
+
+typedef struct _IE_WMM_HDR_T {
+	UINT_8 ucId;		/* Element ID */
+	UINT_8 ucLength;	/* Length */
+	UINT_8 aucOui[3];	/* OUI */
+	UINT_8 ucOuiType;	/* OUI Type */
+	UINT_8 ucOuiSubtype;	/* OUI Subtype */
+	UINT_8 ucVersion;	/* Version */
+	UINT_8 aucBody[1];	/* IE body */
+} IE_WMM_HDR_T, *P_IE_WMM_HDR_T;
+
+typedef struct _AC_QUE_PARMS_T {
+	UINT_16 u2CWmin;	/*!< CWmin */
+	UINT_16 u2CWmax;	/*!< CWmax */
+	UINT_16 u2TxopLimit;	/*!< TXOP limit */
+	UINT_16 u2Aifsn;	/*!< AIFSN */
+	UINT_8 ucGuradTime;	/*!< GuardTime for STOP/FLUSH. */
+	BOOLEAN fgIsACMSet;
+} AC_QUE_PARMS_T, *P_AC_QUE_PARMS_T;
+
+/* WMM ACI (AC index) */
+typedef enum _ENUM_WMM_ACI_T {
+	WMM_AC_BE_INDEX = 0,
+	WMM_AC_BK_INDEX,
+	WMM_AC_VI_INDEX,
+	WMM_AC_VO_INDEX,
+	WMM_AC_INDEX_NUM
+} ENUM_WMM_ACI_T, *P_ENUM_WMM_ACI_T;
+
+/* Used for CMD Queue Operation */
+typedef enum _ENUM_FRAME_ACTION_T {
+	FRAME_ACTION_DROP_PKT = 0,
+	FRAME_ACTION_QUEUE_PKT,
+	FRAME_ACTION_TX_PKT,
+	FRAME_ACTION_NUM
+} ENUM_FRAME_ACTION_T;
+
+typedef enum _ENUM_FRAME_TYPE_IN_CMD_Q_T {
+	FRAME_TYPE_802_1X = 0,
+	FRAME_TYPE_MMPDU,
+	FRAME_TYPE_NUM
+} ENUM_FRAME_TYPE_IN_CMD_Q_T;
+
+typedef enum _ENUM_FREE_QUOTA_MODET_T {
+	FREE_QUOTA_UPDATE_MODE_INIT = 0,
+	FREE_QUOTA_UPDATE_MODE_OVERWRITE,
+	FREE_QUOTA_UPDATE_MODE_INCREASE,
+	FREE_QUOTA_UPDATE_MODE_DECREASE
+} ENUM_FREE_QUOTA_MODET_T, *P_ENUM_FREE_QUOTA_MODET_T;
+
+typedef struct _CMD_UPDATE_WMM_PARMS_T {
+	AC_QUE_PARMS_T arACQueParms[AC_NUM];
+	UINT_8 ucNetTypeIndex;
+	UINT_8 fgIsQBSS;
+	UINT_8 aucReserved[2];
+} CMD_UPDATE_WMM_PARMS_T, *P_CMD_UPDATE_WMM_PARMS_T;
+
+typedef struct _CMD_TX_AMPDU_T {
+	BOOLEAN fgEnable;
+	UINT_8 aucReserved[3];
+} CMD_TX_AMPDU_T, *P_CMD_TX_AMPDU_T;
+
+typedef struct _CMD_ADDBA_REJECT {
+	BOOLEAN fgEnable;
+	UINT_8 aucReserved[3];
+} CMD_ADDBA_REJECT_T, *P_CMD_ADDBA_REJECT_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#define QM_TX_SET_NEXT_MSDU_INFO(_prMsduInfoPreceding, _prMsduInfoNext) \
+	((((_prMsduInfoPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prMsduInfoNext))
+
+#define QM_TX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \
+	((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext))
+
+#define QM_TX_GET_NEXT_MSDU_INFO(_prMsduInfo) \
+	((P_MSDU_INFO_T)(((_prMsduInfo)->rQueEntry).prNext))
+
+#define QM_RX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \
+	((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext))
+
+#define QM_RX_GET_NEXT_SW_RFB(_prSwRfb) \
+	((P_SW_RFB_T)(((_prSwRfb)->rQueEntry).prNext))
+
+#if 0
+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \
+	((((_ucIndex) != STA_REC_INDEX_BMCAST) && ((_ucIndex) != STA_REC_INDEX_NOT_FOUND)) ?\
+	&(_prAdapter->arStaRec[_ucIndex]) : NULL)
+#endif
+
+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \
+	cnmGetStaRecByIndex(_prAdapter, _ucIndex)
+
+#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(\
+					_prMsduInfo,\
+					_ucTC,\
+					_ucPacketType,\
+					_ucFormatID,\
+					_fgIs802_1x,\
+					_fgIs802_11,\
+					_u2PalLLH,\
+					_u2AclSN,\
+					_ucPsForwardingType,\
+					_ucPsSessionID\
+					) \
+{\
+	ASSERT(_prMsduInfo);\
+	(_prMsduInfo)->ucTC                 = (_ucTC);\
+	(_prMsduInfo)->ucPacketType         = (_ucPacketType);\
+	(_prMsduInfo)->ucFormatID           = (_ucFormatID);\
+	(_prMsduInfo)->fgIs802_1x           = (_fgIs802_1x);\
+	(_prMsduInfo)->fgIs802_11           = (_fgIs802_11);\
+	(_prMsduInfo)->u2PalLLH             = (_u2PalLLH);\
+	(_prMsduInfo)->u2AclSN              = (_u2AclSN);\
+	(_prMsduInfo)->ucPsForwardingType   = (_ucPsForwardingType);\
+	(_prMsduInfo)->ucPsSessionID        = (_ucPsSessionID);\
+	(_prMsduInfo)->fgIsBurstEnd         = (FALSE);\
+}
+
+#define QM_INIT_STA_REC(\
+	_prStaRec,\
+	_fgIsValid,\
+	_fgIsQoS,\
+	_pucMacAddr\
+	)\
+{\
+	ASSERT(_prStaRec);\
+	(_prStaRec)->fgIsValid      = (_fgIsValid);\
+	(_prStaRec)->fgIsQoS        = (_fgIsQoS);\
+	(_prStaRec)->fgIsInPS         = FALSE; \
+	(_prStaRec)->ucPsSessionID  = 0xFF;\
+	COPY_MAC_ADDR((_prStaRec)->aucMacAddr, (_pucMacAddr));\
+}
+
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+#define QM_GET_TX_QUEUE_LEN(_prAdapter, _u4QueIdx) \
+	((_prAdapter->rQM.au4AverageQueLen[(_u4QueIdx)] >> QM_QUE_LEN_MOVING_AVE_FACTOR))
+#endif
+
+#define WMM_IE_OUI_TYPE(fp)      (((P_IE_WMM_HDR_T)(fp))->ucOuiType)
+#define WMM_IE_OUI_SUBTYPE(fp)   (((P_IE_WMM_HDR_T)(fp))->ucOuiSubtype)
+#define WMM_IE_OUI(fp)           (((P_IE_WMM_HDR_T)(fp))->aucOui)
+
+#if QM_DEBUG_COUNTER
+#define QM_DBG_CNT_INC(_prQM, _index) { (_prQM)->au4QmDebugCounters[(_index)]++; }
+#else
+#define QM_DBG_CNT_INC(_prQM, _index) {}
+#endif
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Queue Management and STA_REC Initialization                                */
+/*----------------------------------------------------------------------------*/
+
+VOID qmInit(IN P_ADAPTER_T prAdapter);
+
+#if QM_TEST_MODE
+VOID qmTestCases(IN P_ADAPTER_T prAdapter);
+#endif
+
+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx);
+
+/*----------------------------------------------------------------------------*/
+/* TX-Related Queue Management                                                */
+/*----------------------------------------------------------------------------*/
+
+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter);
+
+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx);
+
+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead);
+
+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus);
+
+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus);
+
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter);
+
+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter);
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* RX-Related Queue Management                                                */
+/*----------------------------------------------------------------------------*/
+
+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter);
+
+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter);
+
+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead);
+
+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue);
+
+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue);
+
+VOID
+qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue);
+
+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue);
+
+BOOLEAN
+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout);
+
+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue);
+
+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg);
+
+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater);
+
+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+
+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+
+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid);
+
+BOOLEAN
+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter,
+	       IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize);
+
+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost);
+
+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength);
+
+VOID
+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter,
+		       IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride);
+
+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams);
+
+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec);
+
+/* Utility function: for deciding STA-REC index */
+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType);
+
+UINT_32
+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD,
+			    UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf);
+
+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter,
+			    P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode);
+
+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+ENUM_FRAME_ACTION_T
+qmGetFrameAction(IN P_ADAPTER_T prAdapter,
+		 IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType,
+		 IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType);
+
+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+
+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+
+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength);
+
+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+
+VOID
+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter,
+		  IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone);
+
+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter);
+
+#if ARP_MONITER_ENABLE
+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+VOID qmResetArpDetect(VOID);
+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb);
+#endif
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _QUE_MGT_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h
new file mode 100644
index 0000000000000..2804b0387f5f0
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h
@@ -0,0 +1,1010 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/wlan_def.h#1
+*/
+
+/*! \file   "wlan_def.h"
+    \brief  This file includes the basic definition of WLAN
+
+*/
+
+/*
+** Log: wlan_def.h
+**
+** 09 02 2013 cp.wu
+** add path to handle reassociation request
+ *
+ * 12 05 2011 cp.wu
+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
+ * add CONNECT_BY_BSSID policy
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 06 22 2011 wh.su
+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h and let the sw
+ * structure not align at byte
+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte,
+ * Notice needed update P2P.ko.
+ *
+ * 04 08 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix for sigma
+ *
+ * 03 17 2011 yuche.tsai
+ * NULL
+ * Resize the Secondary Device Type array when WiFi Direct is enabled.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Add new station type MACRO.
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 10 11 2010 kevin.huang
+ * [WCXRP00000068] [MT6620 Wi-Fi][Driver][FW] Fix STA RECORD sync issue and remove unused code
+ * Update ENUM_STA_ROLE_INDEX_T by using a fixed base value
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by
+ * ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 14 2010 chinghwa.yu
+ * NULL
+ * Update OP_MODE_BOW and include bow_fsm.h.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * Change P2P Descriptor List to a pointer and allocate it dynamically to avoid structure corrupt by BssDescriptor free.
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse()
+ *
+ * 08 12 2010 yuche.tsai
+ * NULL
+ * Add a pointer in BSS Descriptor for P2P Descriptor.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add an Interface in BSS Descriptor.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Modify data structure for P2P Scan result.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Add an operation mode for P2P device.
+ *
+ * 07 23 2010 cp.wu
+ *
+ * P2P/RSN/WAPI IEs need to be declared with compact structure.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add for P2P Scan Result Parsing & Saving.
+ *
+ * 07 20 2010 wh.su
+ *
+ * adding the wapi code.
+ *
+ * 07 09 2010 cp.wu
+ *
+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly
+ * dropped by returning BUSY
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 28 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * 1st draft code for RLM module
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * modify Beacon/ProbeResp to complete parsing,
+ * because host software has looser memory usage restriction
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Add P2P present boolean flag in BSS & Pre-BSS descriptor.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration the security related function from firmware.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add definitions for module migration.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * move bss related data types to wlan_def.h to avoid recursive dependency.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wlan_def.h.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge cnm_scan.h and hem_mbox.h
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:40 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _WLAN_DEF_H
+#define _WLAN_DEF_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* disconnect reason */
+#define DISCONNECT_REASON_CODE_RESERVED         0
+#define DISCONNECT_REASON_CODE_RADIO_LOST       1
+#define DISCONNECT_REASON_CODE_DEAUTHENTICATED  2
+#define DISCONNECT_REASON_CODE_DISASSOCIATED    3
+#define DISCONNECT_REASON_CODE_NEW_CONNECTION   4
+#define DISCONNECT_REASON_CODE_REASSOCIATION    5
+#define DISCONNECT_REASON_CODE_ROAMING          6
+
+/* The rate definitions */
+#define TX_MODE_CCK             0x00
+#define TX_MODE_OFDM            0x40
+#define TX_MODE_HT_MM           0x80
+#define TX_MODE_HT_GF           0xC0
+
+#define RATE_CCK_SHORT_PREAMBLE 0x10
+#define RATE_OFDM               0x20
+
+#define PHY_RATE_1M             0x0
+#define PHY_RATE_2M             0x1
+#define PHY_RATE_5_5M           0x2
+#define PHY_RATE_11M            0x3
+#define PHY_RATE_6M             0xB
+#define PHY_RATE_9M             0xF
+#define PHY_RATE_12M            0xA
+#define PHY_RATE_18M            0xE
+#define PHY_RATE_24M            0x9
+#define PHY_RATE_36M            0xD
+#define PHY_RATE_48M            0x8
+#define PHY_RATE_54M            0xC
+#define PHY_RATE_MCS0           0x0
+#define PHY_RATE_MCS1           0x1
+#define PHY_RATE_MCS2           0x2
+#define PHY_RATE_MCS3           0x3
+#define PHY_RATE_MCS4           0x4
+#define PHY_RATE_MCS5           0x5
+#define PHY_RATE_MCS6           0x6
+#define PHY_RATE_MCS7           0x7
+#define PHY_RATE_MCS32          0x20
+
+#define RATE_CCK_1M_LONG        (TX_MODE_CCK | PHY_RATE_1M)
+#define RATE_CCK_2M_LONG        (TX_MODE_CCK | PHY_RATE_2M)
+#define RATE_CCK_5_5M_LONG      (TX_MODE_CCK | PHY_RATE_5_5M)
+#define RATE_CCK_11M_LONG       (TX_MODE_CCK | PHY_RATE_11M)
+#define RATE_CCK_2M_SHORT       (TX_MODE_CCK | PHY_RATE_2M | RATE_CCK_SHORT_PREAMBLE)
+#define RATE_CCK_5_5M_SHORT     (TX_MODE_CCK | PHY_RATE_5_5M | RATE_CCK_SHORT_PREAMBLE)
+#define RATE_CCK_11M_SHORT      (TX_MODE_CCK | PHY_RATE_11M | RATE_CCK_SHORT_PREAMBLE)
+#define RATE_OFDM_6M            (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_6M)
+#define RATE_OFDM_9M            (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_9M)
+#define RATE_OFDM_12M           (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_12M)
+#define RATE_OFDM_18M           (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_18M)
+#define RATE_OFDM_24M           (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_24M)
+#define RATE_OFDM_36M           (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_36M)
+#define RATE_OFDM_48M           (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_48M)
+#define RATE_OFDM_54M           (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_54M)
+
+#define RATE_MM_MCS_0           (TX_MODE_HT_MM | PHY_RATE_MCS0)
+#define RATE_MM_MCS_1           (TX_MODE_HT_MM | PHY_RATE_MCS1)
+#define RATE_MM_MCS_2           (TX_MODE_HT_MM | PHY_RATE_MCS2)
+#define RATE_MM_MCS_3           (TX_MODE_HT_MM | PHY_RATE_MCS3)
+#define RATE_MM_MCS_4           (TX_MODE_HT_MM | PHY_RATE_MCS4)
+#define RATE_MM_MCS_5           (TX_MODE_HT_MM | PHY_RATE_MCS5)
+#define RATE_MM_MCS_6           (TX_MODE_HT_MM | PHY_RATE_MCS6)
+#define RATE_MM_MCS_7           (TX_MODE_HT_MM | PHY_RATE_MCS7)
+#define RATE_MM_MCS_32          (TX_MODE_HT_MM | PHY_RATE_MCS32)
+
+#define RATE_GF_MCS_0           (TX_MODE_HT_GF | PHY_RATE_MCS0)
+#define RATE_GF_MCS_1           (TX_MODE_HT_GF | PHY_RATE_MCS1)
+#define RATE_GF_MCS_2           (TX_MODE_HT_GF | PHY_RATE_MCS2)
+#define RATE_GF_MCS_3           (TX_MODE_HT_GF | PHY_RATE_MCS3)
+#define RATE_GF_MCS_4           (TX_MODE_HT_GF | PHY_RATE_MCS4)
+#define RATE_GF_MCS_5           (TX_MODE_HT_GF | PHY_RATE_MCS5)
+#define RATE_GF_MCS_6           (TX_MODE_HT_GF | PHY_RATE_MCS6)
+#define RATE_GF_MCS_7           (TX_MODE_HT_GF | PHY_RATE_MCS7)
+#define RATE_GF_MCS_32          (TX_MODE_HT_GF | PHY_RATE_MCS32)
+
+#define RATE_TX_MODE_MASK                   BITS(6, 7)
+#define RATE_TX_MODE_OFFSET                 6
+#define RATE_CODE_GET_TX_MODE(_ucRateCode)  ((_ucRateCode & RATE_TX_MODE_MASK) >> RATE_TX_MODE_OFFSET)
+#define RATE_PHY_RATE_MASK                  BITS(0, 5)
+#define RATE_PHY_RATE_OFFSET                0
+#define RATE_CODE_GET_PHY_RATE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_MASK) >> RATE_PHY_RATE_OFFSET)
+#define RATE_PHY_RATE_SHORT_PREAMBLE        BIT(4)
+#define RATE_CODE_IS_SHORT_PREAMBLE(_ucRateCode)  ((_ucRateCode & RATE_PHY_RATE_SHORT_PREAMBLE)?TRUE:FALSE)
+
+#define CHNL_LIST_SZ_2G         14
+#define CHNL_LIST_SZ_5G         14
+
+/*! CNM(STA_RECORD_T) related definition */
+#define CFG_STA_REC_NUM         20
+
+/* PHY TYPE bit definitions */
+#define PHY_TYPE_BIT_HR_DSSS    BIT(PHY_TYPE_HR_DSSS_INDEX)	/* HR/DSSS PHY (clause 18) */
+#define PHY_TYPE_BIT_ERP        BIT(PHY_TYPE_ERP_INDEX)	/* ERP PHY (clause 19) */
+#define PHY_TYPE_BIT_OFDM       BIT(PHY_TYPE_OFDM_INDEX)	/* OFDM 5 GHz PHY (clause 17) */
+#define PHY_TYPE_BIT_HT         BIT(PHY_TYPE_HT_INDEX)	/* HT PHY (clause 20) */
+
+/* PHY TYPE set definitions */
+#define PHY_TYPE_SET_802_11ABGN (PHY_TYPE_BIT_OFDM | \
+				 PHY_TYPE_BIT_HR_DSSS | \
+				 PHY_TYPE_BIT_ERP | \
+				 PHY_TYPE_BIT_HT)
+
+#define PHY_TYPE_SET_802_11BGN  (PHY_TYPE_BIT_HR_DSSS | \
+				 PHY_TYPE_BIT_ERP | \
+				 PHY_TYPE_BIT_HT)
+
+#define PHY_TYPE_SET_802_11GN   (PHY_TYPE_BIT_ERP | \
+				 PHY_TYPE_BIT_HT)
+
+#define PHY_TYPE_SET_802_11AN   (PHY_TYPE_BIT_OFDM | \
+				 PHY_TYPE_BIT_HT)
+
+#define PHY_TYPE_SET_802_11ABG  (PHY_TYPE_BIT_OFDM | \
+				 PHY_TYPE_BIT_HR_DSSS | \
+				 PHY_TYPE_BIT_ERP)
+
+#define PHY_TYPE_SET_802_11BG   (PHY_TYPE_BIT_HR_DSSS | \
+				 PHY_TYPE_BIT_ERP)
+
+#define PHY_TYPE_SET_802_11A    (PHY_TYPE_BIT_OFDM)
+
+#define PHY_TYPE_SET_802_11G    (PHY_TYPE_BIT_ERP)
+
+#define PHY_TYPE_SET_802_11B    (PHY_TYPE_BIT_HR_DSSS)
+
+#define PHY_TYPE_SET_802_11N    (PHY_TYPE_BIT_HT)
+
+/* Rate set bit definitions */
+#define RATE_SET_BIT_1M         BIT(RATE_1M_INDEX)	/* Bit 0: 1M */
+#define RATE_SET_BIT_2M         BIT(RATE_2M_INDEX)	/* Bit 1: 2M */
+#define RATE_SET_BIT_5_5M       BIT(RATE_5_5M_INDEX)	/* Bit 2: 5.5M */
+#define RATE_SET_BIT_11M        BIT(RATE_11M_INDEX)	/* Bit 3: 11M */
+#define RATE_SET_BIT_22M        BIT(RATE_22M_INDEX)	/* Bit 4: 22M */
+#define RATE_SET_BIT_33M        BIT(RATE_33M_INDEX)	/* Bit 5: 33M */
+#define RATE_SET_BIT_6M         BIT(RATE_6M_INDEX)	/* Bit 6: 6M */
+#define RATE_SET_BIT_9M         BIT(RATE_9M_INDEX)	/* Bit 7: 9M */
+#define RATE_SET_BIT_12M        BIT(RATE_12M_INDEX)	/* Bit 8: 12M */
+#define RATE_SET_BIT_18M        BIT(RATE_18M_INDEX)	/* Bit 9: 18M */
+#define RATE_SET_BIT_24M        BIT(RATE_24M_INDEX)	/* Bit 10: 24M */
+#define RATE_SET_BIT_36M        BIT(RATE_36M_INDEX)	/* Bit 11: 36M */
+#define RATE_SET_BIT_48M        BIT(RATE_48M_INDEX)	/* Bit 12: 48M */
+#define RATE_SET_BIT_54M        BIT(RATE_54M_INDEX)	/* Bit 13: 54M */
+#define RATE_SET_BIT_HT_PHY     BIT(RATE_HT_PHY_INDEX)	/* Bit 14: BSS Selector */
+
+/* Rate set definitions */
+#define RATE_SET_HR_DSSS            (RATE_SET_BIT_1M | \
+				     RATE_SET_BIT_2M | \
+				     RATE_SET_BIT_5_5M | \
+				     RATE_SET_BIT_11M)
+
+#define RATE_SET_ERP                (RATE_SET_BIT_1M | \
+				     RATE_SET_BIT_2M | \
+				     RATE_SET_BIT_5_5M | \
+				     RATE_SET_BIT_11M | \
+				     RATE_SET_BIT_6M | \
+				     RATE_SET_BIT_9M | \
+				     RATE_SET_BIT_12M | \
+				     RATE_SET_BIT_18M | \
+				     RATE_SET_BIT_24M | \
+				     RATE_SET_BIT_36M | \
+				     RATE_SET_BIT_48M | \
+				     RATE_SET_BIT_54M)
+
+#define RATE_SET_ERP_P2P            (RATE_SET_BIT_6M | \
+				     RATE_SET_BIT_9M | \
+				     RATE_SET_BIT_12M | \
+				     RATE_SET_BIT_18M | \
+				     RATE_SET_BIT_24M | \
+				     RATE_SET_BIT_36M | \
+				     RATE_SET_BIT_48M | \
+				     RATE_SET_BIT_54M)
+
+#define RATE_SET_OFDM               (RATE_SET_BIT_6M | \
+				     RATE_SET_BIT_9M | \
+				     RATE_SET_BIT_12M | \
+				     RATE_SET_BIT_18M | \
+				     RATE_SET_BIT_24M | \
+				     RATE_SET_BIT_36M | \
+				     RATE_SET_BIT_48M | \
+				     RATE_SET_BIT_54M)
+
+#define RATE_SET_HT                 (RATE_SET_ERP)
+/* #define RATE_SET_HT                 (RATE_SET_ERP | RATE_SET_BIT_HT_PHY)  *//* NOTE(Kevin): TBD */
+
+#define RATE_SET_ALL_ABG             RATE_SET_ERP
+
+#define BASIC_RATE_SET_HR_DSSS      (RATE_SET_BIT_1M | \
+				     RATE_SET_BIT_2M)
+
+#define BASIC_RATE_SET_HR_DSSS_ERP  (RATE_SET_BIT_1M | \
+				     RATE_SET_BIT_2M | \
+				     RATE_SET_BIT_5_5M | \
+				     RATE_SET_BIT_11M)
+
+#define BASIC_RATE_SET_ERP          (RATE_SET_BIT_1M | \
+				     RATE_SET_BIT_2M | \
+				     RATE_SET_BIT_5_5M | \
+				     RATE_SET_BIT_11M | \
+				     RATE_SET_BIT_6M | \
+				     RATE_SET_BIT_12M | \
+				     RATE_SET_BIT_24M)
+
+#define BASIC_RATE_SET_OFDM         (RATE_SET_BIT_6M | \
+				     RATE_SET_BIT_12M | \
+				     RATE_SET_BIT_24M)
+
+#define BASIC_RATE_SET_ERP_P2P      (RATE_SET_BIT_6M | \
+				     RATE_SET_BIT_12M | \
+				     RATE_SET_BIT_24M)
+
+#define INITIAL_RATE_SET_RCPI_100    RATE_SET_ALL_ABG
+
+#define INITIAL_RATE_SET_RCPI_80    (RATE_SET_BIT_1M | \
+				     RATE_SET_BIT_2M | \
+				     RATE_SET_BIT_5_5M | \
+				     RATE_SET_BIT_11M | \
+				     RATE_SET_BIT_6M | \
+				     RATE_SET_BIT_9M | \
+				     RATE_SET_BIT_12M | \
+				     RATE_SET_BIT_24M)
+
+#define INITIAL_RATE_SET_RCPI_60    (RATE_SET_BIT_1M | \
+				     RATE_SET_BIT_2M | \
+				     RATE_SET_BIT_5_5M | \
+				     RATE_SET_BIT_11M | \
+				     RATE_SET_BIT_6M)
+
+#define INITIAL_RATE_SET(_rcpi)     (INITIAL_RATE_SET_ ## _rcpi)
+
+#define RCPI_100                    100	/* -60 dBm */
+#define RCPI_80                     80	/* -70 dBm */
+#define RCPI_60                     60	/* -80 dBm */
+
+/* The number of RCPI records used to calculate their average value */
+#define MAX_NUM_RCPI_RECORDS        10
+
+/* The number of RCPI records used to calculate their average value */
+#define NO_RCPI_RECORDS             -128
+#define MAX_RCPI_DBM                0
+#define MIN_RCPI_DBM                -100
+
+#define MAC_TX_RESERVED_FIELD       0	/* NOTE(Kevin): Should defined in tx.h */
+
+#define MAX_ASSOC_ID                (CFG_STA_REC_NUM)	/* Available AID: 1 ~ 20(STA_REC_NUM) */
+
+#define MAX_DEAUTH_INFO_COUNT       4	/* NOTE(Kevin): Used in auth.c */
+#define MIN_DEAUTH_INTERVAL_MSEC    500	/* The minimum interval if continuously send Deauth Frame */
+
+/* Authentication Type */
+#define AUTH_TYPE_OPEN_SYSTEM                       BIT(AUTH_ALGORITHM_NUM_OPEN_SYSTEM)
+#define AUTH_TYPE_SHARED_KEY                        BIT(AUTH_ALGORITHM_NUM_SHARED_KEY)
+#define AUTH_TYPE_FAST_BSS_TRANSITION               BIT(AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION)
+
+/* Authentication Retry Limit */
+#define TX_AUTH_ASSOCI_RETRY_LIMIT                  2
+#define TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING      1
+
+/* WMM-2.2.1 WMM Information Element */
+#define ELEM_MAX_LEN_WMM_INFO       7
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef UINT_16 PHY_TYPE, *P_PHY_TYPE;
+typedef UINT_8 RCPI, *P_RCPI;
+typedef UINT_8 ALC_VAL, *P_ALC_VAL;
+
+typedef enum _ENUM_HW_BSSID_T {
+	BSSID_0 = 0,
+	BSSID_1,
+	BSSID_NUM
+} ENUM_HW_BSSID_T;
+
+typedef enum _ENUM_HW_MAC_ADDR_T {
+	MAC_ADDR_0 = 0,
+	MAC_ADDR_1,
+	MAC_ADDR_NUM
+} ENUM_HW_MAC_ADDR_T;
+
+typedef enum _ENUM_HW_OP_MODE_T {
+	HW_OP_MODE_STA = 0,
+	HW_OP_MODE_AP,
+	HW_OP_MODE_ADHOC,
+	HW_OP_MODE_NUM
+} ENUM_HW_OP_MODE_T;
+
+typedef enum _ENUM_TSF_T {
+	ENUM_LOCAL_TSF_0,
+	ENUM_LOCAL_TSF_1,
+	ENUM_LOCAL_TSF_NUM
+} ENUM_LOCAL_TSF_T, *P_ENUM_LOCAL_TSF_T;
+
+typedef enum _HAL_TS_HW_UPDATE_MODE {
+	HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME,
+	HAL_TSF_HW_UPDATE_BY_TICK_ONLY,
+	HAL_TSF_HW_UPDATE_BY_RECEIVED_FRAME_ONLY,
+	HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME_AD_HOC
+} HAL_TSF_HW_UPDATE_MODE;
+
+typedef enum _ENUM_AC_T {
+	AC0 = 0,
+	AC1,
+	AC2,
+	AC3,
+	AC_NUM
+} ENUM_AC_T, *P_ENUM_AC_T;
+
+/* The Type of Network been activated */
+typedef enum _ENUM_NETWORK_TYPE_INDEX_T {
+	NETWORK_TYPE_AIS_INDEX = 0,
+	NETWORK_TYPE_P2P_INDEX,
+	NETWORK_TYPE_BOW_INDEX,
+	NETWORK_TYPE_INDEX_NUM
+} ENUM_NETWORK_TYPE_INDEX_T;
+
+/* The Type of STA Type. */
+typedef enum _ENUM_STA_TYPE_INDEX_T {
+	STA_TYPE_LEGACY_INDEX = 0,
+	STA_TYPE_P2P_INDEX,
+	STA_TYPE_BOW_INDEX,
+	STA_TYPE_INDEX_NUM
+} ENUM_STA_TYPE_INDEX_T;
+
+#define STA_ROLE_BASE_INDEX     4
+
+typedef enum _ENUM_STA_ROLE_INDEX_T {
+	STA_ROLE_ADHOC_INDEX = STA_ROLE_BASE_INDEX,	/* 4 */
+	STA_ROLE_CLIENT_INDEX,
+	STA_ROLE_AP_INDEX,
+	STA_ROLE_TDLS_INDEX,
+	STA_ROLE_DLS_INDEX	/* Note: need to extend P_CMD_UPDATE_STA_RECORD_T */
+} ENUM_STA_ROLE_INDEX_T;
+
+/* The Power State of a specific Network */
+typedef enum _ENUM_PWR_STATE_T {
+	PWR_STATE_IDLE = 0,
+	PWR_STATE_ACTIVE,
+	PWR_STATE_PS,
+	PWR_STATE_NUM
+} ENUM_PWR_STATE_T;
+
+typedef enum _ENUM_PHY_TYPE_INDEX_T {
+	/* PHY_TYPE_DSSS_INDEX, *//* DSSS PHY (clause 15) -- Not used anymore */
+	PHY_TYPE_HR_DSSS_INDEX = 0,	/* HR/DSSS PHY (clause 18) */
+	PHY_TYPE_ERP_INDEX,	/* ERP PHY (clause 19) */
+	PHY_TYPE_ERP_P2P_INDEX,	/* ERP PHY (clause 19) w/o HR/DSSS */
+	PHY_TYPE_OFDM_INDEX,	/* OFDM 5 GHz PHY (clause 17) */
+	PHY_TYPE_HT_INDEX,	/* HT PHY (clause 20) */
+	PHY_TYPE_INDEX_NUM	/* 5 */
+} ENUM_PHY_TYPE_INDEX_T, *P_ENUM_PHY_TYPE_INDEX_T;
+
+typedef enum _ENUM_ACPI_STATE_T {
+	ACPI_STATE_D0 = 0,
+	ACPI_STATE_D1,
+	ACPI_STATE_D2,
+	ACPI_STATE_D3
+} ENUM_ACPI_STATE_T;
+
+/* The operation mode of a specific Network */
+typedef enum _ENUM_OP_MODE_T {
+	OP_MODE_INFRASTRUCTURE = 0,	/* Infrastructure/GC */
+	OP_MODE_IBSS,		/* AdHoc */
+	OP_MODE_ACCESS_POINT,	/* For GO */
+	OP_MODE_P2P_DEVICE,	/* P2P Device */
+	OP_MODE_BOW,
+	OP_MODE_NUM
+} ENUM_OP_MODE_T, *P_ENUM_OP_MODE_T;
+
+typedef enum _ENUM_CHNL_EXT_T {
+	CHNL_EXT_SCN = 0,
+	CHNL_EXT_SCA = 1,
+	CHNL_EXT_RES = 2,
+	CHNL_EXT_SCB = 3
+} ENUM_CHNL_EXT_T, *P_ENUM_CHNL_EXT_T;
+
+/* This starting freq of the band is unit of kHz */
+typedef enum _ENUM_BAND_T {
+	BAND_NULL,
+	BAND_2G4,
+	BAND_5G,
+	BAND_NUM
+} ENUM_BAND_T, *P_ENUM_BAND_T;
+
+/* Provide supported channel list to other components in array format */
+typedef struct _RF_CHANNEL_INFO_T {
+	ENUM_BAND_T eBand;
+	UINT_8 ucChannelNum;
+} RF_CHANNEL_INFO_T, *P_RF_CHANNEL_INFO_T;
+
+typedef enum _ENUM_RATE_INDEX_T {
+	RATE_1M_INDEX = 0,	/* 1M */
+	RATE_2M_INDEX,		/* 2M */
+	RATE_5_5M_INDEX,	/* 5.5M */
+	RATE_11M_INDEX,		/* 11M */
+	RATE_22M_INDEX,		/* 22M */
+	RATE_33M_INDEX,		/* 33M */
+	RATE_6M_INDEX,		/* 6M */
+	RATE_9M_INDEX,		/* 9M */
+	RATE_12M_INDEX,		/* 12M */
+	RATE_18M_INDEX,		/* 18M */
+	RATE_24M_INDEX,		/* 24M */
+	RATE_36M_INDEX,		/* 36M */
+	RATE_48M_INDEX,		/* 48M */
+	RATE_54M_INDEX,		/* 54M */
+	RATE_HT_PHY_INDEX,	/* BSS Selector - HT PHY */
+	RATE_NUM		/* 15 */
+} ENUM_RATE_INDEX_T, *P_ENUM_RATE_INDEX_T;
+
+typedef enum _ENUM_HT_RATE_INDEX_T {
+	HT_RATE_MCS0_INDEX = 0,
+	HT_RATE_MCS1_INDEX,
+	HT_RATE_MCS2_INDEX,
+	HT_RATE_MCS3_INDEX,
+	HT_RATE_MCS4_INDEX,
+	HT_RATE_MCS5_INDEX,
+	HT_RATE_MCS6_INDEX,
+	HT_RATE_MCS7_INDEX,
+	HT_RATE_MCS32_INDEX,
+	HT_RATE_NUM		/* 9 */
+} ENUM_HT_RATE_INDEX_T, *P_ENUM_HT_RATE_INDEX_T;
+
+typedef enum _ENUM_PREMABLE_OPTION_T {
+	PREAMBLE_DEFAULT_LONG_NONE = 0,	/* LONG for PHY_TYPE_HR_DSSS, NONE for PHY_TYPE_OFDM */
+	PREAMBLE_OPTION_SHORT,	/* SHORT mandatory for PHY_TYPE_ERP, SHORT option for PHY_TYPE_HR_DSSS */
+	PREAMBLE_HT_MIXED_MODE,
+	PREAMBLE_HT_GREEN_FIELD,
+	PREAMBLE_OPTION_NUM
+} ENUM_PREMABLE_OPTION_T, *P_ENUM_PREMABLE_OPTION_T;
+
+typedef enum _ENUM_CHANNEL_WIDTH_T {
+	CW_20_40MHZ = 0,
+	CW_80MHZ = 1,
+	CW_160MHZ = 2,
+	CW_80P80MHZ = 3
+} ENUM_CHANNEL_WIDTH_T, *P_ENUM_CHANNEL_WIDTH_P;
+
+typedef enum _ENUM_MODULATION_SYSTEM_T {
+	MODULATION_SYSTEM_CCK = 0,
+	MODULATION_SYSTEM_OFDM,
+	MODULATION_SYSTEM_HT20,
+	MODULATION_SYSTEM_HT40,
+	MODULATION_SYSTEM_NUM
+} ENUM_MODULATION_SYSTEM_T, *P_ENUM_MODULATION_SYSTEM_T;
+
+typedef enum _ENUM_MODULATION_TYPE_T {
+	MODULATION_TYPE_CCK_BPSK = 0,
+	MODULATION_TYPE_QPSK,
+	MODULATION_TYPE_16QAM,
+	MODULATION_TYPE_64QAM,
+	MODULATION_TYPE_NUM
+} ENUM_MODULATION_TYPE_T, *P_ENUM_MODULATION_TYPE_T;
+
+typedef enum _ENUM_PS_FORWARDING_TYPE_T {
+	PS_FORWARDING_TYPE_NON_PS = 0,
+	PS_FORWARDING_TYPE_DELIVERY_ENABLED,
+	PS_FORWARDING_TYPE_NON_DELIVERY_ENABLED,
+	PS_FORWARDING_MORE_DATA_ENABLED,
+	PS_FORWARDING_TYPE_NUM
+} ENUM_PS_FORWARDING_TYPE_T, *P_ENUM_PS_FORWARDING_TYPE_T;
+
+typedef struct _DEAUTH_INFO_T {
+	UINT_8 aucRxAddr[MAC_ADDR_LEN];
+	OS_SYSTIME rLastSendTime;
+} DEAUTH_INFO_T, *P_DEAUTH_INFO_T;
+
+/*----------------------------------------------------------------------------*/
+/* Information Element (IE) handlers                                          */
+/*----------------------------------------------------------------------------*/
+typedef VOID(*PFN_APPEND_IE_FUNC) (P_ADAPTER_T, P_MSDU_INFO_T);
+typedef VOID(*PFN_HANDLE_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T);
+typedef VOID(*PFN_VERIFY_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T, PUINT_16);
+typedef UINT_32(*PFN_CALCULATE_VAR_IE_LEN_FUNC) (P_ADAPTER_T, ENUM_NETWORK_TYPE_INDEX_T, P_STA_RECORD_T);
+
+typedef struct _APPEND_IE_ENTRY_T {
+	UINT_16 u2EstimatedIELen;
+	PFN_APPEND_IE_FUNC pfnAppendIE;
+} APPEND_IE_ENTRY_T, *P_APPEND_IE_ENTRY_T;
+
+typedef struct _APPEND_VAR_IE_ENTRY_T {
+	UINT_16 u2EstimatedFixedIELen;	/* For Fixed Length */
+	PFN_CALCULATE_VAR_IE_LEN_FUNC pfnCalculateVariableIELen;
+	PFN_APPEND_IE_FUNC pfnAppendIE;
+} APPEND_VAR_IE_ENTRY_T, *P_APPEND_VAR_IE_ENTRY_T;
+
+typedef struct _HANDLE_IE_ENTRY_T {
+	UINT_8 ucElemID;
+	PFN_HANDLE_IE_FUNC pfnHandleIE;
+} HANDLE_IE_ENTRY_T, *P_HANDLE_IE_ENTRY_T;
+
+typedef struct _VERIFY_IE_ENTRY_T {
+	UINT_8 ucElemID;
+	PFN_VERIFY_IE_FUNC pfnVarifyIE;
+} VERIFY_IE_ENTRY_T, *P_VERIFY_IE_ENTRY_T;
+
+/*----------------------------------------------------------------------------*/
+/* Parameters of User Configuration                                           */
+/*----------------------------------------------------------------------------*/
+typedef enum _ENUM_PARAM_CONNECTION_POLICY_T {
+	CONNECT_BY_SSID_BEST_RSSI = 0,
+	CONNECT_BY_SSID_GOOD_RSSI_MIN_CH_LOAD,
+	CONNECT_BY_SSID_ANY,	/* NOTE(Kevin): Needed by WHQL */
+	CONNECT_BY_BSSID,
+	CONNECT_BY_CUSTOMIZED_RULE	/* NOTE(Kevin): TBD */
+} ENUM_PARAM_CONNECTION_POLICY_T, *P_ENUM_PARAM_CONNECTION_POLICY_T;
+
+typedef enum _ENUM_PARAM_PREAMBLE_TYPE_T {
+	PREAMBLE_TYPE_LONG = 0,
+	PREAMBLE_TYPE_SHORT,
+	PREAMBLE_TYPE_AUTO	/*!< Try preamble short first, if fail tray preamble long. */
+} ENUM_PARAM_PREAMBLE_TYPE_T, *P_ENUM_PARAM_PREAMBLE_TYPE_T;
+
+/* This is enum defined for user to select a phy config listed in combo box */
+typedef enum _ENUM_PARAM_PHY_CONFIG_T {
+	/*!< Can associated with 802.11abg AP but without n capability, Scan dual band. */
+	PHY_CONFIG_802_11ABG = 0,
+	PHY_CONFIG_802_11BG,	/*!< Can associated with 802_11bg AP, Scan single band and not report 5G BSSs. */
+	PHY_CONFIG_802_11G,	/*!< Can associated with 802_11g only AP, Scan single band and not report 5G BSSs. */
+	PHY_CONFIG_802_11A,	/*!< Can associated with 802_11a only AP, Scan single band and not report 2.4G BSSs. */
+	PHY_CONFIG_802_11B,	/*!< Can associated with 802_11b only AP, Scan single band and not report 5G BSSs. */
+	PHY_CONFIG_802_11ABGN,	/*!< Can associated with 802.11abgn AP, Scan dual band. */
+	PHY_CONFIG_802_11BGN,	/*!< Can associated with 802_11bgn AP, Scan single band and not report 5G BSSs. */
+	PHY_CONFIG_802_11AN,	/*!< Can associated with 802_11an AP, Scan single band and not report 2.4G BSSs. */
+	PHY_CONFIG_802_11GN,	/*!< Can associated with 802_11gn AP, Scan single band and not report 5G BSSs. */
+	PHY_CONFIG_NUM		/* 9 */
+} ENUM_PARAM_PHY_CONFIG_T, *P_ENUM_PARAM_PHY_CONFIG_T;
+
+/* This is enum defined for user to select an AP Mode */
+typedef enum _ENUM_PARAM_AP_MODE_T {
+	AP_MODE_11B = 0,	/*!< Create 11b BSS if we support 802.11abg/802.11bg. */
+	AP_MODE_MIXED_11BG,	/*!< Create 11bg mixed BSS if we support 802.11abg/802.11bg/802.11g. */
+	AP_MODE_11G,		/*!< Create 11g only BSS if we support 802.11abg/802.11bg/802.11g. */
+	AP_MODE_11G_P2P,	/*!< Create 11g only BSS for P2P if we support 802.11abg/802.11bg/802.11g. */
+	AP_MODE_11A,		/*!< Create 11a only BSS if we support 802.11abg. */
+	AP_MODE_NUM		/* 4 */
+} ENUM_PARAM_AP_MODE_T, *P_ENUM_PARAM_AP_MODE_T;
+
+/* Masks for determining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */
+#define NETWORK_TYPE_AIS_MASK               BIT(NETWORK_TYPE_AIS_INDEX)
+#define NETWORK_TYPE_P2P_MASK               BIT(NETWORK_TYPE_P2P_INDEX)
+#define NETWORK_TYPE_BOW_MASK               BIT(NETWORK_TYPE_BOW_INDEX)
+#define STA_TYPE_LEGACY_MASK                 BIT(STA_TYPE_LEGACY_INDEX)
+#define STA_TYPE_P2P_MASK                       BIT(STA_TYPE_P2P_INDEX)
+#define STA_TYPE_BOW_MASK                     BIT(STA_TYPE_BOW_INDEX)
+#define STA_TYPE_ADHOC_MASK                 BIT(STA_ROLE_ADHOC_INDEX)
+#define STA_TYPE_CLIENT_MASK                BIT(STA_ROLE_CLIENT_INDEX)
+#define STA_TYPE_AP_MASK                    BIT(STA_ROLE_AP_INDEX)
+#define STA_TYPE_DLS_MASK                   BIT(STA_ROLE_DLS_INDEX)
+#define STA_TYPE_TDLS_MASK                  BIT(STA_ROLE_TDLS_INDEX)
+
+/* Macros for obtaining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */
+#define IS_STA_IN_AIS(_prStaRec)        ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX)
+#define IS_STA_IN_P2P(_prStaRec)        ((_prStaRec)->ucNetTypeIndex ==  NETWORK_TYPE_P2P_INDEX)
+#define IS_STA_IN_BOW(_prStaRec)        ((_prStaRec)->ucNetTypeIndex ==  NETWORK_TYPE_BOW_INDEX)
+#define IS_STA_LEGACY_TYPE(_prStaRec)        ((_prStaRec->eStaType) & STA_TYPE_LEGACY_MASK)
+#define IS_STA_P2P_TYPE(_prStaRec)        ((_prStaRec->eStaType) & STA_TYPE_P2P_MASK)
+#define IS_STA_BOW_TYPE(_prStaRec)        ((_prStaRec->eStaType) & STA_TYPE_BOW_MASK)
+#define IS_ADHOC_STA(_prStaRec)         ((_prStaRec->eStaType) & STA_TYPE_ADHOC_MASK)
+#define IS_CLIENT_STA(_prStaRec)        ((_prStaRec->eStaType) & STA_TYPE_CLIENT_MASK)
+#define IS_AP_STA(_prStaRec)            ((_prStaRec->eStaType) & STA_TYPE_AP_MASK)
+#define IS_DLS_STA(_prStaRec)           ((_prStaRec->eStaType) & STA_TYPE_DLS_MASK)
+#define IS_TDLS_STA(_prStaRec)          ((_prStaRec->eStaType) & STA_TYPE_TDLS_MASK)
+
+/* The ENUM_STA_TYPE_T accounts for ENUM_NETWORK_TYPE_T and ENUM_STA_ROLE_INDEX_T.
+ * *   It is a merged version of Network Type and STA Role.
+ * */
+typedef enum _ENUM_STA_TYPE_T {
+	STA_TYPE_LEGACY_AP = (STA_TYPE_LEGACY_MASK | STA_TYPE_AP_MASK),
+	STA_TYPE_LEGACY_CLIENT = (STA_TYPE_LEGACY_MASK | STA_TYPE_CLIENT_MASK),
+	STA_TYPE_ADHOC_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_ADHOC_MASK),
+#if CFG_ENABLE_WIFI_DIRECT
+	STA_TYPE_P2P_GO = (STA_TYPE_P2P_MASK | STA_TYPE_AP_MASK),
+	STA_TYPE_P2P_GC = (STA_TYPE_P2P_MASK | STA_TYPE_CLIENT_MASK),
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+	STA_TYPE_BOW_AP = (STA_TYPE_BOW_MASK | STA_TYPE_AP_MASK),
+	STA_TYPE_BOW_CLIENT = (STA_TYPE_BOW_MASK | STA_TYPE_CLIENT_MASK),
+#endif
+	STA_TYPE_DLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_DLS_MASK),
+	STA_TYPE_TDLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_TDLS_MASK)
+} ENUM_STA_TYPE_T, *P_ENUM_STA_TYPE_T;
+
+/* The type of BSS we discovered */
+typedef enum _ENUM_BSS_TYPE_T {
+	BSS_TYPE_INFRASTRUCTURE = 1,
+	BSS_TYPE_IBSS,
+	BSS_TYPE_P2P_DEVICE,
+	BSS_TYPE_BOW_DEVICE,
+	BSS_TYPE_NUM
+} ENUM_BSS_TYPE_T, *P_ENUM_BSS_TYPE_T;
+
+/*----------------------------------------------------------------------------*/
+/* RSN structures                                                             */
+/*----------------------------------------------------------------------------*/
+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */
+/* #pragma pack(1) */
+/* #endif */
+
+#define MAX_NUM_SUPPORTED_CIPHER_SUITES 8	/* max number of supported cipher suites */
+#if CFG_SUPPORT_802_11W
+#define MAX_NUM_SUPPORTED_AKM_SUITES    8	/* max number of supported AKM suites */
+#else
+#define MAX_NUM_SUPPORTED_AKM_SUITES    6	/* max number of supported AKM suites */
+#endif
+
+/* Structure of RSN Information */
+typedef struct _RSN_INFO_T {
+	UINT_8 ucElemId;
+	UINT_16 u2Version;
+	UINT_32 u4GroupKeyCipherSuite;
+	UINT_32 u4PairwiseKeyCipherSuiteCount;
+	UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_CIPHER_SUITES];
+	UINT_32 u4AuthKeyMgtSuiteCount;
+	UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_AKM_SUITES];
+	UINT_16 u2RsnCap;
+	BOOLEAN fgRsnCapPresent;
+} /*__KAL_ATTRIB_PACKED__*/ RSN_INFO_T, *P_RSN_INFO_T;
+
+#define MAX_NUM_SUPPORTED_WAPI_AKM_SUITES    1	/* max number of supported AKM suites */
+#define MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES 1	/* max number of supported cipher suites */
+
+/* Structure of WAPI Information */
+typedef struct _WAPI_INFO_T {
+	UINT_8 ucElemId;
+	UCHAR ucLength;
+	UINT_16 u2Version;
+	UINT_32 u4AuthKeyMgtSuiteCount;
+	UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_WAPI_AKM_SUITES];
+	UINT_32 u4PairwiseKeyCipherSuiteCount;
+	UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES];
+	UINT_32 u4GroupKeyCipherSuite;
+	UINT_16 u2WapiCap;
+	UINT_16 u2Bkid;
+	UINT_8 aucBkid[1][16];
+} /* __KAL_ATTRIB_PACKED__ */ WAPI_INFO_T, *P_WAPI_INFO_T;
+
+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */
+/* #pragma pack() */
+/* #endif */
+
+#if CFG_ENABLE_WIFI_DIRECT
+
+typedef struct _P2P_DEVICE_TYPE_T {
+	UINT_16 u2CategoryID;
+	UINT_16 u2SubCategoryID;
+} P2P_DEVICE_TYPE_T, *P_P2P_DEVICE_TYPE_T;
+
+typedef struct _P2P_DEVICE_DESC_T {
+	LINK_ENTRY_T rLinkEntry;
+	BOOLEAN fgDevInfoValid;
+	UINT_8 aucDeviceAddr[MAC_ADDR_LEN];	/* Device Address. */
+	UINT_8 aucInterfaceAddr[MAC_ADDR_LEN];	/* Interface Address. */
+	UINT_8 ucDeviceCapabilityBitmap;
+	UINT_8 ucGroupCapabilityBitmap;
+	UINT_16 u2ConfigMethod;	/* Configure Method support. */
+	P2P_DEVICE_TYPE_T rPriDevType;
+	UINT_8 ucSecDevTypeNum;
+	P2P_DEVICE_TYPE_T arSecDevType[8];	/* Reference to P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT */
+	UINT_16 u2NameLength;
+	UINT_8 aucName[32];	/* Reference to WPS_ATTRI_MAX_LEN_DEVICE_NAME */
+	/* TODO: Service Information or PasswordID valid? */
+} P2P_DEVICE_DESC_T, *P_P2P_DEVICE_DESC_T;
+
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+static const UINT_8 aucRateIndex2RateCode[PREAMBLE_OPTION_NUM][RATE_NUM] = {
+	{			/* Long Preamble */
+	 RATE_CCK_1M_LONG,	/* RATE_1M_INDEX = 0 */
+	 RATE_CCK_2M_LONG,	/* RATE_2M_INDEX */
+	 RATE_CCK_5_5M_LONG,	/* RATE_5_5M_INDEX */
+	 RATE_CCK_11M_LONG,	/* RATE_11M_INDEX */
+	 RATE_CCK_1M_LONG,	/* RATE_22M_INDEX - Not supported */
+	 RATE_CCK_1M_LONG,	/* RATE_33M_INDEX - Not supported */
+	 RATE_OFDM_6M,		/* RATE_6M_INDEX */
+	 RATE_OFDM_9M,		/* RATE_9M_INDEX */
+	 RATE_OFDM_12M,		/* RATE_12M_INDEX */
+	 RATE_OFDM_18M,		/* RATE_18M_INDEX */
+	 RATE_OFDM_24M,		/* RATE_24M_INDEX */
+	 RATE_OFDM_36M,		/* RATE_36M_INDEX */
+	 RATE_OFDM_48M,		/* RATE_48M_INDEX */
+	 RATE_OFDM_54M,		/* RATE_54M_INDEX */
+	 },
+	{			/* Short Preamble */
+	 RATE_CCK_1M_LONG,	/* RATE_1M_INDEX = 0 */
+	 RATE_CCK_2M_SHORT,	/* RATE_2M_INDEX */
+	 RATE_CCK_5_5M_SHORT,	/* RATE_5_5M_INDEX */
+	 RATE_CCK_11M_SHORT,	/* RATE_11M_INDEX */
+	 RATE_CCK_1M_LONG,	/* RATE_22M_INDEX - Not supported */
+	 RATE_CCK_1M_LONG,	/* RATE_33M_INDEX - Not supported */
+	 RATE_OFDM_6M,		/* RATE_6M_INDEX */
+	 RATE_OFDM_9M,		/* RATE_9M_INDEX */
+	 RATE_OFDM_12M,		/* RATE_12M_INDEX */
+	 RATE_OFDM_18M,		/* RATE_18M_INDEX */
+	 RATE_OFDM_24M,		/* RATE_24M_INDEX */
+	 RATE_OFDM_36M,		/* RATE_36M_INDEX */
+	 RATE_OFDM_48M,		/* RATE_48M_INDEX */
+	 RATE_OFDM_54M,		/* RATE_54M_INDEX */
+	 },
+	{			/* Mixed Mode(Option) */
+	 RATE_MM_MCS_0,		/* RATE_MCS0_INDEX, */
+	 RATE_MM_MCS_1,		/* RATE_MCS1_INDEX, */
+	 RATE_MM_MCS_2,		/* RATE_MCS2_INDEX, */
+	 RATE_MM_MCS_3,		/* RATE_MCS3_INDEX, */
+	 RATE_MM_MCS_4,		/* RATE_MCS4_INDEX, */
+	 RATE_MM_MCS_5,		/* RATE_MCS5_INDEX, */
+	 RATE_MM_MCS_6,		/* RATE_MCS6_INDEX, */
+	 RATE_MM_MCS_7,		/* RATE_MCS7_INDEX, */
+	 RATE_MM_MCS_32		/* RATE_MCS32_INDEX, */
+	 },
+	{			/* Green Field(Option) */
+	 RATE_GF_MCS_0,		/* RATE_MCS0_INDEX, */
+	 RATE_GF_MCS_1,		/* RATE_MCS1_INDEX, */
+	 RATE_GF_MCS_2,		/* RATE_MCS2_INDEX, */
+	 RATE_GF_MCS_3,		/* RATE_MCS3_INDEX, */
+	 RATE_GF_MCS_4,		/* RATE_MCS4_INDEX, */
+	 RATE_GF_MCS_5,		/* RATE_MCS5_INDEX, */
+	 RATE_GF_MCS_6,		/* RATE_MCS6_INDEX, */
+	 RATE_GF_MCS_7,		/* RATE_MCS7_INDEX, */
+	 RATE_GF_MCS_32		/* RATE_MCS32_INDEX, */
+	 }
+};
+
+static const UINT_8 aucRateTableSize[PREAMBLE_OPTION_NUM] = {
+	RATE_HT_PHY_INDEX,
+	RATE_HT_PHY_INDEX,
+	HT_RATE_NUM,
+	HT_RATE_NUM
+};
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/* Macros to get and set the wireless LAN frame fields those are 16/32 bits in
+   length. */
+#define WLAN_GET_FIELD_16(_memAddr_p, _value_p) \
+	{ \
+	    PUINT_8 __cp = (PUINT_8) (_memAddr_p); \
+	    *(PUINT_16)(_value_p) = ((UINT_16) __cp[0]) | ((UINT_16) __cp[1] << 8); \
+	}
+
+#define WLAN_GET_FIELD_BE16(_memAddr_p, _value_p) \
+	{ \
+	    PUINT_8 __cp = (PUINT_8) (_memAddr_p); \
+	    *(PUINT_16)(_value_p) = ((UINT_16) __cp[0] << 8) | ((UINT_16) __cp[1]); \
+	}
+
+#define WLAN_GET_FIELD_32(_memAddr_p, _value_p) \
+	{ \
+	    PUINT_8 __cp = (PUINT_8) (_memAddr_p); \
+	    *(PUINT_32)(_value_p) = ((UINT_32) __cp[0])       | ((UINT_32) __cp[1] << 8) | \
+				    ((UINT_32) __cp[2] << 16) | ((UINT_32) __cp[3] << 24); \
+	}
+
+#define WLAN_GET_FIELD_64(_memAddr_p, _value_p) \
+	{ \
+	    PUINT_8 __cp = (PUINT_8) (_memAddr_p); \
+	    *(PUINT_64)(_value_p) = \
+		((UINT_64) __cp[0])       | ((UINT_64) __cp[1] << 8)  | \
+		((UINT_64) __cp[2] << 16) | ((UINT_64) __cp[3] << 24) | \
+		((UINT_64) __cp[4] << 32) | ((UINT_64) __cp[5] << 40) | \
+		((UINT_64) __cp[6] << 48) | ((UINT_64) __cp[7] << 56); \
+	}
+
+#define WLAN_SET_FIELD_16(_memAddr_p, _value) \
+	{ \
+	    PUINT_8 __cp = (PUINT_8) (_memAddr_p); \
+	    __cp[0] = (UINT_8) (_value); \
+	    __cp[1] = (UINT_8) ((_value) >> 8); \
+	}
+
+#define WLAN_SET_FIELD_BE16(_memAddr_p, _value) \
+	{ \
+	    PUINT_8 __cp = (PUINT_8) (_memAddr_p); \
+	    __cp[0] = (UINT_8) ((_value) >> 8); \
+	    __cp[1] = (UINT_8) (_value); \
+	}
+
+#define WLAN_SET_FIELD_32(_memAddr_p, _value) \
+	{ \
+	    PUINT_8 __cp = (PUINT_8) (_memAddr_p); \
+	    __cp[0] = (UINT_8) (_value); \
+	    __cp[1] = (UINT_8) ((_value) >> 8); \
+	    __cp[2] = (UINT_8) ((_value) >> 16); \
+	    __cp[3] = (UINT_8) ((_value) >> 24); \
+	}
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _WLAN_DEF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h
new file mode 100644
index 0000000000000..aba2e040c1949
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h
@@ -0,0 +1,2290 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_cmd_event.h#1
+*/
+
+/*! \file   "nic_cmd_event.h"
+    \brief This file contains the declairation file of the WLAN OID processing routines
+	   of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: nic_cmd_event.h
+ *
+ * 03 29 2012 eason.tsai
+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define
+ * add conditional define.
+ *
+ * 03 04 2012 eason.tsai
+ * NULL
+ * modify the cal fail report code.
+ *
+ * 01 06 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * redefine the CMD_ID_SET_TXPWR_CTRL value.
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 11 30 2011 cm.chang
+ * [WCXRP00001128] [MT5931 Wi-Fi][FW] Update BB/RF setting based on RF doc v0.7 for LGE spec
+ * 1. Add a new CMD for driver to set device mode
+ * 2. Update calibration parameters
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Update RSSI for P2P.
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 10 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add TX_DONE status detail information.
+ *
+ * 11 08 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error.
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 10 26 2011 cp.wu
+ * [WCXRP00001065] [MT6620 Wi-Fi][MT5931][FW][DRV] Adding parameter for controlling
+ * minimum channel dwell time for scanning
+ * add interface for control minimum channel dwell time for scanning.
+ *
+ * 09 20 2011 cm.chang
+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
+ * New CMD definition about RLM parameters
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 08 25 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add DFS switch.
+ *
+ * 08 24 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Update RDD test mode cases.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628-specific definitions.
+ *
+ * 08 11 2011 cp.wu
+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
+ * sparse channel detection:
+ * driver: collect sparse channel information with scan-done event
+ *
+ * 08 09 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ *
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ * 07 28 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS cmd and event.
+ *
+ * 07 22 2011 jeffrey.chang
+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time
+ * add osc stable time command structure
+ *
+ * 07 22 2011 jeffrey.chang
+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time
+ * modify driver to set OSC stable time after f/w download
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 07 18 2011 cp.wu
+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than
+ * one SSID in a single scanning request
+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID
+ * support as well as uProbeDelay in NDIS 6.x driver model
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content
+ * check with firmware for valid MAC address.
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * change parameter name from PeerAddr to BSSID
+ *
+ * 06 20 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * 1. specify target's BSSID when requesting channel privilege.
+ * 2. pass BSSID information to firmware domain
+ *
+ * 06 09 2011 tsaiyuan.hsu
+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size
+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size.
+ *
+ * 05 27 2011 cp.wu
+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 03 31 2011 chinglan.wang
+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not.
+ * .
+ *
+ * 03 18 2011 cm.chang
+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command
+ * As CR title
+ *
+ * 03 17 2011 yarco.yang
+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage
+ * .
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add Security check related code.
+ *
+ * 03 02 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * Support UAPSD/OppPS/NoA parameter setting
+ *
+ * 02 16 2011 cm.chang
+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism
+ * .
+ *
+ * 02 10 2011 cp.wu
+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers
+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle.
+ *
+ * 02 08 2011 eddie.chen
+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
+ * Add event STA agint timeout
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Update cmd format of BSS INFO, always sync OwnMac to FW no matter P2P is enabled or not..
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Add Oid for sw control debug command
+ *
+ * 01 15 2011 puff.wen
+ * NULL
+ * Add Stress test
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * Sync HT operation element information from host to FW
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * report EEPROM used flag via NIC_CAPABILITY
+ *
+ * 12 28 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools
+ *
+ * 12 23 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * 1. update WMM IE parsing, with ASSOC REQ handling
+ * 2. extend U-APSD parameter passing from driver to FW
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 11 29 2010 cm.chang
+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for
+ * initial TX rate selection of auto-rate algorithm
+ * Sync RCPI of STA_REC to FW as reference of initial TX rate
+ *
+ * 11 08 2010 cm.chang
+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID
+ * Remove CNM channel reover message ID
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 25 2010 cp.wu
+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition
+ * follow-up for CMD_5G_PWR_OFFSET_T definition change
+ *
+ * 10 20 2010 cp.wu
+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
+ * use OID_CUSTOM_TEST_MODE as indication for driver reset
+ * by dropping pending TX packets
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Add the code to support disconnect p2p group
+ *
+ * 09 15 2010 cm.chang
+ * NULL
+ * Add new CMD for TX power, 5G power offset and power parameters
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * Add a pointer in P2P SCAN RESULT structure. This pointer
+ * is pointed to a IE buffer for this P2p device.
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * add new CMD ID definition
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Add a field in BSS INFO cmd to change interface address for P2P. (switching between Device Addr & Interface Addr)
+ *
+ * 08 12 2010 yuche.tsai
+ * NULL
+ * Add interface address indication when indicate connection status.
+ * It is requested by supplicant to do 4 way handshake.
+ *
+ * 08 07 2010 wh.su
+ * NULL
+ * adding the privacy related code for P2P network
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Change data structure for P2P Device scan result, all channel time for scan command.
+ *
+ * 08 04 2010 george.huang
+ * NULL
+ * handle change PS mode OID/ CMD
+ *
+ * 08 04 2010 yarco.yang
+ * NULL
+ * Add TX_AMPDU and ADDBA_REJECT command
+ *
+ * 08 03 2010 george.huang
+ * NULL
+ * handle event for updating NOA parameters indicated from FW
+ *
+ * 08 02 2010 george.huang
+ * NULL
+ * add WMM-PS test related OID/ CMD handlers
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Add P2P Device Found Event.
+ * Channel extension option in scan abort command.
+ *
+ * 07 23 2010 cp.wu
+ *
+ * add AIS-FSM handling for beacon timeout event.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add for P2P Scan Result Parsing & Saving.
+ *
+ * 07 20 2010 george.huang
+ *
+ * DWORD align for the CMD data structure
+ *
+ * 07 20 2010 cp.wu
+ *
+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8..
+ *
+ * 07 19 2010 wh.su
+ *
+ * update for security supporting.
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 16 2010 yarco.yang
+ *
+ * 1. Support BSS Absence/Presence Event
+ * 2. Support STA change PS mode Event
+ * 3. Support BMC forwarding for AP mode.
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * pass band with channel number information as scan parameter
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 09 2010 cp.wu
+ *
+ * reorder members of CMD_SET_BSS_INFO.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * update prStaRecOfAP with BSS-INFO.
+ *
+ * 07 07 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support state of STA record change from 1 to 1
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support sync command of STA_REC
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 30 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * sync. with CMD/EVENT document ver0.07.
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE.
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) sync to. CMD/EVENT document v0.03
+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
+ * 3) send command packet to indicate FW-PM after
+ *     a) 1st beacon is received after AIS has connected to an AP
+ *     b) IBSS-ALONE has been created
+ *     c) IBSS-MERGE has occurred
+ *
+ * 06 28 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Create beacon update path, with expose bssUpdateBeaconContent()
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add BSS/STA_REC commands for integration.
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Add TX Done Event handle entry
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) do not take timeout mechanism for power mode oids
+ * 2) retrieve network type from connection status
+ * 3) after disassciation, set radio state to off
+ * 4) TCP option over IPv6 is supported
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct OID_802_11_DISASSOCIATE handling.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * sync statistics data structure definition with firmware implementation
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * statistics information OIDs are now handled by querying from firmware domain
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * indicate media stream mode after set is done
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add a temporary flag for integration with CMD/EVENT v0.9.
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior.
+ *  * the frequency is used for adhoc connection only
+ *  * 2) update with SD1 v0.9 CMD/EVENT documentation
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 22 2010 cp.wu
+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list
+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ *  *  *  *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
+ *
+ * 03 15 2010 kevin.huang
+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test
+ * Add event for activate STA_RECORD_T
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement custom OID: EEPROM read/write access
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_3_MULTICAST_LIST oid handling
+ *
+ * 02 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c
+ * 'cause it involves OS dependent data structure handling
+ *
+ * 02 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set.
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  *  *  *  * 2. follow MSDN defined behavior when associates to another AP
+ *  *  *  *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 01 27 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * .
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  *  *  *  *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  *  *  *  *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  *  *  *  *  * 4. correct some HAL implementation
+ *
+ * 01 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement following 802.11 OIDs:
+ *  *  * OID_802_11_RSSI,
+ *  *  * OID_802_11_RSSI_TRIGGER,
+ *  *  * OID_802_11_STATISTICS,
+ *  *  * OID_802_11_DISASSOCIATE,
+ *  *  * OID_802_11_POWER_MODE
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_11_MEDIA_STREAM_MODE
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  *  *  *  * and result is retrieved by get ATInfo instead
+ *  *  *  *  *  * 2) add 4 counter for recording aggregation statistics
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-12-11 18:35:07 GMT mtk02752
+**  add CMD added in CMD/EVEN document v0.8
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-12-10 16:39:37 GMT mtk02752
+**  eliminate unused definitions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-12-10 09:55:11 GMT mtk02752
+**  command ID/event ID revised
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-09 13:57:37 GMT MTK02468
+**  Added event ids (EVENT_ID_RX_ADDBA and EVENT_ID_RX_DELBA)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-08 17:35:39 GMT mtk02752
+**  + add event ID for EVENT_ID_TEST_STATUS (rf test)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-12-07 23:01:09 GMT mtk02752
+**  add data structure for RF_TEST
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-12-03 16:22:56 GMT mtk01461
+**  Modify the element - i4RSSI in EVENT of SCAN RESULT
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-30 10:54:44 GMT mtk02752
+**  1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T, while 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-26 10:16:58 GMT mtk02752
+**  resync EVENT_CONNECTION_STATUS
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-25 21:34:01 GMT mtk02752
+**  sync. EVENT_SCAN_RESULT_T with firmware
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-25 21:03:48 GMT mtk02752
+**  refine MGMT_FRAME
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-25 18:17:47 GMT mtk02752
+**  refine GL_WLAN_INFO_T for buffering scan result and presume max. ie length = 600 bytes
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 22:41:20 GMT mtk02752
+**  add EVENT_SCAN_RESULT_T definition
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-11-23 20:29:16 GMT mtk02752
+**   fix typo
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-11-23 14:46:01 GMT mtk02752
+**  add new command/event structure upon CM@SD1's documentation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-13 15:13:40 GMT mtk02752
+**  add command definition for CMD_BUILD_CONNECTION and EVENT_CONNECTION_STATUS
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-20 12:22:22 GMT mtk01461
+**  Add SeqNum field to Event Header
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:11 GMT mtk01461
+**  Update structure of HIF_EVENT_HEADER_T and EVENT_HDR_SIZE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 12:10:36 GMT mtk01461
+**  Add Common Set CMD Callback for MCR Write and other Set OID
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:17 GMT mtk01461
+**  Command Done Handler
+*/
+#ifndef _NIC_CMD_EVENT_H
+#define _NIC_CMD_EVENT_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define CMD_STATUS_SUCCESS      0
+#define CMD_STATUS_REJECTED     1
+#define CMD_STATUS_UNKNOWN      2
+
+#define EVENT_HDR_SIZE          OFFSET_OF(WIFI_EVENT_T, aucBuffer[0])
+
+#define MAX_IE_LENGTH       (600)
+#define MAX_WSC_IE_LENGTH   (400)
+
+/* Action field in structure CMD_CH_PRIVILEGE_T */
+#define CMD_CH_ACTION_REQ           0
+#define CMD_CH_ACTION_ABORT         1
+
+/* Status field in structure EVENT_CH_PRIVILEGE_T */
+#define EVENT_CH_STATUS_GRANT       0
+
+#define SCN_PSCAN_SWC_RSSI_WIN_MAX  75
+#define SCN_PSCAN_SWC_MAX_NUM       8
+#define SCN_PSCAN_HOTLIST_REPORT_MAX_NUM 8
+
+typedef enum _ENUM_CMD_ID_T {
+	CMD_ID_TEST_MODE = 1,	/* 0x01 (Set) */
+	CMD_ID_RESET_REQUEST,	/* 0x02 (Set) */
+	CMD_ID_BUILD_CONNECTION,	/* 0x03 (Set) */
+	CMD_ID_SCAN_REQ_V2,	/* 0x04 (Set) */
+	CMD_ID_NIC_POWER_CTRL,	/* 0x05 (Set) */
+	CMD_ID_POWER_SAVE_MODE,	/* 0x06 (Set) */
+	CMD_ID_LINK_ATTRIB,	/* 0x07 (Set) */
+	CMD_ID_ADD_REMOVE_KEY,	/* 0x08 (Set) */
+	CMD_ID_DEFAULT_KEY_ID,	/* 0x09 (Set) */
+	CMD_ID_INFRASTRUCTURE,	/* 0x0a (Set) */
+	CMD_ID_SET_RX_FILTER,	/* 0x0b (Set) */
+	CMD_ID_DOWNLOAD_BUF,	/* 0x0c (Set) */
+	CMD_ID_WIFI_START,	/* 0x0d (Set) */
+	CMD_ID_CMD_BT_OVER_WIFI,	/* 0x0e (Set) */
+	CMD_ID_SET_MEDIA_CHANGE_DELAY_TIME,	/* 0x0f (Set) */
+	CMD_ID_SEND_ADDBA_RSP,	/* 0x10 (Set) */
+	CMD_ID_WAPI_MODE,	/* 0x11 (Set)  (obsolete) */
+	CMD_ID_WAPI_ASSOC_INFO,	/* 0x12 (Set)  (obsolete) */
+	CMD_ID_SET_DOMAIN_INFO,	/* 0x13 (Set) */
+	CMD_ID_SET_IP_ADDRESS,	/* 0x14 (Set) */
+	CMD_ID_BSS_ACTIVATE_CTRL,	/* 0x15 (Set) */
+	CMD_ID_SET_BSS_INFO,	/* 0x16 (Set) */
+	CMD_ID_UPDATE_STA_RECORD,	/* 0x17 (Set) */
+	CMD_ID_REMOVE_STA_RECORD,	/* 0x18 (Set) */
+	CMD_ID_INDICATE_PM_BSS_CREATED,	/* 0x19 (Set) */
+	CMD_ID_INDICATE_PM_BSS_CONNECTED,	/* 0x1a (Set) */
+	CMD_ID_INDICATE_PM_BSS_ABORT,	/* 0x1b (Set) */
+	CMD_ID_UPDATE_BEACON_CONTENT,	/* 0x1c (Set) */
+	CMD_ID_SET_BSS_RLM_PARAM,	/* 0x1d (Set) */
+	CMD_ID_SCAN_REQ,	/* 0x1e (Set) */
+	CMD_ID_SCAN_CANCEL,	/* 0x1f (Set) */
+	CMD_ID_CH_PRIVILEGE,	/* 0x20 (Set) */
+	CMD_ID_UPDATE_WMM_PARMS,	/* 0x21 (Set) */
+	CMD_ID_SET_WMM_PS_TEST_PARMS,	/* 0x22 (Set) */
+	CMD_ID_TX_AMPDU,	/* 0x23 (Set) */
+	CMD_ID_ADDBA_REJECT,	/* 0x24 (Set) */
+	CMD_ID_SET_PS_PROFILE_ADV,	/* 0x25 (Set) */
+	CMD_ID_SET_RAW_PATTERN,	/* 0x26 (Set) */
+	CMD_ID_CONFIG_PATTERN_FUNC,	/* 0x27 (Set) */
+	CMD_ID_SET_TX_PWR,	/* 0x28 (Set) */
+	CMD_ID_SET_5G_PWR_OFFSET,	/* 0x29 (Set) */
+	CMD_ID_SET_PWR_PARAM,	/* 0x2A (Set) */
+	CMD_ID_P2P_ABORT,	/* 0x2B (Set) */
+#if CFG_STRESS_TEST_SUPPORT
+	CMD_ID_RANDOM_RX_RESET_EN = 0x2C,	/* 0x2C (Set ) */
+	CMD_ID_RANDOM_RX_RESET_DE = 0x2D,	/* 0x2D (Set ) */
+	CMD_ID_SAPP_EN = 0x2E,	/* 0x2E (Set ) */
+	CMD_ID_SAPP_DE = 0x2F,	/* 0x2F (Set ) */
+#endif
+	CMD_ID_ROAMING_TRANSIT = 0x30,	/* 0x30 (Set) */
+	CMD_ID_SET_PHY_PARAM,	/* 0x31 (Set) */
+	CMD_ID_SET_NOA_PARAM,	/* 0x32 (Set) */
+	CMD_ID_SET_OPPPS_PARAM,	/* 0x33 (Set) */
+	CMD_ID_SET_UAPSD_PARAM,	/* 0x34 (Set) */
+	CMD_ID_SET_SIGMA_STA_SLEEP,	/* 0x35 (Set) */
+	CMD_ID_SET_EDGE_TXPWR_LIMIT,	/* 0x36 (Set) */
+	CMD_ID_SET_DEVICE_MODE,	/* 0x37 (Set) */
+	CMD_ID_SET_TXPWR_CTRL,	/* 0x38 (Set) */
+	CMD_ID_SET_AUTOPWR_CTRL,	/* 0x39 (Set) */
+	CMD_ID_SET_WFD_CTRL,	/* 0x3A (Set) */
+	CMD_ID_SET_5G_EDGE_TXPWR_LIMIT,	/* 0x3B (Set) */
+	CMD_ID_SET_RSSI_COMPENSATE,	/* 0x3C (Set) */
+	CMD_ID_SET_BAND_SUPPORT = 0x3D,	/* 0x3D (Set) */
+	CMD_ID_SET_NLO_REQ,	/* 0x3E (Set) */
+	CMD_ID_SET_NLO_CANCEL,	/* 0x3F (Set) */
+	CMD_ID_SET_BATCH_REQ,	/* 0x40 (Set) */
+	CMD_ID_SET_WOWLAN,	/* 0x41 (Set) */ /*CFG_SUPPORT_WOWLAN */
+	CMD_ID_GET_PSCAN_CAPABILITY = 0x42,	/* 0x42 (Set) */
+	CMD_ID_SET_PSCN_ENABLE = 0x43,	/* 0x43 (Set) */
+	CMD_ID_SET_PSCAN_PARAM = 0x44,	/* 0x44 (Set) */
+	CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID = 0x45,	/* 0x45 (Set) */
+	CMD_ID_SET_PSCN_ADD_SW_BSSID = 0x46,	/* 0x46 (Set) */
+	CMD_ID_SET_PSCN_MAC_ADDR = 0x47,	/* 0x47 (Set) */
+	CMD_ID_GET_GSCN_SCN_RESULT = 0x48,	/* 0x48 (Get) */
+	CMD_ID_SET_COUNTRY_POWER_LIMIT = 0x4A,	/* 0x4A (Set) */
+	CMD_ID_SET_SYSTEM_SUSPEND = 0x60,	/* 0x60 (Set) */
+	CMD_ID_GET_NIC_CAPABILITY = 0x80,	/* 0x80 (Query) */
+	CMD_ID_GET_LINK_QUALITY,	/* 0x81 (Query) */
+	CMD_ID_GET_STATISTICS,	/* 0x82 (Query) */
+	CMD_ID_GET_CONNECTION_STATUS,	/* 0x83 (Query) */
+	CMD_ID_GET_ASSOC_INFO,	/* 0x84 (Query) (obsolete) */
+	CMD_ID_GET_STA_STATISTICS = 0x85,	/* 0x85 (Query) */
+	CMD_ID_GET_DEBUG_CODE = 0x86,	/* 0x86 (Query) */
+	CMD_ID_GET_LTE_CHN = 0x87,	/* 0x87 (Query) */
+	CMD_ID_GET_CHN_LOADING = 0x88,	/* 0x88 (Query) */
+	CMD_ID_GET_STATISTICS_PL = 0x89,	/* 0x87 (Query) */
+	CMD_ID_BASIC_CONFIG = 0xc1,	/* 0xc1 (Set / Query) */
+	CMD_ID_ACCESS_REG,	/* 0xc2 (Set / Query) */
+	CMD_ID_MAC_MCAST_ADDR,	/* 0xc3 (Set / Query) */
+	CMD_ID_802_11_PMKID,	/* 0xc4 (Set / Query) */
+	CMD_ID_ACCESS_EEPROM,	/* 0xc5 (Set / Query) */
+	CMD_ID_SW_DBG_CTRL,	/* 0xc6 (Set / Query) */
+#if 1				/* CFG_SUPPORT_ANTI_PIRACY */
+	CMD_ID_SEC_CHECK,	/* 0xc7 (Set / Query) */
+#endif
+	CMD_ID_DUMP_MEM,	/* 0xc8 (Query) */
+
+	CMD_ID_CHIP_CONFIG = 0xCA,	/* 0xca (Set / Query) */
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+	CMD_ID_SET_RDD_CH = 0xE1,
+#endif
+
+	CMD_ID_SET_BWCS = 0xF1,
+	CMD_ID_SET_ROAMING_INFO = 0xF3,
+
+#if CFG_SUPPORT_BUILD_DATE_CODE
+	CMD_ID_GET_BUILD_DATE_CODE = 0xF8,
+#endif
+	CMD_ID_GET_BSS_INFO = 0xF9,
+#if 1				/* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */
+	CMD_ID_SET_HOTSPOT_OPTIMIZATION = 0xFA,	/* 0xFA (Set) */
+#endif
+
+	CMD_ID_TDLS_CORE = 0xFC,
+	CMD_ID_STATS = 0xFD,
+	CMD_ID_TX_AR_ERR_CONFIG = 0xFF
+} ENUM_CMD_ID_T, *P_ENUM_CMD_ID_T;
+
+typedef enum _ENUM_EVENT_ID_T {
+	EVENT_ID_CMD_RESULT = 1,	/* 0x01 (Query) */
+	EVENT_ID_NIC_CAPABILITY,	/* 0x02 (Query) */
+	EVENT_ID_CONNECTION_STATUS,	/* 0x03 (Query / Unsolicited) (obsolete) */
+	EVENT_ID_SCAN_RESULT,	/* 0x04 (Query / Unsolicited) (obselete) */
+	EVENT_ID_LINK_QUALITY,	/* 0x05 (Query / Unsolicited) */
+	EVENT_ID_STATISTICS,	/* 0x06 (Query) */
+	EVENT_ID_MIC_ERR_INFO,	/* 0x07 (Unsolicited) */
+	EVENT_ID_ASSOC_INFO,	/* 0x08 (Query - CMD_ID_GET_ASSOC_INFO) */
+	EVENT_ID_BASIC_CONFIG,	/* 0x09 (Query - CMD_ID_BASIC_CONFIG) */
+	EVENT_ID_ACCESS_REG,	/* 0x0a (Query - CMD_ID_ACCESS_REG) */
+	EVENT_ID_MAC_MCAST_ADDR,	/* 0x0b (Query - CMD_ID_MAC_MCAST_ADDR) */
+	EVENT_ID_802_11_PMKID,	/* 0x0c (Query - CMD_ID_802_11_PMKID) */
+	EVENT_ID_ACCESS_EEPROM,	/* 0x0d (Query - CMD_ID_ACCESS_EEPROM) */
+	EVENT_ID_SLEEPY_NOTIFY,	/* 0x0e (Query) */
+	EVENT_ID_BT_OVER_WIFI,	/* 0x0f (Unsolicited) */
+	EVENT_ID_TEST_STATUS,	/* 0x10 (Query - CMD_ID_TEST_MODE) */
+	EVENT_ID_RX_ADDBA,	/* 0x11 (Unsolicited) (obsolete) */
+	EVENT_ID_RX_DELBA,	/* 0x12 (Unsolicited) (obsolete) */
+	EVENT_ID_ACTIVATE_STA_REC_T,	/* 0x13 (Unsolicited) */
+	EVENT_ID_DEACTIVATE_STA_REC_T,	/* 0x14 (Unsolicited) */
+	EVENT_ID_SCAN_DONE,	/* 0x15 (Unsoiicited) */
+	EVENT_ID_RX_FLUSH,	/* 0x16 (Unsolicited) */
+	EVENT_ID_TX_DONE,	/* 0x17 (Unsolicited) */
+	EVENT_ID_CH_PRIVILEGE,	/* 0x18 (Unsolicited) */
+	EVENT_ID_BSS_ABSENCE_PRESENCE = 0x19,	/* 0x19 (Unsolicited) */
+	EVENT_ID_STA_CHANGE_PS_MODE,	/* 0x1A (Unsolicited) */
+	EVENT_ID_BSS_BEACON_TIMEOUT,	/* 0x1B (Unsolicited) */
+	EVENT_ID_UPDATE_NOA_PARAMS,	/* 0x1C (Unsolicited) */
+	EVENT_ID_AP_OBSS_STATUS,	/* 0x1D (Unsolicited) */
+	EVENT_ID_STA_UPDATE_FREE_QUOTA,	/* 0x1E (Unsolicited) */
+	EVENT_ID_SW_DBG_CTRL,	/* 0x1F (Query - CMD_ID_SW_DBG_CTRL) */
+	EVENT_ID_ROAMING_STATUS,	/* 0x20 (Unsolicited) */
+	EVENT_ID_STA_AGING_TIMEOUT,	/* 0x21 (Unsolicited) */
+#if 1				/* CFG_SUPPORT_ANTI_PIRACY */
+	EVENT_ID_SEC_CHECK_RSP,	/* 0x22 (Unsolicited) */
+#endif
+	EVENT_ID_SEND_DEAUTH,	/* 0x23 (Unsolicited) */
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+	EVENT_ID_UPDATE_RDD_STATUS,	/* 0x24 (Unsolicited) */
+#endif
+
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
+	EVENT_ID_UPDATE_BWCS_STATUS = 0x25,	/* 0x25 (Unsolicited) */
+	EVENT_ID_UPDATE_BCM_DEBUG,	/* 0x26 (Unsolicited) */
+#endif
+	EVENT_ID_RX_ERR,
+	EVENT_ID_DUMP_MEM,
+	EVENT_ID_STA_STATISTICS = 0x29,	/* 0x29 (Query ) */
+	EVENT_ID_STA_STATISTICS_UPDATE,	/* 0x2A (Unsolicited) */
+	EVENT_ID_NLO_DONE = 0x2b,
+
+	EVENT_ID_GSCAN_CAPABILITY = 0x30,
+	EVENT_ID_GSCAN_SCAN_COMPLETE = 0x31,
+	EVENT_ID_GSCAN_FULL_RESULT = 0x32,
+	EVENT_ID_GSCAN_SIGNIFICANT_CHANGE = 0x33,
+	EVENT_ID_GSCAN_GEOFENCE_FOUND = 0x34,
+	EVENT_ID_GSCAN_SCAN_AVAILABLE = 0x35,
+	EVENT_ID_GSCAN_RESULT = 0x36,
+	EVENT_ID_BATCH_RESULT = 0x37,
+
+	EVENT_ID_TDLS = 0x80,
+	EVENT_ID_STATS_ENV = 0x81,
+
+#if CFG_SUPPORT_BUILD_DATE_CODE
+	EVENT_ID_BUILD_DATE_CODE = 0xF8,
+#endif
+	EVENT_ID_GET_AIS_BSS_INFO = 0xF9,
+	EVENT_ID_DEBUG_CODE = 0xFB,
+	EVENT_ID_RFTEST_READY = 0xFC,	/* 0xFC */
+	EVENT_ID_TX_DONE_STATUS = 0xFD,
+	EVENT_ID_FW_LOG_ENV = 0xFE,	/* 0xFE, FW real time debug log */
+} ENUM_EVENT_ID_T, *P_ENUM_EVENT_ID_T;
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#ifndef LINUX
+typedef UINT_8 CMD_STATUS;
+#endif
+
+typedef struct _EVENT_TX_DONE_STATUS_T {
+	UINT_8 ucPacketSeq;
+	UINT_8 ucStatus;
+	UINT_16 u2SequenceNumber;
+	UINT_32 au4Reserved1;
+	UINT_32 au4Reserved2;
+	UINT_32 au4Reserved3;
+	UINT_32 u4PktBufInfo;
+	UINT_8 aucPktBuf[200];
+} EVENT_TX_DONE_STATUS_T, *P_EVENT_TX_DONE_STATUS_T;
+
+/* for Event Packet (via HIF-RX) */
+    /* following CM's documentation v0.7 */
+typedef struct _WIFI_CMD_T {
+	UINT_16 u2TxByteCount_UserPriority;
+	UINT_8 ucEtherTypeOffset;
+	UINT_8 ucResource_PktType_CSflags;
+	UINT_8 ucCID;
+	UINT_8 ucSetQuery;
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved2;
+
+	UINT_8 aucBuffer[0];
+} WIFI_CMD_T, *P_WIFI_CMD_T;
+
+/* for Command Packet (via HIF-TX) */
+    /* following CM's documentation v0.7 */
+typedef struct _WIFI_EVENT_T {
+	UINT_16 u2PacketLen;
+	UINT_16 u2PacketType;
+	UINT_8 ucEID;
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved2[2];
+
+	UINT_8 aucBuffer[0];
+} WIFI_EVENT_T, *P_WIFI_EVENT_T;
+
+/* CMD_ID_TEST_MODE */
+typedef struct _CMD_TEST_CTRL_T {
+	UINT_8 ucAction;
+	UINT_8 aucReserved[3];
+	union {
+		UINT_32 u4OpMode;
+		UINT_32 u4ChannelFreq;
+		PARAM_MTK_WIFI_TEST_STRUCT_T rRfATInfo;
+	} u;
+} CMD_TEST_CTRL_T, *P_CMD_TEST_CTRL_T;
+
+/* EVENT_TEST_STATUS */
+typedef struct _PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T {
+	UINT_32 u4PktSentStatus;
+	UINT_32 u4PktSentCount;
+	UINT_16 u2AvgAlc;
+	UINT_8 ucCckGainControl;
+	UINT_8 ucOfdmGainControl;
+} PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T {
+	UINT_32 u4IntRxOk;	/*!< number of packets that Rx ok from interrupt */
+	UINT_32 u4IntCrcErr;	/*!< number of packets that CRC error from interrupt */
+	UINT_32 u4IntShort;	/*!< number of packets that is short preamble from interrupt */
+	UINT_32 u4IntLong;	/*!< number of packets that is long preamble from interrupt */
+	UINT_32 u4PauRxPktCount;	/*!< number of packets that Rx ok from PAU */
+	UINT_32 u4PauCrcErrCount;	/*!< number of packets that CRC error from PAU */
+	UINT_32 u4PauRxFifoFullCount;	/*!< number of packets that is short preamble from PAU */
+	UINT_32 u4PauCCACount;	/*!< CCA rising edge count */
+} PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T;
+
+typedef union _EVENT_TEST_STATUS {
+	PARAM_MTK_WIFI_TEST_STRUCT_T rATInfo;
+/* PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T   rTxStatus; */
+/* PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T   rRxStatus; */
+} EVENT_TEST_STATUS, *P_EVENT_TEST_STATUS;
+
+/* CMD_BUILD_CONNECTION */
+typedef struct _CMD_BUILD_CONNECTION {
+	UINT_8 ucInfraMode;
+	UINT_8 ucAuthMode;
+	UINT_8 ucEncryptStatus;
+	UINT_8 ucSsidLen;
+	UINT_8 aucSsid[PARAM_MAX_LEN_SSID];
+	UINT_8 aucBssid[PARAM_MAC_ADDR_LEN];
+
+	/* Ad-hoc mode */
+	UINT_16 u2BeaconPeriod;
+	UINT_16 u2ATIMWindow;
+	UINT_8 ucJoinOnly;
+	UINT_8 ucReserved;
+	UINT_32 u4FreqInKHz;
+
+	/* for faster connection */
+	UINT_8 aucScanResult[0];
+} CMD_BUILD_CONNECTION, *P_CMD_BUILD_CONNECTION;
+
+/* CMD_ADD_REMOVE_KEY */
+typedef struct _CMD_802_11_KEY {
+	UINT_8 ucAddRemove;
+	UINT_8 ucTxKey;
+	UINT_8 ucKeyType;
+	UINT_8 ucIsAuthenticator;
+	UINT_8 aucPeerAddr[6];
+	UINT_8 ucNetType;
+	UINT_8 ucAlgorithmId;
+	UINT_8 ucKeyId;
+	UINT_8 ucKeyLen;
+	UINT_8 aucReverved[2];
+	UINT_8 aucKeyMaterial[32];
+	UINT_8 aucKeyRsc[16];
+} CMD_802_11_KEY, *P_CMD_802_11_KEY;
+
+/* WPA2 PMKID cache structure */
+typedef struct _PMKID_ENTRY_T {
+	PARAM_BSSID_INFO_T rBssidInfo;
+	BOOLEAN fgPmkidExist;
+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T;
+
+typedef struct _CMD_802_11_PMKID {
+	ULONG u4BSSIDInfoCount;
+	P_PMKID_ENTRY_T arPMKIDInfo[1];
+} CMD_802_11_PMKID, *P_CMD_802_11_PMKID;
+
+/* CMD_BASIC_CONFIG */
+typedef struct _CMD_CSUM_OFFLOAD {
+	UINT_16 u2RxChecksum;	/* bit0: IP, bit1: UDP, bit2: TCP */
+	UINT_16 u2TxChecksum;	/* bit0: IP, bit1: UDP, bit2: TCP */
+} CMD_CSUM_OFFLOAD, *P_CMD_CSUM_OFFLOAD;
+
+typedef struct _CMD_BASIC_CONFIG {
+	PARAM_MAC_ADDRESS rMyMacAddr;
+	UINT_8 ucNative80211;
+	UINT_8 aucReserved[1];
+
+	CMD_CSUM_OFFLOAD rCsumOffload;
+} CMD_BASIC_CONFIG, *P_CMD_BASIC_CONFIG, EVENT_BASIC_CONFIG, *P_EVENT_BASIC_CONFIG;
+
+/* CMD_MAC_MCAST_ADDR */
+typedef struct _CMD_MAC_MCAST_ADDR {
+	UINT_32 u4NumOfGroupAddr;
+	UINT_8 ucNetTypeIndex;
+	UINT_8 aucReserved[3];
+	PARAM_MAC_ADDRESS arAddress[MAX_NUM_GROUP_ADDR];
+} CMD_MAC_MCAST_ADDR, *P_CMD_MAC_MCAST_ADDR, EVENT_MAC_MCAST_ADDR, *P_EVENT_MAC_MCAST_ADDR;
+
+/* CMD_ACCESS_EEPROM */
+typedef struct _CMD_ACCESS_EEPROM {
+	UINT_16 u2Offset;
+	UINT_16 u2Data;
+} CMD_ACCESS_EEPROM, *P_CMD_ACCESS_EEPROM, EVENT_ACCESS_EEPROM, *P_EVENT_ACCESS_EEPROM;
+
+typedef struct _CMD_CUSTOM_NOA_PARAM_STRUCT_T {
+	UINT_32 u4NoaDurationMs;
+	UINT_32 u4NoaIntervalMs;
+	UINT_32 u4NoaCount;
+} CMD_CUSTOM_NOA_PARAM_STRUCT_T, *P_CMD_CUSTOM_NOA_PARAM_STRUCT_T;
+
+typedef struct _CMD_CUSTOM_OPPPS_PARAM_STRUCT_T {
+	UINT_32 u4CTwindowMs;
+} CMD_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_CMD_CUSTOM_OPPPS_PARAM_STRUCT_T;
+
+typedef struct _CMD_CUSTOM_UAPSD_PARAM_STRUCT_T {
+	UINT_8 fgEnAPSD;
+	UINT_8 fgEnAPSD_AcBe;
+	UINT_8 fgEnAPSD_AcBk;
+	UINT_8 fgEnAPSD_AcVo;
+	UINT_8 fgEnAPSD_AcVi;
+	UINT_8 ucMaxSpLen;
+	UINT_8 aucResv[2];
+} CMD_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_CMD_CUSTOM_UAPSD_PARAM_STRUCT_T;
+
+/* EVENT_CONNECTION_STATUS */
+typedef struct _EVENT_CONNECTION_STATUS {
+	UINT_8 ucMediaStatus;
+	UINT_8 ucReasonOfDisconnect;
+
+	UINT_8 ucInfraMode;
+	UINT_8 ucSsidLen;
+	UINT_8 aucSsid[PARAM_MAX_LEN_SSID];
+	UINT_8 aucBssid[PARAM_MAC_ADDR_LEN];
+	UINT_8 ucAuthenMode;
+	UINT_8 ucEncryptStatus;
+	UINT_16 u2BeaconPeriod;
+	UINT_16 u2AID;
+	UINT_16 u2ATIMWindow;
+	UINT_8 ucNetworkType;
+	UINT_8 aucReserved[1];
+	UINT_32 u4FreqInKHz;
+
+#if CFG_ENABLE_WIFI_DIRECT
+	UINT_8 aucInterfaceAddr[PARAM_MAC_ADDR_LEN];
+#endif
+
+} EVENT_CONNECTION_STATUS, *P_EVENT_CONNECTION_STATUS;
+
+/* EVENT_NIC_CAPABILITY */
+typedef struct _EVENT_NIC_CAPABILITY {
+	UINT_16 u2ProductID;
+	UINT_16 u2FwVersion;
+	UINT_16 u2DriverVersion;
+	UINT_8 ucHw5GBandDisabled;
+	UINT_8 ucEepromUsed;
+	UINT_8 ucEfuseValid;
+	UINT_8 ucMacAddrValid;
+#if CFG_REPORT_RFBB_VERSION
+	UINT_8 ucRfVersion;
+	UINT_8 ucPhyVersion;
+#endif
+#if CFG_ENABLE_CAL_LOG
+	UINT_8 ucRfCalFail;
+	UINT_8 ucBbCalFail;
+#endif
+
+#define FEATURE_SET_OFFSET_TDLS					0
+#define FEATURE_SET_OFFSET_5G_SUPPORT			1
+	UINT_8 ucFeatureSet;	/* bit0: TDLS */
+
+	UINT_8 aucReserved[1];
+#if CFG_EMBED_FIRMWARE_BUILD_DATE_CODE
+	UINT_8 aucDateCode[16];
+#endif
+} EVENT_NIC_CAPABILITY, *P_EVENT_NIC_CAPABILITY;
+
+/* modified version of WLAN_BEACON_FRAME_BODY_T for simplier buffering */
+typedef struct _WLAN_BEACON_FRAME_BODY_T_LOCAL {
+	/* Beacon frame body */
+	UINT_32 au4Timestamp[2];	/* Timestamp */
+	UINT_16 u2BeaconInterval;	/* Beacon Interval */
+	UINT_16 u2CapInfo;	/* Capability */
+	UINT_8 aucInfoElem[MAX_IE_LENGTH];	/* Various IEs, start from SSID */
+	UINT_16 u2IELength;	/* This field is *NOT* carried by F/W but caculated by nic_rx */
+} WLAN_BEACON_FRAME_BODY_T_LOCAL, *P_WLAN_BEACON_FRAME_BODY_T_LOCAL;
+
+/* EVENT_SCAN_RESULT */
+typedef struct _EVENT_SCAN_RESULT_T {
+	INT_32 i4RSSI;
+	UINT_32 u4LinkQuality;
+	UINT_32 u4DSConfig;	/* Center frequency */
+	UINT_32 u4DomainInfo;	/* Require CM opinion */
+	UINT_32 u4Reserved;
+	UINT_8 ucNetworkType;
+	UINT_8 ucOpMode;
+	UINT_8 aucBssid[MAC_ADDR_LEN];
+	UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
+	WLAN_BEACON_FRAME_BODY_T_LOCAL rBeaconFrameBody;
+} EVENT_SCAN_RESULT_T, *P_EVENT_SCAN_RESULT_T;
+
+/* event of tkip mic error */
+typedef struct _EVENT_MIC_ERR_INFO {
+	UINT_32 u4Flags;
+} EVENT_MIC_ERR_INFO, *P_EVENT_MIC_ERR_INFO;
+
+typedef struct _EVENT_PMKID_CANDIDATE_LIST_T {
+	UINT_32 u4Version;	/*!< Version */
+	UINT_32 u4NumCandidates;	/*!< How many candidates follow */
+	PARAM_PMKID_CANDIDATE_T arCandidateList[1];
+} EVENT_PMKID_CANDIDATE_LIST_T, *P_EVENT_PMKID_CANDIDATE_LIST_T;
+
+typedef struct _EVENT_CMD_RESULT {
+	UINT_8 ucCmdID;
+	UINT_8 ucStatus;
+	UINT_8 aucReserved[2];
+} EVENT_CMD_RESULT, *P_EVENT_CMD_RESULT;
+
+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */
+typedef struct _CMD_ACCESS_REG {
+	UINT_32 u4Address;
+	UINT_32 u4Data;
+} CMD_ACCESS_REG, *P_CMD_ACCESS_REG;
+
+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+
+typedef struct _CMD_ACCESS_CHN_LOAD {
+	UINT_32 u4Address;
+	UINT_32 u4Data;
+	UINT_16 u2Channel;
+	UINT_8 aucReserved[2];
+} CMD_ACCESS_CHN_LOAD, *P_ACCESS_CHN_LOAD;
+
+#endif
+/* CMD_DUMP_MEMORY */
+typedef struct _CMD_DUMP_MEM {
+	UINT_32 u4Address;
+	UINT_32 u4Length;
+	UINT_32 u4RemainLength;
+	UINT_8 ucFragNum;
+} CMD_DUMP_MEM, *P_CMD_DUMP_MEM;
+
+typedef struct _EVENT_DUMP_MEM_T {
+	UINT_32 u4Address;
+	UINT_32 u4Length;
+	UINT_32 u4RemainLength;
+	UINT_8 ucFragNum;
+	UINT_8 aucBuffer[1];
+} EVENT_DUMP_MEM_T, *P_EVENT_DUMP_MEM_T;
+
+typedef struct _CMD_SW_DBG_CTRL_T {
+	UINT_32 u4Id;
+	UINT_32 u4Data;
+	/* Debug Support */
+	UINT_32 u4DebugCnt[64];
+} CMD_SW_DBG_CTRL_T, *P_CMD_SW_DBG_CTRL_T;
+
+/* CMD_ID_LINK_ATTRIB */
+typedef struct _CMD_LINK_ATTRIB {
+	INT_8 cRssiTrigger;
+	UINT_8 ucDesiredRateLen;
+	UINT_16 u2DesiredRate[32];
+	UINT_8 ucMediaStreamMode;
+	UINT_8 aucReserved[1];
+} CMD_LINK_ATTRIB, *P_CMD_LINK_ATTRIB;
+
+/* CMD_ID_NIC_POWER_CTRL */
+typedef struct _CMD_NIC_POWER_CTRL {
+	UINT_8 ucPowerMode;
+	UINT_8 aucReserved[3];
+} CMD_NIC_POWER_CTRL, *P_CMD_NIC_POWER_CTRL;
+
+/* CMD_ID_POWER_SAVE_MODE */
+typedef struct _CMD_PS_PROFILE_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucPsProfile;
+	UINT_8 aucReserved[2];
+} CMD_PS_PROFILE_T, *P_CMD_PS_PROFILE_T;
+
+/* EVENT_LINK_QUALITY */
+typedef struct _EVENT_LINK_QUALITY {
+	INT_8 cRssi;
+	INT_8 cLinkQuality;
+	UINT_16 u2LinkSpeed;
+	UINT_8 ucMediumBusyPercentage;
+} EVENT_LINK_QUALITY, *P_EVENT_LINK_QUALITY;
+
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+/* EVENT_LINK_QUALITY */
+typedef struct _EVENT_LINK_QUALITY_EX {
+	INT_8 cRssi;
+	INT_8 cLinkQuality;
+	UINT_16 u2LinkSpeed;
+	UINT_8 ucMediumBusyPercentage;
+	UINT_8 ucIsLQ0Rdy;
+	INT_8 cRssiP2P;		/* For P2P Network. */
+	INT_8 cLinkQualityP2P;
+	UINT_16 u2LinkSpeedP2P;
+	UINT_8 ucMediumBusyPercentageP2P;
+	UINT_8 ucIsLQ1Rdy;
+} EVENT_LINK_QUALITY_EX, *P_EVENT_LINK_QUALITY_EX;
+#endif
+
+/* EVENT_ID_STATISTICS */
+typedef struct _EVENT_STATISTICS {
+	LARGE_INTEGER rTransmittedFragmentCount;
+	LARGE_INTEGER rMulticastTransmittedFrameCount;
+	LARGE_INTEGER rFailedCount;
+	LARGE_INTEGER rRetryCount;
+	LARGE_INTEGER rMultipleRetryCount;
+	LARGE_INTEGER rRTSSuccessCount;
+	LARGE_INTEGER rRTSFailureCount;
+	LARGE_INTEGER rACKFailureCount;
+	LARGE_INTEGER rFrameDuplicateCount;
+	LARGE_INTEGER rReceivedFragmentCount;
+	LARGE_INTEGER rMulticastReceivedFrameCount;
+	LARGE_INTEGER rFCSErrorCount;
+} EVENT_STATISTICS, *P_EVENT_STATISTICS;
+
+/* EVENT_ID_FW_SLEEPY_NOTIFY */
+typedef struct _EVENT_SLEEPY_NOTIFY {
+	UINT_8 ucSleepyState;
+	UINT_8 aucReserved[3];
+} EVENT_SLEEPY_NOTIFY, *P_EVENT_SLEEPY_NOTIFY;
+
+typedef struct _EVENT_ACTIVATE_STA_REC_T {
+	UINT_8 aucMacAddr[6];
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucNetworkTypeIndex;
+	BOOLEAN fgIsQoS;
+	BOOLEAN fgIsAP;
+	UINT_8 aucReserved[2];
+} EVENT_ACTIVATE_STA_REC_T, *P_EVENT_ACTIVATE_STA_REC_T;
+
+typedef struct _EVENT_DEACTIVATE_STA_REC_T {
+	UINT_8 ucStaRecIdx;
+	UINT_8 aucReserved[3];
+} EVENT_DEACTIVATE_STA_REC_T, *P_EVENT_DEACTIVATE_STA_REC_T;
+
+/* CMD_BT_OVER_WIFI */
+typedef struct _CMD_BT_OVER_WIFI {
+	UINT_8 ucAction;	/* 0: query, 1: setup, 2: destroy */
+	UINT_8 ucChannelNum;
+	PARAM_MAC_ADDRESS rPeerAddr;
+	UINT_16 u2BeaconInterval;
+	UINT_8 ucTimeoutDiscovery;
+	UINT_8 ucTimeoutInactivity;
+	UINT_8 ucRole;
+	UINT_8 PAL_Capabilities;
+	UINT_8 cMaxTxPower;
+	UINT_8 ucChannelBand;
+	UINT_8 ucReserved[1];
+} CMD_BT_OVER_WIFI, *P_CMD_BT_OVER_WIFI;
+
+/* EVENT_BT_OVER_WIFI */
+typedef struct _EVENT_BT_OVER_WIFI {
+	UINT_8 ucLinkStatus;
+	UINT_8 ucSelectedChannel;
+	INT_8 cRSSI;
+	UINT_8 ucReserved[1];
+} EVENT_BT_OVER_WIFI, *P_EVENT_BT_OVER_WIFI;
+
+/* Same with DOMAIN_SUBBAND_INFO */
+typedef struct _CMD_SUBBAND_INFO {
+	UINT_8 ucRegClass;
+	UINT_8 ucBand;
+	UINT_8 ucChannelSpan;
+	UINT_8 ucFirstChannelNum;
+	UINT_8 ucNumChannels;
+	UINT_8 aucReserved[3];
+} CMD_SUBBAND_INFO, *P_CMD_SUBBAND_INFO;
+
+/* CMD_SET_DOMAIN_INFO */
+typedef struct _CMD_SET_DOMAIN_INFO_T {
+	UINT_16 u2CountryCode;
+	UINT_16 u2IsSetPassiveScan;	/* 0: set channel domain; 1: set passive scan channel domain */
+	CMD_SUBBAND_INFO rSubBand[6];
+
+	UINT_8 uc2G4Bandwidth;	/* CONFIG_BW_20_40M or CONFIG_BW_20M */
+	UINT_8 uc5GBandwidth;	/* CONFIG_BW_20_40M or CONFIG_BW_20M */
+	UINT_8 aucReserved[2];
+} CMD_SET_DOMAIN_INFO_T, *P_CMD_SET_DOMAIN_INFO_T;
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+
+/* CMD_SET_PWR_LIMIT_TABLE */
+typedef struct _CMD_CHANNEL_POWER_LIMIT {
+	UINT_8 ucCentralCh;
+	INT_8 cPwrLimitCCK;
+	INT_8 cPwrLimit20;
+	INT_8 cPwrLimit40;
+	INT_8 cPwrLimit80;
+	INT_8 cPwrLimit160;
+	UINT_8 ucFlag;
+	UINT_8 aucReserved[1];
+} CMD_CHANNEL_POWER_LIMIT, *P_CMD_CHANNEL_POWER_LIMIT;
+
+typedef struct _CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T {
+	UINT_16 u2CountryCode;
+	UINT_8 ucCountryFlag;
+	UINT_8 ucNum;
+	UINT_8 aucReserved[4];
+	CMD_CHANNEL_POWER_LIMIT rChannelPowerLimit[1];
+} CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T, *P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T;
+
+#endif
+
+/* CMD_SET_IP_ADDRESS */
+typedef struct _IPV4_NETWORK_ADDRESS {
+	UINT_8 aucIpAddr[4];
+} IPV4_NETWORK_ADDRESS, *P_IPV4_NETWORK_ADDRESS;
+
+typedef struct _CMD_SET_NETWORK_ADDRESS_LIST {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucAddressCount;
+	UINT_8 ucReserved[2];
+	IPV4_NETWORK_ADDRESS arNetAddress[1];
+} CMD_SET_NETWORK_ADDRESS_LIST, *P_CMD_SET_NETWORK_ADDRESS_LIST;
+
+typedef struct _PATTERN_DESCRIPTION {
+	UINT_8 fgCheckBcA1;
+	UINT_8 fgCheckMcA1;
+	UINT_8 ePatternHeader;
+	UINT_8 fgAndOp;
+	UINT_8 fgNotOp;
+	UINT_8 ucPatternMask;
+	UINT_16 ucPatternOffset;
+	UINT_8 aucPattern[8];
+} PATTERN_DESCRIPTION, *P_PATTERN_DESCRIPTION;
+
+typedef struct _CMD_RAW_PATTERN_CONFIGURATION_T {
+	PATTERN_DESCRIPTION arPatternDesc[4];
+} CMD_RAW_PATTERN_CONFIGURATION_T, *P_CMD_RAW_PATTERN_CONFIGURATION_T;
+
+typedef struct _CMD_PATTERN_FUNC_CONFIG {
+	BOOLEAN fgBcA1En;
+	BOOLEAN fgMcA1En;
+	BOOLEAN fgBcA1MatchDrop;
+	BOOLEAN fgMcA1MatchDrop;
+} CMD_PATTERN_FUNC_CONFIG, *P_CMD_PATTERN_FUNC_CONFIG;
+
+typedef struct _EVENT_TX_DONE_T {
+	UINT_8 ucPacketSeq;
+	UINT_8 ucStatus;
+	UINT_16 u2SequenceNumber;
+	UINT_32 au4Reserved1;
+	UINT_32 au4Reserved2;
+	UINT_32 au4Reserved3;
+} EVENT_TX_DONE_T, *P_EVENT_TX_DONE_T;
+
+typedef struct _CMD_BSS_ACTIVATE_CTRL {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucActive;
+	UINT_8 aucReserved[2];
+} CMD_BSS_ACTIVATE_CTRL, *P_CMD_BSS_ACTIVATE_CTRL;
+
+typedef struct _CMD_SET_BSS_RLM_PARAM_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucRfBand;
+	UINT_8 ucPrimaryChannel;
+	UINT_8 ucRfSco;
+	UINT_8 ucErpProtectMode;
+	UINT_8 ucHtProtectMode;
+	UINT_8 ucGfOperationMode;
+	UINT_8 ucTxRifsMode;
+	UINT_16 u2HtOpInfo3;
+	UINT_16 u2HtOpInfo2;
+	UINT_8 ucHtOpInfo1;
+	UINT_8 ucUseShortPreamble;
+	UINT_8 ucUseShortSlotTime;
+	UINT_8 ucCheckId;	/* Fixed value: 0x72 */
+} CMD_SET_BSS_RLM_PARAM_T, *P_CMD_SET_BSS_RLM_PARAM_T;
+
+typedef struct _CMD_SET_BSS_INFO {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucConnectionState;
+	UINT_8 ucCurrentOPMode;
+	UINT_8 ucSSIDLen;
+	UINT_8 aucSSID[32];
+	UINT_8 aucBSSID[6];
+	UINT_8 ucIsQBSS;
+	UINT_8 ucReserved1;
+	UINT_16 u2OperationalRateSet;
+	UINT_16 u2BSSBasicRateSet;
+	UINT_8 ucStaRecIdxOfAP;
+	UINT_8 ucReserved2;
+	UINT_8 ucReserved3;
+	UINT_8 ucNonHTBasicPhyType;	/* For Slot Time and CWmin */
+	UINT_8 ucAuthMode;
+	UINT_8 ucEncStatus;
+	UINT_8 ucPhyTypeSet;
+	UINT_8 aucOwnMac[6];
+	UINT_8 fgWapiMode;
+	UINT_8 fgIsApMode;
+	UINT_8 fgHiddenSsidMode;
+	CMD_SET_BSS_RLM_PARAM_T rBssRlmParam;
+} CMD_SET_BSS_INFO, *P_CMD_SET_BSS_INFO;
+
+typedef struct _CMD_UPDATE_STA_RECORD_T {
+	UINT_8 ucIndex;
+	UINT_8 ucStaType;
+	UINT_8 aucMacAddr[MAC_ADDR_LEN];
+	UINT_16 u2AssocId;
+	UINT_16 u2ListenInterval;
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucDesiredPhyTypeSet;
+	UINT_16 u2DesiredNonHTRateSet;
+	UINT_16 u2BSSBasicRateSet;
+	UINT_8 ucIsQoS;
+	UINT_8 ucIsUapsdSupported;
+	UINT_8 ucStaState;
+	UINT_8 ucMcsSet;
+	UINT_8 ucSupMcs32;
+	UINT_8 ucAmpduParam;
+	UINT_16 u2HtCapInfo;
+	UINT_16 u2HtExtendedCap;
+	UINT_32 u4TxBeamformingCap;
+	UINT_8 ucAselCap;
+	UINT_8 ucRCPI;
+	UINT_8 ucNeedResp;
+	UINT_8 ucUapsdAc;	/* b0~3: Trigger enabled, b4~7: Delivery enabled */
+	UINT_8 ucUapsdSp;	/* 0: all, 1: max 2, 2: max 4, 3: max 6 */
+	UINT_8 aucReserved[3];
+	/* TBD */
+} CMD_UPDATE_STA_RECORD_T, *P_CMD_UPDATE_STA_RECORD_T;
+
+typedef struct _CMD_REMOVE_STA_RECORD_T {
+	UINT_8 ucIndex;
+	UINT_8 ucReserved;
+	UINT_8 aucMacAddr[MAC_ADDR_LEN];
+} CMD_REMOVE_STA_RECORD_T, *P_CMD_REMOVE_STA_RECORD_T;
+
+typedef struct _CMD_INDICATE_PM_BSS_CREATED_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucDtimPeriod;
+	UINT_16 u2BeaconInterval;
+	UINT_16 u2AtimWindow;
+	UINT_8 aucReserved[2];
+} CMD_INDICATE_PM_BSS_CREATED, *P_CMD_INDICATE_PM_BSS_CREATED;
+
+typedef struct _CMD_INDICATE_PM_BSS_CONNECTED_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucDtimPeriod;
+	UINT_16 u2AssocId;
+	UINT_16 u2BeaconInterval;
+	UINT_16 u2AtimWindow;
+	UINT_8 fgIsUapsdConnection;
+	UINT_8 ucBmpDeliveryAC;
+	UINT_8 ucBmpTriggerAC;
+	UINT_8 aucReserved[1];
+} CMD_INDICATE_PM_BSS_CONNECTED, *P_CMD_INDICATE_PM_BSS_CONNECTED;
+
+typedef struct _CMD_INDICATE_PM_BSS_ABORT {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 aucReserved[3];
+} CMD_INDICATE_PM_BSS_ABORT, *P_CMD_INDICATE_PM_BSS_ABORT;
+
+typedef struct _CMD_BEACON_TEMPLATE_UPDATE {
+	UINT_8 ucUpdateMethod;	/* 0: update randomly,
+				 * 1: update all,
+				 * 2: delete all (1 and 2 will update directly without search)
+				 */
+	UINT_8 ucNetTypeIndex;
+	UINT_8 aucReserved[2];
+	UINT_16 u2Capability;
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+} CMD_BEACON_TEMPLATE_UPDATE, *P_CMD_BEACON_TEMPLATE_UPDATE;
+
+typedef struct _CMD_SET_WMM_PS_TEST_STRUCT_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 bmfgApsdEnAc;	/* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */
+	UINT_8 ucIsEnterPsAtOnce;	/* enter PS immediately without 5 second guard after connected */
+	UINT_8 ucIsDisableUcTrigger;	/* not to trigger UC on beacon TIM is matched (under U-APSD) */
+} CMD_SET_WMM_PS_TEST_STRUCT_T, *P_CMD_SET_WMM_PS_TEST_STRUCT_T;
+
+/* Definition for CHANNEL_INFO.ucBand:
+ * 0:       Reserved
+ * 1:       BAND_2G4
+ * 2:       BAND_5G
+ * Others:  Reserved
+ */
+typedef struct _CHANNEL_INFO_T {
+	UINT_8 ucBand;
+	UINT_8 ucChannelNum;
+} CHANNEL_INFO_T, *P_CHANNEL_INFO_T;
+
+typedef struct _CMD_SCAN_REQ_EXT_CH_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetworkType;
+	UINT_8 ucScanType;
+	UINT_8 ucSSIDType;	/* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */
+	UINT_8 ucSSIDLength;
+	UINT_8 aucReserved[1];
+	UINT_16 u2ChannelMinDwellTime;
+	UINT_8 aucSSID[32];
+	UINT_16 u2ChannelDwellTime;	/* For P2P */
+	UINT_8 ucChannelType;
+	UINT_8 ucChannelListNum;
+	CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST];
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+} CMD_SCAN_REQ_EXT_CH, *P_CMD_SCAN_REQ_EXT_CH;
+
+typedef struct _CMD_SCAN_REQ_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetworkType;
+	UINT_8 ucScanType;
+	UINT_8 ucSSIDType;	/* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */
+	UINT_8 ucSSIDLength;
+	UINT_8 aucReserved[1];
+	UINT_16 u2ChannelMinDwellTime;
+	UINT_8 aucSSID[32];
+	UINT_16 u2ChannelDwellTime;	/* For P2P */
+	UINT_8 ucChannelType;
+	UINT_8 ucChannelListNum;
+	CHANNEL_INFO_T arChannelList[32];
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+} CMD_SCAN_REQ, *P_CMD_SCAN_REQ;
+
+typedef struct _CMD_SCAN_REQ_V2_EXT_CH_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetworkType;
+	UINT_8 ucScanType;
+	UINT_8 ucSSIDType;
+	PARAM_SSID_T arSSID[4];
+	UINT_16 u2ProbeDelayTime;
+	UINT_16 u2ChannelDwellTime;	/* For P2P */
+	UINT_8 ucChannelType;
+	UINT_8 ucChannelListNum;
+	CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST];
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+} CMD_SCAN_REQ_V2_EXT_CH, *P_CMD_SCAN_REQ_V2_EXT_CH;
+
+typedef struct _CMD_SCAN_REQ_V2_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetworkType;
+	UINT_8 ucScanType;
+	UINT_8 ucSSIDType;
+	PARAM_SSID_T arSSID[4];
+	UINT_16 u2ProbeDelayTime;
+	UINT_16 u2ChannelDwellTime;	/* For P2P */
+	UINT_8 ucChannelType;
+	UINT_8 ucChannelListNum;
+	CHANNEL_INFO_T arChannelList[32];
+	UINT_16 u2IELen;
+	UINT_8 aucIE[MAX_IE_LENGTH];
+} CMD_SCAN_REQ_V2, *P_CMD_SCAN_REQ_V2;
+
+typedef struct _CMD_SCAN_CANCEL_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucIsExtChannel;	/* For P2P channel extension. */
+	UINT_8 aucReserved[2];
+} CMD_SCAN_CANCEL, *P_CMD_SCAN_CANCEL;
+
+typedef struct _EVENT_SCAN_DONE_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucSparseChannelValid;
+	CHANNEL_INFO_T rSparseChannel;
+} EVENT_SCAN_DONE, *P_EVENT_SCAN_DONE;
+
+#if CFG_SUPPORT_GET_CH_ENV
+typedef struct _CH_ENV_T {
+	UINT_8 ucChNum;
+	UINT_8 ucApNum;
+} CH_ENV_T, *P_CH_ENV_T;
+#endif
+
+#if 0				/* CFG_SUPPORT_BATCH_SCAN */
+typedef struct _CMD_BATCH_REQ_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucCmd;		/* Start/ Stop */
+	UINT_8 ucMScan;		/* an integer number of scans per batch */
+	UINT_8 ucBestn;		/* an integer number of the max AP to remember per scan */
+	UINT_8 ucRtt;		/* an integer number of highest-strength AP for which we'd
+				   like approximate distance reported */
+	UINT_8 ucChannel;	/* channels */
+	UINT_8 ucChannelType;
+	UINT_8 ucChannelListNum;
+	UINT_8 aucReserved[3];
+	UINT_32 u4Scanfreq;	/* an integer number of seconds between scans */
+	CHANNEL_INFO_T arChannelList[32];	/* channels */
+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T;
+
+typedef struct _EVENT_BATCH_RESULT_ENTRY_T {
+	UINT_8 aucBssid[MAC_ADDR_LEN];
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];
+	UINT_8 ucSSIDLen;
+	INT_8 cRssi;
+	UINT_32 ucFreq;
+	UINT_32 u4Age;
+	UINT_32 u4Dist;
+	UINT_32 u4Distsd;
+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T;
+
+typedef struct _EVENT_BATCH_RESULT_T {
+	UINT_8 ucScanCount;
+	UINT_8 aucReserved[3];
+	EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12];	/* Must be the same with SCN_BATCH_STORE_MAX_NUM */
+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T;
+#endif
+
+typedef struct _CMD_CH_PRIVILEGE_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucTokenID;
+	UINT_8 ucAction;
+	UINT_8 ucPrimaryChannel;
+	UINT_8 ucRfSco;
+	UINT_8 ucRfBand;
+	UINT_8 ucReqType;
+	UINT_8 ucReserved;
+	UINT_32 u4MaxInterval;	/* In unit of ms */
+	UINT_8 aucBSSID[6];
+	UINT_8 aucReserved[2];
+} CMD_CH_PRIVILEGE_T, *P_CMD_CH_PRIVILEGE_T;
+
+typedef struct _CMD_TX_PWR_T {
+	INT_8 cTxPwr2G4Cck;	/* signed, in unit of 0.5dBm */
+#if defined(MT6620)
+	INT_8 acReserved[3];
+#elif defined(MT6628)
+	INT_8 cTxPwr2G4Dsss;	/* signed, in unit of 0.5dBm */
+	INT_8 acReserved[2];
+#else
+#error "No valid definition!"
+#endif
+
+	INT_8 cTxPwr2G4OFDM_BPSK;
+	INT_8 cTxPwr2G4OFDM_QPSK;
+	INT_8 cTxPwr2G4OFDM_16QAM;
+	INT_8 cTxPwr2G4OFDM_Reserved;
+	INT_8 cTxPwr2G4OFDM_48Mbps;
+	INT_8 cTxPwr2G4OFDM_54Mbps;
+
+	INT_8 cTxPwr2G4HT20_BPSK;
+	INT_8 cTxPwr2G4HT20_QPSK;
+	INT_8 cTxPwr2G4HT20_16QAM;
+	INT_8 cTxPwr2G4HT20_MCS5;
+	INT_8 cTxPwr2G4HT20_MCS6;
+	INT_8 cTxPwr2G4HT20_MCS7;
+
+	INT_8 cTxPwr2G4HT40_BPSK;
+	INT_8 cTxPwr2G4HT40_QPSK;
+	INT_8 cTxPwr2G4HT40_16QAM;
+	INT_8 cTxPwr2G4HT40_MCS5;
+	INT_8 cTxPwr2G4HT40_MCS6;
+	INT_8 cTxPwr2G4HT40_MCS7;
+
+	INT_8 cTxPwr5GOFDM_BPSK;
+	INT_8 cTxPwr5GOFDM_QPSK;
+	INT_8 cTxPwr5GOFDM_16QAM;
+	INT_8 cTxPwr5GOFDM_Reserved;
+	INT_8 cTxPwr5GOFDM_48Mbps;
+	INT_8 cTxPwr5GOFDM_54Mbps;
+
+	INT_8 cTxPwr5GHT20_BPSK;
+	INT_8 cTxPwr5GHT20_QPSK;
+	INT_8 cTxPwr5GHT20_16QAM;
+	INT_8 cTxPwr5GHT20_MCS5;
+	INT_8 cTxPwr5GHT20_MCS6;
+	INT_8 cTxPwr5GHT20_MCS7;
+
+	INT_8 cTxPwr5GHT40_BPSK;
+	INT_8 cTxPwr5GHT40_QPSK;
+	INT_8 cTxPwr5GHT40_16QAM;
+	INT_8 cTxPwr5GHT40_MCS5;
+	INT_8 cTxPwr5GHT40_MCS6;
+	INT_8 cTxPwr5GHT40_MCS7;
+} CMD_TX_PWR_T, *P_CMD_TX_PWR_T;
+
+typedef struct _CMD_5G_PWR_OFFSET_T {
+	INT_8 cOffsetBand0;	/* 4.915-4.980G */
+	INT_8 cOffsetBand1;	/* 5.000-5.080G */
+	INT_8 cOffsetBand2;	/* 5.160-5.180G */
+	INT_8 cOffsetBand3;	/* 5.200-5.280G */
+	INT_8 cOffsetBand4;	/* 5.300-5.340G */
+	INT_8 cOffsetBand5;	/* 5.500-5.580G */
+	INT_8 cOffsetBand6;	/* 5.600-5.680G */
+	INT_8 cOffsetBand7;	/* 5.700-5.825G */
+} CMD_5G_PWR_OFFSET_T, *P_CMD_5G_PWR_OFFSET_T;
+
+typedef struct _CMD_PWR_PARAM_T {
+	UINT_32 au4Data[28];
+	UINT_32 u4RefValue1;
+	UINT_32 u4RefValue2;
+} CMD_PWR_PARAM_T, *P_CMD_PWR_PARAM_T;
+
+typedef struct _CMD_PHY_PARAM_T {
+	UINT_8 aucData[144];	/* eFuse content */
+} CMD_PHY_PARAM_T, *P_CMD_PHY_PARAM_T;
+
+typedef struct _CMD_AUTO_POWER_PARAM_T {
+	UINT_8 ucType;		/* 0: Disable 1: Enalbe 0x10: Change parameters */
+	UINT_8 ucNetTypeIndex;
+	UINT_8 aucReserved[2];
+	UINT_8 aucLevelRcpiTh[3];
+	UINT_8 aucReserved2[1];
+	INT_8 aicLevelPowerOffset[3];	/* signed, in unit of 0.5dBm */
+	UINT_8 aucReserved3[1];
+	UINT_8 aucReserved4[8];
+} CMD_AUTO_POWER_PARAM_T, *P_CMD_AUTO_POWER_PARAM_T;
+
+typedef struct _EVENT_CH_PRIVILEGE_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucTokenID;
+	UINT_8 ucStatus;
+	UINT_8 ucPrimaryChannel;
+	UINT_8 ucRfSco;
+	UINT_8 ucRfBand;
+	UINT_8 ucReqType;
+	UINT_8 ucReserved;
+	UINT_32 u4GrantInterval;	/* In unit of ms */
+} EVENT_CH_PRIVILEGE_T, *P_EVENT_CH_PRIVILEGE_T;
+
+typedef enum _ENUM_BEACON_TIMEOUT_TYPE_T {
+	BEACON_TIMEOUT_LOST_BEACON = 0,
+	BEACON_TIMEOUT_AGE,
+	BEACON_TIMEOUT_CONNECT,
+	BEACON_TIMEOUT_BEACON_INTERVAL,
+	BEACON_TIMEOUT_ABORT,
+	BEACON_TIMEOUT_TX_ERROR,
+	BEACON_TIMEOUT_TYPE_NUM
+} ENUM_BEACON_TIMEOUT_TYPE_T, *P_ENUM_BEACON_TIMEOUT_TYPE_T;
+
+typedef struct _EVENT_BSS_BEACON_TIMEOUT_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucReason;	/* ENUM_BEACON_TIMEOUT_TYPE_T */
+	UINT_8 aucReserved[2];
+} EVENT_BSS_BEACON_TIMEOUT_T, *P_EVENT_BSS_BEACON_TIMEOUT_T;
+
+typedef struct _EVENT_STA_AGING_TIMEOUT_T {
+	UINT_8 ucStaRecIdx;
+	UINT_8 aucReserved[3];
+} EVENT_STA_AGING_TIMEOUT_T, *P_EVENT_STA_AGING_TIMEOUT_T;
+
+typedef struct _EVENT_NOA_TIMING_T {
+	UINT_8 fgIsInUse;	/* Indicate if this entry is in use or not */
+	UINT_8 ucCount;		/* Count */
+	UINT_8 aucReserved[2];
+
+	UINT_32 u4Duration;	/* Duration */
+	UINT_32 u4Interval;	/* Interval */
+	UINT_32 u4StartTime;	/* Start Time */
+} EVENT_NOA_TIMING_T, *P_EVENT_NOA_TIMING_T;
+
+typedef struct _EVENT_UPDATE_NOA_PARAMS_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 aucReserved[2];
+	UINT_8 fgEnableOppPS;
+	UINT_16 u2CTWindow;
+
+	UINT_8 ucNoAIndex;
+	UINT_8 ucNoATimingCount;	/* Number of NoA Timing */
+	EVENT_NOA_TIMING_T arEventNoaTiming[8 /*P2P_MAXIMUM_NOA_COUNT */];
+} EVENT_UPDATE_NOA_PARAMS_T, *P_EVENT_UPDATE_NOA_PARAMS_T;
+
+typedef struct _EVENT_AP_OBSS_STATUS_T {
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucObssErpProtectMode;
+	UINT_8 ucObssHtProtectMode;
+	UINT_8 ucObssGfOperationMode;
+	UINT_8 ucObssRifsOperationMode;
+	UINT_8 ucObssBeaconForcedTo20M;
+	UINT_8 aucReserved[2];
+} EVENT_AP_OBSS_STATUS_T, *P_EVENT_AP_OBSS_STATUS_T;
+
+typedef struct _CMD_EDGE_TXPWR_LIMIT_T {
+	INT_8 cBandEdgeMaxPwrCCK;
+	INT_8 cBandEdgeMaxPwrOFDM20;
+	INT_8 cBandEdgeMaxPwrOFDM40;
+	INT_8 cReserved;
+} CMD_EDGE_TXPWR_LIMIT_T, *P_CMD_EDGE_TXPWR_LIMIT_T;
+
+typedef struct _CMD_RSSI_COMPENSATE_T {
+	UINT_8 uc2GRssiCompensation;
+	UINT_8 uc5GRssiCompensation;
+	UINT_8 ucRssiCompensationValidbit;
+	UINT_8 cReserved;
+} CMD_RSSI_COMPENSATE_T, *P_CMD_RSSI_COMPENSATE_T;
+
+typedef struct _CMD_BAND_SUPPORT_T {
+	UINT_8 uc5GBandSupport;
+	UINT_8 cReserved[3];
+} CMD_BAND_SUPPORT_T, *P_CMD_BAND_SUPPORT_T;
+
+typedef struct _CMD_TX_PWR_CE_T {
+	INT_8 cTxPwrCckLmt;	/* signed, in unit of 0.5dBm */
+	INT_8 cTxPwrOfdmLmt;	/* signed, in unit of 0.5dBm */
+	INT_8 cTxPwrHt20Lmt;
+	INT_8 cTxPwrHt40Lmt;
+} CMD_TX_PWR_CE_T, *P_CMD_TX_PWR_CE_T;
+
+typedef struct _CMD_SET_DEVICE_MODE_T {
+	UINT_16 u2ChipID;
+	UINT_16 u2Mode;
+} CMD_SET_DEVICE_MODE_T, *P_CMD_SET_DEVICE_MODE_T;
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+typedef struct _CMD_RDD_CH_T {
+	UINT_8 ucRddTestMode;
+	UINT_8 ucRddShutCh;
+	UINT_8 ucRddStartCh;
+	UINT_8 ucRddStopCh;
+	UINT_8 ucRddDfs;
+	UINT_8 ucReserved;
+	UINT_8 ucReserved1;
+	UINT_8 ucReserved2;
+} CMD_RDD_CH_T, *P_CMD_RDD_CH_T;
+
+typedef struct _EVENT_RDD_STATUS_T {
+	UINT_8 ucRddStatus;
+	UINT_8 aucReserved[3];
+} EVENT_RDD_STATUS_T, *P_EVENT_RDD_STATUS_T;
+#endif
+
+typedef struct _EVENT_AIS_BSS_INFO_T {
+	ENUM_PARAM_MEDIA_STATE_T eConnectionState;	/* Connected Flag used in AIS_NORMAL_TR */
+	ENUM_OP_MODE_T eCurrentOPMode;	/* Current Operation Mode - Infra/IBSS */
+	BOOLEAN fgIsNetActive;	/* TRUE if this network has been actived */
+	UINT_8 ucReserved[3];
+} EVENT_AIS_BSS_INFO_T, *P_EVENT_AIS_BSS_INFO_T;
+
+typedef struct _CMD_SET_TXPWR_CTRL_T {
+	INT_8 c2GLegacyStaPwrOffset;	/* Unit: 0.5dBm, default: 0 */
+	INT_8 c2GHotspotPwrOffset;
+	INT_8 c2GP2pPwrOffset;
+	INT_8 c2GBowPwrOffset;
+	INT_8 c5GLegacyStaPwrOffset;	/* Unit: 0.5dBm, default: 0 */
+	INT_8 c5GHotspotPwrOffset;
+	INT_8 c5GP2pPwrOffset;
+	INT_8 c5GBowPwrOffset;
+	UINT_8 ucConcurrencePolicy;	/* TX power policy when concurrence
+					   in the same channel
+					   0: Highest power has priority
+					   1: Lowest power has priority */
+	INT_8 acReserved1[3];	/* Must be zero */
+
+	/* Power limit by channel for all data rates */
+	INT_8 acTxPwrLimit2G[14];	/* Channel 1~14, Unit: 0.5dBm */
+	INT_8 acTxPwrLimit5G[4];	/* UNII 1~4 */
+	INT_8 acReserved2[2];	/* Must be zero */
+} CMD_SET_TXPWR_CTRL_T, *P_CMD_SET_TXPWR_CTRL_T;
+
+#if CFG_SUPPORT_BUILD_DATE_CODE
+typedef struct _CMD_GET_BUILD_DATE_CODE {
+	UINT_8 aucReserved[4];
+} CMD_GET_BUILD_DATE_CODE, *P_CMD_GET_BUILD_DATE_CODE;
+
+typedef struct _EVENT_BUILD_DATE_CODE {
+	UINT_8 aucDateCode[16];
+} EVENT_BUILD_DATE_CODE, *P_EVENT_BUILD_DATE_CODE;
+#endif
+
+typedef struct _CMD_GET_STA_STATISTICS_T {
+	UINT_8 ucIndex;
+	UINT_8 ucFlags;
+	UINT_8 ucReadClear;
+	UINT_8 aucReserved0[1];
+	UINT_8 aucMacAddr[MAC_ADDR_LEN];
+	UINT_8 aucReserved1[2];
+	UINT_8 aucReserved2[16];
+} CMD_GET_STA_STATISTICS_T, *P_CMD_GET_STA_STATISTICS_T;
+
+/* CFG_SUPPORT_WFD */
+typedef struct _EVENT_STA_STATISTICS_T {
+	/* Event header */
+	/* UINT_16     u2Length; */
+	/* UINT_16     u2Reserved1; *//* Must be filled with 0x0001 (EVENT Packet) */
+	/* UINT_8            ucEID; */
+	/* UINT_8      ucSeqNum; */
+	/* UINT_8            aucReserved2[2]; */
+
+	/* Event Body */
+	UINT_8 ucVersion;
+	UINT_8 aucReserved1[3];
+	UINT_32 u4Flags;	/* Bit0: valid */
+
+	UINT_8 ucStaRecIdx;
+	UINT_8 ucNetworkTypeIndex;
+	UINT_8 ucWTEntry;
+	UINT_8 aucReserved4[1];
+
+	UINT_8 ucMacAddr[MAC_ADDR_LEN];
+	UINT_8 ucPer;		/* base: 128 */
+	UINT_8 ucRcpi;
+
+	UINT_32 u4PhyMode;	/* SGI BW */
+	UINT_16 u2LinkSpeed;	/* unit is 0.5 Mbits */
+	UINT_8 ucLinkQuality;
+	UINT_8 ucLinkReserved;
+
+	UINT_32 u4TxCount;
+	UINT_32 u4TxFailCount;
+	UINT_32 u4TxLifeTimeoutCount;
+	UINT_32 u4TxDoneAirTime;
+
+	UINT_8 aucReserved[64];
+} EVENT_STA_STATISTICS_T, *P_EVENT_STA_STATISTICS_T;
+
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+typedef struct _CMD_HOTSPOT_OPTIMIZATION_CONFIG {
+	UINT_32 fgHotspotOptimizationEn;
+	UINT_32 u4Level;
+} CMD_HOTSPOT_OPTIMIZATION_CONFIG, *P_HOTSPOT_OPTIMIZATION_CONFIG;
+#endif
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+
+/* 4 Auto Channel Selection */
+
+typedef struct _CMD_GET_CHN_LOAD_T {
+	UINT_8 ucIndex;
+	UINT_8 ucFlags;
+	UINT_8 ucReadClear;
+	UINT_8 aucReserved0[1];
+
+	UINT_8 ucChannel;
+	UINT_16 u2ChannelLoad;
+	UINT_8 aucReserved1[1];
+	UINT_8 aucReserved2[16];
+} CMD_GET_CHN_LOAD_T, *P_CMD_GET_CHN_LOAD_T;
+/* 4  Auto Channel Selection */
+
+typedef struct _EVENT_CHN_LOAD_T {
+	/* Event Body */
+	UINT_8 ucVersion;
+	UINT_8 aucReserved1[3];
+	UINT_32 u4Flags;	/* Bit0: valid */
+
+	UINT_8 ucChannel;
+	UINT_16 u2ChannelLoad;
+	UINT_8 aucReserved4[1];
+
+	UINT_8 aucReserved[64];
+
+} EVENT_CHN_LOAD_T, *P_EVENT_CHN_LOAD_T;
+typedef struct _CMD_GET_LTE_SAFE_CHN_T {
+	UINT_8 ucIndex;
+	UINT_8 ucFlags;
+	UINT_8 aucReserved0[2];
+
+	UINT_8 aucReserved2[16];
+} CMD_GET_LTE_SAFE_CHN_T, *P_CMD_GET_LTE_SAFE_CHN_T;
+
+typedef struct _EVENT_LTE_MODE_T {
+	/* Event Body */
+	UINT_8 ucVersion;
+	UINT_8 aucReserved1[3];
+	UINT_32 u4Flags;	/* Bit0: valid */
+
+	LTE_SAFE_CH_INFO_T rLteSafeChn;
+	UINT_8 aucReserved4[3];
+
+	UINT_8 aucReserved[4];
+
+} EVENT_LTE_MODE_T, *P_EVENT_LTE_MODE_T;
+#endif
+typedef struct _CMD_ROAMING_INFO_T {
+	UINT_32 fgIsFastRoamingApplied;
+	UINT_32 Reserved[9];
+} CMD_ROAMING_INFO_T;
+
+typedef struct _CMD_WFD_DEBUG_MODE_INFO_T {
+	UINT_8 ucDebugMode;
+	UINT_16 u2PeriodInteval;
+	UINT_8 Reserved;
+} CMD_WFD_DEBUG_MODE_INFO_T, *P_CMD_WFD_DEBUG_MODE_INFO_T;
+
+typedef struct _EVENT_FW_LOG_T {
+	UINT_8 fileName[64];
+	UINT_32 lineNo;
+	UINT_32 WifiUpTime;
+	UINT_8 log[896];	/* total size is aucBuffer in WIFI_EVENT_T */
+} EVENT_FW_LOG_T, *P_EVENT_FW_LOG_T;
+
+typedef enum _ENUM_NLO_CIPHER_ALGORITHM {
+	NLO_CIPHER_ALGO_NONE = 0x00,
+	NLO_CIPHER_ALGO_WEP40 = 0x01,
+	NLO_CIPHER_ALGO_TKIP = 0x02,
+	NLO_CIPHER_ALGO_CCMP = 0x04,
+	NLO_CIPHER_ALGO_WEP104 = 0x05,
+	NLO_CIPHER_ALGO_WPA_USE_GROUP = 0x100,
+	NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100,
+	NLO_CIPHER_ALGO_WEP = 0x101,
+} ENUM_NLO_CIPHER_ALGORITHM, *P_ENUM_NLO_CIPHER_ALGORITHM;
+
+typedef enum _ENUM_NLO_AUTH_ALGORITHM {
+	NLO_AUTH_ALGO_80211_OPEN = 1,
+	NLO_AUTH_ALGO_80211_SHARED_KEY = 2,
+	NLO_AUTH_ALGO_WPA = 3,
+	NLO_AUTH_ALGO_WPA_PSK = 4,
+	NLO_AUTH_ALGO_WPA_NONE = 5,
+	NLO_AUTH_ALGO_RSNA = 6,
+	NLO_AUTH_ALGO_RSNA_PSK = 7,
+} ENUM_NLO_AUTH_ALGORITHM, *P_ENUM_NLO_AUTH_ALGORITHM;
+
+typedef struct _NLO_NETWORK {
+	UINT_8 ucNumChannelHint[4];
+	UINT_8 ucSSIDLength;
+	UINT_8 ucCipherAlgo;
+	UINT_16 u2AuthAlgo;
+	UINT_8 aucSSID[32];
+} NLO_NETWORK, *P_NLO_NETWORK;
+
+typedef struct _CMD_NLO_REQ {
+	UINT_8 ucSeqNum;
+	UINT_8 ucBssIndex;
+	UINT_8 ucNetworkType;
+	UINT_8 fgStopAfterIndication;
+	UINT_8 ucFastScanIteration;
+	UINT_16 u2FastScanPeriod;
+	UINT_16 u2SlowScanPeriod;
+	UINT_8 ucEntryNum;
+	UINT_8 ucReserved;
+	UINT_16 u2IELen;
+	NLO_NETWORK arNetworkList[16];
+	UINT_8 aucIE[0];
+	UINT_8 ucScanType;
+} CMD_NLO_REQ, *P_CMD_NLO_REQ;
+
+typedef struct _CMD_NLO_CANCEL_T {
+	UINT_8 ucSeqNum;
+	UINT_8 aucReserved[3];
+} CMD_NLO_CANCEL, *P_CMD_NLO_CANCEL;
+
+typedef struct _EVENT_NLO_DONE_T {
+	UINT_8      ucSeqNum;
+	UINT_8      ucStatus;
+	UINT_8      aucReserved[2];
+} EVENT_NLO_DONE_T, *P_EVENT_NLO_DONE_T;
+
+typedef struct _EVENT_GSCAN_CAPABILITY_T {
+	UINT_8 ucVersion;
+	UINT_8 aucReserved1[3];
+	UINT_32 u4MaxScanCacheSize;
+	UINT_32 u4MaxScanBuckets;
+	UINT_32 u4MaxApCachePerScan;
+	UINT_32 u4MaxRssiSampleSize;
+	UINT_32 u4MaxScanReportingThreshold;
+	UINT_32 u4MaxHotlistAps;
+	UINT_32 u4MaxSignificantWifiChangeAps;
+	UINT_32 au4Reserved[4];
+} EVENT_GSCAN_CAPABILITY_T, *P_EVENT_GSCAN_CAPABILITY_T;
+
+typedef struct _EVENT_GSCAN_SCAN_AVAILABLE_T {
+	UINT_16 u2Num;
+	UINT_8 aucReserved[2];
+} EVENT_GSCAN_SCAN_AVAILABLE_T, *P_EVENT_GSCAN_SCAN_AVAILABLE_T;
+
+typedef struct _EVENT_GSCAN_SCAN_COMPLETE_T {
+	UINT_8 ucScanState;
+	UINT_8 aucReserved[3];
+} EVENT_GSCAN_SCAN_COMPLETE_T, *P_EVENT_GSCAN_SCAN_COMPLETE_T;
+
+typedef struct WIFI_GSCAN_RESULT {
+	UINT_64 u8Ts;		/* Time of discovery           */
+	UINT_8 arSsid[ELEM_MAX_LEN_SSID + 1];	/* null terminated             */
+	UINT_8 arMacAddr[6];	/* BSSID                       */
+	UINT_32 u4Channel;	/* channel frequency in MHz    */
+	INT_32 i4Rssi;		/* in db                       */
+	UINT_64 u8Rtt;		/* in nanoseconds              */
+	UINT_64 u8RttSd;	/* standard deviation in rtt   */
+	UINT_16 u2BeaconPeriod;	/* units are Kusec             */
+	UINT_16 u2Capability;	/* Capability information      */
+	UINT_32 u4IeLength;	/* byte length of Information Elements */
+	UINT_8 ucIeData[1];	/* IE data to follow           */
+} WIFI_GSCAN_RESULT_T, *P_WIFI_GSCAN_RESULT_T;
+
+typedef struct _EVENT_GSCAN_RESULT_T {
+	UINT_8 ucVersion;
+	UINT_8 aucReserved[3];
+	UINT_16 u2ScanId;
+	UINT_16 u2ScanFlags;
+	UINT_16 u2NumOfResults;
+	WIFI_GSCAN_RESULT_T rResult[1];
+} EVENT_GSCAN_RESULT_T, *P_EVENT_GSCAN_RESULT_T;
+
+typedef struct _EVENT_GSCAN_FULL_RESULT_T {
+	UINT_8 ucVersion;
+	UINT_8 aucReserved[3];
+	WIFI_GSCAN_RESULT_T rResult;
+} EVENT_GSCAN_FULL_RESULT_T, *P_EVENT_GSCAN_FULL_RESULT_T;
+
+typedef struct GSCAN_SWC_NET {
+	UINT_16 u2Flags;
+	UINT_16 u2Channel;
+	UINT_8 arBssid[6];
+	INT_8 aicRssi[SCN_PSCAN_SWC_RSSI_WIN_MAX];
+} GSCAN_SWC_NET_T, P_GSCAN_SWC_NET_T;
+
+typedef struct _EVENT_GSCAN_SIGNIFICANT_CHANGE_T {
+	UINT_8 ucVersion;
+	UINT_8 aucReserved[3];
+	GSCAN_SWC_NET_T arNet[SCN_PSCAN_SWC_MAX_NUM];
+} EVENT_GSCAN_SIGNIFICANT_CHANGE_T, *P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T;
+
+typedef struct _EVENT_GSCAN_GEOFENCE_FOUND_T {
+	UINT_8 ucVersion;
+	UINT_8 aucReserved[3];
+	WIFI_GSCAN_RESULT_T rResult[SCN_PSCAN_HOTLIST_REPORT_MAX_NUM];
+} EVENT_GSCAN_GEOFENCE_FOUND_T, *P_EVENT_GSCAN_GEOFENCE_FOUND_T;
+
+#if CFG_SUPPORT_BATCH_SCAN
+
+#if 0				/* !CFG_SUPPORT_GSCN */
+typedef struct _CMD_BATCH_REQ_T {
+	UINT_8 ucSeqNum;
+	UINT_8 ucNetTypeIndex;
+	UINT_8 ucCmd;		/* Start/ Stop */
+	UINT_8 ucMScan;		/* an integer number of scans per batch */
+	UINT_8 ucBestn;		/* an integer number of the max AP to remember per scan */
+	UINT_8 ucRtt;		/* an integer number of highest-strength AP for which
+				   we'd like approximate distance reported */
+	UINT_8 ucChannel;	/* channels */
+	UINT_8 ucChannelType;
+	UINT_8 ucChannelListNum;
+	UINT_8 aucReserved[3];
+	UINT_32 u4Scanfreq;	/* an integer number of seconds between scans */
+	CHANNEL_INFO_T arChannelList[32];	/* channels */
+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T;
+
+#endif
+
+typedef struct _EVENT_BATCH_RESULT_ENTRY_T {
+	UINT_8 aucBssid[MAC_ADDR_LEN];
+	UINT_8 aucSSID[ELEM_MAX_LEN_SSID];
+	UINT_8 ucSSIDLen;
+	INT_8 cRssi;
+	UINT_32 ucFreq;
+	UINT_32 u4Age;
+	UINT_32 u4Dist;
+	UINT_32 u4Distsd;
+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T;
+
+typedef struct _EVENT_BATCH_RESULT_T {
+	UINT_8 ucScanCount;
+	UINT_8 aucReserved[3];
+	EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12];	/* Must be the same with SCN_BATCH_STORE_MAX_NUM */
+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T;
+#endif
+
+typedef struct _CMD_RLM_INFO_T {
+	UINT_32 u4Version;
+	UINT_32 fgIsErrRatioEnhanceApplied;
+	UINT_8 ucErrRatio2LimitMinRate;
+	/*
+	   0:1M, 1:2M, 2:5.5M, 3:11M, 6:6M, 7:9M, 8:12M, 9:18M, 10:24M, 11:36M, 12:48M, 13:54M
+	 */
+	UINT_8 ucMinLegacyRateIdx;
+	INT_8 cMinRssiThreshold;
+	BOOLEAN fgIsRtsApplied;
+	UINT_8 ucRecoverTime;
+
+	UINT_32 u4Reserved[0];
+} CMD_RLM_INFO_T;
+
+typedef struct _WIFI_SYSTEM_SUSPEND_CMD_T {
+	BOOLEAN fgIsSystemSuspend;
+	UINT_8 reserved[3];
+} WIFI_SYSTEM_SUSPEND_CMD_T, *P_WIFI_SYSTEM_SUSPEND_CMD_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+/* Statistics responder */
+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+/* for timeout check */
+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+#if CFG_SUPPORT_BUILD_DATE_CODE
+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+#endif
+
+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+/* 4 Auto Channel Selection */
+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+#endif
+
+#if CFG_SUPPORT_BATCH_SCAN
+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+#endif
+
+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _NIC_CMD_EVENT_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h
new file mode 100644
index 0000000000000..994c589190dee
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h
@@ -0,0 +1,177 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_init_cmd_event.h#1
+*/
+
+/*! \file   "nic_init_cmd_event.h"
+    \brief This file contains the declairation file of the WLAN initialization routines
+	   for MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: nic_init_cmd_event.h
+ *
+ * 09 26 2011 cp.wu
+ * [WCXRP00001011] [MT6628 Wi-Fi] Firmware Download Agent: make CRC validation as an optional feature
+ * add definition for disabling CRC32 validation (for MT6628 only)
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add two option for ACK and ENCRYPTION for firmware download
+ *
+ * 03 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add command/event definitions for initial states
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement host-side firmware download logic
+ *
+ * 02 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * prepare for implementing fw download logic
+ *
+*/
+#ifndef _NIC_INIT_CMD_EVENT_H
+#define _NIC_INIT_CMD_EVENT_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "gl_typedef.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define INIT_CMD_STATUS_SUCCESS                 0
+#define INIT_CMD_STATUS_REJECTED_INVALID_PARAMS 1
+#define INIT_CMD_STATUS_REJECTED_CRC_ERROR      2
+#define INIT_CMD_STATUS_REJECTED_DECRYPT_FAIL   3
+#define INIT_CMD_STATUS_UNKNOWN                 4
+
+#define EVENT_HDR_SIZE          OFFSET_OF(WIFI_EVENT_T, aucBuffer[0])
+
+typedef enum _ENUM_INIT_CMD_ID {
+	INIT_CMD_ID_DOWNLOAD_BUF = 1,
+	INIT_CMD_ID_WIFI_START,
+	INIT_CMD_ID_ACCESS_REG,
+	INIT_CMD_ID_QUERY_PENDING_ERROR
+} ENUM_INIT_CMD_ID, *P_ENUM_INIT_CMD_ID;
+
+typedef enum _ENUM_INIT_EVENT_ID {
+	INIT_EVENT_ID_CMD_RESULT = 1,
+	INIT_EVENT_ID_ACCESS_REG,
+	INIT_EVENT_ID_PENDING_ERROR
+} ENUM_INIT_EVENT_ID, *P_ENUM_INIT_EVENT_ID;
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef UINT_8 CMD_STATUS;
+
+/* commands */
+typedef struct _INIT_WIFI_CMD_T {
+	UINT_8 ucCID;
+	UINT_8 ucSeqNum;
+	UINT_16 u2Reserved;
+	UINT_8 aucBuffer[0];
+} INIT_WIFI_CMD_T, *P_INIT_WIFI_CMD_T;
+
+typedef struct _INIT_HIF_TX_HEADER_T {
+	UINT_16 u2TxByteCount;
+	UINT_8 ucEtherTypeOffset;
+	UINT_8 ucCSflags;
+	INIT_WIFI_CMD_T rInitWifiCmd;
+} INIT_HIF_TX_HEADER_T, *P_INIT_HIF_TX_HEADER_T;
+
+#define DOWNLOAD_BUF_ENCRYPTION_MODE    BIT(0)
+#define DOWNLOAD_BUF_NO_CRC_CHECKING    BIT(30)
+#define DOWNLOAD_BUF_ACK_OPTION         BIT(31)
+typedef struct _INIT_CMD_DOWNLOAD_BUF {
+	UINT_32 u4Address;
+	UINT_32 u4Length;
+	UINT_32 u4CRC32;
+	UINT_32 u4DataMode;
+	UINT_8 aucBuffer[0];
+} INIT_CMD_DOWNLOAD_BUF, *P_INIT_CMD_DOWNLOAD_BUF;
+
+typedef struct _INIT_CMD_WIFI_START {
+	UINT_32 u4Override;
+	UINT_32 u4Address;
+} INIT_CMD_WIFI_START, *P_INIT_CMD_WIFI_START;
+
+typedef struct _INIT_CMD_ACCESS_REG {
+	UINT_8 ucSetQuery;
+	UINT_8 aucReserved[3];
+	UINT_32 u4Address;
+	UINT_32 u4Data;
+} INIT_CMD_ACCESS_REG, *P_INIT_CMD_ACCESS_REG;
+
+/* Events */
+typedef struct _INIT_WIFI_EVENT_T {
+	UINT_16 u2RxByteCount;
+	UINT_8 ucEID;
+	UINT_8 ucSeqNum;
+	UINT_8 aucBuffer[0];
+} INIT_WIFI_EVENT_T, *P_INIT_WIFI_EVENT_T;
+
+typedef struct _INIT_HIF_RX_HEADER_T {
+	INIT_WIFI_EVENT_T rInitWifiEvent;
+} INIT_HIF_RX_HEADER_T, *P_INIT_HIF_RX_HEADER_T;
+
+typedef struct _INIT_EVENT_CMD_RESULT {
+	UINT_8 ucStatus;	/* 0: success */
+	/* 1: rejected by invalid param */
+	/* 2: rejected by incorrect CRC */
+	/* 3: rejected by decryption failure */
+	/* 4: unknown CMD */
+	UINT_8 aucReserved[3];
+} INIT_EVENT_CMD_RESULT, *P_INIT_EVENT_CMD_RESULT, INIT_EVENT_PENDING_ERROR, *P_INIT_EVENT_PENDING_ERROR;
+
+typedef struct _INIT_EVENT_ACCESS_REG {
+	UINT_32 u4Address;
+	UINT_32 u4Data;
+} INIT_EVENT_ACCESS_REG, *P_INIT_EVENT_ACCESS_REG;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _NIC_INIT_CMD_EVENT_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h
new file mode 100644
index 0000000000000..85af819f4e624
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h
@@ -0,0 +1,201 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/p2p_precomp.h#1
+*/
+
+/*! \file   p2p_precomp.h
+    \brief  Collection of most compiler flags for p2p driver are described here.
+
+    In this file we collect all compiler flags and detail the p2p driver behavior if
+    enable/disable such switch or adjust numeric parameters.
+*/
+
+#ifndef _P2P_PRECOMP_H
+#define _P2P_PRECOMP_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_os.h"		/* Include "config.h" */
+
+#include "gl_p2p_os.h"
+
+#include "debug.h"
+
+#include "link.h"
+#include "queue.h"
+
+/*------------------------------------------------------------------------------
+ * .\include\mgmt
+ *------------------------------------------------------------------------------
+ */
+#include "wlan_typedef.h"
+
+#include "mac.h"
+
+/* Dependency:  mac.h (MAC_ADDR_LEN) */
+#include "wlan_def.h"
+
+#include "roaming_fsm.h"
+
+/*------------------------------------------------------------------------------
+ * .\include\nic
+ *------------------------------------------------------------------------------
+ */
+/* Dependency:  wlan_def.h (ENUM_NETWORK_TYPE_T) */
+#include "cmd_buf.h"
+
+/* Dependency:  mac.h (MAC_ADDR_LEN) */
+#include "nic_cmd_event.h"
+
+/* Dependency:  nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */
+#include "nic.h"
+
+#include "nic_init_cmd_event.h"
+
+#include "hif_rx.h"
+#include "hif_tx.h"
+
+#include "nic_tx.h"
+
+/* Dependency:  hif_rx.h (P_HIF_RX_HEADER_T) */
+#include "nic_rx.h"
+
+#include "que_mgt.h"
+
+#if CFG_ENABLE_WIFI_DIRECT
+#include "p2p_typedef.h"
+#include "p2p_cmd_buf.h"
+#include "p2p_nic_cmd_event.h"
+#include "p2p_mac.h"
+#include "p2p_nic.h"
+#endif
+
+/*------------------------------------------------------------------------------
+ * .\include\mgmt
+ *------------------------------------------------------------------------------
+ */
+
+#include "hem_mbox.h"
+
+#include "scan.h"
+#include "bss.h"
+
+#include "wlan_lib.h"
+#include "wlan_oid.h"
+#include "wlan_bow.h"
+
+#include "wlan_p2p.h"
+
+#include "hal.h"
+
+#if defined(MT6620)
+#include "mt6620_reg.h"
+#endif
+
+#include "rlm.h"
+#include "rlm_domain.h"
+#include "rlm_protection.h"
+#include "rlm_obss.h"
+#include "rate.h"
+
+#include "aa_fsm.h"
+
+#include "cnm_timer.h"
+
+#if CFG_ENABLE_BT_OVER_WIFI
+#include "bow.h"
+#include "bow_fsm.h"
+#endif
+
+#include "pwr_mgt.h"
+
+#include "cnm.h"
+/* Dependency:  aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */
+#include "cnm_mem.h"
+#include "cnm_scan.h"
+
+#include "p2p_rlm_obss.h"
+#include "p2p_bss.h"
+#include "p2p.h"
+/* Dependency:  cnm_timer.h (TIMER_T) */
+#include "p2p_fsm.h"
+#include "p2p_scan.h"
+#include "p2p_state.h"
+#include "p2p_func.h"
+#include "p2p_rlm.h"
+#include "p2p_assoc.h"
+#include "p2p_ie.h"
+
+#include "privacy.h"
+
+#include "mib.h"
+
+#include "auth.h"
+#include "assoc.h"
+
+#include "ais_fsm.h"
+
+#include "adapter.h"
+
+#include "que_mgt.h"
+#include "rftest.h"
+
+#if CFG_RSN_MIGRATION
+#include "rsn.h"
+#include "sec_fsm.h"
+#endif
+
+#if CFG_SUPPORT_WAPI
+#include "wapi.h"
+#endif
+
+/*------------------------------------------------------------------------------
+ * NVRAM structure
+ *------------------------------------------------------------------------------
+ */
+#include "CFG_Wifi_File.h"
+
+#include "gl_p2p_kal.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /*_P2P_PRECOMP_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h
new file mode 100644
index 0000000000000..a02d391d36430
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h
@@ -0,0 +1,165 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/p2p_typedef.h#1
+*/
+
+/*! \file   p2p_typedef.h
+    \brief  Declaration of data type and return values of internal protocol stack.
+
+    In this file we declare the data type and return values which will be exported
+    to all MGMT Protocol Stack.
+*/
+
+#ifndef _P2P_TYPEDEF_H
+#define _P2P_TYPEDEF_H
+
+#if CFG_ENABLE_WIFI_DIRECT
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*
+* type definition of pointer to p2p structure
+*/
+/* typedef struct _GL_P2P_INFO_T   GL_P2P_INFO_T, *P_GL_P2P_INFO_T; */
+typedef struct _P2P_INFO_T P2P_INFO_T, *P_P2P_INFO_T;
+
+typedef struct _P2P_FSM_INFO_T P2P_FSM_INFO_T, *P_P2P_FSM_INFO_T;
+
+typedef struct _P2P_CONNECTION_SETTINGS_T P2P_CONNECTION_SETTINGS_T, *P_P2P_CONNECTION_SETTINGS_T;
+
+/* Type definition for function pointer to p2p function*/
+typedef BOOLEAN(*P2P_LAUNCH) (P_GLUE_INFO_T prGlueInfo);
+
+typedef BOOLEAN(*P2P_REMOVE) (P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsWlanLaunched);
+
+typedef BOOLEAN(*KAL_P2P_GET_CIPHER) (IN P_GLUE_INFO_T prGlueInfo);
+
+typedef BOOLEAN(*KAL_P2P_GET_TKIP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo);
+
+typedef BOOLEAN(*KAL_P2P_GET_CCMP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo);
+
+typedef BOOLEAN(*KAL_P2P_GET_WSC_MODE) (IN P_GLUE_INFO_T prGlueInfo);
+
+typedef struct net_device *(*KAL_P2P_GET_DEV_HDLR) (P_GLUE_INFO_T prGlueInfo);
+
+typedef VOID(*KAL_P2P_SET_MULTICAST_WORK_ITEM) (P_GLUE_INFO_T prGlueInfo);
+
+typedef VOID(*P2P_NET_REGISTER) (P_GLUE_INFO_T prGlueInfo);
+
+typedef VOID(*P2P_NET_UNREGISTER) (P_GLUE_INFO_T prGlueInfo);
+
+typedef VOID(*KAL_P2P_UPDATE_ASSOC_INFO) (IN P_GLUE_INFO_T prGlueInfo,
+					  IN PUINT_8 pucFrameBody,
+					  IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest);
+
+typedef BOOLEAN(*P2P_VALIDATE_AUTH) (IN P_ADAPTER_T prAdapter,
+				     IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode);
+
+typedef BOOLEAN(*P2P_VALIDATE_ASSOC_REQ) (IN P_ADAPTER_T prAdapter,
+					  IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu4ControlFlags);
+
+typedef VOID(*P2P_RUN_EVENT_AAA_TX_FAIL) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+typedef BOOLEAN(*P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM) (IN P_ADAPTER_T prAdapter,
+						     IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType);
+
+typedef WLAN_STATUS(*P2P_RUN_EVENT_AAA_COMPLETE) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+typedef VOID(*P2P_PROCESS_EVENT_UPDATE_NOA_PARAM) (IN P_ADAPTER_T prAdapter,
+						   UINT_8 ucNetTypeIndex,
+						   P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam);
+
+typedef VOID(*SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP) (IN P_ADAPTER_T prAdapter,
+						       IN P_SW_RFB_T prSwRfb,
+						       IN P_WLAN_STATUS prStatus,
+						       IN P_BSS_DESC_T prBssDesc,
+						       IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame);
+
+typedef VOID(*P2P_RX_PUBLIC_ACTION_FRAME) (P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+typedef VOID(*RLM_RSP_GENERATE_OBSS_SCAN_IE) (P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+typedef VOID(*RLM_UPDATE_BW_BY_CH_LIST_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+typedef VOID(*RLM_PROCESS_PUBLIC_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb);
+
+typedef VOID(*RLM_PROCESS_HT_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb);
+
+typedef VOID(*RLM_UPDATE_PARAMS_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon);
+
+typedef VOID(*RLM_HANDLE_OBSS_STATUS_EVENT_PKT) (P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus);
+
+typedef BOOLEAN(*P2P_FUNC_VALIDATE_PROBE_REQ) (IN P_ADAPTER_T prAdapter,
+					       IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags);
+
+typedef VOID(*RLM_BSS_INIT_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+typedef UINT_32(*P2P_GET_PROB_RSP_IE_TABLE_SIZE) (VOID);
+
+typedef PUINT_8(*P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES) (IN P_ADAPTER_T prAdapter,
+							  IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer);
+
+typedef VOID(*P2P_FUNC_DISCONNECT) (IN P_ADAPTER_T prAdapter,
+				    IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode);
+
+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DEAUTH) (IN P_ADAPTER_T prAdapter,
+					    IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb);
+
+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DISASSOC) (IN P_ADAPTER_T prAdapter,
+					      IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb);
+
+typedef BOOLEAN(*P2P_FUN_IS_AP_MODE) (IN P_P2P_FSM_INFO_T prP2pFsmInfo);
+
+typedef VOID(*P2P_FSM_RUN_EVENT_BEACON_TIMEOUT) (IN P_ADAPTER_T prAdapter);
+
+typedef VOID(*P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER) (IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+typedef VOID(*P2P_GENERATE_P2P_IE) (IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+typedef UINT_32(*P2P_CALCULATE_P2P_IE_LEN) (IN P_ADAPTER_T prAdapter,
+					    IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /*CFG_ENABLE_WIFI_DIRECT */
+
+#endif /* _P2P_TYPEDEF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h
new file mode 100644
index 0000000000000..1b7e7ede66e1a
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h
@@ -0,0 +1,388 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/precomp.h#2
+*/
+
+/*! \file   precomp.h
+    \brief  Collection of most compiler flags are described here.
+
+    In this file we collect all compiler flags and detail the driver behavior if
+    enable/disable such switch or adjust numeric parameters.
+*/
+
+/*
+** Log: precomp.h
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628-specific definitions.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 03 15 2011 eddie.chen
+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter
+ * Add sw debug counter for QM.
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 12 13 2010 cp.wu
+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
+ * create branch for Wi-Fi driver v1.1
+ *
+ * 10 07 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * add firmware download for MT5931.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 09 14 2010 chinghwa.yu
+ * NULL
+ * Fix BOW_FSM_INFO_T dependence.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 20 2010 wh.su
+ *
+ * adding the wapi code.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Modify CNM message handler for new flow
+ *
+ * 06 28 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * 1st draft code for RLM module
+ *
+ * 06 19 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * consdier the concurrent network setting.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration the security related function from firmware.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration from MT6620 firmware.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge cnm_scan.h and hem_mbox.h
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 03 16 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * build up basic data structure and definitions to support BT-over-WiFi
+ *
+ * 02 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * prepare for implementing fw download logic
+ *
+ * 01 27 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * .
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 11:30:58 GMT mtk02752
+**  add rftest.h for implementing RF test mode in driver land
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-23 22:02:00 GMT mtk02468
+**  Added que_mgt.h
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-13 21:58:36 GMT mtk01084
+**  update for new macro define
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:40:11 GMT mtk01461
+**  Add nic_cmd_event.h
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 20:00:26 GMT mtk01461
+**  Add cmd_buf.h
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:44 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:25 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:38 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _PRECOMP_H
+#define _PRECOMP_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_os.h"		/* Include "config.h" */
+
+#if CFG_ENABLE_WIFI_DIRECT
+#include "gl_p2p_os.h"
+#endif
+
+#include "debug.h"
+
+#include "link.h"
+#include "queue.h"
+
+/*------------------------------------------------------------------------------
+ * .\include\mgmt
+ *------------------------------------------------------------------------------
+ */
+#include "wlan_typedef.h"
+
+#include "mac.h"
+
+/* Dependency:  mac.h (MAC_ADDR_LEN) */
+#include "wlan_def.h"
+
+#if CFG_SUPPORT_SWCR
+#include "swcr.h"
+#endif
+
+/*------------------------------------------------------------------------------
+ * .\include\nic
+ *------------------------------------------------------------------------------
+ */
+/* Dependency:  wlan_def.h (ENUM_NETWORK_TYPE_T) */
+#include "cmd_buf.h"
+
+/* Dependency:  mac.h (MAC_ADDR_LEN) */
+#include "nic_cmd_event.h"
+
+/* Dependency:  nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */
+#include "nic.h"
+
+#include "nic_init_cmd_event.h"
+
+#include "hif_rx.h"
+#include "hif_tx.h"
+
+#include "nic_tx.h"
+
+/* Dependency:  hif_rx.h (P_HIF_RX_HEADER_T) */
+#include "nic_rx.h"
+
+#include "que_mgt.h"
+
+#if CFG_ENABLE_WIFI_DIRECT
+#include "p2p_typedef.h"
+#include "p2p_cmd_buf.h"
+#include "p2p_nic_cmd_event.h"
+#include "p2p_mac.h"
+#include "p2p_nic.h"
+#endif
+
+/*------------------------------------------------------------------------------
+ * .\include\mgmt
+ *------------------------------------------------------------------------------
+ */
+
+#include "hem_mbox.h"
+
+#include "scan.h"
+#include "bss.h"
+
+#include "wlan_lib.h"
+#include "wlan_oid.h"
+#include "wlan_bow.h"
+
+#if CFG_ENABLE_WIFI_DIRECT
+#include "wlan_p2p.h"
+#endif
+
+#include "hal.h"
+
+#if defined(MT6620)
+#include "mt6620_reg.h"
+#elif defined(MT6628)
+/* #include "mt6628_reg.h" */
+#include "mtreg.h"
+#endif
+
+#include "rlm.h"
+#include "rlm_domain.h"
+#include "rlm_protection.h"
+#include "rlm_obss.h"
+#include "rate.h"
+#if CFG_SUPPORT_802_11V
+#include "wnm.h"
+#endif
+
+#include "aa_fsm.h"
+
+#include "cnm_timer.h"
+
+#if CFG_ENABLE_BT_OVER_WIFI
+#include "bow.h"
+#include "bow_fsm.h"
+#endif
+
+#include "pwr_mgt.h"
+
+#if (CFG_SUPPORT_STATISTICS == 1)
+#include "stats.h"
+#endif /* CFG_SUPPORT_STATISTICS */
+
+#include "cnm.h"
+/* Dependency:  aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */
+#include "cnm_mem.h"
+#include "cnm_scan.h"
+
+#if CFG_ENABLE_WIFI_DIRECT
+#include "p2p_rlm_obss.h"
+#include "p2p_bss.h"
+#include "p2p.h"
+#include "p2p_fsm.h"
+#include "p2p_scan.h"
+#include "p2p_state.h"
+#include "p2p_func.h"
+#include "p2p_rlm.h"
+#include "p2p_assoc.h"
+#include "p2p_ie.h"
+#endif
+
+#include "privacy.h"
+
+#include "mib.h"
+
+#include "auth.h"
+#include "assoc.h"
+
+#if CFG_SUPPORT_ROAMING
+#include "roaming_fsm.h"
+#endif /* CFG_SUPPORT_ROAMING */
+
+#include "ais_fsm.h"
+
+#include "adapter.h"
+
+#include "que_mgt.h"
+#include "rftest.h"
+
+#if CFG_RSN_MIGRATION
+#include "rsn.h"
+#include "sec_fsm.h"
+#endif
+
+#if CFG_SUPPORT_WAPI
+#include "wapi.h"
+#endif
+
+/*------------------------------------------------------------------------------
+ * NVRAM structure
+ *------------------------------------------------------------------------------
+ */
+#include "CFG_Wifi_File.h"
+
+#if CFG_ENABLE_WIFI_DIRECT
+#include "gl_p2p_kal.h"
+#endif
+
+typedef int (*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode);
+typedef void (*set_dbg_level) (unsigned char modules[DBG_MODULE_NUM]);
+
+extern void wlanRegisterNotifier(void);
+extern void wlanUnregisterNotifier(void);
+extern void register_set_p2p_mode_handler(set_p2p_mode handler);
+extern void register_set_dbg_level_handler(set_dbg_level handler);
+
+#if CFG_TC1_FEATURE
+#define NIC_INF_NAME_IN_AP_MODE  "legacy%d"
+extern volatile int wlan_if_changed;
+#endif
+extern BOOLEAN fgIsResetting;
+
+extern UINT_8 g_aucBufIpAddr[32];
+extern UINT_8 aucDebugModule[];
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PRECOMP_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h
new file mode 100644
index 0000000000000..40f52dcc9d681
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h
@@ -0,0 +1,141 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/pwr_mgt.h#1
+*/
+
+/*! \file   "pwr_mgt.h"
+    \brief  In this file we define the STATE and EVENT for Power Management FSM.
+
+    The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter
+    ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail
+    description.
+*/
+
+/*
+** Log: pwr_mgt.h
+ *
+ * 07 09 2010 george.huang
+ *
+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 04 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL
+ * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well.
+
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * firmware download load address & start address are now configured from config.h
+ *  *  * due to the different configurations on FPGA and ASIC
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-10 16:39:10 GMT mtk02752
+**  disable PM macros temporally
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-29 19:48:37 GMT mtk01084
+**  temp remove power management macro
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-08 16:51:11 GMT mtk01084
+**  update for power management control macro
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-03 14:59:58 GMT mtk01426
+**  Add #if CFG_HIF_LOOPBACK_PRETEST
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:53:10 GMT mtk01084
+**  modify ACQUIRE_POWER_CONTROL_FROM_PM() and RECLAIM_POWER_CONTROL_TO_PM() macro
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:32:47 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:20 GMT mtk01084
+**  Initial version
+**
+*/
+
+#ifndef _PWR_MGT_H
+#define _PWR_MGT_H
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define PM_UAPSD_AC0                        (BIT(0))
+#define PM_UAPSD_AC1                        (BIT(1))
+#define PM_UAPSD_AC2                        (BIT(2))
+#define PM_UAPSD_AC3                        (BIT(3))
+
+#define PM_UAPSD_ALL                        (PM_UAPSD_AC0 | PM_UAPSD_AC1 | PM_UAPSD_AC2 | PM_UAPSD_AC3)
+#define PM_UAPSD_NONE                       0
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _PM_PROFILE_SETUP_INFO_T {
+	/* Profile setup */
+	UINT_8 ucBmpDeliveryAC;	/* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */
+	UINT_8 ucBmpTriggerAC;	/* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */
+
+	UINT_8 ucUapsdSp;	/* Number of triggered packets in UAPSD */
+
+} PM_PROFILE_SETUP_INFO_T, *P_PM_PROFILE_SETUP_INFO_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#if !CFG_ENABLE_FULL_PM
+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter)
+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST)
+#else
+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) \
+	{ \
+		if (_prAdapter->fgIsFwOwn) { \
+			nicpmSetDriverOwn(_prAdapter); \
+		} \
+		/* Increase Block to Enter Low Power Semaphore count */ \
+		GLUE_INC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \
+	}
+
+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) \
+	{ \
+		ASSERT(_prAdapter->u4PwrCtrlBlockCnt != 0); \
+		/* Decrease Block to Enter Low Power Semaphore count */ \
+		GLUE_DEC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \
+		if (_prAdapter->fgWiFiInSleepyState && (_prAdapter->u4PwrCtrlBlockCnt == 0)) { \
+			nicpmSetFWOwn(_prAdapter, _fgEnableGINT_in_IST); \
+		} \
+	}
+#endif
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PWR_MGT_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h
new file mode 100644
index 0000000000000..a9e74b58a8c97
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h
@@ -0,0 +1,195 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/queue.h#1
+*/
+
+/*! \file   queue.h
+    \brief  Definition for singly queue operations.
+
+    In this file we define the singly queue data structure and its
+    queue operation MACROs.
+*/
+
+/*
+** Log: queue.h
+ *
+ * 07 16 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * bugfix for SCN migration
+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue
+ * 2) before AIS issues scan request, network(BSS) needs to be activated first
+ * 3) only invoke COPY_SSID when using specified SSID for scan
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 04 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * .
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:46 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _QUEUE_H
+#define _QUEUE_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_typedef.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Singly Queue Structures - Entry Part */
+typedef struct _QUE_ENTRY_T {
+	struct _QUE_ENTRY_T *prNext;
+	struct _QUE_ENTRY_T *prPrev;	/* For Rx buffer reordering used only */
+} QUE_ENTRY_T, *P_QUE_ENTRY_T;
+
+/* Singly Queue Structures - Queue Part */
+typedef struct _QUE_T {
+	P_QUE_ENTRY_T prHead;
+	P_QUE_ENTRY_T prTail;
+	UINT_32 u4NumElem;
+} QUE_T, *P_QUE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*
+  * To resolve compiler warning of address check -Waddress
+  * Redefine a ASSERT dedicate for queue operation
+  */
+#if DBG
+#define QUE_ASSERT ASSERT
+#else
+#define QUE_ASSERT(_exp)
+#endif
+
+#define QUEUE_INITIALIZE(prQueue) \
+	{ \
+	    (prQueue)->prHead = (P_QUE_ENTRY_T)NULL; \
+	    (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \
+	    (prQueue)->u4NumElem = 0; \
+	}
+
+#define QUEUE_IS_EMPTY(prQueue)             (((P_QUE_T)(prQueue))->prHead == (P_QUE_ENTRY_T)NULL)
+
+#define QUEUE_IS_NOT_EMPTY(prQueue)         ((prQueue)->u4NumElem > 0)
+
+#define QUEUE_GET_HEAD(prQueue)             ((prQueue)->prHead)
+
+#define QUEUE_GET_TAIL(prQueue)             ((prQueue)->prTail)
+
+#define QUEUE_GET_NEXT_ENTRY(prQueueEntry)  ((prQueueEntry)->prNext)
+
+#define QUEUE_INSERT_HEAD(prQueue, prQueueEntry) \
+	{ \
+	    QUE_ASSERT(prQueue); \
+	    QUE_ASSERT(prQueueEntry); \
+	    (prQueueEntry)->prNext = (prQueue)->prHead; \
+	    (prQueue)->prHead = (prQueueEntry); \
+	    if ((prQueue)->prTail == (P_QUE_ENTRY_T)NULL) { \
+		(prQueue)->prTail = (prQueueEntry); \
+	    } \
+	    ((prQueue)->u4NumElem)++; \
+	}
+
+#define QUEUE_INSERT_TAIL(prQueue, prQueueEntry) \
+	{ \
+	    QUE_ASSERT(prQueue); \
+	    QUE_ASSERT(prQueueEntry); \
+	    (prQueueEntry)->prNext = (P_QUE_ENTRY_T)NULL; \
+	    if ((prQueue)->prTail) { \
+		((prQueue)->prTail)->prNext = (prQueueEntry); \
+	    } else { \
+		(prQueue)->prHead = (prQueueEntry); \
+	    } \
+	    (prQueue)->prTail = (prQueueEntry); \
+	    ((prQueue)->u4NumElem)++; \
+	}
+
+/* NOTE: We assume the queue entry located at the beginning of "prQueueEntry Type",
+ * so that we can cast the queue entry to other data type without doubts.
+ * And this macro also decrease the total entry count at the same time.
+ */
+#define QUEUE_REMOVE_HEAD(prQueue, prQueueEntry, _P_TYPE) \
+	{ \
+	    QUE_ASSERT(prQueue); \
+	    prQueueEntry = (_P_TYPE)((prQueue)->prHead); \
+	    if (prQueueEntry) { \
+		(prQueue)->prHead = ((P_QUE_ENTRY_T)(prQueueEntry))->prNext; \
+		if ((prQueue)->prHead == (P_QUE_ENTRY_T)NULL) { \
+			(prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \
+		} \
+		((P_QUE_ENTRY_T)(prQueueEntry))->prNext = (P_QUE_ENTRY_T)NULL; \
+		((prQueue)->u4NumElem)--; \
+	    } \
+	}
+
+#define QUEUE_MOVE_ALL(prDestQueue, prSrcQueue) \
+	{ \
+	    QUE_ASSERT(prDestQueue); \
+	    QUE_ASSERT(prSrcQueue); \
+	    *(P_QUE_T)prDestQueue = *(P_QUE_T)prSrcQueue; \
+	    QUEUE_INITIALIZE(prSrcQueue); \
+	}
+
+#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \
+	{ \
+	    QUE_ASSERT(prDestQueue); \
+	    QUE_ASSERT(prSrcQueue); \
+	    if (prSrcQueue->u4NumElem > 0) { \
+		if ((prDestQueue)->prTail) { \
+			((prDestQueue)->prTail)->prNext = (prSrcQueue)->prHead; \
+		} else { \
+		    (prDestQueue)->prHead = (prSrcQueue)->prHead; \
+		} \
+		(prDestQueue)->prTail = (prSrcQueue)->prTail; \
+		((prDestQueue)->u4NumElem) += ((prSrcQueue)->u4NumElem); \
+		QUEUE_INITIALIZE(prSrcQueue); \
+	    } \
+	}
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _QUEUE_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h
new file mode 100644
index 0000000000000..4489e56013025
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h
@@ -0,0 +1,294 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/rftest.h#1
+*/
+
+/*! \file   "rftest.h"
+    \brief  definitions for RF Productino test
+
+*/
+
+/*
+** Log: rftest.h
+ *
+ * 12 20 2011 cp.wu
+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information
+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO
+ * to expose version information
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * information buffer for query oid/ioctl is now buffered in prCmdInfo
+ *  *  *  * instead of glue-layer variable to improve multiple oid/ioctl capability
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  *  *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  *  *  *  *  * and result is retrieved by get ATInfo instead
+ *  *  *  *  *  *  * 2) add 4 counter for recording aggregation statistics
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-08 17:35:11 GMT mtk02752
+**  * comment out RF test which is not supported on MT6620
+**  + API decalre for rftest
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-12-08 11:29:07 GMT mtk02752
+**  definitions for RF test mode
+**
+*/
+#ifndef _RFTEST_H
+#define _RFTEST_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* Table Version */
+#define RF_AUTO_TEST_FUNCTION_TABLE_VERSION 0x01000001
+
+/* Power */
+#define RF_AT_PARAM_POWER_MASK      BITS(0, 7)
+#define RF_AT_PARAM_POWER_MAX       RF_AT_PARAM_POWER_MASK
+
+/* Rate */
+#define RF_AT_PARAM_RATE_MCS_MASK   BIT(31)
+#define RF_AT_PARAM_RATE_MASK       BITS(0, 7)
+#define RF_AT_PARAM_RATE_CCK_MAX    3
+#define RF_AT_PARAM_RATE_1M         0
+#define RF_AT_PARAM_RATE_2M         1
+#define RF_AT_PARAM_RATE_5_5M       2
+#define RF_AT_PARAM_RATE_11M        3
+#define RF_AT_PARAM_RATE_6M         4
+#define RF_AT_PARAM_RATE_9M         5
+#define RF_AT_PARAM_RATE_12M        6
+#define RF_AT_PARAM_RATE_18M        7
+#define RF_AT_PARAM_RATE_24M        8
+#define RF_AT_PARAM_RATE_36M        9
+#define RF_AT_PARAM_RATE_48M        10
+#define RF_AT_PARAM_RATE_54M        11
+
+/* Antenna */
+#define RF_AT_PARAM_ANTENNA_ID_MASK BITS(0, 7)
+#define RF_AT_PARAM_ANTENNA_ID_MAX  1
+
+/* Packet Length */
+#define RF_AT_PARAM_TX_80211HDR_BYTE_MAX     (32)
+#define RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX (2048)
+
+#define RF_AT_PARAM_TX_PKTLEN_BYTE_DEFAULT  1024
+#define RF_AT_PARAM_TX_PKTLEN_BYTE_MAX  \
+	((UINT_16)(RF_AT_PARAM_TX_80211HDR_BYTE_MAX + RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX))
+
+/* Packet Count */
+#define RF_AT_PARAM_TX_PKTCNT_DEFAULT    1000
+#define RF_AT_PARAM_TX_PKTCNT_UNLIMITED  0
+
+/* Packet Interval */
+#define RF_AT_PARAM_TX_PKT_INTERVAL_US_DEFAULT  50
+
+/* ALC */
+#define RF_AT_PARAM_ALC_DISABLE     0
+#define RF_AT_PARAM_ALC_ENABLE      1
+
+/* TXOP */
+#define RF_AT_PARAM_TXOP_DEFAULT    0
+#define RF_AT_PARAM_TXOPQUE_QMASK   BITS(16, 31)
+#define RF_AT_PARAM_TXOPQUE_TMASK   BITS(0, 15)
+#define RF_AT_PARAM_TXOPQUE_AC0     (0<<16)
+#define RF_AT_PARAM_TXOPQUE_AC1     (1<<16)
+#define RF_AT_PARAM_TXOPQUE_AC2     (2<<16)
+#define RF_AT_PARAM_TXOPQUE_AC3     (3<<16)
+#define RF_AT_PARAM_TXOPQUE_AC4     (4<<16)
+#define RF_AT_PARAM_TXOPQUE_QOFFSET 16
+
+/* Retry Limit */
+#define RF_AT_PARAM_TX_RETRY_DEFAULT    0
+#define RF_AT_PARAM_TX_RETRY_MAX        6
+
+/* QoS Queue */
+#define RF_AT_PARAM_QOSQUE_AC0      0
+#define RF_AT_PARAM_QOSQUE_AC1      1
+#define RF_AT_PARAM_QOSQUE_AC2      2
+#define RF_AT_PARAM_QOSQUE_AC3      3
+#define RF_AT_PARAM_QOSQUE_AC4      4
+#define RF_AT_PARAM_QOSQUE_DEFAULT  RF_AT_PARAM_QOSQUE_AC0
+
+/* Bandwidth */
+#define RF_AT_PARAM_BANDWIDTH_20MHZ             0
+#define RF_AT_PARAM_BANDWIDTH_40MHZ             1
+#define RF_AT_PARAM_BANDWIDTH_U20_IN_40MHZ      2
+#define RF_AT_PARAM_BANDWIDTH_D20_IN_40MHZ      3
+#define RF_AT_PARAM_BANDWIDTH_DEFAULT   RF_AT_PARAM_BANDWIDTH_20MHZ
+
+/* GI (Guard Interval) */
+#define RF_AT_PARAM_GI_800NS    0
+#define RF_AT_PARAM_GI_400NS    1
+#define RF_AT_PARAM_GI_DEFAULT  RF_AT_PARAM_GI_800NS
+
+/* STBC */
+#define RF_AT_PARAM_STBC_DISABLE    0
+#define RF_AT_PARAM_STBC_ENABLE     1
+
+/* RIFS */
+#define RF_AT_PARAM_RIFS_DISABLE    0
+#define RF_AT_PARAM_RIFS_ENABLE     1
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Function ID List */
+typedef enum _ENUM_RF_AT_FUNCID_T {
+	RF_AT_FUNCID_VERSION = 0,
+	RF_AT_FUNCID_COMMAND,
+	RF_AT_FUNCID_POWER,
+	RF_AT_FUNCID_RATE,
+	RF_AT_FUNCID_PREAMBLE,
+	RF_AT_FUNCID_ANTENNA,
+	RF_AT_FUNCID_PKTLEN,
+	RF_AT_FUNCID_PKTCNT,
+	RF_AT_FUNCID_PKTINTERVAL,
+	RF_AT_FUNCID_TEMP_COMPEN,
+	RF_AT_FUNCID_TXOPLIMIT,
+	RF_AT_FUNCID_ACKPOLICY,
+	RF_AT_FUNCID_PKTCONTENT,
+	RF_AT_FUNCID_RETRYLIMIT,
+	RF_AT_FUNCID_QUEUE,
+	RF_AT_FUNCID_BANDWIDTH,
+	RF_AT_FUNCID_GI,
+	RF_AT_FUNCID_STBC,
+	RF_AT_FUNCID_CHNL_FREQ,
+	RF_AT_FUNCID_RIFS,
+	RF_AT_FUNCID_TRSW_TYPE,
+	RF_AT_FUNCID_RF_SX_SHUTDOWN,
+	RF_AT_FUNCID_PLL_SHUTDOWN,
+	RF_AT_FUNCID_SLOW_CLK_MODE,
+	RF_AT_FUNCID_ADC_CLK_MODE,
+	RF_AT_FUNCID_MEASURE_MODE,
+	RF_AT_FUNCID_VOLT_COMPEN,
+	RF_AT_FUNCID_DPD_TX_GAIN,
+	RF_AT_FUNCID_DPD_MODE,
+	RF_AT_FUNCID_TSSI_MODE,
+	RF_AT_FUNCID_TX_GAIN_CODE,
+	RF_AT_FUNCID_TX_PWR_MODE,
+
+	/* Query command */
+	RF_AT_FUNCID_TXED_COUNT = 32,
+	RF_AT_FUNCID_TXOK_COUNT,
+	RF_AT_FUNCID_RXOK_COUNT,
+	RF_AT_FUNCID_RXERROR_COUNT,
+	RF_AT_FUNCID_RESULT_INFO,
+	RF_AT_FUNCID_TRX_IQ_RESULT,
+	RF_AT_FUNCID_TSSI_RESULT,
+	RF_AT_FUNCID_DPD_RESULT,
+	RF_AT_FUNCID_RXV_DUMP,
+	RF_AT_FUNCID_RX_PHY_STATIS,
+	RF_AT_FUNCID_MEASURE_RESULT,
+	RF_AT_FUNCID_TEMP_SENSOR,
+	RF_AT_FUNCID_VOLT_SENSOR,
+	RF_AT_FUNCID_READ_EFUSE,
+	RF_AT_FUNCID_RX_RSSI,
+	RF_AT_FUNCID_FW_INFO,
+	RF_AT_FUNCID_DRV_INFO,
+
+	/* Set command */
+	RF_AT_FUNCID_SET_DPD_RESULT = 64,
+	RF_AT_FUNCID_SET_CW_MODE,
+	RF_AT_FUNCID_SET_JAPAN_CH14_FILTER,
+	RF_AT_FUNCID_WRITE_EFUSE,
+	RF_AT_FUNCID_SET_MAC_ADDRESS
+} ENUM_RF_AT_FUNCID_T;
+
+/* Command */
+typedef enum _ENUM_RF_AT_COMMAND_T {
+	RF_AT_COMMAND_STOPTEST = 0,
+	RF_AT_COMMAND_STARTTX,
+	RF_AT_COMMAND_STARTRX,
+	RF_AT_COMMAND_RESET,
+	RF_AT_COMMAND_OUTPUT_POWER,	/* Payload */
+	RF_AT_COMMAND_LO_LEAKAGE,	/* Local freq is renamed to Local leakage */
+	RF_AT_COMMAND_CARRIER_SUPPR,	/* OFDM (LTF/STF), CCK (PI,PI/2) */
+	RF_AT_COMMAND_TRX_IQ_CAL,
+	RF_AT_COMMAND_TSSI_CAL,
+	RF_AT_COMMAND_DPD_CAL,
+	RF_AT_COMMAND_CW,
+	RF_AT_COMMAND_NUM
+} ENUM_RF_AT_COMMAND_T;
+
+/* Preamble */
+typedef enum _ENUM_RF_AT_PREAMBLE_T {
+	RF_AT_PREAMBLE_NORMAL = 0,
+	RF_AT_PREAMBLE_CCK_SHORT,
+	RF_AT_PREAMBLE_11N_MM,
+	RF_AT_PREAMBLE_11N_GF,
+	RF_AT_PREAMBLE_NUM
+} ENUM_RF_AT_PREAMBLE_T;
+
+/* Ack Policy */
+typedef enum _ENUM_RF_AT_ACK_POLICY_T {
+	RF_AT_ACK_POLICY_NORMAL = 0,
+	RF_AT_ACK_POLICY_NOACK,
+	RF_AT_ACK_POLICY_NOEXPLICTACK,
+	RF_AT_ACK_POLICY_BLOCKACK,
+	RF_AT_ACK_POLICY_NUM
+} ENUM_RF_AT_ACK_POLICY_T;
+
+typedef enum _ENUM_RF_AUTOTEST_STATE_T {
+	RF_AUTOTEST_STATE_STANDBY = 0,
+	RF_AUTOTEST_STATE_TX,
+	RF_AUTOTEST_STATE_RX,
+	RF_AUTOTEST_STATE_RESET,
+	RF_AUTOTEST_STATE_OUTPUT_POWER,
+	RF_AUTOTEST_STATE_LOCA_FREQUENCY,
+	RF_AUTOTEST_STATE_CARRIER_SUPRRESION,
+	RF_AUTOTEST_STATE_NUM
+} ENUM_RF_AUTOTEST_STATE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData);
+
+WLAN_STATUS
+rftestQueryATInfo(IN P_ADAPTER_T prAdapter,
+		  UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen);
+
+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen);
+
+#endif /* _RFTEST_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h
new file mode 100644
index 0000000000000..8ee184591fc2f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h
@@ -0,0 +1,427 @@
+/*
+** Id: include/tdls_extr.h#1
+*/
+
+/*! \file   "tdls_extr.h"
+    \brief This file contains the external used in other modules
+	 for MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: tdls_extr.h
+ *
+ * 11 18 2013 vend_samp.lin
+ * NULL
+ * Initial version.
+ *
+ **
+ */
+
+#ifndef _TDLS_EXTR_H
+#define _TDLS_EXTR_H
+
+#if (CFG_SUPPORT_TDLS == 1)
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#define TDLS_TX_QUOTA_EMPTY_TIMEOUT			10
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* protocol */
+#define TDLS_FRM_PROT_TYPE					0x890d
+
+/*	TDLS uses Ethertype 89-0d frames. The UP shall be AC_VI, unless otherwise specified. */
+#define USER_PRIORITY_TDLS					5
+
+/* Status code */
+#define TDLS_STATUS							WLAN_STATUS
+
+#define TDLS_STATUS_SUCCESS					WLAN_STATUS_SUCCESS
+#define TDLS_STATUS_FAILURE					WLAN_STATUS_FAILURE
+#define TDLS_STATUS_INVALID_LENGTH			WLAN_STATUS_INVALID_LENGTH
+#define TDLS_STATUS_RESOURCES				WLAN_STATUS_RESOURCES
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#define TDLS_U32							UINT32
+#define TDLS_U16							UINT16
+#define TDLS_U8								UINT8
+
+typedef enum _TDLS_REASON_CODE {
+	TDLS_REASON_CODE_UNREACHABLE = 25,
+	TDLS_REASON_CODE_UNSPECIFIED = 26,
+
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN = 0x80,	/* 128 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WIFI_OFF = 0x81,	/* 129 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING = 0x82,	/* 130 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT = 0x83,	/* 131 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT = 0x84,	/* 132 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY = 0x85,	/* 133 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL = 0x86,	/* 134 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL = 0x87,	/* 135 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX = 0x88,	/* 136 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3 = 0x89,	/* 137 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY = 0x8a,	/* 138 */
+	TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN = 0x8b	/* 139 */
+} TDLS_REASON_CODE;
+
+/* TDLS FSM */
+typedef struct _TDLS_CMD_PEER_ADD_T {
+
+	TDLS_U8 aucPeerMac[6];
+
+#if 0
+	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;
+	UINT_16 u2CapInfo;
+
+	UINT_16 u2OperationalRateSet;
+	UINT_16 u2BSSBasicRateSet;
+	BOOLEAN fgIsUnknownBssBasicRate;
+
+	UINT_8 ucPhyTypeSet;
+#endif
+} TDLS_CMD_PEER_ADD_T;
+
+typedef struct _TDLS_CMD_LINK_T {
+
+	TDLS_U8 aucPeerMac[6];
+	BOOLEAN fgIsEnabled;
+} TDLS_CMD_LINK_T;
+
+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T {
+	TDLS_U8 arRxMask[10];
+	TDLS_U16 u2RxHighest;
+	TDLS_U8 ucTxParams;
+	TDLS_U8 Reserved[3];
+} TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T;
+
+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_T {
+	TDLS_U16 u2CapInfo;
+	TDLS_U8 ucAmpduParamsInfo;
+
+	/* 16 bytes MCS information */
+	TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T rMCS;
+
+	TDLS_U16 u2ExtHtCapInfo;
+	TDLS_U32 u4TxBfCapInfo;
+	TDLS_U8 ucAntennaSelInfo;
+} TDLS_CMD_PEER_UPDATE_HT_CAP_T;
+
+typedef struct _TDLS_CMD_PEER_UPDATE_T {
+
+	TDLS_U8 aucPeerMac[6];
+
+#define TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX			50
+	TDLS_U8 aucSupChan[TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX];
+
+	TDLS_U16 u2StatusCode;
+
+#define TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX			50
+	TDLS_U8 aucSupRate[TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX];
+	TDLS_U16 u2SupRateLen;
+
+	TDLS_U8 UapsdBitmap;
+	TDLS_U8 UapsdMaxSp;	/* MAX_SP */
+
+	TDLS_U16 u2Capability;
+#define TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN			5
+	TDLS_U8 aucExtCap[TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN];
+	TDLS_U16 u2ExtCapLen;
+
+	TDLS_CMD_PEER_UPDATE_HT_CAP_T rHtCap;
+	BOOLEAN fgIsSupHt;
+
+} TDLS_CMD_PEER_UPDATE_T;
+
+/* Command to TDLS core module */
+typedef enum _TDLS_CMD_CORE_ID {
+	TDLS_CORE_CMD_TEST_NULL_RCV = 0x00,
+	TDLS_CORE_CMD_TEST_PTI_RSP = 0x01,
+	TDLS_CORE_CMD_MIB_UPDATE = 0x02,
+	TDLS_CORE_CMD_TEST_TX_FAIL_SKIP = 0x03,
+	TDLS_CORE_CMD_UAPSD_CONF = 0x04,
+	TDLS_CORE_CMD_TEST_DATA_RCV = 0x05,
+	TDLS_CORE_CMD_TEST_PTI_REQ = 0x06,
+	TDLS_CORE_CMD_TEST_CHSW_REQ = 0x07,
+	TDLS_CORE_CMD_CHSW_CONF = 0x08,
+	TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP = 0x09,
+	TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP = 0x0a,
+	TDLS_CORE_CMD_TEST_CHSW_RSP = 0x0b,
+	TDLS_CORE_CMD_TEST_SCAN_SKIP = 0x0c,
+	TDLS_CORE_CMD_SETUP_CONF = 0x0d,
+	TDLS_CORE_CMD_TEST_TEAR_DOWN = 0x0e,
+	TDLS_CORE_CMD_KEY_INFO = 0x0f,
+	TDLS_CORE_CMD_TEST_PTI_TX_FAIL = 0x10
+} TDLS_CMD_CORE_ID;
+
+typedef struct _TDLS_CMD_CORE_TEST_NULL_RCV_T {
+
+	TDLS_U32 u4PM;
+} TDLS_CMD_CORE_TEST_NULL_RCV_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T {
+
+	TDLS_U32 u4DialogToken;
+} TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T {
+
+	TDLS_U32 u4DialogToken;
+	TDLS_U32 u4PM;
+} TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T {
+
+	TDLS_U32 u4ReasonCode;
+} TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T {
+
+	TDLS_U32 u4Chan;
+	TDLS_U32 u4RegClass;
+	TDLS_U32 u4SecChanOff;
+	TDLS_U32 u4SwitchTime;
+	TDLS_U32 u4SwitchTimeout;
+} TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T {
+
+	TDLS_U32 u4Chan;
+	TDLS_U32 u4SwitchTime;
+	TDLS_U32 u4SwitchTimeout;
+	TDLS_U32 u4StatusCode;
+} TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_DATA_RCV_T {
+
+	TDLS_U32 u4PM;
+	TDLS_U32 u4UP;
+	TDLS_U32 u4EOSP;
+	TDLS_U32 u4IsNull;
+} TDLS_CMD_CORE_TEST_DATA_RCV_T;
+
+typedef struct _TDLS_CMD_CORE_MIB_PARAM_UPDATE_T {
+
+	BOOLEAN Tdlsdot11TunneledDirectLinkSetupImplemented;
+	BOOLEAN Tdlsdot11TDLSPeerUAPSDBufferSTAActivated;
+	BOOLEAN Tdlsdot11TDLSPeerPSMActivated;
+	TDLS_U16 Tdlsdot11TDLSPeerUAPSDIndicationWindow;
+	BOOLEAN Tdlsdot11TDLSChannelSwitchingActivated;
+	TDLS_U8 Tdlsdot11TDLSPeerSTAMissingAckRetryLimit;
+	TDLS_U8 Tdlsdot11TDLSResponseTimeout;
+	TDLS_U16 Tdlsdot11TDLSProbeDelay;
+	TDLS_U8 Tdlsdot11TDLSDiscoveryRequestWindow;
+	TDLS_U8 Tdlsdot11TDLSACDeterminationInterval;
+} TDLS_CMD_CORE_MIB_PARAM_UPDATE_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T {
+
+	BOOLEAN fgIsEnable;
+} TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T;
+
+typedef struct _TDLS_CMD_CORE_UAPSD_CONFIG_T {
+
+	BOOLEAN fgIsSpTimeoutSkip;
+	BOOLEAN fgIsPtiTimeoutSkip;
+} TDLS_CMD_CORE_UAPSD_CONFIG_T;
+
+typedef struct _TDLS_CMD_CORE_SETUP_CONFIG_T {
+
+	BOOLEAN fgIs2040Supported;
+} TDLS_CMD_CORE_SETUP_CONFIG_T;
+
+typedef struct _TDLS_CMD_CORE_CHSW_CONFIG_T {
+
+	TDLS_U8 ucNetTypeIndex;
+	BOOLEAN fgIsChSwEnabled;
+	BOOLEAN fgIsChSwStarted;
+	TDLS_U8 ucRegClass;
+	TDLS_U8 ucTargetChan;
+	TDLS_U8 ucSecChanOff;
+	BOOLEAN fgIsChSwRegular;
+} TDLS_CMD_CORE_CHSW_CONFIG_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T {
+
+	BOOLEAN fgIsEnable;
+} TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T {
+
+	BOOLEAN fgIsEnable;
+} TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_PROHIBIT_T {
+
+	BOOLEAN fgIsEnable;
+	BOOLEAN fgIsSet;
+} TDLS_CMD_CORE_TEST_PROHIBIT_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_SCAN_SKIP_T {
+
+	BOOLEAN fgIsEnable;
+} TDLS_CMD_CORE_TEST_SCAN_SKIP_T;
+
+typedef struct _TDLS_CMD_CORE_INFO_DISPLAY_T {
+
+	BOOLEAN fgIsToClearAllHistory;
+} TDLS_CMD_CORE_INFO_DISPLAY_T;
+
+typedef struct _TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T {
+
+	BOOLEAN fgIsEnable;
+} TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T;
+
+typedef struct _TDLS_CMD_CORE_T {
+
+	TDLS_U32 u4Command;	/* TDLS_CMD_CORE_ID */
+
+	TDLS_U8 aucPeerMac[6];
+	TDLS_U8 ucNetTypeIndex;
+
+#define TDLS_CMD_CORE_RESERVED_SIZE					50
+	union {
+		TDLS_CMD_CORE_TEST_NULL_RCV_T rCmdNullRcv;
+		TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T rCmdPtiReqRcv;
+		TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T rCmdPtiRspRcv;
+		TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T rCmdTearDownRcv;
+		TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T rCmdChStReqRcv;
+		TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T rCmdChStRspRcv;
+		TDLS_CMD_CORE_TEST_DATA_RCV_T rCmdDatRcv;
+		TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T rCmdTxFailSkip;
+		TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T rCmdKeepAliveSkip;
+		TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T rCmdChSwTimeoutSkip;
+		TDLS_CMD_CORE_TEST_PROHIBIT_T rCmdProhibit;
+		TDLS_CMD_CORE_TEST_SCAN_SKIP_T rCmdScanSkip;
+		TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T rCmdPtiTxFail;
+
+		TDLS_CMD_CORE_MIB_PARAM_UPDATE_T rCmdMibUpdate;
+		TDLS_CMD_CORE_UAPSD_CONFIG_T rCmdUapsdConf;
+		TDLS_CMD_CORE_CHSW_CONFIG_T rCmdChSwConf;
+		TDLS_CMD_CORE_SETUP_CONFIG_T rCmdSetupConf;
+		TDLS_CMD_CORE_INFO_DISPLAY_T rCmdInfoDisplay;
+		TDLS_U8 Reserved[TDLS_CMD_CORE_RESERVED_SIZE];
+	} Content;
+} TDLS_CMD_CORE_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/*
+	assign station record idx for the packet only when STA_STATE_3
+	Or we will try to send data frame when the TDLS peer's state is STA_STATE_1
+	EX:
+		1. mtk_cfg80211_add_station: First create the STA_RECORD_T;
+		2. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame.
+		3. mtk_cfg80211_add_station: Change state to STA_STATE_1.
+		4. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame.
+*/
+#define TDLSEX_STA_REC_IDX_GET(__prAdapter__, __MsduInfo__) \
+{ \
+	STA_RECORD_T *__StaRec__; \
+	__MsduInfo__->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; \
+	__StaRec__ = cnmGetStaRecByAddress(__prAdapter__, \
+						(UINT_8) NETWORK_TYPE_AIS_INDEX, \
+						__MsduInfo__->aucEthDestAddr); \
+	if ((__StaRec__ != NULL) && \
+		((__StaRec__)->ucStaState == STA_STATE_3) && \
+		(IS_TDLS_STA(__StaRec__))) { \
+		__MsduInfo__->ucStaRecIndex = __StaRec__->ucIndex; \
+	} \
+}
+
+/* fill wiphy flag */
+#define TDLSEX_WIPHY_FLAGS_INIT(__fgFlag__)\
+{ \
+	__fgFlag__ |= (WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP);\
+}
+
+/* assign user priority of a TDLS action frame */
+/*
+	According to 802.11z: Setup req/resp are sent in AC_BK, otherwise we should default
+	to AC_VI.
+*/
+#define TDLSEX_UP_ASSIGN(__UserPriority__) \
+{ \
+	__UserPriority__ = USER_PRIORITY_TDLS; \
+}
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+int
+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev,
+		       const u8 *peer, u8 action_code, u8 dialog_token,
+		       u16 status_code, u32 peer_capability,
+		       bool initiator, const u8 *buf, size_t len);
+
+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev,
+			const u8 *peer, enum nl80211_tdls_operation oper);
+
+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE);
+
+VOID TdlsexEventHandle(P_GLUE_INFO_T prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen);
+
+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey);
+
+VOID TdlsexInit(ADAPTER_T *prAdapter);
+
+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter);
+
+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+VOID
+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo,
+			BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode);
+
+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+TDLS_STATUS TdlsexPeerAdd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen);
+
+TDLS_STATUS TdlsexPeerUpdate(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen);
+
+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt);
+
+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen);
+
+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo);
+
+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota);
+
+VOID TdlsexUninit(ADAPTER_T *prAdapter);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* CFG_SUPPORT_TDLS */
+
+#endif /* _TDLS_EXTR_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h
new file mode 100644
index 0000000000000..7ab62dae8813e
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h
@@ -0,0 +1,244 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/typedef.h#1
+*/
+
+/*! \file   typedef.h
+    \brief  Declaration of data type and return values of internal protocol stack.
+
+    In this file we declare the data type and return values which will be exported
+    to the GLUE Layer.
+*/
+
+/*
+** Log: typedef.h
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 12 30 2010 cp.wu
+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
+ * host driver not to set FW-own when there is still pending interrupts
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * integrate .
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add necessary changes to driver data paths.
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add definitions for module migration.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * move timer callback to glue layer.
+ *
+ * 05 31 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add cfg80211 interface, which is to replace WE, for further extension
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 02 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add Ethernet destination address information in packet info for TX
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add new API: wlanProcessQueuedPackets()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:41:37 GMT mtk01461
+**  Update PACKET_INFO_INIT for TX Path
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:30:17 GMT mtk01461
+**  Add parameter in PACKET_INFO_T for HIF Loopback
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:22 GMT mtk01461
+**  Fix LINT warning
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:28 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:54 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _TYPEDEF_H
+#define _TYPEDEF_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/* ieee80211.h of linux has duplicated definitions */
+#if defined(WLAN_STATUS_SUCCESS)
+#undef WLAN_STATUS_SUCCESS
+#endif
+
+#define WLAN_STATUS_SUCCESS                     ((WLAN_STATUS) 0x00000000L)
+#define WLAN_STATUS_PENDING                     ((WLAN_STATUS) 0x00000103L)
+#define WLAN_STATUS_NOT_ACCEPTED                ((WLAN_STATUS) 0x00010003L)
+
+#define WLAN_STATUS_MEDIA_CONNECT               ((WLAN_STATUS) 0x4001000BL)
+#define WLAN_STATUS_MEDIA_DISCONNECT            ((WLAN_STATUS) 0x4001000CL)
+#define WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY	((WLAN_STATUS) 0x4001000DL)
+
+#define WLAN_STATUS_MEDIA_SPECIFIC_INDICATION   ((WLAN_STATUS) 0x40010012L)
+
+#define WLAN_STATUS_SCAN_COMPLETE               ((WLAN_STATUS) 0x60010001L)
+#define WLAN_STATUS_MSDU_OK                     ((WLAN_STATUS) 0x60010002L)
+
+/* TODO(Kevin): double check if 0x60010001 & 0x60010002 is proprietary */
+#define WLAN_STATUS_ROAM_OUT_FIND_BEST          ((WLAN_STATUS) 0x60010101L)
+#define WLAN_STATUS_ROAM_DISCOVERY              ((WLAN_STATUS) 0x60010102L)
+
+#define WLAN_STATUS_FAILURE                     ((WLAN_STATUS) 0xC0000001L)
+#define WLAN_STATUS_RESOURCES                   ((WLAN_STATUS) 0xC000009AL)
+#define WLAN_STATUS_NOT_SUPPORTED               ((WLAN_STATUS) 0xC00000BBL)
+
+#define WLAN_STATUS_MULTICAST_FULL              ((WLAN_STATUS) 0xC0010009L)
+#define WLAN_STATUS_INVALID_PACKET              ((WLAN_STATUS) 0xC001000FL)
+#define WLAN_STATUS_ADAPTER_NOT_READY           ((WLAN_STATUS) 0xC0010011L)
+#define WLAN_STATUS_NOT_INDICATING              ((WLAN_STATUS) 0xC0010013L)
+#define WLAN_STATUS_INVALID_LENGTH              ((WLAN_STATUS) 0xC0010014L)
+#define WLAN_STATUS_INVALID_DATA                ((WLAN_STATUS) 0xC0010015L)
+#define WLAN_STATUS_BUFFER_TOO_SHORT            ((WLAN_STATUS) 0xC0010016L)
+
+#define WLAN_STATUS_BWCS_UPDATE            ((WLAN_STATUS) 0xC0010017L)
+
+#define WLAN_STATUS_CONNECT_INDICATION          ((WLAN_STATUS) 0xC0010018L)
+
+/* NIC status flags */
+#define ADAPTER_FLAG_HW_ERR                     0x00400000
+
+/* Type Length */
+#define TL_IPV4     0x0008
+#define TL_IPV6     0xDD86
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Type definition for GLUE_INFO structure */
+typedef struct _GLUE_INFO_T GLUE_INFO_T, *P_GLUE_INFO_T;
+
+/* Type definition for WLAN STATUS */
+typedef UINT_32 WLAN_STATUS, *P_WLAN_STATUS;
+
+/* Type definition for ADAPTER structure */
+typedef struct _ADAPTER_T ADAPTER_T, *P_ADAPTER_T;
+
+/* Type definition for MESSAGE HEADER structure */
+typedef struct _MSG_HDR_T MSG_HDR_T, *P_MSG_HDR_T;
+
+/* Type definition for WLAN configuration */
+typedef struct _WLAN_CFG_T WLAN_CFG_T, *P_WLAN_CFG_T;
+
+/* Type definition for WLAN configuration entry */
+typedef struct _WLAN_CFG_ENTRY_T WLAN_CFG_ENTRY_T, *P_WLAN_CFG_ENTRY_T;
+
+/* Type definition for WLAN configuration callback */
+typedef WLAN_STATUS(*WLAN_CFG_SET_CB) (P_ADAPTER_T prAdapter,
+				       PUINT_8 pucKey, PUINT_8 pucValue, PVOID pPrivate, UINT_32 u4Flags);
+
+/* Type definition for Pointer to OS Native Packet */
+typedef void *P_NATIVE_PACKET;
+
+/* Type definition for STA_RECORD_T structure to handle the connectivity and packet reception
+ * for a particular STA.
+ */
+typedef struct _STA_RECORD_T STA_RECORD_T, *P_STA_RECORD_T, **PP_STA_RECORD_T;
+
+/* CMD_INFO_T is used by Glue Layer to send a cluster of Command(OID) information to
+ * the TX Path to reduce the parameters of a function call.
+ */
+typedef struct _CMD_INFO_T CMD_INFO_T, *P_CMD_INFO_T;
+
+/* Following typedef should be removed later, because Glue Layer should not
+ * be aware of following data type.
+ */
+typedef struct _SW_RFB_T SW_RFB_T, *P_SW_RFB_T, **PP_SW_RFB_T;
+
+typedef struct _MSDU_INFO_T MSDU_INFO_T, *P_MSDU_INFO_T;
+
+typedef struct _REG_ENTRY_T REG_ENTRY_T, *P_REG_ENTRY_T;
+
+/* IST handler definition */
+typedef VOID(*IST_EVENT_FUNCTION) (P_ADAPTER_T);
+
+/* Type definition for function pointer of timer handler */
+typedef VOID(*PFN_TIMER_CALLBACK) (IN P_GLUE_INFO_T);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _TYPEDEF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h
new file mode 100644
index 0000000000000..e8937166dc4f3
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h
@@ -0,0 +1,352 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_bow.h#1
+*/
+
+/*! \file   "wlan_bow.h"
+    \brief This file contains the declairations of 802.11 PAL
+	   command processing routines for
+	   MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: wlan_bow.h
+ *
+ * 05 25 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Add BoW Cancel Scan Request and Turn On deactive network function.
+ *
+ * 05 23 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Add some BoW error handling.
+ *
+ * 05 21 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Protect BoW connection establishment.
+ *
+ * 05 17 2011 terry.wu
+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting
+ * Send deauth while disconnecting BoW link.
+ *
+ * 05 06 2011 terry.wu
+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue
+ * Fix BoW Multiple Physical Link connect/disconnect issue.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW short range mode.
+ *
+ * 03 27 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support multiple physical link.
+ *
+ * 03 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW table.
+ *
+ * 02 16 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add bowNotifyAllLinkDisconnected  interface and change channel grant procedure for bow starting..
+ *
+ * 02 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update bowString and channel grant.
+ *
+ * 01 11 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update BOW Activity Report structure and bug fix.
+ *
+ * 09 27 2010 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
+ * Update BCM/BoW design and settings.
+ *
+ * 09 14 2010 chinghwa.yu
+ * NULL
+ * Add bowRunEventAAAComplete.
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Update BOW for the 1st time.
+ *
+ * 07 30 2010 cp.wu
+ * NULL
+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
+ *
+ * 07 15 2010 cp.wu
+ *
+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 05 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * 1) all BT physical handles shares the same RSSI/Link Quality.
+ * 2) simplify BT command composing
+ *
+ * 04 28 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change prefix for data structure used to communicate with 802.11 PAL
+ * to avoid ambiguous naming with firmware interface
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add multiple physical link support
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+**
+*/
+
+#ifndef _WLAN_BOW_H
+#define _WLAN_BOW_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "nic/bow.h"
+#include "nic/cmd_buf.h"
+
+#if CFG_ENABLE_BT_OVER_WIFI
+
+#if CFG_BOW_TEST
+extern UINT_32 g_arBowRevPalPacketTime[32];
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define BOWCMD_STATUS_SUCCESS       0
+#define BOWCMD_STATUS_FAILURE       1
+#define BOWCMD_STATUS_UNACCEPTED    2
+#define BOWCMD_STATUS_INVALID       3
+#define BOWCMD_STATUS_TIMEOUT       4
+
+#define BOW_WILDCARD_SSID               "AMP"
+#define BOW_WILDCARD_SSID_LEN       3
+#define BOW_SSID_LEN                            21
+
+ /* 0: query, 1: setup, 2: destroy */
+#define BOW_QUERY_CMD                   0
+#define BOW_SETUP_CMD                   1
+#define BOW_DESTROY_CMD               2
+
+#define BOW_INITIATOR                   0
+#define BOW_RESPONDER                  1
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+typedef struct _BOW_TABLE_T {
+	UINT_8 ucAcquireID;
+	BOOLEAN fgIsValid;
+	ENUM_BOW_DEVICE_STATE eState;
+	UINT_8 aucPeerAddress[6];
+	/* UINT_8                      ucRole; */
+	/* UINT_8                      ucChannelNum; */
+	UINT_16 u2Reserved;
+} BOW_TABLE_T, *P_BOW_TABLE_T;
+
+typedef WLAN_STATUS(*PFN_BOW_CMD_HANDLE) (P_ADAPTER_T, P_AMPC_COMMAND);
+
+typedef struct _BOW_CMD_T {
+	UINT_8 uCmdID;
+	PFN_BOW_CMD_HANDLE pfCmdHandle;
+} BOW_CMD_T, *P_BOW_CMD_T;
+
+typedef struct _BOW_EVENT_ACTIVITY_REPORT_T {
+	UINT_8 ucReason;
+	UINT_8 aucReserved;
+	UINT_8 aucPeerAddress[6];
+} BOW_EVENT_ACTIVITY_REPORT_T, *P_BOW_EVENT_ACTIVITY_REPORT_T;
+
+/*
+ucReason:	0: success
+	1: general failure
+	2: too much time (> 2/3 second totally) requested for scheduling.
+	Others: reserved.
+*/
+
+typedef struct _BOW_EVENT_SYNC_TSF_T {
+	UINT_64 u4TsfTime;
+	UINT_32 u4TsfSysTime;
+	UINT_32 u4ScoTime;
+	UINT_32 u4ScoSysTime;
+} BOW_EVENT_SYNC_TSF_T, *P_BOW_EVENT_SYNC_TSF_T;
+
+typedef struct _BOW_ACTIVITY_REPORT_BODY_T {
+	UINT_32 u4StartTime;
+	UINT_32 u4Duration;
+	UINT_32 u4Periodicity;
+} BOW_ACTIVITY_REPORT_BODY_T, *P_BOW_ACTIVITY_REPORT_BODY_T;
+
+typedef struct _BOW_ACTIVITY_REPORT_T {
+	UINT_8 aucPeerAddress[6];
+	UINT_8 ucScheduleKnown;
+	UINT_8 ucNumReports;
+	BOW_ACTIVITY_REPORT_BODY_T arBowActivityReportBody[MAX_ACTIVITY_REPORT];
+} BOW_ACTIVITY_REPORT_T, *P_BOW_ACTIVITY_REPORT_T;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*--------------------------------------------------------------*/
+/* Firmware Command Packer                                      */
+/*--------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter,
+			  UINT_8 ucCID,
+			  BOOLEAN fgSetQuery,
+			  BOOLEAN fgNeedResp,
+			  PFN_CMD_DONE_HANDLER pfCmdDoneHandler,
+			  PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler,
+			  UINT_32 u4SetQueryInfoLen, PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber);
+
+/*--------------------------------------------------------------*/
+/* Command Dispatcher                                           */
+/*--------------------------------------------------------------*/
+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+/*--------------------------------------------------------------*/
+/* Routines to handle command                                   */
+/*--------------------------------------------------------------*/
+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd);
+
+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf);
+
+/*--------------------------------------------------------------*/
+/* Callbacks for event indication                               */
+/*--------------------------------------------------------------*/
+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+VOID bowStopping(IN P_ADAPTER_T prAdapter);
+
+VOID bowStarting(IN P_ADAPTER_T prAdapter);
+
+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen);
+
+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags);
+
+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+
+VOID bowResponderScan(IN P_ADAPTER_T prAdapter);
+
+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention);
+
+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc);
+
+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID
+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter,
+				ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication);
+
+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb);
+
+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
+
+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode);
+
+BOOLEAN
+bowValidateAuth(IN P_ADAPTER_T prAdapter,
+		IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode);
+
+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr);
+
+VOID bowRequestCh(IN P_ADAPTER_T prAdapter);
+
+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter);
+
+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam);
+
+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]);
+
+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable);
+
+BOOLEAN
+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx);
+
+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx);
+
+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]);
+
+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState);
+
+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif
+#endif /* _WLAN_BOW_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h
new file mode 100644
index 0000000000000..87259397a93d1
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h
@@ -0,0 +1,1001 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_lib.h#1
+*/
+
+/*! \file   "wlan_lib.h"
+    \brief  The declaration of the functions of the wlanAdpater objects
+
+    Detail description.
+*/
+
+/*
+** Log: wlan_lib.h
+ *
+ * 06 08 2012 eason.tsai
+ * NULL
+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool
+ *
+ * 01 16 2012 cp.wu
+ * [MT6620 Wi-Fi][Driver] API and behavior modification for
+ * preferred band configuration with corresponding network configuration
+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for
+ * setting preferred band configuration corresponding to network type.
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 10 03 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * eliminate win32 native data types.
+ *
+ * 10 03 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * add firmware download path in divided scatters.
+ *
+ * 10 03 2011 cp.wu
+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * add firmware downloading aggregated path.
+ *
+ * 09 20 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * change window registry of driver for roaming.
+ *
+ * 09 08 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 08 25 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add DFS switch.
+ *
+ * 08 24 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Update RDD test mode cases.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms.
+ *
+ * 08 02 2011 yuche.tsai
+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client,
+ * TX deauth to a disconnecting device issue.
+ * Fix GO send deauth frame issue.
+ *
+ * 07 22 2011 jeffrey.chang
+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time
+ * modify driver to set OSC stable time after f/w download
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 05 27 2011 cp.wu
+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
+ *
+ * 05 11 2011 cp.wu
+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke.
+ *
+ * 04 18 2011 cp.wu
+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
+ * 1) add API for glue layer to query ACPI state
+ * 2) Windows glue should not access to hardware after switched into D3 state
+ *
+ * 03 10 2011 cp.wu
+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
+ * deprecate configuration used by MT6620 E2
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 27 2011 george.huang
+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability
+ * Support current measure mode, assigned by registry (XP only).
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 10 2011 cp.wu
+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result
+ * in OID handling layer when the corresponding BSS is disconnected due to beacon timeout
+ * remove from scanning result when the BSS is disconnected due to beacon timeout.
+ *
+ * 10 27 2010 george.huang
+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to
+ * disable Beacon Timeout function for SQA test by using E1 EVB
+ * Support registry option for disable beacon lost detection.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 26 2010 eddie.chen
+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB
+ * Add auto rate parameter in registry.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * adding fixed rate support for distance test. (from registry setting)
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * code reorganization to improve isolation between GLUE and CORE layers.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature
+ * Modify online scan as a run-time adjustable option (for Windows, in registry)
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
+ * use firmware reported mac address right after wlanAdapterStart() as permanent address
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add skeleton for NVRAM integration
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * Add AT GO test configure mode under WinXP.
+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * .
+ *
+ * 07 21 2010 cp.wu
+ *
+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term
+ * 2) only clear scanning result when scan is permitted to do
+ *
+ * 07 13 2010 cp.wu
+ *
+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid
+ * descriptor underflow under concurrent network operation
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 24 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change MAC address updating logic.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * simplify timer usage.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * cnm_timer has been migrated.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add extra 64 adjustable parameters for CoEX scenario.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) for some OID, never do timeout expiration
+ *  * 2) add 2 kal API for later integration
+ *
+ * 04 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change to use WIFI_TCM_ALWAYS_ON as firmware image
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted
+ *
+ * 03 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add two option for ACK and ENCRYPTION for firmware download
+ *
+ * 02 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * separate wlanProcesQueuePacket() into 2 APIs upon request
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add new API: wlanProcessQueuedPackets()
+ *
+ * 02 11 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. add logic for firmware download
+ *  *  * 2. firmware image filename and start/load address are now retrieved from registry
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
+ *  *  *  * 2) firmware image length is now retrieved via NdisFileOpen
+ *  *  *  * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
+ *  *  *  * 4) nicRxWaitResponse() revised
+ *  *  *  * 5) another set of TQ counter default value is added for fw-download state
+ *  *  *  * 6) Wi-Fi load address is now retrieved from registry too
+ *
+ * 02 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * prepare for implementing fw download logic
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  *  *  *  *  *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  *  *  *  *  *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  *  *  *  *  *  * 4. correct some HAL implementation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:39:55 GMT mtk02752
+**  eliminate unused API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:58:41 GMT mtk01084
+**  update for new macro define
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-19 10:43:06 GMT mtk01461
+**  Add wlanReleasePendingOid()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-13 16:38:44 GMT mtk01084
+**  add WIFI start function
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-08 16:51:14 GMT mtk01084
+**  Update for the image download part
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:57:38 GMT mtk01461
+**  Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:31:02 GMT mtk01461
+**  Add declaration of FW Image download reference code
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:31 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:04 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _WLAN_LIB_H
+#define _WLAN_LIB_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "CFG_Wifi_File.h"
+#include "rlm_domain.h"
+#include "wlan_typedef.h"
+
+
+extern BOOLEAN fgIsResetting;
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define MAX_NUM_GROUP_ADDR                      32	/* max number of group addresses */
+
+#define TX_CS_TCP_UDP_GEN        BIT(1)
+#define TX_CS_IP_GEN             BIT(0)
+
+#define CSUM_OFFLOAD_EN_TX_TCP      BIT(0)
+#define CSUM_OFFLOAD_EN_TX_UDP      BIT(1)
+#define CSUM_OFFLOAD_EN_TX_IP       BIT(2)
+#define CSUM_OFFLOAD_EN_RX_TCP      BIT(3)
+#define CSUM_OFFLOAD_EN_RX_UDP      BIT(4)
+#define CSUM_OFFLOAD_EN_RX_IPv4     BIT(5)
+#define CSUM_OFFLOAD_EN_RX_IPv6     BIT(6)
+#define CSUM_OFFLOAD_EN_TX_MASK     BITS(0, 2)
+#define CSUM_OFFLOAD_EN_ALL         BITS(0, 6)
+
+/* TCP, UDP, IP Checksum */
+#define RX_CS_TYPE_UDP           BIT(7)
+#define RX_CS_TYPE_TCP           BIT(6)
+#define RX_CS_TYPE_IPv6          BIT(5)
+#define RX_CS_TYPE_IPv4          BIT(4)
+
+#define RX_CS_STATUS_UDP         BIT(3)
+#define RX_CS_STATUS_TCP         BIT(2)
+#define RX_CS_STATUS_IP          BIT(0)
+
+#define CSUM_NOT_SUPPORTED      0x0
+
+#define TXPWR_USE_PDSLOPE 0
+
+/* NVRAM error code definitions */
+#define NVRAM_ERROR_VERSION_MISMATCH        BIT(1)
+#define NVRAM_ERROR_INVALID_TXPWR           BIT(2)
+#define NVRAM_ERROR_INVALID_DPD             BIT(3)
+#define NVRAM_ERROR_INVALID_MAC_ADDR        BIT(4)
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+#define NVRAM_POWER_LIMIT_TABLE_INVALID     BIT(5)
+#endif
+
+#define NUM_TC_RESOURCE_TO_STATISTICS       4
+
+#define WLAN_CFG_ARGV_MAX 8
+#define WLAN_CFG_ENTRY_NUM_MAX 128
+#define WLAN_CFG_KEY_LEN_MAX 32	/* include \x00  EOL */
+#define WLAN_CFG_VALUE_LEN_MAX 32	/* include \x00 EOL */
+#define WLAN_CFG_FLAG_SKIP_CB BIT(0)
+#define WLAN_CFG_FILE_BUF_SIZE 2048
+
+#define WLAN_CFG_SET_CHIP_LEN_MAX 10
+#define WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX 10
+#define WLAN_CFG_SET_SW_CTRL_LEN_MAX 10
+
+#define WLAN_OID_TIMEOUT_THRESHOLD                  2000	/* OID timeout (in ms) */
+#define WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING      300	/* OID timeout during chip-resetting  (in ms) */
+
+#define WLAN_OID_NO_ACK_THRESHOLD                   3
+
+#define WLAN_TX_THREAD_TASK_PRIORITY        0	/* If not setting the priority, 0 is the default */
+#define WLAN_TX_THREAD_TASK_NICE            (-10)	/* If not setting the nice, -10 is the default */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC) (IN P_ADAPTER_T prAdapter,
+					    IN PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen);
+
+typedef enum _ENUM_CSUM_TYPE_T {
+	CSUM_TYPE_IPV4,
+	CSUM_TYPE_IPV6,
+	CSUM_TYPE_TCP,
+	CSUM_TYPE_UDP,
+	CSUM_TYPE_NUM
+} ENUM_CSUM_TYPE_T, *P_ENUM_CSUM_TYPE_T;
+
+typedef enum _ENUM_CSUM_RESULT_T {
+	CSUM_RES_NONE,
+	CSUM_RES_SUCCESS,
+	CSUM_RES_FAILED,
+	CSUM_RES_NUM
+} ENUM_CSUM_RESULT_T, *P_ENUM_CSUM_RESULT_T;
+
+typedef enum _ENUM_PHY_MODE_T {
+	ENUM_PHY_2G4_CCK,
+	ENUM_PHY_2G4_OFDM_BPSK,
+	ENUM_PHY_2G4_OFDM_QPSK,
+	ENUM_PHY_2G4_OFDM_16QAM,
+	ENUM_PHY_2G4_OFDM_48M,
+	ENUM_PHY_2G4_OFDM_54M,
+	ENUM_PHY_2G4_HT20_BPSK,
+	ENUM_PHY_2G4_HT20_QPSK,
+	ENUM_PHY_2G4_HT20_16QAM,
+	ENUM_PHY_2G4_HT20_MCS5,
+	ENUM_PHY_2G4_HT20_MCS6,
+	ENUM_PHY_2G4_HT20_MCS7,
+	ENUM_PHY_2G4_HT40_BPSK,
+	ENUM_PHY_2G4_HT40_QPSK,
+	ENUM_PHY_2G4_HT40_16QAM,
+	ENUM_PHY_2G4_HT40_MCS5,
+	ENUM_PHY_2G4_HT40_MCS6,
+	ENUM_PHY_2G4_HT40_MCS7,
+	ENUM_PHY_5G_OFDM_BPSK,
+	ENUM_PHY_5G_OFDM_QPSK,
+	ENUM_PHY_5G_OFDM_16QAM,
+	ENUM_PHY_5G_OFDM_48M,
+	ENUM_PHY_5G_OFDM_54M,
+	ENUM_PHY_5G_HT20_BPSK,
+	ENUM_PHY_5G_HT20_QPSK,
+	ENUM_PHY_5G_HT20_16QAM,
+	ENUM_PHY_5G_HT20_MCS5,
+	ENUM_PHY_5G_HT20_MCS6,
+	ENUM_PHY_5G_HT20_MCS7,
+	ENUM_PHY_5G_HT40_BPSK,
+	ENUM_PHY_5G_HT40_QPSK,
+	ENUM_PHY_5G_HT40_16QAM,
+	ENUM_PHY_5G_HT40_MCS5,
+	ENUM_PHY_5G_HT40_MCS6,
+	ENUM_PHY_5G_HT40_MCS7,
+	ENUM_PHY_MODE_NUM
+} ENUM_PHY_MODE_T, *P_ENUM_PHY_MODE_T;
+
+typedef enum _ENUM_POWER_SAVE_POLL_MODE_T {
+	ENUM_POWER_SAVE_POLL_DISABLE,
+	ENUM_POWER_SAVE_POLL_LEGACY_NULL,
+	ENUM_POWER_SAVE_POLL_QOS_NULL,
+	ENUM_POWER_SAVE_POLL_NUM
+} ENUM_POWER_SAVE_POLL_MODE_T, *P_ENUM_POWER_SAVE_POLL_MODE_T;
+
+typedef enum _ENUM_AC_TYPE_T {
+	ENUM_AC_TYPE_AC0,
+	ENUM_AC_TYPE_AC1,
+	ENUM_AC_TYPE_AC2,
+	ENUM_AC_TYPE_AC3,
+	ENUM_AC_TYPE_AC4,
+	ENUM_AC_TYPE_AC5,
+	ENUM_AC_TYPE_AC6,
+	ENUM_AC_TYPE_BMC,
+	ENUM_AC_TYPE_NUM
+} ENUM_AC_TYPE_T, *P_ENUM_AC_TYPE_T;
+
+typedef enum _ENUM_ADV_AC_TYPE_T {
+	ENUM_ADV_AC_TYPE_RX_NSW,
+	ENUM_ADV_AC_TYPE_RX_PTA,
+	ENUM_ADV_AC_TYPE_RX_SP,
+	ENUM_ADV_AC_TYPE_TX_PTA,
+	ENUM_ADV_AC_TYPE_TX_RSP,
+	ENUM_ADV_AC_TYPE_NUM
+} ENUM_ADV_AC_TYPE_T, *P_ENUM_ADV_AC_TYPE_T;
+
+typedef enum _ENUM_REG_CH_MAP_T {
+	REG_CH_MAP_COUNTRY_CODE,
+	REG_CH_MAP_TBL_IDX,
+	REG_CH_MAP_CUSTOMIZED,
+	REG_CH_MAP_NUM
+} ENUM_REG_CH_MAP_T, *P_ENUM_REG_CH_MAP_T;
+
+#define CHIP_CONFIG_RESP_SIZE 320
+enum {
+	CHIP_CONFIG_TYPE_WO_RESPONSE = 0x00,
+	CHIP_CONFIG_TYPE_MEM8 = 0x01,
+	CHIP_CONFIG_TYPE_MEM32 = 0x02,
+	CHIP_CONFIG_TYPE_ASCII = 0x03,
+	CHIP_CONFIG_TYPE_BINARY = 0x04,
+	CHIP_CONFIG_TYPE_DRV_PASSTHROUGH = 0x05,
+	CHIP_CONFIG_TYPE_END
+};
+
+typedef struct _SET_TXPWR_CTRL_T {
+	INT_8 c2GLegacyStaPwrOffset;	/* Unit: 0.5dBm, default: 0 */
+	INT_8 c2GHotspotPwrOffset;
+	INT_8 c2GP2pPwrOffset;
+	INT_8 c2GBowPwrOffset;
+	INT_8 c5GLegacyStaPwrOffset;	/* Unit: 0.5dBm, default: 0 */
+	INT_8 c5GHotspotPwrOffset;
+	INT_8 c5GP2pPwrOffset;
+	INT_8 c5GBowPwrOffset;
+	UINT_8 ucConcurrencePolicy;	/* TX power policy when concurrence
+					   in the same channel
+					   0: Highest power has priority
+					   1: Lowest power has priority */
+	INT_8 acReserved1[3];	/* Must be zero */
+
+	/* Power limit by channel for all data rates */
+	INT_8 acTxPwrLimit2G[14];	/* Channel 1~14, Unit: 0.5dBm */
+	INT_8 acTxPwrLimit5G[4];	/* UNII 1~4 */
+	INT_8 acReserved2[2];	/* Must be zero */
+} SET_TXPWR_CTRL_T, *P_SET_TXPWR_CTRL_T;
+
+/* For storing driver initialization value from glue layer */
+typedef struct _REG_INFO_T {
+	UINT_32 u4SdBlockSize;	/* SDIO block size */
+	UINT_32 u4SdBusWidth;	/* SDIO bus width. 1 or 4 */
+	UINT_32 u4SdClockRate;	/* SDIO clock rate. (in unit of HZ) */
+	UINT_32 u4StartAddress;	/* Starting address of Wi-Fi Firmware */
+	UINT_32 u4LoadAddress;	/* Load address of Wi-Fi Firmware */
+	UINT_16 aucFwImgFilename[65];	/* Firmware filename */
+	UINT_16 aucFwImgFilenameE6[65];	/* Firmware filename for E6 */
+	UINT_32 u4StartFreq;	/* Start Frequency for Ad-Hoc network : in unit of KHz */
+	UINT_32 u4AdhocMode;	/* Default mode for Ad-Hoc network : ENUM_PARAM_AD_HOC_MODE_T */
+	UINT_32 u4RddStartFreq;
+	UINT_32 u4RddStopFreq;
+	UINT_32 u4RddTestMode;
+	UINT_32 u4RddShutFreq;
+	UINT_32 u4RddDfs;
+	INT_32 i4HighRssiThreshold;
+	INT_32 i4MediumRssiThreshold;
+	INT_32 i4LowRssiThreshold;
+	INT_32 au4TxPriorityTag[ENUM_AC_TYPE_NUM];
+	INT_32 au4RxPriorityTag[ENUM_AC_TYPE_NUM];
+	INT_32 au4AdvPriorityTag[ENUM_ADV_AC_TYPE_NUM];
+	UINT_32 u4FastPSPoll;
+	UINT_32 u4PTA;		/* 0: disable, 1: enable */
+	UINT_32 u4TXLimit;	/* 0: disable, 1: enable */
+	UINT_32 u4SilenceWindow;	/* range: 100 - 625, unit: us */
+	UINT_32 u4TXLimitThreshold;	/* range: 250 - 1250, unit: us */
+	UINT_32 u4PowerMode;
+	UINT_32 fgEnArpFilter;
+	UINT_32 u4PsCurrentMeasureEn;
+	UINT_32 u4UapsdAcBmp;
+	UINT_32 u4MaxSpLen;
+	UINT_32 fgDisOnlineScan;	/* 0: enable online scan, non-zero: disable online scan */
+	UINT_32 fgDisBcnLostDetection;	/* 0: enable online scan, non-zero: disable online scan */
+	UINT_32 u4FixedRate;	/* 0: automatic, non-zero: fixed rate */
+	UINT_32 u4ArSysParam0;
+	UINT_32 u4ArSysParam1;
+	UINT_32 u4ArSysParam2;
+	UINT_32 u4ArSysParam3;
+	UINT_32 fgDisRoaming;	/* 0:enable roaming 1:disable */
+
+	/* NVRAM - MP Data -START- */
+	UINT_8 aucMacAddr[6];
+	UINT_16 au2CountryCode[4];	/* Country code (in ISO 3166-1 expression, ex: "US", "TW")  */
+	TX_PWR_PARAM_T rTxPwr;
+	UINT_8 aucEFUSE[144];
+	UINT_8 ucTxPwrValid;
+	UINT_8 ucSupport5GBand;
+	UINT_8 fg2G4BandEdgePwrUsed;
+	INT_8 cBandEdgeMaxPwrCCK;
+	INT_8 cBandEdgeMaxPwrOFDM20;
+	INT_8 cBandEdgeMaxPwrOFDM40;
+	ENUM_REG_CH_MAP_T eRegChannelListMap;
+	UINT_8 ucRegChannelListIndex;
+	DOMAIN_INFO_ENTRY rDomainInfo;
+	/* NVRAM - MP Data -END- */
+
+	/* NVRAM - Functional Data -START- */
+	UINT_8 uc2G4BwFixed20M;
+	UINT_8 uc5GBwFixed20M;
+	UINT_8 ucEnable5GBand;
+	UINT_8 uc2GRssiCompensation;
+	UINT_8 uc5GRssiCompensation;
+	UINT_8 fgRssiCompensationValidbit;
+	UINT_8 ucRxAntennanumber;
+	/* NVRAM - Functional Data -END- */
+
+} REG_INFO_T, *P_REG_INFO_T;
+
+/* for divided firmware loading */
+typedef struct _FWDL_SECTION_INFO_T {
+	UINT_32 u4Offset;
+	UINT_32 u4Reserved;
+	UINT_32 u4Length;
+	UINT_32 u4DestAddr;
+} FWDL_SECTION_INFO_T, *P_FWDL_SECTION_INFO_T;
+
+typedef struct _FIRMWARE_DIVIDED_DOWNLOAD_T {
+	UINT_32 u4Signature;
+	UINT_32 u4CRC;		/* CRC calculated without first 8 bytes included */
+	UINT_32 u4NumOfEntries;
+	UINT_32 u4Reserved;
+	FWDL_SECTION_INFO_T arSection[];
+} FIRMWARE_DIVIDED_DOWNLOAD_T, *P_FIRMWARE_DIVIDED_DOWNLOAD_T;
+
+typedef struct _PARAM_MCR_RW_STRUCT_T {
+	UINT_32 u4McrOffset;
+	UINT_32 u4McrData;
+} PARAM_MCR_RW_STRUCT_T, *P_PARAM_MCR_RW_STRUCT_T;
+
+typedef struct _PARAM_GET_STA_STATISTICS {
+	UINT_8 ucInvalid;
+	UINT_8 ucVersion;
+	/* Per-STA statistic */
+	UINT_8 aucMacAddr[MAC_ADDR_LEN];
+	UINT_32 u4LinkScore;
+	UINT_32 u4Flag;
+
+	/* From FW */
+	UINT_8 ucPer;		/* base: 128 */
+	UINT_8 ucRcpi;
+	UINT_32 u4PhyMode;
+	UINT_16 u2LinkSpeed;	/* unit is 0.5 Mbits */
+
+	UINT_32 u4TxFailCount;
+	UINT_32 u4TxLifeTimeoutCount;
+	UINT_32 u4TxAverageAirTime;
+
+	/* From driver */
+	UINT_32 u4TxTotalCount;
+	UINT_32 u4TxExceedThresholdCount;
+	UINT_32 u4TxAverageProcessTime;
+
+	UINT_32 u4TxMaxTime;
+	UINT_32 u4TxMaxHifTime;
+	UINT_32 u4TxAverageHifTime;
+
+	/*
+	 * How many packages Enqueue/Deqeue during statistics interval
+	 */
+	UINT_32 u4EnqueueCounter;
+	UINT_32 u4DequeueCounter;
+
+	UINT_32 u4EnqueueStaCounter;
+	UINT_32 u4DequeueStaCounter;
+
+	UINT_32 IsrCnt;
+	UINT_32 IsrPassCnt;
+	UINT_32 TaskIsrCnt;
+
+	UINT_32 IsrAbnormalCnt;
+	UINT_32 IsrSoftWareCnt;
+	UINT_32 IsrRxCnt;
+	UINT_32 IsrTxCnt;
+
+	UINT_32 au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS];
+	UINT_32 au4DequeueNoTcResource[NUM_TC_RESOURCE_TO_STATISTICS];
+	UINT_32 au4TcResourceBackCount[NUM_TC_RESOURCE_TO_STATISTICS];
+
+	UINT_32 au4TcResourceUsedCount[NUM_TC_RESOURCE_TO_STATISTICS];
+	UINT_32 au4TcResourceWantedCount[NUM_TC_RESOURCE_TO_STATISTICS];
+
+	UINT_32 au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS];
+	/* Global queue management statistic */
+	UINT_32 au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS];
+	UINT_32 au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS];
+
+	/* Reserved fields */
+	UINT_8 au4Reserved[32];
+} PARAM_GET_STA_STA_STATISTICS, *P_PARAM_GET_STA_STATISTICS;
+
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR {
+	NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0,
+	NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1,
+	NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34,
+	NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149,
+	NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184,
+
+	NL80211_TESTMODE_AVAILABLE_CHAN_NUM,
+} ENUM_TESTMODE_AVAILABLE_CHAN_ATTR;
+
+typedef struct _LTE_SAFE_CH_INFO_T {
+	UINT_32 au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1];
+} LTE_SAFE_CH_INFO_T, *P_CMD_LTE_SAFE_CH_INFO_T;
+
+    /* Record Each CH Load */
+typedef struct _PARAM_CHN_LOAD_INFO {
+	/* Per-CHN Load */
+	UINT_32 u4Flag;
+
+	UINT_8 ucChannel;
+	UINT_16 u2ChannelLoad;
+	UINT_8 au4Reserved[1];
+
+	UINT_16 u2APNum;
+	UINT_16 u2APNumTmpCountingBuf;
+
+	/* Reserved fields */
+	UINT_8 au4Reserved1[8];
+} PARAM_CHN_LOAD_INFO, *P_PARAM_CHN_LOAD_INFO;
+
+typedef struct _PARAM_GET_CHN_LOAD {
+	LTE_SAFE_CH_INFO_T rLteSafeChnList;
+	PARAM_CHN_LOAD_INFO rEachChnLoad[MAX_AUTO_CHAL_NUM];
+	BOOLEAN fgDataReadyBit;
+	UINT_8 au4Reserved1[3];
+} PARAM_GET_CHN_LOAD, *P_PARAM_GET_CHN_LOAD;
+
+typedef struct _PARAM_PREFER_CHN_INFO {
+
+	UINT_8 ucChannel;
+	UINT_16 u2APNum;
+	UINT_8 au4Reserved1[1];
+} PARAM_PREFER_CHN_INFO, *P_PARAM_PREFER_CHN_INFO;
+
+typedef struct _PARAM_GET_LTE_MODE {
+	/* Event Body */
+	UINT_8 ucVersion;
+	UINT_8 aucReserved1[3];
+	UINT_32 u4Flags;	/* Bit0: valid */
+
+	LTE_SAFE_CH_INFO_T LTE_MODE;
+	UINT_8 aucReserved4[3];
+
+	UINT_8 aucReserved[4];
+
+} PARAM_GET_LTE_MODE, *P_PARAM_GET_LTE_MODE;
+
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define BUILD_SIGN(ch0, ch1, ch2, ch3) \
+	((UINT_32)(UINT_8)(ch0) | ((UINT_32)(UINT_8)(ch1) << 8) |   \
+	((UINT_32)(UINT_8)(ch2) << 16) | ((UINT_32)(UINT_8)(ch3) << 24))
+
+#define MTK_WIFI_SIGNATURE BUILD_SIGN('M', 'T', 'K', 'W')
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter);
+
+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter);
+
+VOID wlanIST(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl);
+
+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue);
+
+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData);
+
+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType);
+
+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket);
+
+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData);
+
+WLAN_STATUS
+wlanQueryInformation(IN P_ADAPTER_T prAdapter,
+		     IN PFN_OID_HANDLER_FUNC pfOidQryHandler,
+		     IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen);
+
+WLAN_STATUS
+wlanSetInformation(IN P_ADAPTER_T prAdapter,
+		   IN PFN_OID_HANDLER_FUNC pfOidSetHandler,
+		   IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanAdapterStart(IN P_ADAPTER_T prAdapter,
+		 IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength);
+
+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter);
+
+#if CFG_SUPPORT_WAPI
+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter);
+#endif
+
+VOID wlanReturnRxPacket(IN PVOID pvAdapter, IN PVOID pvPacket);
+
+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast);
+
+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo);
+
+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode);
+
+#if CFG_ENABLE_FW_DOWNLOAD
+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
+WLAN_STATUS
+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter,
+				   IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf);
+#endif
+
+WLAN_STATUS
+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter,
+			 IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf);
+
+#if !CFG_ENABLE_FW_DOWNLOAD_ACK
+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter);
+#else
+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum);
+#endif
+
+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress);
+
+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len);
+
+#endif
+
+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode);
+
+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo);
+
+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead);
+
+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead);
+
+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler);
+
+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter);
+
+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter);
+
+/* Security Frame Handling */
+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket);
+
+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+
+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo);
+
+/*----------------------------------------------------------------------------*/
+/* OID/IOCTL Handling                                                         */
+/*----------------------------------------------------------------------------*/
+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter);
+
+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID);
+
+#if CFG_TEST_WIFI_DIRECT_GO
+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter);
+
+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter);
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* Address Retrieve by Polling                                                */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* NIC Capability Retrieve by Polling                                         */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* NIC Capability Retrieve by Polling                                         */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* Compiler Flags Retrieve by Polling                                         */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* PD MCR Retrieve by Polling                                         */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, IN P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo);
+/*----------------------------------------------------------------------------*/
+/* Loading Manufacture Data                                                   */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo);
+
+/*----------------------------------------------------------------------------*/
+/* Media Stream Mode                                                          */
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* Timer Timeout Check (for Glue Layer)                                       */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* Mailbox Message Check (for Glue Layer)                                     */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* TX Pending Packets Handling (for Glue Layer)                               */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket);
+
+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess);
+
+/*----------------------------------------------------------------------------*/
+/* Low Power Acquire/Release (for Glue Layer)                                 */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter);
+
+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* Pending Packets Number Reporting (for Glue Layer)                          */
+/*----------------------------------------------------------------------------*/
+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* ACPI state inquiry (for Glue Layer)                                        */
+/*----------------------------------------------------------------------------*/
+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter);
+
+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState);
+
+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* get ECO version from Revision ID register (for Win32)                      */
+/*----------------------------------------------------------------------------*/
+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* set preferred band configuration corresponding to network type             */
+/*----------------------------------------------------------------------------*/
+VOID
+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+/*----------------------------------------------------------------------------*/
+/* get currently operating channel information                                */
+/*----------------------------------------------------------------------------*/
+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+/*----------------------------------------------------------------------------*/
+/* get BSS Descriptor information                                             */
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex);
+
+/*----------------------------------------------------------------------------*/
+/* check for system configuration to generate message on scan list            */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter);
+
+/*----------------------------------------------------------------------------*/
+/* query sta statistics information from driver and firmware                  */
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]);
+
+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey);
+
+WLAN_STATUS
+wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags);
+
+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef);
+
+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef);
+
+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value);
+
+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags);
+
+WLAN_STATUS
+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags);
+
+#if CFG_SUPPORT_CFG_FILE
+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags);
+
+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter);
+#endif /* CFG_SUPPORT_CFG_FILE */
+
+extern VOID mtk_wcn_wmt_set_wifi_ver(UINT_32 Value);
+
+#endif /* _WLAN_LIB_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h
new file mode 100644
index 0000000000000..45919df996e95
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h
@@ -0,0 +1,1715 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_oid.h#2
+*/
+
+/*! \file   "wlan_oid.h"
+    \brief This file contains the declairation file of the WLAN OID processing routines
+	   of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: wlan_oid.h
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 03 22 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * link with supplicant commands
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 02 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * Support UAPSD/OppPS/NoA parameter setting
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Add Oid for sw control debug command
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * adding fixed rate support for distance test. (from registry setting)
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add skeleton for NVRAM integration
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * Finish SLT TX/RX & Rate Changing Support.
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * revert changelist #15371, efuse read/write access will be done by RF test approach
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * add OID definitions for EFUSE read/write access.
+ *
+ * 08 04 2010 yarco.yang
+ * NULL
+ * Add TX_AMPDU and ADDBA_REJECT command
+ *
+ * 08 02 2010 george.huang
+ * NULL
+ * add WMM-PS test related OID/ CMD handlers
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration from MT6620 firmware.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wlan_def.h.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * move timer callback to glue layer.
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 18 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement Wakeup-on-LAN except firmware integration part
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS.
+ *
+
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 05 13 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add NULL OID implementation for WOL-related OIDs.
+ *
+ * 04 22 2010 cp.wu
+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support
+ * enable RX filter OID
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * information buffer for query oid/ioctl is now buffered in prCmdInfo
+ *  *  *  *  * instead of glue-layer variable to improve multiple oid/ioctl capability
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * indicate media stream mode after set is done
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement custom OID: EEPROM read/write access
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  *  *  *  *  * 2. follow MSDN defined behavior when associates to another AP
+ *  *  *  *  *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) implement timeout mechanism when OID is pending for longer than 1 second
+ *  *  * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on
+ *
+ * 01 27 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * .
+ *
+ * 01 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement following 802.11 OIDs:
+ *  *  *  * OID_802_11_RSSI,
+ *  *  *  * OID_802_11_RSSI_TRIGGER,
+ *  *  *  * OID_802_11_STATISTICS,
+ *  *  *  * OID_802_11_DISASSOCIATE,
+ *  *  *  * OID_802_11_POWER_MODE
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_11_MEDIA_STREAM_MODE
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-08 11:38:11 GMT mtk02752
+**  add declares for RF test related APIs
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-24 22:41:53 GMT mtk02752
+**  remove u4SysTime, MSDN 10-second will be implemented in FW side
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 20:30:13 GMT mtk02752
+**  add u4SysTime field in PARAM_BSSID_EX_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-12 19:48:35 GMT mtk02752
+**  allow upper layer to set a packet filter with PROMISCUOUS mode
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:12 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _WLAN_OID_H
+#define _WLAN_OID_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#if DBG
+extern UINT_8 aucDebugModule[DBG_MODULE_NUM];
+extern UINT_32 u4DebugModule;
+UINT_32 u4DebugModuleTemp;
+#endif /* DBG */
+extern int sprintf(char *buf, const char *fmt, ...);
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define PARAM_MAX_LEN_SSID                      32
+
+#define PARAM_MAC_ADDR_LEN                      6
+
+#define ETHERNET_HEADER_SZ                      14
+#define ETHERNET_MIN_PKT_SZ                     60
+#define ETHERNET_MAX_PKT_SZ                     1514
+
+#define PARAM_MAX_LEN_RATES                     8
+#define PARAM_MAX_LEN_RATES_EX                  16
+
+#define PARAM_AUTH_REQUEST_REAUTH               0x01
+#define PARAM_AUTH_REQUEST_KEYUPDATE            0x02
+#define PARAM_AUTH_REQUEST_PAIRWISE_ERROR       0x06
+#define PARAM_AUTH_REQUEST_GROUP_ERROR          0x0E
+
+#define PARAM_EEPROM_READ_METHOD_READ           1
+#define PARAM_EEPROM_READ_METHOD_GETSIZE        0
+
+#define PARAM_WHQL_RSSI_MAX_DBM                 (-10)
+#define PARAM_WHQL_RSSI_MIN_DBM                 (-200)
+
+#define PARAM_DEVICE_WAKE_UP_ENABLE                     0x00000001
+#define PARAM_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE       0x00000002
+#define PARAM_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE        0x00000004
+
+#define PARAM_WAKE_UP_MAGIC_PACKET              0x00000001
+#define PARAM_WAKE_UP_PATTERN_MATCH             0x00000002
+#define PARAM_WAKE_UP_LINK_CHANGE               0x00000004
+
+/* Packet filter bit definitioin (UINT_32 bit-wise definition) */
+#define PARAM_PACKET_FILTER_DIRECTED            0x00000001
+#define PARAM_PACKET_FILTER_MULTICAST           0x00000002
+#define PARAM_PACKET_FILTER_ALL_MULTICAST       0x00000004
+#define PARAM_PACKET_FILTER_BROADCAST           0x00000008
+#define PARAM_PACKET_FILTER_PROMISCUOUS         0x00000020
+#define PARAM_PACKET_FILTER_ALL_LOCAL           0x00000080
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+#define PARAM_PACKET_FILTER_P2P_MASK             0xC0000000
+#define PARAM_PACKET_FILTER_PROBE_REQ           0x80000000
+#define PARAM_PACKET_FILTER_ACTION_FRAME      0x40000000
+#endif
+
+#if CFG_SLT_SUPPORT
+#define PARAM_PACKET_FILTER_SUPPORTED   (PARAM_PACKET_FILTER_DIRECTED | \
+					 PARAM_PACKET_FILTER_MULTICAST | \
+					 PARAM_PACKET_FILTER_BROADCAST | \
+					 PARAM_PACKET_FILTER_ALL_MULTICAST)
+#else
+#define PARAM_PACKET_FILTER_SUPPORTED   (PARAM_PACKET_FILTER_DIRECTED | \
+					 PARAM_PACKET_FILTER_MULTICAST | \
+					 PARAM_PACKET_FILTER_BROADCAST)
+#endif
+
+#define PARAM_MEM_DUMP_MAX_SIZE         2048
+
+#define BT_PROFILE_PARAM_LEN        8
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Parameters of User Configuration which match to NDIS5.1                    */
+/*----------------------------------------------------------------------------*/
+/* NDIS_802_11_AUTHENTICATION_MODE */
+typedef enum _ENUM_PARAM_AUTH_MODE_T {
+	AUTH_MODE_OPEN,		/*!< Open system */
+	AUTH_MODE_SHARED,	/*!< Shared key */
+	AUTH_MODE_AUTO_SWITCH,	/*!< Either open system or shared key */
+	AUTH_MODE_WPA,
+	AUTH_MODE_WPA_PSK,
+	AUTH_MODE_WPA_NONE,	/*!< For Ad hoc */
+	AUTH_MODE_WPA2,
+	AUTH_MODE_WPA2_PSK,
+	AUTH_MODE_NUM		/*!< Upper bound, not real case */
+} ENUM_PARAM_AUTH_MODE_T, *P_ENUM_PARAM_AUTH_MODE_T;
+
+/* NDIS_802_11_ENCRYPTION_STATUS *//* Encryption types */
+typedef enum _ENUM_WEP_STATUS_T {
+	ENUM_WEP_ENABLED,
+	ENUM_ENCRYPTION1_ENABLED = ENUM_WEP_ENABLED,
+	ENUM_WEP_DISABLED,
+	ENUM_ENCRYPTION_DISABLED = ENUM_WEP_DISABLED,
+	ENUM_WEP_KEY_ABSENT,
+	ENUM_ENCRYPTION1_KEY_ABSENT = ENUM_WEP_KEY_ABSENT,
+	ENUM_WEP_NOT_SUPPORTED,
+	ENUM_ENCRYPTION_NOT_SUPPORTED = ENUM_WEP_NOT_SUPPORTED,
+	ENUM_ENCRYPTION2_ENABLED,
+	ENUM_ENCRYPTION2_KEY_ABSENT,
+	ENUM_ENCRYPTION3_ENABLED,
+	ENUM_ENCRYPTION3_KEY_ABSENT
+} ENUM_PARAM_ENCRYPTION_STATUS_T, *P_ENUM_PARAM_ENCRYPTION_STATUS_T;
+
+typedef UINT_8 PARAM_MAC_ADDRESS[PARAM_MAC_ADDR_LEN];
+
+typedef UINT_32 PARAM_KEY_INDEX;
+typedef UINT_64 PARAM_KEY_RSC;
+typedef INT_32 PARAM_RSSI;
+
+typedef UINT_32 PARAM_FRAGMENTATION_THRESHOLD;
+typedef UINT_32 PARAM_RTS_THRESHOLD;
+
+typedef UINT_8 PARAM_RATES[PARAM_MAX_LEN_RATES];
+typedef UINT_8 PARAM_RATES_EX[PARAM_MAX_LEN_RATES_EX];
+
+typedef enum _ENUM_PARAM_PHY_TYPE_T {
+	PHY_TYPE_802_11ABG = 0,	/*!< Can associated with 802.11abg AP,
+				Scan dual band. */
+	PHY_TYPE_802_11BG,	/*!< Can associated with 802_11bg AP,
+				Scan single band and not report 802_11a BSSs. */
+	PHY_TYPE_802_11G,	/*!< Can associated with 802_11g only AP,
+				Scan single band and not report 802_11ab BSSs. */
+	PHY_TYPE_802_11A,	/*!< Can associated with 802_11a only AP,
+				Scan single band and not report 802_11bg BSSs. */
+	PHY_TYPE_802_11B,	/*!< Can associated with 802_11b only AP,
+				Scan single band and not report 802_11ag BSSs. */
+	PHY_TYPE_NUM		/* 5 */
+} ENUM_PARAM_PHY_TYPE_T, *P_ENUM_PARAM_PHY_TYPE_T;
+
+typedef enum _ENUM_PARAM_OP_MODE_T {
+	NET_TYPE_IBSS = 0,	/*!< Try to merge/establish an AdHoc, do periodic SCAN for merging. */
+	NET_TYPE_INFRA,		/*!< Try to join an Infrastructure, do periodic SCAN for joining. */
+	NET_TYPE_AUTO_SWITCH,	/*!< Try to join an Infrastructure, if fail then try to merge or
+				   establish an AdHoc, do periodic SCAN for joining or merging. */
+	NET_TYPE_DEDICATED_IBSS,	/*!< Try to merge an AdHoc first,
+					if fail then establish AdHoc permanently, no more SCAN. */
+	NET_TYPE_NUM		/* 4 */
+} ENUM_PARAM_OP_MODE_T, *P_ENUM_PARAM_OP_MODE_T;
+
+typedef struct _PARAM_SSID_T {
+	UINT_32 u4SsidLen;	/*!< SSID length in bytes. Zero length is broadcast(any) SSID */
+	UINT_8 aucSsid[PARAM_MAX_LEN_SSID];
+	UINT_32 u4CenterFreq;
+} PARAM_SSID_T, *P_PARAM_SSID_T;
+
+typedef struct _PARAM_CONNECT_T {
+	UINT_32 u4SsidLen;	/*!< SSID length in bytes. Zero length is broadcast(any) SSID */
+	UINT_8 *pucSsid;
+	UINT_8 *pucBssid;
+	UINT_32 u4CenterFreq;
+} PARAM_CONNECT_T, *P_PARAM_CONNECT_T;
+
+/* This is enum defined for user to select an AdHoc Mode */
+typedef enum _ENUM_PARAM_AD_HOC_MODE_T {
+	AD_HOC_MODE_11B = 0,	/*!< Create 11b IBSS if we support 802.11abg/802.11bg. */
+	AD_HOC_MODE_MIXED_11BG,	/*!< Create 11bg mixed IBSS if we support 802.11abg/802.11bg/802.11g. */
+	AD_HOC_MODE_11G,	/*!< Create 11g only IBSS if we support 802.11abg/802.11bg/802.11g. */
+	AD_HOC_MODE_11A,	/*!< Create 11a only IBSS if we support 802.11abg. */
+	AD_HOC_MODE_NUM		/* 4 */
+} ENUM_PARAM_AD_HOC_MODE_T, *P_ENUM_PARAM_AD_HOC_MODE_T;
+
+typedef enum _ENUM_PARAM_MEDIA_STATE_T {
+	PARAM_MEDIA_STATE_CONNECTED,
+	PARAM_MEDIA_STATE_DISCONNECTED,
+	PARAM_MEDIA_STATE_TO_BE_INDICATED	/* for following MSDN re-association behavior */
+} ENUM_PARAM_MEDIA_STATE_T, *P_ENUM_PARAM_MEDIA_STATE_T;
+
+typedef enum _ENUM_PARAM_NETWORK_TYPE_T {
+	PARAM_NETWORK_TYPE_FH,
+	PARAM_NETWORK_TYPE_DS,
+	PARAM_NETWORK_TYPE_OFDM5,
+	PARAM_NETWORK_TYPE_OFDM24,
+	PARAM_NETWORK_TYPE_AUTOMODE,
+	PARAM_NETWORK_TYPE_NUM	/*!< Upper bound, not real case */
+} ENUM_PARAM_NETWORK_TYPE_T, *P_ENUM_PARAM_NETWORK_TYPE_T;
+
+typedef struct _PARAM_NETWORK_TYPE_LIST {
+	UINT_32 NumberOfItems;	/*!< At least 1 */
+	ENUM_PARAM_NETWORK_TYPE_T eNetworkType[1];
+} PARAM_NETWORK_TYPE_LIST, *PPARAM_NETWORK_TYPE_LIST;
+
+typedef enum _ENUM_PARAM_PRIVACY_FILTER_T {
+	PRIVACY_FILTER_ACCEPT_ALL,
+	PRIVACY_FILTER_8021xWEP,
+	PRIVACY_FILTER_NUM
+} ENUM_PARAM_PRIVACY_FILTER_T, *P_ENUM_PARAM_PRIVACY_FILTER_T;
+
+typedef enum _ENUM_RELOAD_DEFAULTS {
+	ENUM_RELOAD_WEP_KEYS
+} PARAM_RELOAD_DEFAULTS, *P_PARAM_RELOAD_DEFAULTS;
+
+typedef struct _PARAM_PM_PACKET_PATTERN {
+	UINT_32 Priority;	/* Importance of the given pattern. */
+	UINT_32 Reserved;	/* Context information for transports. */
+	UINT_32 MaskSize;	/* Size in bytes of the pattern mask. */
+	UINT_32 PatternOffset;	/* Offset from beginning of this */
+	/* structure to the pattern bytes. */
+	UINT_32 PatternSize;	/* Size in bytes of the pattern. */
+	UINT_32 PatternFlags;	/* Flags (TBD). */
+} PARAM_PM_PACKET_PATTERN, *P_PARAM_PM_PACKET_PATTERN;
+
+/*--------------------------------------------------------------*/
+/*! \brief Struct definition to indicate specific event.                */
+/*--------------------------------------------------------------*/
+typedef enum _ENUM_STATUS_TYPE_T {
+	ENUM_STATUS_TYPE_AUTHENTICATION,
+	ENUM_STATUS_TYPE_MEDIA_STREAM_MODE,
+	ENUM_STATUS_TYPE_CANDIDATE_LIST,
+	ENUM_STATUS_TYPE_NUM	/*!< Upper bound, not real case */
+} ENUM_STATUS_TYPE_T, *P_ENUM_STATUS_TYPE_T;
+
+typedef struct _PARAM_802_11_CONFIG_FH_T {
+	UINT_32 u4Length;	/*!< Length of structure */
+	UINT_32 u4HopPattern;	/*!< Defined as 802.11 */
+	UINT_32 u4HopSet;	/*!< to one if non-802.11 */
+	UINT_32 u4DwellTime;	/*!< In unit of Kusec */
+} PARAM_802_11_CONFIG_FH_T, *P_PARAM_802_11_CONFIG_FH_T;
+
+typedef struct _PARAM_802_11_CONFIG_T {
+	UINT_32 u4Length;	/*!< Length of structure */
+	UINT_32 u4BeaconPeriod;	/*!< In unit of Kusec */
+	UINT_32 u4ATIMWindow;	/*!< In unit of Kusec */
+	UINT_32 u4DSConfig;	/*!< Channel frequency in unit of kHz */
+	PARAM_802_11_CONFIG_FH_T rFHConfig;
+} PARAM_802_11_CONFIG_T, *P_PARAM_802_11_CONFIG_T;
+
+typedef struct _PARAM_STATUS_INDICATION_T {
+	ENUM_STATUS_TYPE_T eStatusType;
+} PARAM_STATUS_INDICATION_T, *P_PARAM_STATUS_INDICATION_T;
+
+typedef struct _PARAM_AUTH_REQUEST_T {
+	UINT_32 u4Length;	/*!< Length of this struct */
+	PARAM_MAC_ADDRESS arBssid;
+	UINT_32 u4Flags;	/*!< Definitions are as follows */
+} PARAM_AUTH_REQUEST_T, *P_PARAM_AUTH_REQUEST_T;
+
+typedef struct _PARAM_AUTH_EVENT_T {
+	PARAM_STATUS_INDICATION_T rStatus;
+	PARAM_AUTH_REQUEST_T arRequest[1];
+} PARAM_AUTH_EVENT_T, *P_PARAM_AUTH_EVENT_T;
+
+/*! \brief Capabilities, privacy, rssi and IEs of each BSSID */
+typedef struct _PARAM_BSSID_EX_T {
+	UINT_32 u4Length;	/*!< Length of structure */
+	PARAM_MAC_ADDRESS arMacAddress;	/*!< BSSID */
+	UINT_8 Reserved[2];
+	PARAM_SSID_T rSsid;	/*!< SSID */
+	UINT_32 u4Privacy;	/*!< Need WEP encryption */
+	PARAM_RSSI rRssi;	/*!< in dBm */
+	ENUM_PARAM_NETWORK_TYPE_T eNetworkTypeInUse;
+	PARAM_802_11_CONFIG_T rConfiguration;
+	ENUM_PARAM_OP_MODE_T eOpMode;
+	PARAM_RATES_EX rSupportedRates;
+	UINT_32 u4IELength;
+	UINT_8 aucIEs[1];
+} PARAM_BSSID_EX_T, *P_PARAM_BSSID_EX_T;
+
+typedef struct _PARAM_BSSID_LIST_EX {
+	UINT_32 u4NumberOfItems;	/*!< at least 1 */
+	PARAM_BSSID_EX_T arBssid[1];
+} PARAM_BSSID_LIST_EX_T, *P_PARAM_BSSID_LIST_EX_T;
+
+typedef struct _PARAM_WEP_T {
+	UINT_32 u4Length;	/*!< Length of structure */
+	UINT_32 u4KeyIndex;	/*!< 0: pairwise key, others group keys */
+	UINT_32 u4KeyLength;	/*!< Key length in bytes */
+	UINT_8 aucKeyMaterial[32];	/*!< Key content by above setting */
+} PARAM_WEP_T, *P_PARAM_WEP_T;
+
+/*! \brief Key mapping of BSSID */
+typedef struct _PARAM_KEY_T {
+	UINT_32 u4Length;	/*!< Length of structure */
+	UINT_32 u4KeyIndex;	/*!< KeyID */
+	UINT_32 u4KeyLength;	/*!< Key length in bytes */
+	PARAM_MAC_ADDRESS arBSSID;	/*!< MAC address */
+	PARAM_KEY_RSC rKeyRSC;
+	UINT_8 aucKeyMaterial[32];	/*!< Key content by above setting */
+} PARAM_KEY_T, *P_PARAM_KEY_T;
+
+typedef struct _PARAM_REMOVE_KEY_T {
+	UINT_32 u4Length;	/*!< Length of structure */
+	UINT_32 u4KeyIndex;	/*!< KeyID */
+	PARAM_MAC_ADDRESS arBSSID;	/*!< MAC address */
+} PARAM_REMOVE_KEY_T, *P_PARAM_REMOVE_KEY_T;
+
+#if CFG_SUPPORT_WAPI
+typedef enum _ENUM_KEY_TYPE {
+	ENUM_WPI_PAIRWISE_KEY = 0,
+	ENUM_WPI_GROUP_KEY
+} ENUM_KEY_TYPE;
+
+typedef enum _ENUM_WPI_PROTECT_TYPE {
+	ENUM_WPI_NONE,
+	ENUM_WPI_RX,
+	ENUM_WPI_TX,
+	ENUM_WPI_RX_TX
+} ENUM_WPI_PROTECT_TYPE;
+
+typedef struct _PARAM_WPI_KEY_T {
+	ENUM_KEY_TYPE eKeyType;
+	ENUM_WPI_PROTECT_TYPE eDirection;
+	UINT_8 ucKeyID;
+	UINT_8 aucRsv[3];
+	UINT_8 aucAddrIndex[12];
+	UINT_32 u4LenWPIEK;
+	UINT_8 aucWPIEK[256];
+	UINT_32 u4LenWPICK;
+	UINT_8 aucWPICK[256];
+	UINT_8 aucPN[16];
+} PARAM_WPI_KEY_T, *P_PARAM_WPI_KEY_T;
+#endif
+
+typedef enum _PARAM_POWER_MODE {
+	Param_PowerModeCAM,
+	Param_PowerModeMAX_PSP,
+	Param_PowerModeFast_PSP,
+#if CFG_SUPPORT_DBG_POWERMODE
+	Param_PowerModeKeepActiveOn,	/* privilege mode, always active */
+	Param_PowerModeKeepActiveOff,	/* to leave privilege mode */
+#endif
+	Param_PowerModeMax	/* Upper bound, not real case */
+} PARAM_POWER_MODE, *PPARAM_POWER_MODE;
+
+typedef enum _PARAM_DEVICE_POWER_STATE {
+	ParamDeviceStateUnspecified = 0,
+	ParamDeviceStateD0,
+	ParamDeviceStateD1,
+	ParamDeviceStateD2,
+	ParamDeviceStateD3,
+	ParamDeviceStateMaximum
+} PARAM_DEVICE_POWER_STATE, *PPARAM_DEVICE_POWER_STATE;
+
+#if CFG_SUPPORT_802_11D
+
+/*! \brief The enumeration definitions for OID_IPN_MULTI_DOMAIN_CAPABILITY */
+typedef enum _PARAM_MULTI_DOMAIN_CAPABILITY {
+	ParamMultiDomainCapDisabled,
+	ParamMultiDomainCapEnabled
+} PARAM_MULTI_DOMAIN_CAPABILITY, *P_PARAM_MULTI_DOMAIN_CAPABILITY;
+#endif
+
+typedef struct _COUNTRY_STRING_ENTRY {
+	UINT_8 aucCountryCode[2];
+	UINT_8 aucEnvironmentCode[2];
+} COUNTRY_STRING_ENTRY, *P_COUNTRY_STRING_ENTRY;
+
+/* Power management related definition and enumerations */
+#define UAPSD_NONE                              0
+#define UAPSD_AC0                               (BIT(0) | BIT(4))
+#define UAPSD_AC1                               (BIT(1) | BIT(5))
+#define UAPSD_AC2                               (BIT(2) | BIT(6))
+#define UAPSD_AC3                               (BIT(3) | BIT(7))
+#define UAPSD_ALL                               (UAPSD_AC0 | UAPSD_AC1 | UAPSD_AC2 | UAPSD_AC3)
+
+typedef enum _ENUM_POWER_SAVE_PROFILE_T {
+	ENUM_PSP_CONTINUOUS_ACTIVE = 0,
+	ENUM_PSP_CONTINUOUS_POWER_SAVE,
+	ENUM_PSP_FAST_SWITCH,
+	ENUM_PSP_NUM
+} ENUM_POWER_SAVE_PROFILE_T, *PENUM_POWER_SAVE_PROFILE_T;
+
+/*--------------------------------------------------------------*/
+/*! \brief Set/Query testing type.                              */
+/*--------------------------------------------------------------*/
+typedef struct _PARAM_802_11_TEST_T {
+	UINT_32 u4Length;
+	UINT_32 u4Type;
+	union {
+		PARAM_AUTH_EVENT_T AuthenticationEvent;
+		PARAM_RSSI RssiTrigger;
+	} u;
+} PARAM_802_11_TEST_T, *P_PARAM_802_11_TEST_T;
+
+/*--------------------------------------------------------------*/
+/*! \brief Set/Query authentication and encryption capability.  */
+/*--------------------------------------------------------------*/
+typedef struct _PARAM_AUTH_ENCRYPTION_T {
+	ENUM_PARAM_AUTH_MODE_T eAuthModeSupported;
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncryptStatusSupported;
+} PARAM_AUTH_ENCRYPTION_T, *P_PARAM_AUTH_ENCRYPTION_T;
+
+typedef struct _PARAM_CAPABILITY_T {
+	UINT_32 u4Length;
+	UINT_32 u4Version;
+	UINT_32 u4NoOfPMKIDs;
+	UINT_32 u4NoOfAuthEncryptPairsSupported;
+	PARAM_AUTH_ENCRYPTION_T arAuthenticationEncryptionSupported[1];
+} PARAM_CAPABILITY_T, *P_PARAM_CAPABILITY_T;
+
+typedef UINT_8 PARAM_PMKID_VALUE[16];
+
+typedef struct _PARAM_BSSID_INFO_T {
+	PARAM_MAC_ADDRESS arBSSID;
+	PARAM_PMKID_VALUE arPMKID;
+} PARAM_BSSID_INFO_T, *P_PARAM_BSSID_INFO_T;
+
+typedef struct _PARAM_PMKID_T {
+	UINT_32 u4Length;
+	UINT_32 u4BSSIDInfoCount;
+	PARAM_BSSID_INFO_T arBSSIDInfo[1];
+} PARAM_PMKID_T, *P_PARAM_PMKID_T;
+
+/*! \brief PMKID candidate lists. */
+typedef struct _PARAM_PMKID_CANDIDATE_T {
+	PARAM_MAC_ADDRESS arBSSID;
+	UINT_32 u4Flags;
+} PARAM_PMKID_CANDIDATE_T, *P_PARAM_PMKID_CANDIDATE_T;
+
+/* #ifdef LINUX */
+typedef struct _PARAM_PMKID_CANDIDATE_LIST_T {
+	UINT_32 u4Version;	/*!< Version */
+	UINT_32 u4NumCandidates;	/*!< How many candidates follow */
+	PARAM_PMKID_CANDIDATE_T arCandidateList[1];
+} PARAM_PMKID_CANDIDATE_LIST_T, *P_PARAM_PMKID_CANDIDATE_LIST_T;
+/* #endif */
+
+typedef struct _PARAM_CUSTOM_MCR_RW_STRUCT_T {
+	UINT_32 u4McrOffset;
+	UINT_32 u4McrData;
+} PARAM_CUSTOM_MCR_RW_STRUCT_T, *P_PARAM_CUSTOM_MCR_RW_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_MEM_DUMP_STRUCT_T {
+	UINT_32 u4Address;
+	UINT_32 u4Length;
+	UINT_32 u4RemainLength;
+	UINT_8 ucFragNum;
+} PARAM_CUSTOM_MEM_DUMP_STRUCT_T, *P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_SW_CTRL_STRUCT_T {
+	UINT_32 u4Id;
+	UINT_32 u4Data;
+} PARAM_CUSTOM_SW_CTRL_STRUCT_T, *P_PARAM_CUSTOM_SW_CTRL_STRUCT_T;
+
+typedef struct _CMD_CHIP_CONFIG_T {
+	UINT_16 u2Id;
+	UINT_8 ucType;
+	UINT_8 ucRespType;
+	UINT_16 u2MsgSize;
+	UINT_8 aucReserved0[2];
+	UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE];
+} CMD_CHIP_CONFIG_T, *P_CMD_CHIP_CONFIG_T;
+
+typedef struct _PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T {
+	UINT_16 u2Id;
+	UINT_8 ucType;
+	UINT_8 ucRespType;
+	UINT_16 u2MsgSize;
+	UINT_8 aucReserved0[2];
+	UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE];
+} PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T, *P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_KEY_CFG_STRUCT_T {
+	UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX];
+	UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX];
+} PARAM_CUSTOM_KEY_CFG_STRUCT_T, *P_PARAM_CUSTOM_KEY_CFG_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_EEPROM_RW_STRUCT_T {
+	UINT_8 ucEepromMethod;	/* For read only read: 1, query size: 0 */
+	UINT_8 ucEepromIndex;
+	UINT_8 reserved;
+	UINT_16 u2EepromData;
+} PARAM_CUSTOM_EEPROM_RW_STRUCT_T, *P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T,
+PARAM_CUSTOM_NVRAM_RW_STRUCT_T, *P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T {
+	UINT_8 bmfgApsdEnAc;	/* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */
+	UINT_8 ucIsEnterPsAtOnce;	/* enter PS immediately without 5 second guard after connected */
+	UINT_8 ucIsDisableUcTrigger;	/* not to trigger UC on beacon TIM is matched (under U-APSD) */
+	UINT_8 reserved;
+} PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T, *P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_NOA_PARAM_STRUCT_T {
+	UINT_32 u4NoaDurationMs;
+	UINT_32 u4NoaIntervalMs;
+	UINT_32 u4NoaCount;
+} PARAM_CUSTOM_NOA_PARAM_STRUCT_T, *P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T {
+	UINT_32 u4CTwindowMs;
+} PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T {
+	UINT_8 fgEnAPSD;
+	UINT_8 fgEnAPSD_AcBe;
+	UINT_8 fgEnAPSD_AcBk;
+	UINT_8 fgEnAPSD_AcVo;
+	UINT_8 fgEnAPSD_AcVi;
+	UINT_8 ucMaxSpLen;
+	UINT_8 aucResv[2];
+} PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T;
+
+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T {
+	UINT_32 u4Enable;
+	UINT_32 u4Mode;
+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T;
+
+typedef enum _ENUM_CFG_SRC_TYPE_T {
+	CFG_SRC_TYPE_EEPROM,
+	CFG_SRC_TYPE_NVRAM,
+	CFG_SRC_TYPE_UNKNOWN,
+	CFG_SRC_TYPE_NUM
+} ENUM_CFG_SRC_TYPE_T, *P_ENUM_CFG_SRC_TYPE_T;
+
+typedef enum _ENUM_EEPROM_TYPE_T {
+	EEPROM_TYPE_NO,
+	EEPROM_TYPE_PRESENT,
+	EEPROM_TYPE_NUM
+} ENUM_EEPROM_TYPE_T, *P_ENUM_EEPROM_TYPE_T;
+
+typedef struct _PARAM_QOS_TSINFO {
+	UINT_8 ucTrafficType;	/* Traffic Type: 1 for isochronous 0 for asynchronous */
+	UINT_8 ucTid;		/* TSID: must be between 8 ~ 15 */
+	UINT_8 ucDirection;	/* direction */
+	UINT_8 ucAccessPolicy;	/* access policy */
+	UINT_8 ucAggregation;	/* aggregation */
+	UINT_8 ucApsd;		/* APSD */
+	UINT_8 ucuserPriority;	/* user priority */
+	UINT_8 ucTsInfoAckPolicy;	/* TSINFO ACK policy */
+	UINT_8 ucSchedule;	/* Schedule */
+} PARAM_QOS_TSINFO, *P_PARAM_QOS_TSINFO;
+
+typedef struct _PARAM_QOS_TSPEC {
+	PARAM_QOS_TSINFO rTsInfo;	/* TS info field */
+	UINT_16 u2NominalMSDUSize;	/* nominal MSDU size */
+	UINT_16 u2MaxMSDUsize;	/* maximum MSDU size */
+	UINT_32 u4MinSvcIntv;	/* minimum service interval */
+	UINT_32 u4MaxSvcIntv;	/* maximum service interval */
+	UINT_32 u4InactIntv;	/* inactivity interval */
+	UINT_32 u4SpsIntv;	/* suspension interval */
+	UINT_32 u4SvcStartTime;	/* service start time */
+	UINT_32 u4MinDataRate;	/* minimum Data rate */
+	UINT_32 u4MeanDataRate;	/* mean data rate */
+	UINT_32 u4PeakDataRate;	/* peak data rate */
+	UINT_32 u4MaxBurstSize;	/* maximum burst size */
+	UINT_32 u4DelayBound;	/* delay bound */
+	UINT_32 u4MinPHYRate;	/* minimum PHY rate */
+	UINT_16 u2Sba;		/* surplus bandwidth allowance */
+	UINT_16 u2MediumTime;	/* medium time */
+} PARAM_QOS_TSPEC, *P_PARAM_QOS_TSPEC;
+
+typedef struct _PARAM_QOS_ADDTS_REQ_INFO {
+	PARAM_QOS_TSPEC rTspec;
+} PARAM_QOS_ADDTS_REQ_INFO, *P_PARAM_QOS_ADDTS_REQ_INFO;
+
+typedef struct _PARAM_VOIP_CONFIG {
+	UINT_32 u4VoipTrafficInterval;	/* 0: disable VOIP configuration */
+} PARAM_VOIP_CONFIG, *P_PARAM_VOIP_CONFIG;
+
+/*802.11 Statistics Struct*/
+typedef struct _PARAM_802_11_STATISTICS_STRUCT_T {
+	UINT_32 u4Length;	/* Length of structure */
+	LARGE_INTEGER rTransmittedFragmentCount;
+	LARGE_INTEGER rMulticastTransmittedFrameCount;
+	LARGE_INTEGER rFailedCount;
+	LARGE_INTEGER rRetryCount;
+	LARGE_INTEGER rMultipleRetryCount;
+	LARGE_INTEGER rRTSSuccessCount;
+	LARGE_INTEGER rRTSFailureCount;
+	LARGE_INTEGER rACKFailureCount;
+	LARGE_INTEGER rFrameDuplicateCount;
+	LARGE_INTEGER rReceivedFragmentCount;
+	LARGE_INTEGER rMulticastReceivedFrameCount;
+	LARGE_INTEGER rFCSErrorCount;
+	LARGE_INTEGER rTKIPLocalMICFailures;
+	LARGE_INTEGER rTKIPICVErrors;
+	LARGE_INTEGER rTKIPCounterMeasuresInvoked;
+	LARGE_INTEGER rTKIPReplays;
+	LARGE_INTEGER rCCMPFormatErrors;
+	LARGE_INTEGER rCCMPReplays;
+	LARGE_INTEGER rCCMPDecryptErrors;
+	LARGE_INTEGER rFourWayHandshakeFailures;
+	LARGE_INTEGER rWEPUndecryptableCount;
+	LARGE_INTEGER rWEPICVErrorCount;
+	LARGE_INTEGER rDecryptSuccessCount;
+	LARGE_INTEGER rDecryptFailureCount;
+} PARAM_802_11_STATISTICS_STRUCT_T, *P_PARAM_802_11_STATISTICS_STRUCT_T;
+
+/* Linux Network Device Statistics Struct */
+typedef struct _PARAM_LINUX_NETDEV_STATISTICS_T {
+	UINT_32 u4RxPackets;
+	UINT_32 u4TxPackets;
+	UINT_32 u4RxBytes;
+	UINT_32 u4TxBytes;
+	UINT_32 u4RxErrors;
+	UINT_32 u4TxErrors;
+	UINT_32 u4Multicast;
+} PARAM_LINUX_NETDEV_STATISTICS_T, *P_PARAM_LINUX_NETDEV_STATISTICS_T;
+
+typedef struct _PARAM_MTK_WIFI_TEST_STRUCT_T {
+	UINT_32 u4FuncIndex;
+	UINT_32 u4FuncData;
+} PARAM_MTK_WIFI_TEST_STRUCT_T, *P_PARAM_MTK_WIFI_TEST_STRUCT_T;
+
+/* 802.11 Media stream constraints */
+typedef enum _ENUM_MEDIA_STREAM_MODE {
+	ENUM_MEDIA_STREAM_OFF,
+	ENUM_MEDIA_STREAM_ON
+} ENUM_MEDIA_STREAM_MODE, *P_ENUM_MEDIA_STREAM_MODE;
+
+/* for NDIS 5.1 Media Streaming Change */
+typedef struct _PARAM_MEDIA_STREAMING_INDICATION {
+	PARAM_STATUS_INDICATION_T rStatus;
+	ENUM_MEDIA_STREAM_MODE eMediaStreamMode;
+} PARAM_MEDIA_STREAMING_INDICATION, *P_PARAM_MEDIA_STREAMING_INDICATION;
+
+#define PARAM_PROTOCOL_ID_DEFAULT       0x00
+#define PARAM_PROTOCOL_ID_TCP_IP        0x02
+#define PARAM_PROTOCOL_ID_IPX           0x06
+#define PARAM_PROTOCOL_ID_NBF           0x07
+#define PARAM_PROTOCOL_ID_MAX           0x0F
+#define PARAM_PROTOCOL_ID_MASK          0x0F
+
+/* for NDIS OID_GEN_NETWORK_LAYER_ADDRESSES */
+typedef struct _PARAM_NETWORK_ADDRESS_IP {
+	UINT_16 sin_port;
+	UINT_32 in_addr;
+	UINT_8 sin_zero[8];
+} PARAM_NETWORK_ADDRESS_IP, *P_PARAM_NETWORK_ADDRESS_IP;
+
+typedef struct _PARAM_NETWORK_ADDRESS {
+	UINT_16 u2AddressLength;	/* length in bytes of Address[] in this */
+	UINT_16 u2AddressType;	/* type of this address (PARAM_PROTOCOL_ID_XXX above) */
+	UINT_8 aucAddress[1];	/* actually AddressLength bytes long */
+} PARAM_NETWORK_ADDRESS, *P_PARAM_NETWORK_ADDRESS;
+
+/* The following is used with OID_GEN_NETWORK_LAYER_ADDRESSES to set network layer addresses on an interface */
+
+typedef struct _PARAM_NETWORK_ADDRESS_LIST {
+	UINT_32 u4AddressCount;	/* number of addresses following */
+	UINT_16 u2AddressType;	/* type of this address (NDIS_PROTOCOL_ID_XXX above) */
+	PARAM_NETWORK_ADDRESS arAddress[1];	/* actually AddressCount elements long */
+} PARAM_NETWORK_ADDRESS_LIST, *P_PARAM_NETWORK_ADDRESS_LIST;
+
+#if CFG_SLT_SUPPORT
+
+#define FIXED_BW_LG20       0x0000
+#define FIXED_BW_UL20       0x2000
+#define FIXED_BW_DL40       0x3000
+
+#define FIXED_EXT_CHNL_U20  0x4000	/* For AGG register. */
+#define FIXED_EXT_CHNL_L20  0xC000	/* For AGG regsiter. */
+
+typedef enum _ENUM_MTK_LP_TEST_MODE_T {
+	ENUM_MTK_LP_TEST_NORMAL,
+	ENUM_MTK_LP_TEST_GOLDEN_SAMPLE,
+	ENUM_MTK_LP_TEST_DUT,
+	ENUM_MTK_LP_TEST_MODE_NUM
+} ENUM_MTK_LP_TEST_MODE_T, *P_ENUM_MTK_LP_TEST_MODE_T;
+
+typedef enum _ENUM_MTK_SLT_FUNC_IDX_T {
+	ENUM_MTK_SLT_FUNC_DO_NOTHING,
+	ENUM_MTK_SLT_FUNC_INITIAL,
+	ENUM_MTK_SLT_FUNC_RATE_SET,
+	ENUM_MTK_SLT_FUNC_LP_SET,
+	ENUM_MTK_SLT_FUNC_NUM
+} ENUM_MTK_SLT_FUNC_IDX_T, *P_ENUM_MTK_SLT_FUNC_IDX_T;
+
+typedef struct _PARAM_MTK_SLT_LP_TEST_STRUCT_T {
+	ENUM_MTK_LP_TEST_MODE_T rLpTestMode;
+	UINT_32 u4BcnRcvNum;
+} PARAM_MTK_SLT_LP_TEST_STRUCT_T, *P_PARAM_MTK_SLT_LP_TEST_STRUCT_T;
+
+typedef struct _PARAM_MTK_SLT_TR_TEST_STRUCT_T {
+	ENUM_PARAM_NETWORK_TYPE_T rNetworkType;	/* Network Type OFDM5G or OFDM2.4G */
+	UINT_32 u4FixedRate;	/* Fixed Rate including BW */
+} PARAM_MTK_SLT_TR_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TR_TEST_STRUCT_T;
+
+typedef struct _PARAM_MTK_SLT_INITIAL_STRUCT_T {
+	UINT_8 aucTargetMacAddr[PARAM_MAC_ADDR_LEN];
+	UINT_16 u2SiteID;
+} PARAM_MTK_SLT_INITIAL_STRUCT_T, *P_PARAM_MTK_SLT_INITIAL_STRUCT_T;
+
+typedef struct _PARAM_MTK_SLT_TEST_STRUCT_T {
+	ENUM_MTK_SLT_FUNC_IDX_T rSltFuncIdx;
+	UINT_32 u4Length;	/* Length of structure,
+				   including myself */
+	UINT_32 u4FuncInfoLen;	/* Include following content
+				   field and myself */
+	union {
+		PARAM_MTK_SLT_INITIAL_STRUCT_T rMtkInitTest;
+		PARAM_MTK_SLT_LP_TEST_STRUCT_T rMtkLpTest;
+		PARAM_MTK_SLT_TR_TEST_STRUCT_T rMtkTRTest;
+	} unFuncInfoContent;
+
+} PARAM_MTK_SLT_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TEST_STRUCT_T;
+
+#endif
+
+/*--------------------------------------------------------------*/
+/*! \brief For Fixed Rate Configuration (Registry)              */
+/*--------------------------------------------------------------*/
+typedef enum _ENUM_REGISTRY_FIXED_RATE_T {
+	FIXED_RATE_NONE,
+	FIXED_RATE_1M,
+	FIXED_RATE_2M,
+	FIXED_RATE_5_5M,
+	FIXED_RATE_11M,
+	FIXED_RATE_6M,
+	FIXED_RATE_9M,
+	FIXED_RATE_12M,
+	FIXED_RATE_18M,
+	FIXED_RATE_24M,
+	FIXED_RATE_36M,
+	FIXED_RATE_48M,
+	FIXED_RATE_54M,
+	FIXED_RATE_MCS0_20M_800NS,
+	FIXED_RATE_MCS1_20M_800NS,
+	FIXED_RATE_MCS2_20M_800NS,
+	FIXED_RATE_MCS3_20M_800NS,
+	FIXED_RATE_MCS4_20M_800NS,
+	FIXED_RATE_MCS5_20M_800NS,
+	FIXED_RATE_MCS6_20M_800NS,
+	FIXED_RATE_MCS7_20M_800NS,
+	FIXED_RATE_MCS0_20M_400NS,
+	FIXED_RATE_MCS1_20M_400NS,
+	FIXED_RATE_MCS2_20M_400NS,
+	FIXED_RATE_MCS3_20M_400NS,
+	FIXED_RATE_MCS4_20M_400NS,
+	FIXED_RATE_MCS5_20M_400NS,
+	FIXED_RATE_MCS6_20M_400NS,
+	FIXED_RATE_MCS7_20M_400NS,
+	FIXED_RATE_MCS0_40M_800NS,
+	FIXED_RATE_MCS1_40M_800NS,
+	FIXED_RATE_MCS2_40M_800NS,
+	FIXED_RATE_MCS3_40M_800NS,
+	FIXED_RATE_MCS4_40M_800NS,
+	FIXED_RATE_MCS5_40M_800NS,
+	FIXED_RATE_MCS6_40M_800NS,
+	FIXED_RATE_MCS7_40M_800NS,
+	FIXED_RATE_MCS32_800NS,
+	FIXED_RATE_MCS0_40M_400NS,
+	FIXED_RATE_MCS1_40M_400NS,
+	FIXED_RATE_MCS2_40M_400NS,
+	FIXED_RATE_MCS3_40M_400NS,
+	FIXED_RATE_MCS4_40M_400NS,
+	FIXED_RATE_MCS5_40M_400NS,
+	FIXED_RATE_MCS6_40M_400NS,
+	FIXED_RATE_MCS7_40M_400NS,
+	FIXED_RATE_MCS32_400NS,
+	FIXED_RATE_NUM
+} ENUM_REGISTRY_FIXED_RATE_T, *P_ENUM_REGISTRY_FIXED_RATE_T;
+
+typedef enum _ENUM_BT_CMD_T {
+	BT_CMD_PROFILE = 0,
+	BT_CMD_UPDATE,
+	BT_CMD_NUM
+} ENUM_BT_CMD_T;
+
+typedef enum _ENUM_BT_PROFILE_T {
+	BT_PROFILE_CUSTOM = 0,
+	BT_PROFILE_SCO,
+	BT_PROFILE_ACL,
+	BT_PROFILE_MIXED,
+	BT_PROFILE_NO_CONNECTION,
+	BT_PROFILE_NUM
+} ENUM_BT_PROFILE_T;
+
+typedef struct _PTA_PROFILE_T {
+	ENUM_BT_PROFILE_T eBtProfile;
+	union {
+		UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN];
+		/*  0: sco reserved slot time,
+		   1: sco idle slot time,
+		   2: acl throughput,
+		   3: bt tx power,
+		   4: bt rssi
+		   5: VoIP interval
+		   6: BIT(0) Use this field, BIT(1) 0 apply single/ 1 dual PTA setting.
+		 */
+		UINT_32 au4Btcr[4];
+	} u;
+} PTA_PROFILE_T, *P_PTA_PROFILE_T;
+
+typedef struct _PTA_IPC_T {
+	UINT_8 ucCmd;
+	UINT_8 ucLen;
+	union {
+		PTA_PROFILE_T rProfile;
+		UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN];
+	} u;
+} PARAM_PTA_IPC_T, *P_PARAM_PTA_IPC_T, PTA_IPC_T, *P_PTA_IPC_T;
+
+/*--------------------------------------------------------------*/
+/*! \brief CFG80211 Scan Request Container                      */
+/*--------------------------------------------------------------*/
+
+typedef struct _PARAM_SCAN_REQUEST_EXT_T {
+	PARAM_SSID_T rSsid;
+	UINT_32 u4IELength;
+	PUINT_8 pucIE;
+} PARAM_SCAN_REQUEST_EXT_T, *P_PARAM_SCAN_REQUEST_EXT_T;
+
+/*--------------------------------------------------------------*/
+/*! \brief CFG80211 Scheduled Scan Request Container            */
+/*--------------------------------------------------------------*/
+typedef struct _PARAM_SCHED_SCAN_REQUEST_T {
+	UINT_32 u4SsidNum;
+	PARAM_SSID_T arSsid[CFG_SCAN_SSID_MATCH_MAX_NUM];
+	UINT_32 u4IELength;
+	PUINT_8 pucIE;
+	UINT_16 u2ScanInterval;	/* in milliseconds */
+} PARAM_SCHED_SCAN_REQUEST, *P_PARAM_SCHED_SCAN_REQUEST;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+typedef struct _PARAM_HS20_SET_BSSID_POOL {
+	BOOLEAN fgIsEnable;
+	UINT_8 ucNumBssidPool;
+	PARAM_MAC_ADDRESS arBSSID[8];
+} PARAM_HS20_SET_BSSID_POOL, *P_PARAM_HS20_SET_BSSID_POOL;
+
+#endif
+
+typedef struct _PARAM_CUSTOM_WFD_DEBUG_STRUCT_T {
+	UINT_8 ucWFDDebugMode;	/* 0: Disable
+				   1:Enable but only show inqueue skb ether SN
+				   2.show skb ether SN and the statistics of skb inqueue time */
+	UINT_16 u2SNPeriod;	/* The Ether SN Period */
+
+	UINT_8 reserved;
+} PARAM_CUSTOM_WFD_DEBUG_STRUCT_T, *P_PARAM_CUSTOM_WFD_DEBUG_STRUCT_T;
+
+typedef struct _CMD_GET_PSCAN_CAPABILITY {
+/* TBD */
+} CMD_GET_GSCAN_CAPABILITY, *P_CMD_GET_GSCAN_CAPABILITY;
+
+typedef struct _CMD_SET_PSCAN_ENABLE {
+	UINT_8 ucPscanAct;
+	UINT_8 aucReserved[3];
+} CMD_SET_PSCAN_ENABLE, *P_CMD_SET_PSCAN_ENABLE;
+
+typedef enum _ENUM_PSCAN_ACT_T {
+	ENABLE,
+	DISABLE,
+	SUSPEND,
+	CLEAR
+} ENUM_PSCAN_ACT_T, *P_ENUM_PSCAN_ACT_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*--------------------------------------------------------------*/
+/* Routines to set parameters or query information.             */
+/*--------------------------------------------------------------*/
+/***** Routines in wlan_oid.c *****/
+WLAN_STATUS
+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter,
+				  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter,
+			     OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter,
+		  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetConnect(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter,
+		 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter,
+			       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter,
+			     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter,
+		     OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+#if 0
+WLAN_STATUS
+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+WLAN_STATUS
+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter,
+			     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer,
+		  IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetChannel(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter,
+		 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter,
+			OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter,
+				     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter,
+				   IN PVOID prSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter,
+		  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter,
+			   OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRfTestRxStatus(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRfTestTxStatus(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter,
+				IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter,
+		     OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+WLAN_STATUS
+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+#ifdef LINUX
+
+WLAN_STATUS
+wlanoidQueryStatisticsForLinux(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+#endif
+
+WLAN_STATUS
+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter,
+			    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter,
+			     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter,
+				IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter,
+				 IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter,
+			   OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+WLAN_STATUS
+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+WLAN_STATUS
+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+/* RF Test related APIs */
+WLAN_STATUS
+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter,
+			   OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+#if CFG_SUPPORT_WAPI
+WLAN_STATUS
+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+#if CFG_SUPPORT_WPS2
+WLAN_STATUS
+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+#if CFG_ENABLE_WAKEUP_ON_LAN
+WLAN_STATUS
+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 u4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+WLAN_STATUS
+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter,
+		       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen);
+
+#if CFG_SLT_SUPPORT
+
+WLAN_STATUS
+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter,
+		      OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+#endif
+
+#if 0
+WLAN_STATUS
+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryBT(IN P_ADAPTER_T prAdapter,
+	       OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+#if CFG_SUPPORT_BUILD_DATE_CODE
+WLAN_STATUS
+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter,
+			  OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+#endif
+
+/*
+WLAN_STATUS
+wlanoidQueryBtSingleAntenna (
+    IN  P_ADAPTER_T prAdapter,
+    OUT PVOID       pvQueryBuffer,
+    IN  UINT_32     u4QueryBufferLen,
+    OUT PUINT_32    pu4QueryInfoLen
+    );
+
+WLAN_STATUS
+wlanoidSetBtSingleAntenna (
+    IN  P_ADAPTER_T prAdapter,
+    IN  PVOID       pvSetBuffer,
+    IN  UINT_32     u4SetBufferLen,
+    OUT PUINT_32    pu4SetInfoLen
+    );
+
+WLAN_STATUS
+wlanoidSetPta (
+    IN  P_ADAPTER_T prAdapter,
+    IN  PVOID       pvSetBuffer,
+    IN  UINT_32     u4SetBufferLen,
+    OUT PUINT_32    pu4SetInfoLen
+    );
+
+WLAN_STATUS
+wlanoidQueryPta (
+    IN  P_ADAPTER_T prAdapter,
+    OUT PVOID       pvQueryBuffer,
+    IN  UINT_32     u4QueryBufferLen,
+    OUT PUINT_32    pu4QueryInfoLen
+    );
+*/
+
+#if CFG_ENABLE_WIFI_DIRECT
+WLAN_STATUS
+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter,
+		  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+#if CFG_SUPPORT_BATCH_SCAN
+WLAN_STATUS
+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter,
+			    OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+#endif
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+WLAN_STATUS
+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter,
+				  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+WLAN_STATUS
+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter,
+		      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetTxRateInfo(
+	IN  P_ADAPTER_T prAdapter,
+	IN  PVOID       pvSetBuffer,
+	IN  UINT_32     u4SetBufferLen,
+	OUT PUINT_32    pu4SetInfoLen
+	);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+WLAN_STATUS
+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+WLAN_STATUS
+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter,
+								IN PVOID pvSetBuffer,
+								IN UINT_32 u4SetBufferLen,
+								OUT PUINT_32 pu4SetInfoLen);
+
+#endif /* _WLAN_OID_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h
new file mode 100644
index 0000000000000..0b558d64034d4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h
@@ -0,0 +1,307 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/wlan_p2p.h#3
+*/
+
+/*! \file   "wlan_p2p.h"
+    \brief This file contains the declairations of Wi-Fi Direct command
+	   processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters.
+*/
+
+/*
+** Log: wlan_p2p.h
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Add RSSI support for P2P network.
+ *
+ * 11 08 2011 yuche.tsai
+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version
+ * query & set support for service discovery version check.
+ * Add support for driver version query & p2p supplicant verseion set.
+ * For new service discovery mechanism sync.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * Support Channel Query.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * New 2.1 branch
+
+ *
+ * 04 27 2011 george.huang
+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
+ * Support P2P ARP filter setting on early suspend/ late resume
+ *
+ * 04 08 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * separate settings of P2P and AIS
+ *
+ * 03 22 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * link with supplicant commands
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add Security check related code.
+ *
+ * 01 05 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface
+ * for supporting Wi-Fi Direct Service Discovery
+ * ioctl implementations for P2P Service Discovery
+ *
+ * 12 22 2010 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface
+ * for supporting Wi-Fi Direct Service Discovery
+ * 1. header file restructure for more clear module isolation
+ * 2. add function interface definition for implementing Service Discovery callbacks
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * add subroutines for P2P to set multicast list.
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * support wlanoidSetP2pPowerSaveProfile() in P2P
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * Support wlanoidSetNetworkAddress() for P2P
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS.
+ *
+
+ *
+**
+*/
+
+#ifndef _WLAN_P2P_H
+#define _WLAN_P2P_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#if CFG_ENABLE_WIFI_DIRECT
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/* Service Discovery */
+typedef struct _PARAM_P2P_SEND_SD_RESPONSE {
+	PARAM_MAC_ADDRESS rReceiverAddr;
+	UINT_8 fgNeedTxDoneIndication;
+	UINT_8 ucChannelNum;
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} PARAM_P2P_SEND_SD_RESPONSE, *P_PARAM_P2P_SEND_SD_RESPONSE;
+
+typedef struct _PARAM_P2P_GET_SD_REQUEST {
+	PARAM_MAC_ADDRESS rTransmitterAddr;
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} PARAM_P2P_GET_SD_REQUEST, *P_PARAM_P2P_GET_SD_REQUEST;
+
+typedef struct _PARAM_P2P_GET_SD_REQUEST_EX {
+	PARAM_MAC_ADDRESS rTransmitterAddr;
+	UINT_16 u2PacketLength;
+	UINT_8 ucChannelNum;	/* Channel Number Where SD Request is received. */
+	UINT_8 ucSeqNum;	/* Get SD Request by sequence number. */
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} PARAM_P2P_GET_SD_REQUEST_EX, *P_PARAM_P2P_GET_SD_REQUEST_EX;
+
+typedef struct _PARAM_P2P_SEND_SD_REQUEST {
+	PARAM_MAC_ADDRESS rReceiverAddr;
+	UINT_8 fgNeedTxDoneIndication;
+	UINT_8 ucVersionNum;	/* Indicate the Service Discovery Supplicant Version. */
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} PARAM_P2P_SEND_SD_REQUEST, *P_PARAM_P2P_SEND_SD_REQUEST;
+
+/* Service Discovery 1.0. */
+typedef struct _PARAM_P2P_GET_SD_RESPONSE {
+	PARAM_MAC_ADDRESS rTransmitterAddr;
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} PARAM_P2P_GET_SD_RESPONSE, *P_PARAM_P2P_GET_SD_RESPONSE;
+
+/* Service Discovery 2.0. */
+typedef struct _PARAM_P2P_GET_SD_RESPONSE_EX {
+	PARAM_MAC_ADDRESS rTransmitterAddr;
+	UINT_16 u2PacketLength;
+	UINT_8 ucSeqNum;	/* Get SD Response by sequence number. */
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} PARAM_P2P_GET_SD_RESPONSE_EX, *P_PARAM_P2P_GET_SD_RESPONSE_EX;
+
+typedef struct _PARAM_P2P_TERMINATE_SD_PHASE {
+	PARAM_MAC_ADDRESS rPeerAddr;
+} PARAM_P2P_TERMINATE_SD_PHASE, *P_PARAM_P2P_TERMINATE_SD_PHASE;
+
+/*! \brief Key mapping of BSSID */
+typedef struct _P2P_PARAM_KEY_T {
+	UINT_32 u4Length;	/*!< Length of structure */
+	UINT_32 u4KeyIndex;	/*!< KeyID */
+	UINT_32 u4KeyLength;	/*!< Key length in bytes */
+	PARAM_MAC_ADDRESS arBSSID;	/*!< MAC address */
+	PARAM_KEY_RSC rKeyRSC;
+	UINT_8 aucKeyMaterial[32];	/*!< Key content by above setting */
+} P2P_PARAM_KEY_T, *P_P2P_PARAM_KEY_T;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*--------------------------------------------------------------*/
+/* Routines to handle command                                   */
+/*--------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+/*--------------------------------------------------------------*/
+/* Service Discovery Subroutines                                */
+/*--------------------------------------------------------------*/
+WLAN_STATUS
+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter,
+			IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 puQueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+#if CFG_SUPPORT_ANTI_PIRACY
+WLAN_STATUS
+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter,
+			  IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+#endif
+
+WLAN_STATUS
+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter,
+		   IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter,
+				IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter,
+			 IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter,
+		       IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+WLAN_STATUS
+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter,
+			       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+WLAN_STATUS
+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter,
+		     IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+WLAN_STATUS
+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter,
+		    IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+#endif
+
+/*--------------------------------------------------------------*/
+/* Callbacks for event indication                               */
+/*--------------------------------------------------------------*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif
+#endif /* _WLAN_P2P_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c
new file mode 100644
index 0000000000000..f2324f13280e3
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c
@@ -0,0 +1,1303 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/aaa_fsm.c#2
+*/
+
+/*! \file   "aaa_fsm.c"
+    \brief  This file defines the FSM for AAA MODULE.
+
+    This file defines the FSM for AAA MODULE.
+*/
+
+/*
+** Log: aaa_fsm.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 02 22 2012 yuche.tsai
+ * NULL
+ * Solve sigma test 5.1.3 issue, assoc response should have P2P IE.
+ *
+ * 12 02 2011 yuche.tsai
+ * NULL
+ * Resolve inorder issue under AP mode.
+ *
+ * data frame may TX before assoc response frame.
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 06 17 2011 terry.wu
+ * NULL
+ * Add BoW 11N support.
+ *
+ * 06 02 2011 eddie.chen
+ * [WCXRP00000759] [MT6620 Wi-Fi][DRV] Update RCPI in AAA
+ * Update RCPI when receiving Assoc request.
+ *
+ * 04 21 2011 terry.wu
+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
+ * Add network type parameter to authSendAuthFrame.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW short range mode.
+ *
+ * 04 09 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Change Link connection event procedure and change skb length check to 1512 bytes.
+ *
+ * 03 09 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * Skip to call p2pRunEventAAAComplete to avoid indicate STA connect twice.
+ *
+ * 03 04 2011 terry.wu
+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection
+ * Remove unused variable.
+ *
+ * 02 16 2011 yuche.tsai
+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue
+ * Add more check after RX assoc frame under Hot-Spot mode.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue
+ * Fix Client Limit Issue.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 01 15 2011 puff.wen
+ * NULL
+ * [On behalf of Frog] Add CFG_ENABLE_WIFI_DIRECT to p2pRunEventAAAComplete
+ *
+ * 01 14 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Modify AAA flow according to CM's comment.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * Fix Compile warning, type cast from UINT_32 to UINT_16.
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * In P2P AT GO test mode under WinXP, we would not indicate connected event to host.
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 20 2010 kevin.huang
+ * NULL
+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete()
+ *
+ * 08 17 2010 yuche.tsai
+ * NULL
+ * Fix bug while enabling P2P GO.
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * refine TX-DONE callback.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * modify due to P2P functino call prototype change.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * First draft for migration P2P FSM from FW to Driver.
+ *
+ * 04 02 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Modify CFG flags
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * add support of Driver STA_RECORD_T activation
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send Event to AIS/BOW/P2P
+*
+* @param[in] rJoinStatus        To indicate JOIN success or failure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+* @param[in] prSwRfb            Pointer to the SW_RFB_T
+
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS aaaFsmSendEventJoinComplete(WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb)
+{
+	P_MSG_SAA_JOIN_COMP_T prJoinCompMsg;
+
+	ASSERT(prStaRec);
+
+	prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T));
+	if (!prJoinCompMsg)
+		return WLAN_STATUS_RESOURCES;
+
+	if (IS_STA_IN_AIS(prStaRec))
+		prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE;
+	else if (IS_STA_IN_P2P(prStaRec))
+		prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE;
+	else if (IS_STA_IN_BOW(prStaRec))
+		prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE;
+	else
+		ASSERT(0);
+
+	prJoinCompMsg->rJoinStatus = rJoinStatus;
+	prJoinCompMsg->prStaRec = prStaRec;
+	prJoinCompMsg->prSwRfb = prSwRfb;
+
+	mboxSendMsg(MBOX_ID_0, (P_MSG_HDR_T) prJoinCompMsg, MSG_SEND_METHOD_BUF);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of saaFsmSendEventJoinComplete() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Start Event to AAA FSM.
+*
+* @param[in] prMsgHdr   Message of Join Request for a particular STA.
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aaaFsmRunEventStart(IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_SAA_JOIN_REQ_T prJoinReqMsg;
+	P_STA_RECORD_T prStaRec;
+	P_AIS_BSS_INFO_T prAisBssInfo;
+
+	ASSERT(prMsgHdr);
+
+	prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr;
+	prStaRec = prJoinReqMsg->prStaRec;
+
+	ASSERT(prStaRec);
+
+	DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n");
+
+	cnmMemFree(prMsgHdr);
+
+	/* 4 <1> Validation of SAA Start Event */
+	if (!IS_AP_STA(prStaRec->eStaType)) {
+
+		DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType);
+
+		/* Ignore the return value because don't care the prSwRfb */
+		saaFsmSendEventJoinComplete(WLAN_STATUS_FAILURE, prStaRec, NULL);
+
+		return;
+	}
+	/* 4 <2> The previous JOIN process is not completed ? */
+	if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
+		DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n");
+		prStaRec->eAuthAssocState = AA_STATE_IDLE;
+	}
+	/* 4 <3> Reset Status Code and Time */
+	/* Update Station Record - Status/Reason Code */
+	prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
+
+	/* Update the record join time. */
+	GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime);
+
+	prStaRec->ucTxAuthAssocRetryCount = 0;
+
+	if (prStaRec->prChallengeText) {
+		cnmMemFree(prStaRec->prChallengeText);
+		prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL;
+	}
+
+	cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer);
+
+	prStaRec->ucStaState = STA_STATE_1;
+
+	/* Trigger SAA MODULE */
+	saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL);
+
+}				/* end of saaFsmRunEventStart() */
+#endif
+
+#if CFG_SUPPORT_AAA
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will process the Rx Auth Request Frame and then
+*        trigger AAA FSM.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	UINT_16 u2StatusCode;
+	BOOLEAN fgReplyAuth = FALSE;
+	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;
+
+	ASSERT(prAdapter);
+
+	do {
+
+		/* 4 <1> Check P2P network conditions */
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered) {
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+			if (prBssInfo->fgIsNetActive) {
+
+				/* 4 <1.1> Validate Auth Frame by Auth Algorithm/Transation Seq */
+				if (WLAN_STATUS_SUCCESS ==
+				    authProcessRxAuth1Frame(prAdapter,
+							    prSwRfb,
+							    prBssInfo->aucBSSID,
+							    AUTH_ALGORITHM_NUM_OPEN_SYSTEM,
+							    AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) {
+
+					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {
+						/* 4 <1.2> Validate Auth Frame for Network Specific Conditions */
+						fgReplyAuth = p2pFuncValidateAuth(prAdapter,
+										  prSwRfb, &prStaRec, &u2StatusCode);
+					} else {
+						fgReplyAuth = TRUE;
+					}
+					eNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+					break;
+				}
+			}
+		}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+		/* 4 <2> Check BOW network conditions */
+#if CFG_ENABLE_BT_OVER_WIFI
+		{
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+			if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) {
+
+				/* 4 <2.1> Validate Auth Frame by Auth Algorithm/Transation Seq */
+				/* Check if for this BSSID */
+				if (WLAN_STATUS_SUCCESS ==
+				    authProcessRxAuth1Frame(prAdapter,
+							    prSwRfb,
+							    prBssInfo->aucBSSID,
+							    AUTH_ALGORITHM_NUM_OPEN_SYSTEM,
+							    AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) {
+
+					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {
+
+						/* 4 <2.2> Validate Auth Frame for Network Specific Conditions */
+						fgReplyAuth =
+						    bowValidateAuth(prAdapter, prSwRfb, &prStaRec, &u2StatusCode);
+
+					} else {
+
+						fgReplyAuth = TRUE;
+					}
+					eNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
+					/* TODO(Kevin): Allocate a STA_RECORD_T for new client */
+					break;
+				}
+			}
+		}
+#endif /* CFG_ENABLE_BT_OVER_WIFI */
+
+		return;
+	} while (FALSE);
+
+	if (prStaRec) {
+		/* update RCPI */
+		prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
+	}
+	/* 4 <3> Update STA_RECORD_T and reply Auth_2(Response to Auth_1) Frame */
+	if (fgReplyAuth) {
+
+		if (prStaRec) {
+
+			if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
+				if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
+					DBGLOG(AAA, WARN, "Previous AuthAssocState (%d) != IDLE.\n",
+							   prStaRec->eAuthAssocState);
+				}
+
+				prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;
+			} else {
+				prStaRec->eAuthAssocState = AA_STATE_IDLE;
+
+				/* NOTE(Kevin): Change to STATE_1 */
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+			}
+
+			/* Update the record join time. */
+			GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);
+
+			/* Update Station Record - Status/Reason Code */
+			prStaRec->u2StatusCode = u2StatusCode;
+
+			prStaRec->ucAuthAlgNum = AUTH_ALGORITHM_NUM_OPEN_SYSTEM;
+		} else {
+			/* NOTE(Kevin): We should have STA_RECORD_T if the status code was successful */
+			ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL));
+		}
+
+		/* NOTE: Ignore the return status for AAA */
+		/* 4 <4> Reply  Auth */
+		authSendAuthFrame(prAdapter, prStaRec, eNetTypeIndex, prSwRfb, AUTH_TRANSACTION_SEQ_2, u2StatusCode);
+
+	}
+
+}				/* end of aaaFsmRunEventRxAuth() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will process the Rx (Re)Association Request Frame and then
+*        trigger AAA FSM.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS           Always return success
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	UINT_16 u2StatusCode = STATUS_CODE_RESERVED;
+	BOOLEAN fgReplyAssocResp = FALSE;
+
+	ASSERT(prAdapter);
+
+	do {
+
+		/* 4 <1> Check if we have the STA_RECORD_T for incoming Assoc Req */
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+		/* We should have the corresponding Sta Record. */
+		if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
+			ASSERT(0);	/* Only for debug phase */
+			break;
+		}
+
+		if (!IS_CLIENT_STA(prStaRec))
+			break;
+
+		if (prStaRec->ucStaState == STA_STATE_3) {
+			/* Do Reassocation */
+		} else if ((prStaRec->ucStaState == STA_STATE_2) &&
+			   (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) {
+			/* Normal case */
+		} else {
+			DBGLOG(AAA, INFO, "Previous AuthAssocState (%d) != SEND_AUTH2, ucStaState:%d.\n",
+				prStaRec->eAuthAssocState,
+				prStaRec->ucStaState);
+			/* TODO: Why assoc req event is faster than tx done of auth */
+			if (prStaRec->eAuthAssocState != AAA_STATE_SEND_AUTH2)
+				break;
+		}
+
+		/* update RCPI */
+		prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
+
+		/* 4 <2> Check P2P network conditions */
+#if CFG_ENABLE_WIFI_DIRECT
+		if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {
+
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+			if (prBssInfo->fgIsNetActive) {
+
+				/* 4 <2.1> Validate Assoc Req Frame and get Status Code */
+				/* Check if for this BSSID */
+				if (WLAN_STATUS_SUCCESS ==
+				    assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) {
+
+					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {
+						/* 4 <2.2> Validate Assoc Req  Frame for Network Specific Conditions */
+						fgReplyAssocResp = p2pFuncValidateAssocReq(prAdapter,
+											   prSwRfb,
+											   (PUINT_16)&u2StatusCode);
+					} else {
+						fgReplyAssocResp = TRUE;
+					}
+
+					break;
+				}
+			}
+		}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+		/* 4 <3> Check BOW network conditions */
+#if CFG_ENABLE_BT_OVER_WIFI
+		if (IS_STA_IN_BOW(prStaRec)) {
+
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);
+
+			if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) {
+
+				/* 4 <3.1> Validate Auth Frame by Auth Algorithm/Transation Seq */
+				/* Check if for this BSSID */
+				if (WLAN_STATUS_SUCCESS ==
+				    assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) {
+
+					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {
+
+						/* 4 <3.2> Validate Auth Frame for Network Specific Conditions */
+						fgReplyAssocResp =
+						    bowValidateAssocReq(prAdapter, prSwRfb, &u2StatusCode);
+
+					} else {
+
+						fgReplyAssocResp = TRUE;
+					}
+
+					/* TODO(Kevin): Allocate a STA_RECORD_T for new client */
+					break;
+				}
+			}
+		}
+#endif /* CFG_ENABLE_BT_OVER_WIFI */
+
+		return WLAN_STATUS_SUCCESS;	/* To release the SW_RFB_T */
+	} while (FALSE);
+
+	/* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */
+	if (fgReplyAssocResp) {
+		UINT_16 u2IELength;
+		PUINT_8 pucIE;
+
+		if ((((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) ==
+		    MAC_FRAME_REASSOC_REQ) {
+
+			u2IELength = prSwRfb->u2PacketLen -
+			    (UINT_16) OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]);
+
+			pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem;
+		} else {
+			u2IELength = prSwRfb->u2PacketLen - (UINT_16) OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]);
+
+			pucIE = ((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem;
+		}
+
+		rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength);
+
+		/* 4 <4.1> Assign Association ID */
+		if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
+
+#if CFG_ENABLE_WIFI_DIRECT
+			if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {
+				if (p2pRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) {
+					prStaRec->u2AssocId = bssAssignAssocID(prStaRec);
+					/* prStaRec->eAuthAssocState = AA_STATE_IDLE; */
+					prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;/* NOTE(Kevin): for TX done */
+
+					/* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */
+					/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */
+				} else {
+					/* Client List FULL. */
+					u2StatusCode = STATUS_CODE_REQ_DECLINED;
+
+					prStaRec->u2AssocId = 0;	/* Invalid Association ID */
+
+					/* If (Re)association fail, the peer can try Association w/o Auth immediately */
+					prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;
+
+					/* NOTE(Kevin): Better to change state here, not at TX Done */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+				}
+			}
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+			if ((IS_STA_IN_BOW(prStaRec))) {
+				/* if (bowRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { */
+				prStaRec->u2AssocId = bssAssignAssocID(prStaRec);
+				prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;	/* NOTE(Kevin): for TX done */
+
+				/* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */
+				/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */
+			}
+#if 0
+			else {
+				/* Client List FULL. */
+				u2StatusCode = STATUS_CODE_REQ_DECLINED;
+
+				prStaRec->u2AssocId = 0;	/* Invalid Association ID */
+
+				/* If (Re)association fail, the peer can try Association w/o Auth immediately */
+				prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;
+
+				/* NOTE(Kevin): Better to change state here, not at TX Done */
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+			}
+		}
+#endif
+#endif
+	} else {
+		prStaRec->u2AssocId = 0;	/* Invalid Association ID */
+
+		/* If (Re)association fail, the peer can try Association w/o Auth immediately */
+		prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;
+
+		/* NOTE(Kevin): Better to change state here, not at TX Done */
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+	}
+
+	/* Update the record join time. */
+	GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);
+
+	/* Update Station Record - Status/Reason Code */
+	prStaRec->u2StatusCode = u2StatusCode;
+
+	/* NOTE: Ignore the return status for AAA */
+	/* 4 <4.2> Reply  Assoc Resp */
+	assocSendReAssocRespFrame(prAdapter, prStaRec);
+
+}
+
+return WLAN_STATUS_SUCCESS;
+
+}				/* end of aaaFsmRunEventRxAssoc() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM.
+*
+* @param[in] prAdapter      Pointer to the Adapter structure.
+* @param[in] prMsduInfo     Pointer to the MSDU_INFO_T.
+* @param[in] rTxDoneStatus  Return TX status of the Auth1/Auth3/AssocReq frame.
+*
+* @retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_STA_RECORD_T prStaRec;
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	DBGLOG(AAA, LOUD, "EVENT-TX DONE: Current Time = %lu\n", (unsigned long)kalGetTimeTick());
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
+		DBGLOG(AAA, INFO, "EVENT-TX DONE: Invalid StaRec");
+		return WLAN_STATUS_SUCCESS;	/* For the case of replying ERROR STATUS CODE */
+	}
+
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+	DBGLOG(AAA, INFO, "TX DONE status: %d, AuthAssocState: %d, SeqNo: %d\n",
+			rTxDoneStatus, prStaRec->eAuthAssocState,
+			prMsduInfo->ucTxSeqNum);
+
+	switch (prStaRec->eAuthAssocState) {
+	case AAA_STATE_SEND_AUTH2:
+		{
+			/* Strictly check the outgoing frame is matched with current AA STATE */
+			if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_2) != WLAN_STATUS_SUCCESS)
+				break;
+
+			if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) {
+				if (TX_RESULT_SUCCESS == rTxDoneStatus) {
+
+					/* NOTE(Kevin): Change to STATE_2 at TX Done */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+				} else {
+
+					prStaRec->eAuthAssocState = AA_STATE_IDLE;
+
+					/* NOTE(Kevin): Change to STATE_1 */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+#if CFG_ENABLE_WIFI_DIRECT
+					if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec)))
+						p2pRunEventAAATxFail(prAdapter, prStaRec);
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+#if CFG_ENABLE_BT_OVER_WIFI
+					if (IS_STA_IN_BOW(prStaRec))
+						bowRunEventAAATxFail(prAdapter, prStaRec);
+#endif /* CFG_ENABLE_BT_OVER_WIFI */
+				}
+
+			}
+			/* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */
+
+		}
+		break;
+
+	case AAA_STATE_SEND_ASSOC2:
+		{
+			/* Strictly check the outgoing frame is matched with current SAA STATE */
+			if (assocCheckTxReAssocRespFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS)
+				break;
+
+			if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) {
+				if (TX_RESULT_SUCCESS == rTxDoneStatus) {
+
+					prStaRec->eAuthAssocState = AA_STATE_IDLE;
+
+					/* NOTE(Kevin): Change to STATE_3 at TX Done */
+#if CFG_ENABLE_WIFI_DIRECT
+					if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec)))
+						p2pRunEventAAASuccess(prAdapter, prStaRec);
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+#if CFG_ENABLE_BT_OVER_WIFI
+
+					if (IS_STA_IN_BOW(prStaRec))
+						bowRunEventAAAComplete(prAdapter, prStaRec);
+#endif /* CFG_ENABLE_BT_OVER_WIFI */
+
+				} else {
+
+					prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;
+
+					/* NOTE(Kevin): Change to STATE_2 */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+
+#if CFG_ENABLE_WIFI_DIRECT
+					if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec)))
+						p2pRunEventAAATxFail(prAdapter, prStaRec);
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+#if CFG_ENABLE_BT_OVER_WIFI
+					if (IS_STA_IN_BOW(prStaRec))
+						bowRunEventAAATxFail(prAdapter, prStaRec);
+#endif /* CFG_ENABLE_BT_OVER_WIFI */
+
+				}
+			}
+			/* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */
+		}
+		break;
+
+	default:
+		break;		/* Ignore other cases */
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of aaaFsmRunEventTxDone() */
+#endif /* CFG_SUPPORT_AAA */
+
+#if 0				/* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will send ABORT Event to JOIN FSM.
+*
+* \param[in] prAdapter  Pointer to the Adapter structure.
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID saaFsmRunEventAbort(IN P_MSG_HDR_T prMsgHdr)
+{
+	P_JOIN_INFO_T prJoinInfo;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("joinFsmRunEventAbort");
+
+	ASSERT(prAdapter);
+	prJoinInfo = &prAdapter->rJoinInfo;
+
+	DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n");
+
+	/* NOTE(Kevin): when reach here, the ARB_STATE should be in ARB_STATE_JOIN. */
+	ASSERT(prJoinInfo->prBssDesc);
+
+	/* 4 <1> Update Flags and Elements of JOIN Module. */
+	/* Reset Send Auth/(Re)Assoc Frame Count */
+	prJoinInfo->ucTxAuthAssocRetryCount = 0;
+
+	/* Cancel all JOIN relative Timer */
+	ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer);
+
+	ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer);
+
+	ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer);
+
+	/* 4 <2> Update the associated STA_RECORD_T during JOIN. */
+	/* Get a Station Record if possible, TA == BSSID for AP */
+	prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID);
+	if (prStaRec)
+		prStaRec->ucStaState = STA_STATE_1; /* Update Station Record - Class 1 Flag */
+#if DBG
+	else
+		ASSERT(0);	/* Shouldn't happened, because we already add this STA_RECORD_T at JOIN_STATE_INIT */
+#endif /* DBG */
+
+	/* 4 <3> Pull back to IDLE. */
+	joinFsmSteps(prAdapter, JOIN_STATE_IDLE);
+
+	/* 4 <4> If we are in Roaming, recover the settings of previous BSS. */
+	/* NOTE: JOIN FAIL -
+	 * Restore original setting from current BSS_INFO_T.
+	 */
+	if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)
+		joinAdoptParametersFromCurrentBss(prAdapter);
+
+}				/* end of joinFsmRunEventAbort() */
+#endif
+
+/* TODO(Kevin): following code will be modified and move to AIS FSM */
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will send Join Timeout Event to JOIN FSM.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \retval WLAN_STATUS_FAILURE   Fail because of Join Timeout
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter)
+{
+	P_JOIN_INFO_T prJoinInfo;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("joinFsmRunEventJoinTimeOut");
+
+	ASSERT(prAdapter);
+	prJoinInfo = &prAdapter->rJoinInfo;
+
+	DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n");
+
+	/* Get a Station Record if possible, TA == BSSID for AP */
+	prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID);
+
+	/* We have renew this Sta Record when in JOIN_STATE_INIT */
+	ASSERT(prStaRec);
+
+	/* Record the Status Code of Authentication Request */
+	prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT;
+
+	/* Increase Failure Count */
+	prStaRec->ucJoinFailureCount++;
+
+	/* Reset Send Auth/(Re)Assoc Frame Count */
+	prJoinInfo->ucTxAuthAssocRetryCount = 0;
+
+	/* Cancel other JOIN relative Timer */
+	ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer);
+
+	ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer);
+
+	/* Restore original setting from current BSS_INFO_T */
+	if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)
+		joinAdoptParametersFromCurrentBss(prAdapter);
+
+	/* Pull back to IDLE */
+	joinFsmSteps(prAdapter, JOIN_STATE_IDLE);
+
+	return WLAN_STATUS_FAILURE;
+
+}				/* end of joinFsmRunEventJoinTimeOut() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will adopt the parameters from Peer BSS.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter)
+{
+	P_JOIN_INFO_T prJoinInfo;
+	P_BSS_DESC_T prBssDesc;
+
+	DEBUGFUNC("joinAdoptParametersFromPeerBss");
+
+	ASSERT(prAdapter);
+	prJoinInfo = &prAdapter->rJoinInfo;
+	prBssDesc = prJoinInfo->prBssDesc;
+
+	/* 4 <1> Adopt Peer BSS' PHY TYPE */
+	prAdapter->eCurrentPhyType = prBssDesc->ePhyType;
+
+	DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n",
+			    prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS");
+
+	/* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */
+	DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand);
+
+	nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10);
+
+	prJoinInfo->fgIsParameterAdopted = TRUE;
+
+}				/* end of joinAdoptParametersFromPeerBss() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will adopt the parameters from current associated BSS.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter)
+{
+	/* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	prBssInfo = &prAdapter->rBssInfo;
+
+	/* 4 <1> Adopt current BSS' PHY TYPE */
+	prAdapter->eCurrentPhyType = prBssInfo->ePhyType;
+
+	/* 4 <2> Adopt current BSS' Frequency(Band/Channel) */
+	DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand);
+
+	nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10);
+
+}				/* end of joinAdoptParametersFromCurrentBss() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will update all the SW variables and HW MCR registers after
+*        the association with target BSS.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID joinComplete(IN P_ADAPTER_T prAdapter)
+{
+	P_JOIN_INFO_T prJoinInfo;
+	P_BSS_DESC_T prBssDesc;
+	P_PEER_BSS_INFO_T prPeerBssInfo;
+	P_BSS_INFO_T prBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_STA_RECORD_T prStaRec;
+	P_TX_CTRL_T prTxCtrl;
+#if CFG_SUPPORT_802_11D
+	P_IE_COUNTRY_T prIECountry;
+#endif
+
+	DEBUGFUNC("joinComplete");
+
+	ASSERT(prAdapter);
+	prJoinInfo = &prAdapter->rJoinInfo;
+	prBssDesc = prJoinInfo->prBssDesc;
+	prPeerBssInfo = &prAdapter->rPeerBssInfo;
+	prBssInfo = &prAdapter->rBssInfo;
+	prConnSettings = &prAdapter->rConnSettings;
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */
+	/* Remove previous AP's Connection Flags if have */
+	scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID);
+
+	prBssDesc->fgIsConnected = TRUE;	/* Mask as Connected */
+
+	if (prBssDesc->fgIsHiddenSSID) {
+		/* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't
+		 * broadcast SSID on its Beacon Frame.
+		 */
+		COPY_SSID(prBssDesc->aucSSID,
+			  prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen);
+
+		if (prBssDesc->ucSSIDLen)
+			prBssDesc->fgIsHiddenSSID = FALSE;
+#if DBG
+		else
+			ASSERT(0);
+#endif /* DBG */
+
+		DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID);
+	}
+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */
+	/* 4 <2.A> PHY Type */
+	prBssInfo->ePhyType = prBssDesc->ePhyType;
+
+	/* 4 <2.B> BSS Type */
+	prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE;
+
+	/* 4 <2.C> BSSID */
+	COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID);
+
+	DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID);
+
+	/* 4 <2.D> SSID */
+	COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+
+	/* 4 <2.E> Channel / Band information. */
+	prBssInfo->eBand = prBssDesc->eBand;
+	prBssInfo->ucChnl = prBssDesc->ucChannelNum;
+
+	/* 4 <2.F> RSN/WPA information. */
+	secFsmRunEventStart(prAdapter);
+	prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher;
+	prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher;
+	prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite;
+
+	if (secRsnKeyHandshakeEnabled())
+		prBssInfo->fgIsWPAorWPA2Enabled = TRUE;
+	else
+		prBssInfo->fgIsWPAorWPA2Enabled = FALSE;
+
+	/* 4 <2.G> Beacon interval. */
+	prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
+
+	/* 4 <2.H> DTIM period. */
+	prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod;
+
+	/* 4 <2.I> ERP Information */
+	if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) &&	/* Our BSS's PHY_TYPE is ERP now. */
+	    (prBssDesc->fgIsERPPresent)) {
+
+		prBssInfo->fgIsERPPresent = TRUE;
+		prBssInfo->ucERP = prBssDesc->ucERP;	/* Save the ERP for later check */
+	} else {	/* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */
+		prBssInfo->fgIsERPPresent = FALSE;
+		prBssInfo->ucERP = 0;
+	}
+
+#if CFG_SUPPORT_802_11D
+	/* 4 <2.J> Country inforamtion of the associated AP */
+	if (prConnSettings->fgMultiDomainCapabilityEnabled) {
+		DOMAIN_INFO_ENTRY rDomainInfo;
+
+		if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) {
+			if (prBssDesc->prIECountry) {
+				prIECountry = prBssDesc->prIECountry;
+
+				domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo);
+
+				/* use the domain get from the BSS info */
+				prBssInfo->fgIsCountryInfoPresent = TRUE;
+				nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE);
+			} else {
+				/* use the domain get from the scan result */
+				prBssInfo->fgIsCountryInfoPresent = TRUE;
+				nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE);
+			}
+		}
+	}
+#endif
+
+	/* 4 <2.K> Signal Power of the associated AP */
+	prBssInfo->rRcpi = prBssDesc->rRcpi;
+	prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi);
+	GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime);
+
+	/* 4 <2.L> Capability Field of the associated AP */
+	prBssInfo->u2CapInfo = prBssDesc->u2CapInfo;
+
+	DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n",
+			    prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi);
+
+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */
+	/* 4 <3.A> Association ID */
+	prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId;
+
+	/* 4 <3.B> WMM Information */
+	if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) {
+
+		prBssInfo->fgIsWmmAssoc = TRUE;
+		prTxCtrl->rTxQForVoipAccess = TXQ_AC3;
+
+		qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE);
+
+		if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) {
+			kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
+		} else {
+			kalMemCopy(&prBssInfo->rWmmInfo,
+				   &prPeerBssInfo->rWmmInfo,
+				   sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams));
+		}
+	} else {
+		prBssInfo->fgIsWmmAssoc = FALSE;
+		prTxCtrl->rTxQForVoipAccess = TXQ_AC1;
+
+		kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
+	}
+
+	/* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */
+	prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet;
+	prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet;
+
+	/* 4 <3.D> Short Preamble */
+	if (prBssInfo->fgIsERPPresent) {
+
+		/* NOTE(Kevin 2007/12/24): Truth Table.
+		 * Short Preamble Bit in
+		 * <AssocReq>     <AssocResp w/i ERP>     <BARKER(Long)>  Final Driver Setting(Short)
+		 * TRUE            FALSE                  FALSE           FALSE(shouldn't have such case,
+		 *							  use the AssocResp)
+		 * TRUE            FALSE                  TRUE            FALSE
+		 * FALSE           FALSE                  FALSE           FALSE(shouldn't have such case,
+		 *							  use the AssocResp)
+		 * FALSE           FALSE                  TRUE            FALSE
+		 * TRUE            TRUE                   FALSE           TRUE(follow ERP)
+		 * TRUE            TRUE                   TRUE            FALSE(follow ERP)
+		 * FALSE           TRUE                   FALSE           FALSE(shouldn't have such case,
+		 *							  and we should set to FALSE)
+		 * FALSE           TRUE                   TRUE            FALSE(we should set to FALSE)
+		 */
+		if ((prPeerBssInfo->fgIsShortPreambleAllowed) &&
+		   ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */
+		   ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) &&
+		   (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) {
+
+			prBssInfo->fgIsShortPreambleAllowed = TRUE;
+
+			if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE)
+				prBssInfo->fgUseShortPreamble = FALSE;
+			else
+				prBssInfo->fgUseShortPreamble = TRUE;
+		} else {
+			prBssInfo->fgIsShortPreambleAllowed = FALSE;
+			prBssInfo->fgUseShortPreamble = FALSE;
+		}
+	} else {
+		/* NOTE(Kevin 2007/12/24): Truth Table.
+		 * Short Preamble Bit in
+		 * <AssocReq>     <AssocResp w/o ERP>     Final Driver Setting(Short)
+		 * TRUE            FALSE                  FALSE
+		 * FALSE           FALSE                  FALSE
+		 * TRUE            TRUE                   TRUE
+		 * FALSE           TRUE(status success)   TRUE
+		 * --> Honor the result of prPeerBssInfo.
+		 */
+
+		prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble =
+		    prPeerBssInfo->fgIsShortPreambleAllowed;
+	}
+
+	DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n",
+			    prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble);
+
+	/* 4 <3.E> Short Slot Time */
+	prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime;	/* AP support Short Slot Time */
+
+	DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime);
+
+	nicSetSlotTime(prAdapter,
+		       prBssInfo->ePhyType,
+		       ((prConnSettings->fgIsShortSlotTimeOptionEnable &&
+			 prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE));
+
+	/* 4 <3.F> Update Tx Rate for Control Frame */
+	bssUpdateTxRateForControlFrame(prAdapter);
+
+	/* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */
+	/* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */
+	{
+
+		if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM)
+			prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM;
+		else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)
+			prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY;
+
+		prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes;
+
+		/* Set the stable time of the associated BSS. We won't do roaming decision
+		 * during the stable time.
+		 */
+		SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime,
+				    SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC));
+	}
+
+	/* 4 <3.H> Update Parameter for TX Fragmentation Threshold */
+#if CFG_TX_FRAGMENT
+	txFragInfoUpdate(prAdapter);
+#endif /* CFG_TX_FRAGMENT */
+
+/* 4 <4> Update STA_RECORD_T */
+	/* Get a Station Record if possible */
+	prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID);
+
+	if (prStaRec) {
+		UINT_16 u2OperationalRateSet, u2DesiredRateSet;
+
+		/* 4 <4.A> Desired Rate Set */
+		u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet &
+					prBssInfo->u2OperationalRateSet);
+
+		u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet);
+		if (u2DesiredRateSet) {
+			prStaRec->u2DesiredRateSet = u2DesiredRateSet;
+		} else {
+			/* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */
+			prStaRec->u2DesiredRateSet = u2OperationalRateSet;
+		}
+
+		/* Try to set the best initial rate for this entry */
+		if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet,
+						 prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) {
+
+			if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index))
+				ASSERT(0);
+		}
+
+		DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index);
+
+		/* 4 <4.B> Preamble Mode */
+		prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble;
+
+		/* 4 <4.C> QoS Flag */
+		prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc;
+	}
+#if DBG
+	else
+		ASSERT(0);
+#endif /* DBG */
+
+/* 4 <5> Update NIC */
+	/* 4 <5.A> Update BSSID & Operation Mode */
+	nicSetupBSS(prAdapter, prBssInfo);
+
+	/* 4 <5.B> Update WLAN Table. */
+	if (nicSetHwBySta(prAdapter, prStaRec) == FALSE)
+		ASSERT(FALSE);
+	/* 4 <5.C> Update Desired Rate Set for BT. */
+#if CFG_TX_FRAGMENT
+	if (prConnSettings->fgIsEnableTxAutoFragmentForBT)
+		txRateSetInitForBT(prAdapter, prStaRec);
+#endif /* CFG_TX_FRAGMENT */
+
+	/* 4 <5.D> TX AC Parameter and TX/RX Queue Control */
+	if (prBssInfo->fgIsWmmAssoc) {
+
+#if CFG_TX_AGGREGATE_HW_FIFO
+		nicTxAggregateTXQ(prAdapter, FALSE);
+#endif /* CFG_TX_AGGREGATE_HW_FIFO */
+
+		qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo);
+	} else {
+
+#if CFG_TX_AGGREGATE_HW_FIFO
+		nicTxAggregateTXQ(prAdapter, TRUE);
+#endif /* CFG_TX_AGGREGATE_HW_FIFO */
+
+		nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter);
+
+		nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType);
+	}
+
+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN
+	{
+		prTxCtrl->fgBlockTxDuringJoin = FALSE;
+
+#if !CFG_TX_AGGREGATE_HW_FIFO	/* TX FIFO AGGREGATE already do flush once */
+		nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL);
+#endif /* CFG_TX_AGGREGATE_HW_FIFO */
+
+		nicTxRetransmitOfSendWaitQue(prAdapter);
+
+		if (prTxCtrl->fgIsPacketInOsSendQueue)
+			nicTxRetransmitOfOsSendQue(prAdapter);
+#if CFG_SDIO_TX_ENHANCE
+		halTxLeftClusteredMpdu(prAdapter);
+#endif /* CFG_SDIO_TX_ENHANCE */
+
+	}
+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */
+
+/* 4 <6> Setup CONNECTION flag. */
+	prAdapter->eConnectionState = MEDIA_STATE_CONNECTED;
+	prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED;
+
+	if (prJoinInfo->fgIsReAssoc)
+		prAdapter->fgBypassPortCtrlForRoaming = TRUE;
+	else
+		prAdapter->fgBypassPortCtrlForRoaming = FALSE;
+
+	kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0);
+
+}				/* end of joinComplete() */
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c
new file mode 100644
index 0000000000000..7b5a49a5ba631
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c
@@ -0,0 +1,5039 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ais_fsm.c#1
+*/
+
+/*! \file   "aa_fsm.c"
+    \brief  This file defines the FSM for SAA and AAA MODULE.
+
+    This file defines the FSM for SAA and AAA MODULE.
+*/
+
+/*
+** Log: ais_fsm.c
+**
+** 09 06 2013 cp.wu
+** always paste SSID information to SAA-FSM
+**
+** 09 06 2013 cp.wu
+** add error handling when reassociation request failed to locate bss descriptor
+**
+** 09 05 2013 cp.wu
+** isolate logic regarding roaming & reassociation
+**
+** 09 04 2013 cp.wu
+** fix typo
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+ *
+ * 04 20 2012 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * correct macro
+ *
+ * 01 16 2012 cp.wu
+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with
+ * corresponding network configuration
+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration
+ * corresponding to network type.
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 22 2011 cp.wu
+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous
+ * to asynchronous approach to avoid incomplete state termination
+ * 1. change RDD related compile option brace position.
+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state
+ * without join timeout timer ticking
+ * 3. otherwise, insert AIS_REQUEST into pending request queue
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 04 2011 cp.wu
+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED
+ * cases as an explicit trigger for Android framework
+ * correct reference to BSSID field in Association-Response frame.
+ *
+ * 11 04 2011 cp.wu
+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED
+ * cases as an explicit trigger for Android framework
+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately.
+ * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT
+ * indication to Android Wi-Fi framework
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 10 26 2011 tsaiyuan.hsu
+ * [WCXRP00001064] [MT6620 Wi-Fi][DRV]] add code with roaming awareness when disconnecting AIS network
+ * be aware roaming when disconnecting AIS network.
+ *
+ * 10 25 2011 cm.chang
+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
+ * STA_REC shall be NULL for Beacon's MSDU
+ *
+ * 10 13 2011 cp.wu
+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS
+ * 1. short join failure count limit to 2
+ * 2. treat join timeout as kind of join failure as well
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 30 2011 cm.chang
+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band
+ * .
+ *
+ * 09 20 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * change window registry of driver for roaming.
+ *
+ * 09 20 2011 cm.chang
+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
+ * Handle client mode about preamble type and slot time
+ *
+ * 09 08 2011 tsaiyuan.hsu
+ * [WCXRP00000972] [MT6620 Wi-Fi][DRV]] check if roaming occurs after join failure to avoid state incosistence.
+ * check if roaming occurs after join failure to avoid deactivation of network.
+ *
+ * 08 24 2011 chinghwa.yu
+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Update RDD test mode cases.
+ *
+ * 08 16 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * EnableRoaming in registry is deprecated.
+ *
+ * 08 16 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * use registry to enable or disable roaming.
+ *
+ * 07 07 2011 cp.wu
+ * [WCXRP00000840] [MT6620 Wi-Fi][Driver][AIS] Stop timer for joining when channel is released
+ * due to join failure count exceeding limit
+ * stop timer when joining operation is failed due to try count exceeds limitation
+ *
+ * 06 28 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work
+ * around some tricky AP which use space character as hidden SSID
+ * do not handle SCAN request immediately after connected to increase the probability of receiving 1st beacon frame.
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * change parameter name from PeerAddr to BSSID
+ *
+ * 06 20 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * 1. specify target's BSSID when requesting channel privilege.
+ * 2. pass BSSID information to firmware domain
+ *
+ * 06 16 2011 cp.wu
+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout
+ * ensure DEAUTH is always sent before establish a new connection
+ *
+ * 06 16 2011 cp.wu
+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout
+ * typo fix: a right brace is missed.
+ *
+ * 06 16 2011 cp.wu
+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout
+ * When RECONNECT request is identified as disconnected, it is necessary to check for pending scan request.
+ *
+ * 06 16 2011 cp.wu
+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels
+ * mark fgIsTransition as TRUE for state rolling.
+ *
+ * 06 16 2011 cp.wu
+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout
+ * always check for pending scan after switched into NORMAL_TR state.
+ *
+ * 06 14 2011 cp.wu
+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout
+ * always treat connection request at higher priority over scanning request
+ *
+ * 06 09 2011 tsaiyuan.hsu
+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size
+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size.
+ *
+ * 06 02 2011 cp.wu
+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction
+ * eliminate unused parameters for SAA-FSM
+ *
+ * 05 18 2011 cp.wu
+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state
+ * when DEAUTH frame is dropped due to bss disconnection
+ * change SCAN handling behavior when followed by a CONNECT/DISCONNECT requests by pending instead of dropping.
+ *
+ * 05 17 2011 cp.wu
+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state
+ * when DEAUTH frame is dropped due to bss disconnection
+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state.
+ *
+ * 04 14 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 13 2011 george.huang
+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF
+ * remove assert
+ *
+ * 03 18 2011 cp.wu
+ * [WCXRP00000575] [MT6620 Wi-Fi][Driver][AIS] reduce memory usage when generating mailbox message for scan request
+ * when there is no IE needed for probe request, then request a smaller memory for mailbox message
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 16 2011 tsaiyuan.hsu
+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming
+ * remove obsolete definition and unused variables.
+ *
+ * 03 11 2011 cp.wu
+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel
+ *
+ * 03 09 2011 tsaiyuan.hsu
+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming
+ * avoid clearing fgIsScanReqIssued so as to add scan results.
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 03 04 2011 tsaiyuan.hsu
+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming
+ * reset retry conter of attemp to connect to ap after completion of join.
+ *
+ * 03 04 2011 cp.wu
+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection
+ * surpress compile warning occurred when compiled by GNU compiler collection.
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right
+ * after connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
+ *
+ * 02 26 2011 tsaiyuan.hsu
+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support
+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming.
+ *
+ * 02 23 2011 cp.wu
+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach to
+ * improve response time for scanning request
+ * when handling reconnect request, set fgTryScan as TRUE
+ *
+ * 02 22 2011 cp.wu
+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach
+ * to improve response time for scanning request
+ * handle SCAN and RECONNECT with a FIFO approach.
+ *
+ * 02 09 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * Check if prRegInfo is null or not before initializing roaming parameters.
+ *
+ * 02 01 2011 cp.wu
+ * [WCXRP00000416] [MT6620 Wi-Fi][Driver] treat "unable to find BSS" as connection trial
+ * to prevent infinite reconnection trials
+ * treat "unable to find BSS" as connection trial to prevent infinite reconnection trials.
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Fix Compile Error when DBG is disabled.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 01 14 2011 cp.wu
+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent
+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS.
+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol.
+ *
+ * 01 11 2011 cp.wu
+ * [WCXRP00000307] [MT6620 Wi-Fi][SQA]WHQL test .2c_wlan_adhoc case fail.
+ * [IBSS] when merged in, the bss state should be updated to firmware to pass WHQL adhoc failed item
+ *
+ * 01 10 2011 cp.wu
+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer
+ * when the corresponding BSS is disconnected due to beacon timeout
+ * remove from scanning result when the BSS is disconnected due to beacon timeout.
+ *
+ * 01 03 2011 cp.wu
+ * [WCXRP00000337] [MT6620 Wi-FI][Driver] AIS-FSM not to invoke cnmStaRecResetStatus
+ * directly 'cause it frees all belonging STA-RECs
+ * do not invoke cnmStaRecResetStatus() directly, nicUpdateBss will do the things after bss is disconnected
+ *
+ * 12 30 2010 cp.wu
+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged
+ * do not need to manipulate prStaRec after indicating BSS disconnection to firmware,
+ * 'cause all STA-RECs belongs to BSS has been freed already
+ *
+ * 12 27 2010 cp.wu
+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release
+ * add DEBUGFUNC() macro invoking for more detailed debugging information
+ *
+ * 12 23 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * 1. update WMM IE parsing, with ASSOC REQ handling
+ * 2. extend U-APSD parameter passing from driver to FW
+ *
+ * 12 17 2010 cp.wu
+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged
+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 11 25 2010 yuche.tsai
+ * NULL
+ * Update SLT Function for QoS Support and not be affected by fixed rate function.
+ *
+ * 11 25 2010 cp.wu
+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM
+ * add scanning with specified SSID facility to AIS-FSM
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with
+ * Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate
+ * from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW]
+ * Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 14 2010 wh.su
+ * [WCXRP00000097] [MT6620 Wi-Fi] [Driver] Fixed the P2P not setting the fgIsChannelExt value make scan not abort
+ * initial the fgIsChannelExt value.
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert.
+ * correct erroneous logic: specifying eBand with incompatible eSco
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T
+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 27 2010 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
+ * Update BCM/BoW design and settings.
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000049] [MT6620 Wi-Fi][Driver] Adhoc cannot be created successfully.
+ * keep IBSS-ALONE state retrying until further instruction is received
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD
+ * when entering RF test with AIS associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 09 2010 yuche.tsai
+ * NULL
+ * Fix NULL IE Beacon issue. Sync Beacon Content to FW before enable beacon.
+ * Both in IBSS Create & IBSS Merge
+ *
+ * 09 09 2010 cp.wu
+ * NULL
+ * frequency is in unit of KHz thus no need to divide 1000 once more.
+ *
+ * 09 06 2010 cp.wu
+ * NULL
+ * 1) initialize for correct parameter even for disassociation.
+ * 2) AIS-FSM should have a limit on trials to build connection
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * Finish SLT TX/RX & Rate Changing Support.
+ *
+ * 08 25 2010 cp.wu
+ * NULL
+ * add option for enabling AIS 5GHz scan
+ *
+ * 08 25 2010 cp.wu
+ * NULL
+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing,
+ * RLM/CNM will handle the channel switching when BSS information is updated
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * check-in missed files.
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse()
+ *
+ * 08 09 2010 cp.wu
+ * NULL
+ * reset fgIsScanReqIssued when abort request is received right after join completion.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 08 02 2010 cp.wu
+ * NULL
+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver.
+ *
+ * 07 30 2010 cp.wu
+ * NULL
+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc*
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * allocate on MGMT packet for IBSS beaconing.
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * [AIS-FSM] fix: when join failed, release channel privilege as well
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * reuse join-abort sub-procedure to reduce code size.
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo
+ * 2) change nicMediaStateChange() API prototype
+ *
+ * 07 26 2010 cp.wu
+ *
+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period,
+ * just pend it til 5-sec. period finishes
+ *
+ * 07 26 2010 cp.wu
+ *
+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet
+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found
+ *
+ * 07 26 2010 cp.wu
+ *
+ * re-commit code logic being overwriten.
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 23 2010 cp.wu
+ *
+ * 1) re-enable AIS-FSM beacon timeout handling.
+ * 2) scan done API revised
+ *
+ * 07 23 2010 cp.wu
+ *
+ * 1) enable Ad-Hoc
+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event.
+ *
+ * 07 23 2010 cp.wu
+ *
+ * indicate scan done for linux wireless extension
+ *
+ * 07 23 2010 cp.wu
+ *
+ * add AIS-FSM handling for beacon timeout event.
+ *
+ * 07 22 2010 cp.wu
+ *
+ * 1) refine AIS-FSM indent.
+ * 2) when entering RF Test mode, flush 802.1X frames as well
+ * 3) when entering D3 state, flush 802.1X frames as well
+ *
+ * 07 21 2010 cp.wu
+ *
+ * separate AIS-FSM states into different cases of channel request.
+ *
+ * 07 21 2010 cp.wu
+ *
+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term
+ * 2) only clear scanning result when scan is permitted to do
+ *
+ * 07 20 2010 cp.wu
+ *
+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one
+ * 2) refine disconnection behaviour when issued during BG-SCAN process
+ *
+ * 07 20 2010 cp.wu
+ *
+ * 1) bugfix: do not stop timer for join after switched into normal_tr state,
+ * for providing chance for DHCP handshasking
+ * 2) modify rsnPerformPolicySelection() invoking
+ *
+ * 07 19 2010 cp.wu
+ *
+ * 1) init AIS_BSS_INFO as channel number = 1 with band = 2.4GHz
+ * 2) correct typo
+ *
+ * 07 19 2010 wh.su
+ *
+ * update for security supporting.
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * when IBSS is being merged-in, send command packet to PM for connected indication
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Add Ad-Hoc support to AIS-FSM
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 16 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * bugfix for SCN migration
+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue
+ * 2) before AIS issues scan request, network(BSS) needs to be activated first
+ * 3) only invoke COPY_SSID when using specified SSID for scan
+ *
+ * 07 15 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * for AIS scanning, driver specifies no extra IE for probe request
+ *
+ * 07 15 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * driver no longer generates probe request frames
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * Remove CFG_MQM_MIGRATION
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Refine AIS-FSM by divided into more states
+ *
+ * 07 13 2010 cm.chang
+ *
+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T
+ *
+ * 07 09 2010 cp.wu
+ *
+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
+ * 3) implment DRV-SCN module, currently only accepts single scan request,
+ * other request will be directly dropped by returning BUSY
+ *
+ * 07 09 2010 george.huang
+ *
+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * take use of RLM module for parsing/generating HT IEs for 11n capability
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT
+ *
+ * 07 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * for first connection, if connecting failed do not enter into scan state.
+ *
+ * 07 06 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * once STA-REC is allocated and updated, invoke cnmStaRecChangeState() to sync. with firmware.
+ *
+ * 07 06 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Update arguments for nicUpdateBeaconIETemplate()
+ *
+ * 07 06 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * STA-REC is maintained by CNM only.
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * remove unused definitions.
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * AIS-FSM integration with CNM channel request messages
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 30 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * sync. with CMD/EVENT document ver0.07.
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) sync to. CMD/EVENT document v0.03
+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
+ * 3) send command packet to indicate FW-PM after
+ *     a) 1st beacon is received after AIS has connected to an AP
+ *     b) IBSS-ALONE has been created
+ *     c) IBSS-MERGE has occurred
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * modify Beacon/ProbeResp to complete parsing,
+ * because host software has looser memory usage restriction
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * integrate .
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * comment out RLM APIs by CFG_RLM_MIGRATION.
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Support CFG_MQM_MIGRATION flag
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan_fsm into building.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * RSN/PRIVACY compilation flag awareness correction
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration from MT6620 firmware.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan.c.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * restore utility function invoking via hem_mbox to direct calls
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add bss.c.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change to enqueue TX frame infinitely.
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 01 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add conditionial compiling flag to choose default available bandwidth
+ *
+ * 05 28 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList
+ *
+ * 05 24 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval.
+ *
+ * 05 21 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Fix compile error if CFG_CMD_EVENT_VER_009 == 0 for prEventConnStatus->ucNetworkType.
+ *
+ * 05 21 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set
+ *
+ * 05 17 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Call pmAbort() and add ucNetworkType field in EVENT_CONNECTION_STATUS
+ *
+ * 05 14 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Fix compile warning - define of MQM_WMM_PARSING was removed
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 28 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Removed the use of compiling flag MQM_WMM_PARSING
+ *
+ * 04 27 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ *
+ * Fix typo
+ *
+ * 04 27 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Send Deauth for Class 3 Error and Leave Network Support
+ *
+ * 04 15 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * fixed the protected bit at cap info for ad-hoc.
+ *
+ * 04 13 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add new HW CH macro support
+ *
+ * 04 07 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Add TX Power Control RCPI function.
+ *
+ * 03 29 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * move the wlan table alloc / free to change state function.
+ *
+ * 03 25 2010 wh.su
+ * [BORA00000676][MT6620] Support the frequency setting and query at build connection / connection event
+ * modify the build connection and status event structure bu CMD_EVENT doc 0.09 draft, default is disable.
+ *
+ * 03 24 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * fixed some WHQL testing error.
+ *
+ * 03 24 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ * Add Set / Unset POWER STATE in AIS Network
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 03 03 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add PHY_CONFIG to change Phy Type
+ *
+ * 03 03 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Use bcmWiFiNotify to replace wifi_send_msg to pass information to BCM module.
+ *
+ * 03 03 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Remove wmt_task definition and add PTA function.
+ *
+ * 03 02 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Init TXM and MQM testing procedures in aisFsmRunEventJoinComplete()
+ *
+ * 03 01 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Modified aisUpdateBssInfo() to call TXM's functions for setting WTBL TX parameters
+ *
+ * 03 01 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * clear the pmkid cache while indicate media disconnect.
+ *
+ * 02 26 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * .
+ *
+ * 02 26 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Enabled MQM parsing WMM IEs for non-AP mode
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation
+ *
+ * 02 25 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * use the Rx0 dor event indicate.
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Support dynamic channel selection
+ *
+ * 02 23 2010 wh.su
+ * [BORA00000621][MT6620 Wi-Fi] Add the RSSI indicate to avoid XP stalled for query rssi value
+ * Adding the RSSI event support,
+ * using the HAL function to get the rcpi value and tranlsate to RSSI and indicate to driver
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Use bss info array for concurrent handle
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 27 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Set max AMDPU size supported by the peer to 64 KB,
+ * removed mqmInit() and mqmTxSendAddBaReq() function calls in aisUpdateBssInfo()
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 01 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+ *
+ * 01 20 2010 kevin.huang
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags
+ *
+ * 01 15 2010 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Configured the AMPDU factor to 3 for the APu1rwduu`wvpghlqg|q`mpdkb+ilp
+ *
+ * 01 14 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Add WiFi BCM module for the 1st time.
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 07 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ * Refine JOIN Complete and separate the function of Media State indication
+ *
+ * 01 04 2010 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * For working out the first connection Chariot-verified version
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 10 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the sample code to update the wlan table rate,
+ *
+ * Dec 10 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Different function prototype of wifi_send_msg()
+ *
+ * Dec 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Call rlm related function to process HT info when join complete
+ *
+ * Dec 9 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * default the acquired wlan table entry code off
+ *
+ * Dec 9 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the code to acquired the wlan table entry, and a sample code to update the BA bit at table
+ *
+ * Dec 7 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix the problem of prSwRfb overwrited by event packet in aisFsmRunEventJoinComplete()
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the code to integrate the security related code
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Remove redundant declaration
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add code for JOIN init and JOIN complete
+ *
+ * Nov 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Rename u4RSSI to i4RSSI
+ *
+ * Nov 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Revise ENUM_MEDIA_STATE to ENUM_PARAM_MEDIA_STATE
+ *
+ * Nov 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add fgIsScanReqIssued to CONNECTION_SETTINGS_T
+ *
+ * Nov 26 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Revise Virtual CMD handler due to structure changed
+ *
+ * Nov 25 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add Virtual CMD & RESP for testing CMD PATH
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add aisFsmInitializeConnectionSettings()
+ *
+ * Nov 20 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add CFG_TEST_MGMT_FSM flag for aisFsmTest()
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define AIS_ROAMING_CONNECTION_TRIAL_LIMIT  2
+#define AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME 80
+
+#define CTIA_MAGIC_SSID                     "ctia_test_only_*#*#3646633#*#*"
+#define CTIA_MAGIC_SSID_LEN                 30
+
+#define AIS_JOIN_TIMEOUT                    7
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if DBG
+/*lint -save -e64 Type mismatch */
+static PUINT_8 apucDebugAisState[AIS_STATE_NUM] = {
+	(PUINT_8) DISP_STRING("AIS_STATE_IDLE"),
+	(PUINT_8) DISP_STRING("AIS_STATE_SEARCH"),
+	(PUINT_8) DISP_STRING("AIS_STATE_SCAN"),
+	(PUINT_8) DISP_STRING("AIS_STATE_ONLINE_SCAN"),
+	(PUINT_8) DISP_STRING("AIS_STATE_LOOKING_FOR"),
+	(PUINT_8) DISP_STRING("AIS_STATE_WAIT_FOR_NEXT_SCAN"),
+	(PUINT_8) DISP_STRING("AIS_STATE_REQ_CHANNEL_JOIN"),
+	(PUINT_8) DISP_STRING("AIS_STATE_JOIN"),
+	(PUINT_8) DISP_STRING("AIS_STATE_IBSS_ALONE"),
+	(PUINT_8) DISP_STRING("AIS_STATE_IBSS_MERGE"),
+	(PUINT_8) DISP_STRING("AIS_STATE_NORMAL_TR"),
+	(PUINT_8) DISP_STRING("AIS_STATE_DISCONNECTING"),
+	(PUINT_8) DISP_STRING("AIS_STATE_REQ_REMAIN_ON_CHANNEL"),
+	(PUINT_8) DISP_STRING("AIS_STATE_REMAIN_ON_CHANNEL")
+};
+
+/*lint -restore */
+#endif /* DBG */
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief the function is used to initialize the value of the connection settings for
+*        AIS network
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	UINT_8 aucAnyBSSID[] = BC_BSSID;
+	UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR;
+	int i = 0;
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	/* Setup default values for operation */
+	COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr);
+
+	if (prRegInfo)
+		prConnSettings->ucDelayTimeOfDisconnectEvent =
+		    (!prAdapter->fgIsHw5GBandDisabled && prRegInfo->ucSupport5GBand) ?
+		    AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND : AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4;
+	else
+		prConnSettings->ucDelayTimeOfDisconnectEvent = AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4;
+
+	COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID);
+	prConnSettings->fgIsConnByBssidIssued = FALSE;
+
+	prConnSettings->fgIsConnReqIssued = FALSE;
+	prConnSettings->fgIsDisconnectedByNonRequest = FALSE;
+
+	prConnSettings->ucSSIDLen = 0;
+
+	prConnSettings->eOPMode = NET_TYPE_INFRA;
+
+	prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI;
+
+	if (prRegInfo) {
+		prConnSettings->ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4StartFreq);
+		prConnSettings->eAdHocBand = prRegInfo->u4StartFreq < 5000000 ? BAND_2G4 : BAND_5G;
+		prConnSettings->eAdHocMode = (ENUM_PARAM_AD_HOC_MODE_T) (prRegInfo->u4AdhocMode);
+	}
+
+	prConnSettings->eAuthMode = AUTH_MODE_OPEN;
+
+	prConnSettings->eEncStatus = ENUM_ENCRYPTION_DISABLED;
+
+	prConnSettings->fgIsScanReqIssued = FALSE;
+
+	/* MIB attributes */
+	prConnSettings->u2BeaconPeriod = DOT11_BEACON_PERIOD_DEFAULT;
+
+	prConnSettings->u2RTSThreshold = DOT11_RTS_THRESHOLD_DEFAULT;
+
+	prConnSettings->u2DesiredNonHTRateSet = RATE_SET_ALL_ABG;
+
+	/* prConnSettings->u4FreqInKHz; */ /* Center frequency */
+
+	/* Set U-APSD AC */
+	prConnSettings->bmfgApsdEnAc = PM_UAPSD_NONE;
+
+	secInit(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* Features */
+	prConnSettings->fgIsEnableRoaming = FALSE;
+#if CFG_SUPPORT_ROAMING
+	if (prRegInfo)
+		prConnSettings->fgIsEnableRoaming = ((prRegInfo->fgDisRoaming > 0) ? (FALSE) : (TRUE));
+#endif /* CFG_SUPPORT_ROAMING */
+
+	prConnSettings->fgIsAdHocQoSEnable = FALSE;
+
+	prConnSettings->eDesiredPhyConfig = PHY_CONFIG_802_11ABGN;
+
+	/* Set default bandwidth modes */
+	prConnSettings->uc2G4BandwidthMode = CONFIG_BW_20M;
+	prConnSettings->uc5GBandwidthMode = CONFIG_BW_20_40M;
+
+	prConnSettings->rRsnInfo.ucElemId = 0x30;
+	prConnSettings->rRsnInfo.u2Version = 0x0001;
+	prConnSettings->rRsnInfo.u4GroupKeyCipherSuite = 0;
+	prConnSettings->rRsnInfo.u4PairwiseKeyCipherSuiteCount = 0;
+	for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++)
+		prConnSettings->rRsnInfo.au4PairwiseKeyCipherSuite[i] = 0;
+	prConnSettings->rRsnInfo.u4AuthKeyMgtSuiteCount = 0;
+	for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++)
+		prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[i] = 0;
+	prConnSettings->rRsnInfo.u2RsnCap = 0;
+	prConnSettings->rRsnInfo.fgRsnCapPresent = FALSE;
+
+}				/* end of aisFsmInitializeConnectionSettings() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief the function is used to initialize the value in AIS_FSM_INFO_T for
+*        AIS FSM operation
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 ucScanTimeoutTimes = 0;
+VOID aisFsmInit(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
+
+	DEBUGFUNC("aisFsmInit()");
+	DBGLOG(SW1, TRACE, "->aisFsmInit()\n");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
+
+	/* 4 <1> Initiate FSM */
+	prAisFsmInfo->ePreviousState = AIS_STATE_IDLE;
+	prAisFsmInfo->eCurrentState = AIS_STATE_IDLE;
+
+	prAisFsmInfo->ucAvailableAuthTypes = 0;
+
+	prAisFsmInfo->prTargetBssDesc = (P_BSS_DESC_T) NULL;
+
+	prAisFsmInfo->ucSeqNumOfReqMsg = 0;
+	prAisFsmInfo->ucSeqNumOfChReq = 0;
+	prAisFsmInfo->ucSeqNumOfScanReq = 0;
+
+	prAisFsmInfo->fgIsInfraChannelFinished = TRUE;
+#if CFG_SUPPORT_ROAMING
+	prAisFsmInfo->fgIsRoamingScanPending = FALSE;
+#endif /* CFG_SUPPORT_ROAMING */
+	prAisFsmInfo->fgIsChannelRequested = FALSE;
+	prAisFsmInfo->fgIsChannelGranted = FALSE;
+
+	/* 4 <1.1> Initiate FSM - Timer INIT */
+	cnmTimerInitTimer(prAdapter,
+			  &prAisFsmInfo->rBGScanTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventBGSleepTimeOut, (ULONG) NULL);
+
+	cnmTimerInitTimer(prAdapter,
+			  &prAisFsmInfo->rIbssAloneTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventIbssAloneTimeOut, (ULONG) NULL);
+
+	cnmTimerInitTimer(prAdapter,
+			  &prAisFsmInfo->rIndicationOfDisconnectTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) aisPostponedEventOfDisconnTimeout, (ULONG) NULL);
+
+	cnmTimerInitTimer(prAdapter,
+			  &prAisFsmInfo->rJoinTimeoutTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventJoinTimeout, (ULONG) NULL);
+
+	cnmTimerInitTimer(prAdapter,
+			  &prAisFsmInfo->rScanDoneTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventScanDoneTimeOut, (ULONG) NULL);
+
+	cnmTimerInitTimer(prAdapter,
+			  &prAisFsmInfo->rChannelTimeoutTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventChannelTimeout, (ULONG) NULL);
+
+	cnmTimerInitTimer(prAdapter,
+			  &prAisFsmInfo->rDeauthDoneTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventDeauthTimeout, (ULONG) NULL);
+
+	/* 4 <1.2> Initiate PWR STATE */
+	SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 4 <2> Initiate BSS_INFO_T - common part */
+	BSS_INFO_INIT(prAdapter, NETWORK_TYPE_AIS_INDEX);
+	COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress);
+
+	/* 4 <3> Initiate BSS_INFO_T - private part */
+	/* TODO */
+	prAisBssInfo->eBand = BAND_2G4;
+	prAisBssInfo->ucPrimaryChannel = 1;
+	prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+
+	/* 4 <4> Allocate MSDU_INFO_T for Beacon */
+	prAisBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter,
+						OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH);
+
+	if (prAisBssInfo->prBeacon) {
+		prAisBssInfo->prBeacon->eSrc = TX_PACKET_MGMT;
+		prAisBssInfo->prBeacon->ucStaRecIndex = 0xFF;	/* NULL STA_REC */
+	} else {
+		ASSERT(0);
+	}
+
+#if 0
+	prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL;
+	prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL;
+	prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2;
+#else
+	if (prAdapter->u4UapsdAcBmp == 0) {
+		prAdapter->u4UapsdAcBmp = CFG_INIT_UAPSD_AC_BMP;
+		/* ASSERT(prAdapter->u4UapsdAcBmp); */
+	}
+	prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp;
+	prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp;
+	prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen;
+#endif
+
+	/* request list initialization */
+	LINK_INITIALIZE(&prAisFsmInfo->rPendingReqList);
+
+	/* DBGPRINTF("[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", */
+	/* prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, */
+	/* prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, */
+	/* prAisBssInfo->rPmProfSetupInfo.ucUapsdSp); */
+
+	/*reset ucScanTimeoutTimes value*/
+	ucScanTimeoutTimes = 0;
+
+}				/* end of aisFsmInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief the function is used to uninitialize the value in AIS_FSM_INFO_T for
+*        AIS FSM operation
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
+
+	DEBUGFUNC("aisFsmUninit()");
+	DBGLOG(SW1, INFO, "->aisFsmUninit()\n");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
+
+	/* 4 <1> Stop all timers */
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer);
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer);
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer);
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer);
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer);	/* Add by Enlai */
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer);
+
+	/* 4 <2> flush pending request */
+	aisFsmFlushRequest(prAdapter);
+
+	/* 4 <3> Reset driver-domain BSS-INFO */
+	if (prAisBssInfo->prBeacon) {
+		cnmMgtPktFree(prAdapter, prAisBssInfo->prBeacon);
+		prAisBssInfo->prBeacon = NULL;
+	}
+#if CFG_SUPPORT_802_11W
+	rsnStopSaQuery(prAdapter);
+#endif
+
+}				/* end of aisFsmUninit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Initialization of JOIN STATE
+*
+* @param[in] prBssDesc  The pointer of BSS_DESC_T which is the BSS we will try to join with.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_STA_RECORD_T prStaRec;
+	P_MSG_JOIN_REQ_T prJoinReqMsg;
+
+	DEBUGFUNC("aisFsmStateInit_JOIN()");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	ASSERT(prBssDesc);
+
+	/* 4 <1> We are going to connect to this BSS. */
+	prBssDesc->fgIsConnecting = TRUE;
+
+	/* 4 <2> Setup corresponding STA_RECORD_T */
+	prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_LEGACY_AP, NETWORK_TYPE_AIS_INDEX, prBssDesc);
+	if (prStaRec == NULL) {
+		DBGLOG(AIS, WARN, "Create station record fail\n");
+		return;
+	}
+
+	prAisFsmInfo->prTargetStaRec = prStaRec;
+
+	/* 4 <2.1> sync. to firmware domain */
+	if (prStaRec->ucStaState == STA_STATE_1)
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+	/* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */
+	if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
+
+		prStaRec->fgIsReAssoc = FALSE;
+
+		switch (prConnSettings->eAuthMode) {
+		case AUTH_MODE_OPEN:	/* Note: Omit break here. */
+		case AUTH_MODE_WPA:
+		case AUTH_MODE_WPA_PSK:
+		case AUTH_MODE_WPA2:
+		case AUTH_MODE_WPA2_PSK:
+			prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM;
+			break;
+
+		case AUTH_MODE_SHARED:
+			prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY;
+			break;
+
+		case AUTH_MODE_AUTO_SWITCH:
+			DBGLOG(AIS, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n");
+			prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | AUTH_TYPE_SHARED_KEY);
+			break;
+
+		default:
+			ASSERT(!(prConnSettings->eAuthMode == AUTH_MODE_WPA_NONE));
+			DBGLOG(AIS, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n",
+					    prConnSettings->eAuthMode);
+			/* TODO(Kevin): error handling ? */
+			return;
+		}
+
+		/* TODO(tyhsu): Assume that Roaming Auth Type is equal to ConnSettings eAuthMode */
+		prAisSpecificBssInfo->ucRoamingAuthTypes = prAisFsmInfo->ucAvailableAuthTypes;
+
+		prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT;
+
+	} else {
+		ASSERT(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE);
+		ASSERT(!prBssDesc->fgIsConnected);
+
+		DBGLOG(AIS, LOUD, "JOIN INIT: AUTH TYPE = %d for Roaming\n",
+				   prAisSpecificBssInfo->ucRoamingAuthTypes);
+
+		prStaRec->fgIsReAssoc = TRUE;	/* We do roaming while the medium is connected */
+
+		/* TODO(Kevin): We may call a sub function to acquire the Roaming Auth Type */
+		prAisFsmInfo->ucAvailableAuthTypes = prAisSpecificBssInfo->ucRoamingAuthTypes;
+
+		prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING;
+	}
+
+	/* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */
+	if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) {
+
+		DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n");
+		prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM;
+
+		prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM;
+	} else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) {
+
+		DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n");
+
+		prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY;
+
+		prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY;
+	} else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) {
+
+		DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n");
+
+		prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION;
+
+		prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION;
+	} else {
+		ASSERT(0);
+	}
+
+	/* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */
+	if (prBssDesc->ucSSIDLen)
+		COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+	/* 4 <6> Send a Msg to trigger SAA to start JOIN process. */
+	prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T));
+	if (!prJoinReqMsg) {
+
+		ASSERT(0);	/* Can't trigger SAA FSM */
+		return;
+	}
+
+	prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START;
+	prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg;
+	prJoinReqMsg->prStaRec = prStaRec;
+
+	if (1) {
+		int j;
+		P_FRAG_INFO_T prFragInfo;
+
+		for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) {
+			prFragInfo = &prStaRec->rFragInfo[j];
+
+			if (prFragInfo->pr1stFrag) {
+				/* nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); */
+				prFragInfo->pr1stFrag = (P_SW_RFB_T) NULL;
+			}
+		}
+	}
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF);
+
+}				/* end of aisFsmInit_JOIN() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH
+*
+* @param[in] prStaRec       Pointer to the STA_RECORD_T
+*
+* @retval TRUE      We will retry JOIN
+* @retval FALSE     We will not retry JOIN
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_MSG_JOIN_REQ_T prJoinReqMsg;
+
+	DEBUGFUNC("aisFsmStateInit_RetryJOIN()");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	/* Retry other AuthType if possible */
+	if (!prAisFsmInfo->ucAvailableAuthTypes)
+		return FALSE;
+
+	if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) {
+
+		DBGLOG(AIS, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n");
+
+		prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY;
+
+		prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY;
+	} else {
+		DBGLOG(AIS, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n");
+		ASSERT(0);
+	}
+
+	prAisFsmInfo->ucAvailableAuthTypes = 0;	/* No more available Auth Types */
+
+	/* Trigger SAA to start JOIN process. */
+	prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T));
+	if (!prJoinReqMsg) {
+
+		ASSERT(0);	/* Can't trigger SAA FSM */
+		return FALSE;
+	}
+
+	prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START;
+	prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg;
+	prJoinReqMsg->prStaRec = prStaRec;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF);
+
+	return TRUE;
+
+}				/* end of aisFsmRetryJOIN() */
+
+#if CFG_SUPPORT_ADHOC
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief State Initialization of AIS_STATE_IBSS_ALONE
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_INFO_T prAisBssInfo;
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	/* 4 <1> Check if IBSS was created before ? */
+	if (prAisBssInfo->fgIsBeaconActivated) {
+
+		/* 4 <2> Start IBSS Alone Timer for periodic SCAN and then SEARCH */
+#if !CFG_SLT_SUPPORT
+		cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC));
+#endif
+	}
+
+	aisFsmCreateIBSS(prAdapter);
+
+}				/* end of aisFsmStateInit_IBSS_ALONE() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief State Initialization of AIS_STATE_IBSS_MERGE
+*
+* @param[in] prBssDesc  The pointer of BSS_DESC_T which is the IBSS we will try to merge with.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_INFO_T prAisBssInfo;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+
+	ASSERT(prBssDesc);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	/* 4 <1> We will merge with to this BSS immediately. */
+	prBssDesc->fgIsConnecting = FALSE;
+	prBssDesc->fgIsConnected = TRUE;
+
+	/* 4 <2> Setup corresponding STA_RECORD_T */
+	prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc);
+	if (prStaRec == NULL) {
+		DBGLOG(AIS, WARN, "Create station record fail\n");
+		return;
+	}
+
+	prStaRec->fgIsMerging = TRUE;
+
+	prAisFsmInfo->prTargetStaRec = prStaRec;
+
+	/* 4 <2.1> sync. to firmware domain */
+	cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+	/* 4 <3> IBSS-Merge */
+	aisFsmMergeIBSS(prAdapter, prStaRec);
+
+}				/* end of aisFsmStateInit_IBSS_MERGE() */
+
+#endif /* CFG_SUPPORT_ADHOC */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process of JOIN Abort
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_MSG_JOIN_ABORT_T prJoinAbortMsg;
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	/* 1. Abort JOIN process */
+	prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T));
+	if (!prJoinAbortMsg) {
+
+		ASSERT(0);	/* Can't abort SAA FSM */
+		return;
+	}
+
+	prJoinAbortMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_ABORT;
+	prJoinAbortMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfReqMsg;
+	prJoinAbortMsg->prStaRec = prAisFsmInfo->prTargetStaRec;
+
+	scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr);
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF);
+
+	/* 2. Return channel privilege */
+	aisFsmReleaseCh(prAdapter);
+
+	/* 3.1 stop join timeout timer */
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer);
+
+	/* 3.2 reset local variable */
+	prAisFsmInfo->fgIsInfraChannelFinished = TRUE;
+	prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE;
+
+}				/* end of aisFsmAbortJOIN() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process of SCAN Abort
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_MSG_SCN_SCAN_CANCEL prScanCancelMsg;
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	/* Abort JOIN process. */
+	prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL));
+	if (!prScanCancelMsg) {
+
+		ASSERT(0);	/* Can't abort SCN FSM */
+		return;
+	}
+
+	prScanCancelMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_CANCEL;
+	prScanCancelMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfScanReq;
+	prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX;
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prAdapter->fgIsP2PRegistered)
+		prScanCancelMsg->fgIsChannelExt = FALSE;
+#endif
+
+	/* unbuffered message to guarantee scan is cancelled in sequence */
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_UNBUF);
+
+}				/* end of aisFsmAbortSCAN() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process of NORMAL_TR Abort
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+
+	ASSERT(prAdapter);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	DBGLOG(AIS, TRACE, "aisFsmStateAbort_NORMAL_TR\n");
+
+	/* TODO(Kevin): Do abort other MGMT func */
+
+	/* 1. Release channel to CNM */
+	aisFsmReleaseCh(prAdapter);
+
+	/* 2.1 stop join timeout timer */
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer);
+
+	/* 2.2 reset local variable */
+	prAisFsmInfo->fgIsInfraChannelFinished = TRUE;
+
+}				/* end of aisFsmAbortNORMAL_TR() */
+
+#if CFG_SUPPORT_ADHOC
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process of NORMAL_TR Abort
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_DESC_T prBssDesc;
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	/* reset BSS-DESC */
+	if (prAisFsmInfo->prTargetStaRec) {
+		prBssDesc = scanSearchBssDescByTA(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr);
+
+		if (prBssDesc) {
+			prBssDesc->fgIsConnected = FALSE;
+			prBssDesc->fgIsConnecting = FALSE;
+		}
+	}
+	/* release channel privilege */
+	aisFsmReleaseCh(prAdapter);
+
+}
+#endif /* CFG_SUPPORT_ADHOC */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief The Core FSM engine of AIS(Ad-hoc, Infra STA)
+*
+* @param[in] eNextState Enum value of next AIS STATE
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_DESC_T prBssDesc;
+	P_MSG_CH_REQ_T prMsgChReq;
+	P_MSG_SCN_SCAN_REQ prScanReqMsg;
+	P_AIS_REQ_HDR_T prAisReq;
+	ENUM_BAND_T eBand;
+	UINT_8 ucChannel;
+	UINT_16 u2ScanIELen;
+	ENUM_AIS_STATE_T eOriPreState;
+
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	DEBUGFUNC("aisFsmSteps()");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	eOriPreState = prAisFsmInfo->ePreviousState;
+
+	do {
+
+		/* Do entering Next State */
+		prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState;
+
+#if DBG
+		DBGLOG(AIS, STATE, "TRANSITION: [%s] -> [%s]\n",
+				    apucDebugAisState[prAisFsmInfo->eCurrentState], apucDebugAisState[eNextState]);
+#else
+		DBGLOG(AIS, STATE, "[%d] TRANSITION: [%d] -> [%d]\n",
+				    DBG_AIS_IDX, prAisFsmInfo->eCurrentState, eNextState);
+#endif
+		/* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */
+		prAisFsmInfo->eCurrentState = eNextState;
+
+		fgIsTransition = (BOOLEAN) FALSE;
+
+		/* Do tasks of the State that we just entered */
+		switch (prAisFsmInfo->eCurrentState) {
+			/* NOTE(Kevin): we don't have to rearrange the sequence of following
+			 * switch case. Instead I would like to use a common lookup table of array
+			 * of function pointer to speed up state search.
+			 */
+		case AIS_STATE_IDLE:
+
+			prAisReq = aisFsmGetNextRequest(prAdapter);
+
+			cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer);
+
+			if (prAisReq == NULL || prAisReq->eReqType == AIS_REQUEST_RECONNECT) {
+				if (prConnSettings->fgIsConnReqIssued == TRUE &&
+				    prConnSettings->fgIsDisconnectedByNonRequest == FALSE) {
+
+					prAisFsmInfo->fgTryScan = TRUE;
+
+					SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+					SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+					/* sync with firmware */
+					nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+					/* reset trial count */
+					prAisFsmInfo->ucConnTrialCount = 0;
+
+					eNextState = AIS_STATE_SEARCH;
+					fgIsTransition = TRUE;
+				} else {
+					UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+					SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+					/* sync with firmware */
+					nicDeactivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+					/* check for other pending request */
+					if (prAisReq &&
+						(aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE)) {
+
+						wlanClearScanningResult(prAdapter);
+						eNextState = AIS_STATE_SCAN;
+
+						fgIsTransition = TRUE;
+					}
+				}
+
+				if (prAisReq) {
+					/* free the message */
+					cnmMemFree(prAdapter, prAisReq);
+				}
+			} else if (prAisReq->eReqType == AIS_REQUEST_SCAN) {
+#if CFG_SUPPORT_ROAMING
+				prAisFsmInfo->fgIsRoamingScanPending = FALSE;
+#endif /* CFG_SUPPORT_ROAMING */
+				wlanClearScanningResult(prAdapter);
+
+				eNextState = AIS_STATE_SCAN;
+				fgIsTransition = TRUE;
+
+				/* free the message */
+				cnmMemFree(prAdapter, prAisReq);
+			} else if (prAisReq->eReqType == AIS_REQUEST_ROAMING_CONNECT
+				   || prAisReq->eReqType == AIS_REQUEST_ROAMING_SEARCH) {
+				/* ignore */
+				/* free the message */
+				cnmMemFree(prAdapter, prAisReq);
+			} else if (prAisReq->eReqType == AIS_REQUEST_REMAIN_ON_CHANNEL) {
+				eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL;
+				fgIsTransition = TRUE;
+
+				/* free the message */
+				cnmMemFree(prAdapter, prAisReq);
+			}
+
+			prAisFsmInfo->u4SleepInterval = AIS_BG_SCAN_INTERVAL_MIN_SEC;
+
+			break;
+
+		case AIS_STATE_SEARCH:
+			/* 4 <1> Search for a matched candidate and save it to prTargetBssDesc. */
+#if CFG_SLT_SUPPORT
+			prBssDesc = prAdapter->rWifiVar.rSltInfo.prPseudoBssDesc;
+#else
+			prBssDesc = scanSearchBssDescByPolicy(prAdapter, NETWORK_TYPE_AIS_INDEX);
+#endif
+			/* every time BSS join failure count is integral multiples of SCN_BSS_JOIN_FAIL_THRESOLD,
+			we need to scan again to find if a new BSS is here in the ESS,
+			this can also avoid too frequency to retry the rejected AP */
+			if (prAisFsmInfo->ePreviousState == AIS_STATE_LOOKING_FOR ||
+				((eOriPreState == AIS_STATE_ONLINE_SCAN ||
+				eOriPreState == AIS_STATE_SCAN) && prAisFsmInfo->ePreviousState != eOriPreState)) {
+				/* if previous state is scan/online scan/looking for, don't try to scan again */
+			} else if (prBssDesc && prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD &&
+				((prBssDesc->ucJoinFailureCount - SCN_BSS_JOIN_FAIL_THRESOLD) %
+				SCN_BSS_JOIN_FAIL_THRESOLD) == 0)
+				prBssDesc = NULL;
+
+			/* we are under Roaming Condition. */
+			if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+				if (prAisFsmInfo->ucConnTrialCount > AIS_ROAMING_CONNECTION_TRIAL_LIMIT) {
+#if CFG_SUPPORT_ROAMING
+					roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_CONNLIMIT);
+#endif /* CFG_SUPPORT_ROAMING */
+					/* reset retry count */
+					prAisFsmInfo->ucConnTrialCount = 0;
+
+					/* abort connection trial */
+					prConnSettings->fgIsConnReqIssued = FALSE;
+
+					eNextState = AIS_STATE_NORMAL_TR;
+					fgIsTransition = TRUE;
+
+					break;
+				}
+			}
+			/* 4 <2> We are not under Roaming Condition. */
+			if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
+
+				/* 4 <2.a> If we have the matched one */
+				if (prBssDesc) {
+
+					/* 4 <A> Stored the Selected BSS security cipher.
+					For later asoc req compose IE */
+					prAisBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher;
+					prAisBssInfo->u4RsnSelectedPairwiseCipher =
+					    prBssDesc->u4RsnSelectedPairwiseCipher;
+					prAisBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite;
+
+					/* 4 <B> Do STATE transition and update current Operation Mode. */
+					if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
+
+						prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE;
+
+						/* Record the target BSS_DESC_T for next STATE. */
+						prAisFsmInfo->prTargetBssDesc = prBssDesc;
+
+						/* Transit to channel acquire */
+						eNextState = AIS_STATE_REQ_CHANNEL_JOIN;
+						fgIsTransition = TRUE;
+
+						/* increase connection trial count */
+						prAisFsmInfo->ucConnTrialCount++;
+					}
+#if CFG_SUPPORT_ADHOC
+					else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
+
+						prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS;
+
+						/* Record the target BSS_DESC_T for next STATE. */
+						prAisFsmInfo->prTargetBssDesc = prBssDesc;
+
+						eNextState = AIS_STATE_IBSS_MERGE;
+						fgIsTransition = TRUE;
+					}
+#endif /* CFG_SUPPORT_ADHOC */
+					else {
+						ASSERT(0);
+						eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN;
+						fgIsTransition = TRUE;
+					}
+				}
+				/* 4 <2.b> If we don't have the matched one */
+				else {
+
+					/* increase connection trial count for infrastructure connection */
+					if (prConnSettings->eOPMode == NET_TYPE_INFRA)
+						prAisFsmInfo->ucConnTrialCount++;
+					/* 4 <A> Try to SCAN */
+					if (prAisFsmInfo->fgTryScan) {
+						eNextState = AIS_STATE_LOOKING_FOR;
+
+						fgIsTransition = TRUE;
+						break;
+					}
+					/* 4 <B> We've do SCAN already, now wait in some STATE. */
+					if (prConnSettings->eOPMode == NET_TYPE_INFRA) {
+
+						/* issue reconnect request,
+						 * and retreat to idle state for scheduling */
+						aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT);
+
+						eNextState = AIS_STATE_IDLE;
+						fgIsTransition = TRUE;
+					}
+#if CFG_SUPPORT_ADHOC
+					else if ((prConnSettings->eOPMode == NET_TYPE_IBSS)
+						 || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH)
+						 || (prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)) {
+
+						prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS;
+						prAisFsmInfo->prTargetBssDesc = NULL;
+
+						eNextState = AIS_STATE_IBSS_ALONE;
+						fgIsTransition = TRUE;
+					}
+#endif /* CFG_SUPPORT_ADHOC */
+					else {
+						ASSERT(0);
+						eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN;
+						fgIsTransition = TRUE;
+					}
+				}
+			}
+			/* 4 <3> We are under Roaming Condition. */
+			else {	/* prAdapter->eConnectionState == MEDIA_STATE_CONNECTED. */
+
+				/* 4 <3.a> This BSS_DESC_T is our AP. */
+				/* NOTE(Kevin 2008/05/16): Following cases will go back to NORMAL_TR.
+				 * CASE I: During Roaming, APP(WZC/NDISTEST) change the connection
+				 *         settings. That make we can NOT match the original AP, so the
+				 *         prBssDesc is NULL.
+				 * CASE II: The same reason as CASE I. Because APP change the
+				 *          eOPMode to other network type in connection setting
+				 *          (e.g. NET_TYPE_IBSS), so the BssDesc become the IBSS node.
+				 * (For CASE I/II, before WZC/NDISTEST set the OID_SSID, it will change
+				 * other parameters in connection setting first. So if we do roaming
+				 * at the same time, it will hit these cases.)
+				 *
+				 * CASE III: Normal case, we can't find other candidate to roam
+				 * out, so only the current AP will be matched.
+				 *
+				 * CASE IV: Timestamp of the current AP might be reset
+				 */
+				if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION &&
+				    ((!prBssDesc) ||	/* CASE I */
+				    (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) ||	/* CASE II */
+				    (prBssDesc->fgIsConnected) ||	/* CASE III */
+				    (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID))) /* CASE IV */) {
+#if DBG
+					if ((prBssDesc) && (prBssDesc->fgIsConnected))
+						ASSERT(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID));
+#endif /* DBG */
+					/* We already associated with it, go back to NORMAL_TR */
+					/* TODO(Kevin): Roaming Fail */
+#if CFG_SUPPORT_ROAMING
+					roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE);
+#endif /* CFG_SUPPORT_ROAMING */
+
+					/* Retreat to NORMAL_TR state */
+					eNextState = AIS_STATE_NORMAL_TR;
+					fgIsTransition = TRUE;
+					break;
+				}
+
+				/* 4 <3.b> Try to roam out for JOIN this BSS_DESC_T. */
+				if (prBssDesc == NULL) {
+					/* increase connection trial count for infrastructure connection */
+					if (prConnSettings->eOPMode == NET_TYPE_INFRA)
+						prAisFsmInfo->ucConnTrialCount++;
+					/* 4 <A> Try to SCAN */
+					if (prAisFsmInfo->fgTryScan) {
+						eNextState = AIS_STATE_LOOKING_FOR;
+
+						fgIsTransition = TRUE;
+						break;
+					}
+
+					/* 4 <B> We've do SCAN already, now wait in some STATE. */
+					if (prConnSettings->eOPMode == NET_TYPE_INFRA) {
+
+						/* issue reconnect request, and retreat to idle state
+						 * for scheduling */
+						aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT);
+
+						eNextState = AIS_STATE_IDLE;
+						fgIsTransition = TRUE;
+					}
+#if CFG_SUPPORT_ADHOC
+					else if ((prConnSettings->eOPMode == NET_TYPE_IBSS)
+						 || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH)
+						 || (prConnSettings->eOPMode ==
+						     NET_TYPE_DEDICATED_IBSS)) {
+
+						prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS;
+						prAisFsmInfo->prTargetBssDesc = NULL;
+
+						eNextState = AIS_STATE_IBSS_ALONE;
+						fgIsTransition = TRUE;
+					}
+#endif /* CFG_SUPPORT_ADHOC */
+					else {
+						ASSERT(0);
+						eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN;
+						fgIsTransition = TRUE;
+					}
+				} else {
+#if DBG
+					if (prAisBssInfo->ucReasonOfDisconnect !=
+					    DISCONNECT_REASON_CODE_REASSOCIATION) {
+						ASSERT(UNEQUAL_MAC_ADDR
+						       (prBssDesc->aucBSSID, prAisBssInfo->aucBSSID));
+					}
+#endif /* DBG */
+
+					/* 4 <A> Record the target BSS_DESC_T for next STATE. */
+					prAisFsmInfo->prTargetBssDesc = prBssDesc;
+
+					/* tyhsu: increase connection trial count */
+					prAisFsmInfo->ucConnTrialCount++;
+
+					/* Transit to channel acquire */
+					eNextState = AIS_STATE_REQ_CHANNEL_JOIN;
+					fgIsTransition = TRUE;
+				}
+			}
+
+			break;
+
+		case AIS_STATE_WAIT_FOR_NEXT_SCAN:
+
+			DBGLOG(AIS, LOUD, "SCAN: Idle Begin - Current Time = %u\n", kalGetTimeTick());
+
+			cnmTimerStartTimer(prAdapter,
+					   &prAisFsmInfo->rBGScanTimer, SEC_TO_MSEC(prAisFsmInfo->u4SleepInterval));
+
+			SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+			if (prAisFsmInfo->u4SleepInterval < AIS_BG_SCAN_INTERVAL_MAX_SEC)
+				prAisFsmInfo->u4SleepInterval <<= 1;
+			break;
+
+		case AIS_STATE_SCAN:
+		case AIS_STATE_ONLINE_SCAN:
+		case AIS_STATE_LOOKING_FOR:
+
+			if (!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) {
+				SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+				/* sync with firmware */
+				nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX);
+			}
+
+			/* IE length decision */
+			if (prAisFsmInfo->u4ScanIELength > 0) {
+				u2ScanIELen = (UINT_16) prAisFsmInfo->u4ScanIELength;
+			} else {
+#if CFG_SUPPORT_WPS2
+				u2ScanIELen = prAdapter->prGlueInfo->u2WSCIELen;
+#else
+				u2ScanIELen = 0;
+#endif
+			}
+
+			prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter,
+									RAM_TYPE_MSG,
+									OFFSET_OF(MSG_SCN_SCAN_REQ,
+										  aucIE) + u2ScanIELen);
+			if (!prScanReqMsg) {
+				ASSERT(0);	/* Can't trigger SCAN FSM */
+				return;
+			}
+
+			prScanReqMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_REQ;
+			prScanReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfScanReq;
+			prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX;
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+			prScanReqMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN;
+#else
+			prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN;
+#endif
+
+#if CFG_SUPPORT_ROAMING_ENC
+			if (prAdapter->fgIsRoamingEncEnabled == TRUE) {
+				if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR &&
+				    prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+					prScanReqMsg->u2ChannelDwellTime = AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME;
+				}
+			}
+#endif /* CFG_SUPPORT_ROAMING_ENC */
+
+			if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN
+			    || prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) {
+				if (prAisFsmInfo->ucScanSSIDLen == 0) {
+					/* Scan for all available SSID */
+					prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD;
+				} else {
+					prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
+					COPY_SSID(prScanReqMsg->aucSSID,
+						  prScanReqMsg->ucSSIDLength,
+						  prAisFsmInfo->aucScanSSID, prAisFsmInfo->ucScanSSIDLen);
+				}
+			} else {
+				/* Scan for determined SSID */
+				prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
+				COPY_SSID(prScanReqMsg->aucSSID,
+					  prScanReqMsg->ucSSIDLength,
+					  prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+			}
+
+			/* check if tethering is running and need to fix on specific channel */
+			if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE) {
+				prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED;
+				prScanReqMsg->ucChannelListNum = 1;
+				prScanReqMsg->arChnlInfoList[0].eBand = eBand;
+				prScanReqMsg->arChnlInfoList[0].ucChannelNum = ucChannel;
+			} else {
+#if 0
+				aisFsmSetChannelInfo(prAdapter, prScanReqMsg, prAisFsmInfo->eCurrentState);
+#endif
+				if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX]
+					== BAND_NULL) {
+					if (prAdapter->fgEnable5GBand == TRUE)
+						prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL;
+					else
+						prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4;
+				} else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX]
+						== BAND_2G4) {
+					prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4;
+				} else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX]
+						== BAND_5G) {
+					prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G;
+				} else {
+					prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL;
+					ASSERT(0);
+				}
+
+			}
+
+			if (prAisFsmInfo->u4ScanIELength > 0) {
+				kalMemCopy(prScanReqMsg->aucIE, prAisFsmInfo->aucScanIEBuf,
+					   prAisFsmInfo->u4ScanIELength);
+			} else {
+#if CFG_SUPPORT_WPS2
+				if (prAdapter->prGlueInfo->u2WSCIELen > 0) {
+					kalMemCopy(prScanReqMsg->aucIE, &prAdapter->prGlueInfo->aucWSCIE,
+						   prAdapter->prGlueInfo->u2WSCIELen);
+				}
+			}
+#endif
+
+			prScanReqMsg->u2IELen = u2ScanIELen;
+
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF);
+			DBGLOG(AIS, TRACE, "SendSR%d\n", prScanReqMsg->ucSeqNum);
+			prAisFsmInfo->fgTryScan = FALSE;	/* Will enable background sleep for infrastructure */
+
+			prAdapter->ucScanTime++;
+			break;
+
+		case AIS_STATE_REQ_CHANNEL_JOIN:
+			/* send message to CNM for acquiring channel */
+			prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T));
+			if (!prMsgChReq) {
+				ASSERT(0);	/* Can't indicate CNM for channel acquiring */
+				return;
+			}
+
+			prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ;
+			prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+			prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq;
+			prMsgChReq->eReqType = CH_REQ_TYPE_JOIN;
+			prMsgChReq->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL;
+
+			if (prAisFsmInfo->prTargetBssDesc != NULL) {
+				prMsgChReq->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum;
+				prMsgChReq->eRfSco = prAisFsmInfo->prTargetBssDesc->eSco;
+				prMsgChReq->eRfBand = prAisFsmInfo->prTargetBssDesc->eBand;
+				COPY_MAC_ADDR(prMsgChReq->aucBSSID, prAisFsmInfo->prTargetBssDesc->aucBSSID);
+			}
+
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF);
+
+			prAisFsmInfo->fgIsChannelRequested = TRUE;
+			break;
+
+		case AIS_STATE_JOIN:
+			aisFsmStateInit_JOIN(prAdapter, prAisFsmInfo->prTargetBssDesc);
+			break;
+
+#if CFG_SUPPORT_ADHOC
+		case AIS_STATE_IBSS_ALONE:
+			aisFsmStateInit_IBSS_ALONE(prAdapter);
+			break;
+
+		case AIS_STATE_IBSS_MERGE:
+			aisFsmStateInit_IBSS_MERGE(prAdapter, prAisFsmInfo->prTargetBssDesc);
+			break;
+#endif /* CFG_SUPPORT_ADHOC */
+
+		case AIS_STATE_NORMAL_TR:
+			if (prAisFsmInfo->fgIsInfraChannelFinished == FALSE) {
+				/* Don't do anything when rJoinTimeoutTimer is still ticking */
+			} else {
+				/* 1. Process for pending scan */
+				if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) {
+					wlanClearScanningResult(prAdapter);
+					eNextState = AIS_STATE_ONLINE_SCAN;
+					fgIsTransition = TRUE;
+				}
+				/* 2. Process for pending roaming scan */
+				else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE) == TRUE) {
+					eNextState = AIS_STATE_LOOKING_FOR;
+					fgIsTransition = TRUE;
+				}
+				/* 3. Process for pending roaming scan */
+				else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE) == TRUE) {
+					eNextState = AIS_STATE_SEARCH;
+					fgIsTransition = TRUE;
+				} else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE) ==
+					   TRUE) {
+					eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL;
+					fgIsTransition = TRUE;
+				}
+			}
+
+			break;
+
+		case AIS_STATE_DISCONNECTING:
+			/* send for deauth frame for disconnection */
+			authSendDeauthFrame(prAdapter,
+					    prAisBssInfo->prStaRecOfAP,
+					    (P_SW_RFB_T) NULL, REASON_CODE_DEAUTH_LEAVING_BSS, aisDeauthXmitComplete);
+			cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer, 100);
+			break;
+
+		case AIS_STATE_REQ_REMAIN_ON_CHANNEL:
+			/* send message to CNM for acquiring channel */
+			prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T));
+			if (!prMsgChReq) {
+				ASSERT(0);	/* Can't indicate CNM for channel acquiring */
+				return;
+			}
+
+			/* zero-ize */
+			kalMemZero(prMsgChReq, sizeof(MSG_CH_REQ_T));
+
+			/* filling */
+			prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ;
+			prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+			prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq;
+			prMsgChReq->eReqType = CH_REQ_TYPE_JOIN;
+			prMsgChReq->u4MaxInterval = prAisFsmInfo->rChReqInfo.u4DurationMs;
+			prMsgChReq->ucPrimaryChannel = prAisFsmInfo->rChReqInfo.ucChannelNum;
+			prMsgChReq->eRfSco = prAisFsmInfo->rChReqInfo.eSco;
+			prMsgChReq->eRfBand = prAisFsmInfo->rChReqInfo.eBand;
+
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF);
+
+			prAisFsmInfo->fgIsChannelRequested = TRUE;
+
+			break;
+
+		case AIS_STATE_REMAIN_ON_CHANNEL:
+			SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+			/* sync with firmware */
+			nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX);
+			break;
+
+		default:
+			ASSERT(0);	/* Make sure we have handle all STATEs */
+			break;
+
+		}
+	} while (fgIsTransition);
+
+	return;
+
+}				/* end of aisFsmSteps() */
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState)
+{
+	/*get scan channel infro from prAdapter->prGlueInfo->prScanRequest*/
+	struct cfg80211_scan_request *scan_req_t = NULL;
+	struct ieee80211_channel *channel_tmp = NULL;
+	int i = 0;
+	int j = 0;
+	UINT_8 channel_num = 0;
+	UINT_8 channel_counts = 0;
+
+	if ((prAdapter == NULL) || (ScanReqMsg == NULL))
+		return;
+	if ((CurrentState == AIS_STATE_SCAN) || (CurrentState == AIS_STATE_ONLINE_SCAN)) {
+		if (prAdapter->prGlueInfo->prScanRequest != NULL) {
+			scan_req_t = prAdapter->prGlueInfo->prScanRequest;
+			if ((scan_req_t != NULL) && (scan_req_t->n_channels != 0) &&
+				(scan_req_t->channels != NULL)) {
+				channel_counts = scan_req_t->n_channels;
+				DBGLOG(AIS, TRACE, "channel_counts=%d\n", channel_counts);
+
+				while (j < channel_counts) {
+					channel_tmp = scan_req_t->channels[j];
+					if (channel_tmp == NULL)
+						break;
+
+					DBGLOG(AIS, TRACE, "set channel band=%d\n", channel_tmp->band);
+					if (channel_tmp->band >= IEEE80211_BAND_60GHZ) {
+						j++;
+						continue;
+					}
+					if (i >= MAXIMUM_OPERATION_CHANNEL_LIST)
+						break;
+					if (channel_tmp->band == IEEE80211_BAND_2GHZ)
+						ScanReqMsg->arChnlInfoList[i].eBand = BAND_2G4;
+					else if (channel_tmp->band == IEEE80211_BAND_5GHZ)
+						ScanReqMsg->arChnlInfoList[i].eBand = BAND_5G;
+
+					DBGLOG(AIS, TRACE, "set channel channel_rer =%d\n",
+						channel_tmp->center_freq);
+
+					channel_num = (UINT_8)nicFreq2ChannelNum(
+						channel_tmp->center_freq * 1000);
+
+					DBGLOG(AIS, TRACE, "set channel channel_num=%d\n",
+						channel_num);
+					ScanReqMsg->arChnlInfoList[i].ucChannelNum = channel_num;
+
+					j++;
+					i++;
+				}
+			}
+		}
+	}
+
+	DBGLOG(AIS, INFO, "set channel i=%d\n", i);
+	if (i > 0) {
+		ScanReqMsg->ucChannelListNum = i;
+		ScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED;
+
+		return;
+	}
+
+	if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX]
+		== BAND_NULL) {
+		if (prAdapter->fgEnable5GBand == TRUE)
+			ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL;
+		else
+			ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4;
+		} else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX]
+				== BAND_2G4) {
+			ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4;
+		} else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX]
+				== BAND_5G) {
+			ScanReqMsg->eScanChannel = SCAN_CHANNEL_5G;
+		} else {
+			ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL;
+			ASSERT(0);
+		}
+
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_SCN_SCAN_DONE prScanDoneMsg;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+	UINT_8 ucSeqNumOfCompMsg;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	DEBUGFUNC("aisFsmRunEventScanDone()");
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	ucScanTimeoutTimes = 0;
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr;
+	ASSERT(prScanDoneMsg->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX);
+
+	ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum;
+	cnmMemFree(prAdapter, prMsgHdr);
+
+	eNextState = prAisFsmInfo->eCurrentState;
+
+	if (ucSeqNumOfCompMsg != prAisFsmInfo->ucSeqNumOfScanReq) {
+		DBGLOG(AIS, WARN, "SEQ NO of AIS SCN DONE MSG is not matched %d %d.\n",
+				   ucSeqNumOfCompMsg, prAisFsmInfo->ucSeqNumOfScanReq);
+	} else {
+		switch (prAisFsmInfo->eCurrentState) {
+		case AIS_STATE_SCAN:
+			prConnSettings->fgIsScanReqIssued = FALSE;
+
+			/* reset scan IE buffer */
+			prAisFsmInfo->u4ScanIELength = 0;
+
+			kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS);
+			eNextState = AIS_STATE_IDLE;
+#if CFG_SUPPORT_AGPS_ASSIST
+			scanReportScanResultToAgps(prAdapter);
+#endif
+			break;
+
+		case AIS_STATE_ONLINE_SCAN:
+			prConnSettings->fgIsScanReqIssued = FALSE;
+
+			/* reset scan IE buffer */
+			prAisFsmInfo->u4ScanIELength = 0;
+
+			kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS);
+#if CFG_SUPPORT_ROAMING
+			eNextState = aisFsmRoamingScanResultsUpdate(prAdapter);
+#else
+			eNextState = AIS_STATE_NORMAL_TR;
+#endif /* CFG_SUPPORT_ROAMING */
+#if CFG_SUPPORT_AGPS_ASSIST
+			scanReportScanResultToAgps(prAdapter);
+#endif
+			break;
+
+		case AIS_STATE_LOOKING_FOR:
+			cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer);
+			scanReportBss2Cfg80211(prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL);
+#if CFG_SUPPORT_ROAMING
+			eNextState = aisFsmRoamingScanResultsUpdate(prAdapter);
+#else
+			eNextState = AIS_STATE_SEARCH;
+#endif /* CFG_SUPPORT_ROAMING */
+			break;
+
+		default:
+			cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer);
+			break;
+
+		}
+	}
+
+	if (eNextState != prAisFsmInfo->eCurrentState)
+		aisFsmSteps(prAdapter, eNextState);
+
+}				/* end of aisFsmRunEventScanDone() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_AIS_ABORT_T prAisAbortMsg;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	UINT_8 ucReasonOfDisconnect;
+	BOOLEAN fgDelayIndication;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	DEBUGFUNC("aisFsmRunEventAbort()");
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	/* 4 <1> Extract information of Abort Message and then free memory. */
+	prAisAbortMsg = (P_MSG_AIS_ABORT_T) prMsgHdr;
+	ucReasonOfDisconnect = prAisAbortMsg->ucReasonOfDisconnect;
+	fgDelayIndication = prAisAbortMsg->fgDelayIndication;
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+#if DBG
+	DBGLOG(AIS, STATE, "EVENT-ABORT: Current State %s %d\n",
+			    apucDebugAisState[prAisFsmInfo->eCurrentState], ucReasonOfDisconnect);
+#else
+	DBGLOG(AIS, STATE, "[%d] EVENT-ABORT: Current State [%d %d]\n",
+			    DBG_AIS_IDX, prAisFsmInfo->eCurrentState, ucReasonOfDisconnect);
+#endif
+
+	GET_CURRENT_SYSTIME(&(prAisFsmInfo->rJoinReqTime));
+
+	/* 4 <2> clear previous pending connection request and insert new one */
+	if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DEAUTHENTICATED
+	    || ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DISASSOCIATED) {
+		prConnSettings->fgIsDisconnectedByNonRequest = TRUE;
+	} else {
+		prConnSettings->fgIsDisconnectedByNonRequest = FALSE;
+	}
+	/* to support user space triggered roaming */
+	if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING &&
+	    prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) {
+
+		if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR &&
+		    prAisFsmInfo->fgIsInfraChannelFinished == TRUE) {
+			aisFsmSteps(prAdapter, AIS_STATE_SEARCH);
+		} else {
+			aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE);
+			aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE);
+			aisFsmInsertRequest(prAdapter, AIS_REQUEST_ROAMING_CONNECT);
+		}
+		return;
+	}
+
+	aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE);
+	aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT);
+
+	if (prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) {
+		/* 4 <3> invoke abort handler */
+		aisFsmStateAbort(prAdapter, ucReasonOfDisconnect, fgDelayIndication);
+	}
+
+}				/* end of aisFsmRunEventAbort() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        This function handles AIS-FSM abort event/command
+*
+* \param[in] prAdapter              Pointer of ADAPTER_T
+*            ucReasonOfDisconnect   Reason for disonnection
+*            fgDelayIndication      Option to delay disconnection indication
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	BOOLEAN fgIsCheckConnected;
+
+	ASSERT(prAdapter);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	fgIsCheckConnected = FALSE;
+
+	/* 4 <1> Save information of Abort Message and then free memory. */
+	prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect;
+
+	/* 4 <2> Abort current job. */
+	switch (prAisFsmInfo->eCurrentState) {
+	case AIS_STATE_IDLE:
+	case AIS_STATE_SEARCH:
+		break;
+
+	case AIS_STATE_WAIT_FOR_NEXT_SCAN:
+		/* Do cancel timer */
+		cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer);
+
+		/* in case roaming is triggered */
+		fgIsCheckConnected = TRUE;
+		break;
+
+	case AIS_STATE_SCAN:
+		/* Do abort SCAN */
+		aisFsmStateAbort_SCAN(prAdapter);
+
+		/* queue for later handling */
+		if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE)
+			aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN);
+
+		break;
+
+	case AIS_STATE_LOOKING_FOR:
+		/* Do abort SCAN */
+		aisFsmStateAbort_SCAN(prAdapter);
+
+		/* in case roaming is triggered */
+		fgIsCheckConnected = TRUE;
+		break;
+
+	case AIS_STATE_REQ_CHANNEL_JOIN:
+		/* Release channel to CNM */
+		aisFsmReleaseCh(prAdapter);
+
+		/* in case roaming is triggered */
+		fgIsCheckConnected = TRUE;
+		break;
+
+	case AIS_STATE_JOIN:
+		/* Do abort JOIN */
+		aisFsmStateAbort_JOIN(prAdapter);
+
+		/* in case roaming is triggered */
+		fgIsCheckConnected = TRUE;
+		break;
+
+#if CFG_SUPPORT_ADHOC
+	case AIS_STATE_IBSS_ALONE:
+	case AIS_STATE_IBSS_MERGE:
+		aisFsmStateAbort_IBSS(prAdapter);
+		break;
+#endif /* CFG_SUPPORT_ADHOC */
+
+	case AIS_STATE_ONLINE_SCAN:
+		/* Do abort SCAN */
+		aisFsmStateAbort_SCAN(prAdapter);
+
+		/* queue for later handling */
+		if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE)
+			aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN);
+
+		fgIsCheckConnected = TRUE;
+		break;
+
+	case AIS_STATE_NORMAL_TR:
+		fgIsCheckConnected = TRUE;
+		break;
+
+	case AIS_STATE_DISCONNECTING:
+		/* Do abort NORMAL_TR */
+		aisFsmStateAbort_NORMAL_TR(prAdapter);
+
+		break;
+
+	case AIS_STATE_REQ_REMAIN_ON_CHANNEL:
+		/* release channel */
+		aisFsmReleaseCh(prAdapter);
+		break;
+
+	case AIS_STATE_REMAIN_ON_CHANNEL:
+		/* 1. release channel */
+		aisFsmReleaseCh(prAdapter);
+
+		/* 2. stop channel timeout timer */
+		cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer);
+
+		break;
+
+	default:
+		break;
+	}
+
+	if (fgIsCheckConnected && (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState)) {
+
+		/* switch into DISCONNECTING state for sending DEAUTH if necessary */
+		if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE &&
+		    prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_NEW_CONNECTION &&
+		    prAisBssInfo->prStaRecOfAP && prAisBssInfo->prStaRecOfAP->fgIsInUse) {
+			aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING);
+
+			return;
+		}
+		/* Do abort NORMAL_TR */
+		aisFsmStateAbort_NORMAL_TR(prAdapter);
+
+	}
+
+	aisFsmDisconnect(prAdapter, fgDelayIndication);
+
+
+}				/* end of aisFsmStateAbort() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Join Complete Event from SAA FSM for AIS FSM
+*
+* @param[in] prMsgHdr   Message of Join Complete of SAA FSM.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_JOIN_COMP_T prJoinCompMsg;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+	P_STA_RECORD_T prStaRec;
+	P_SW_RFB_T prAssocRspSwRfb;
+	P_BSS_INFO_T prAisBssInfo;
+	UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID;
+	OS_SYSTIME rCurrentTime;
+
+	DEBUGFUNC("aisFsmRunEventJoinComplete()");
+
+	ASSERT(prMsgHdr);
+
+	GET_CURRENT_SYSTIME(&rCurrentTime);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr;
+	prStaRec = prJoinCompMsg->prStaRec;
+	prAssocRspSwRfb = prJoinCompMsg->prSwRfb;
+
+	eNextState = prAisFsmInfo->eCurrentState;
+
+	DBGLOG(AIS, TRACE, "AISOK\n");
+
+	/* Check State and SEQ NUM */
+	do {
+		if (prAisFsmInfo->eCurrentState != AIS_STATE_JOIN)
+			break;
+
+		prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+		/* Check SEQ NUM */
+		if (prJoinCompMsg->ucSeqNum == prAisFsmInfo->ucSeqNumOfReqMsg) {
+
+			/* 4 <1> JOIN was successful */
+			if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) {
+
+				/* 1. Reset retry count */
+				prAisFsmInfo->ucConnTrialCount = 0;
+
+				/* Completion of roaming */
+				if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+
+#if CFG_SUPPORT_ROAMING
+					/* 2. Deactivate previous BSS */
+					aisFsmRoamingDisconnectPrevAP(prAdapter, prStaRec);
+
+					/* 3. Update bss based on roaming staRec */
+					aisUpdateBssInfoForRoamingAP(prAdapter, prStaRec, prAssocRspSwRfb);
+#endif /* CFG_SUPPORT_ROAMING */
+				} else {
+					/* 4 <1.1> Change FW's Media State immediately. */
+					aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+
+					/* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */
+					if ((prAisBssInfo->prStaRecOfAP) &&
+					    (prAisBssInfo->prStaRecOfAP != prStaRec) &&
+					    (prAisBssInfo->prStaRecOfAP->fgIsInUse)) {
+
+						cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP,
+								     STA_STATE_1);
+					}
+					/* 4 <1.3> Update BSS_INFO_T */
+					aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb);
+
+					/* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+
+					/* 4 <1.5> Update RSSI if necessary */
+					nicUpdateRSSI(prAdapter, NETWORK_TYPE_AIS_INDEX,
+						      (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0);
+
+					/* 4 <1.6> Indicate Connected Event to Host immediately. */
+					/* Require BSSID, Association ID, Beacon Interval.. */
+					/* from AIS_BSS_INFO_T */
+					aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED,
+									FALSE);
+
+					/* add for ctia mode */
+					if (EQUAL_SSID
+					    (aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID,
+					     prAisBssInfo->ucSSIDLen)) {
+						nicEnterCtiaMode(prAdapter, TRUE, FALSE);
+					}
+				}
+
+#if CFG_SUPPORT_ROAMING
+				/* if bssid is given, it means we no need fw roaming */
+				if (prAdapter->rWifiVar.rConnSettings.eConnectionPolicy != CONNECT_BY_BSSID)
+					roamingFsmRunEventStart(prAdapter);
+#endif /* CFG_SUPPORT_ROAMING */
+
+				/* 4 <1.7> Set the Next State of AIS FSM */
+				eNextState = AIS_STATE_NORMAL_TR;
+			}
+			/* 4 <2> JOIN was not successful */
+			else {
+				/* 4 <2.1> Redo JOIN process with other Auth Type if possible */
+				if (aisFsmStateInit_RetryJOIN(prAdapter, prStaRec) == FALSE) {
+					P_BSS_DESC_T prBssDesc;
+
+					/* 1. Increase Failure Count */
+					prStaRec->ucJoinFailureCount++;
+
+					/* 2. release channel */
+					aisFsmReleaseCh(prAdapter);
+
+					/* 3.1 stop join timeout timer */
+					cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer);
+
+					/* 3.2 reset local variable */
+					prAisFsmInfo->fgIsInfraChannelFinished = TRUE;
+
+					prBssDesc = scanSearchBssDescByBssid(prAdapter, prStaRec->aucMacAddr);
+
+					if (prBssDesc == NULL) {
+						/* it maybe NULL when wlanRemove */
+						/*
+						(1) UI does wifi off during SAA does auth/assoc procedure.
+						(2) We will do LINK_INITIALIZE(&prScanInfo->rBSSDescList);
+						in nicUninitMGMT().
+						(3) We will handle prMsduInfo->pfTxDoneHandler
+						in nicTxRelease().
+						(4) prMsduInfo->pfTxDoneHandler will point to
+						saaFsmRunEventTxDone().
+						(5) Then jump to saaFsmSteps() -> saaFsmSendEventJoinComplete()
+						(6) Finally mboxSendMsg() -> aisFsmRunEventJoinComplete().
+						(7) In aisFsmRunEventJoinComplete(), we will check
+						"prBssDesc = scanSearchBssDescByBssid(prAdapter,
+						prStaRec->aucMacAddr);"
+						(8) And prBssDesc will be NULL and hangs in
+						"ASSERT(prBssDesc->fgIsConnecting);" when DBG=0.
+						ASSERT(prBssDesc);
+						ASSERT(prBssDesc->fgIsConnecting);
+						*/
+						break;
+					}
+					/* ASSERT(prBssDesc); */
+					/* ASSERT(prBssDesc->fgIsConnecting); */
+					prBssDesc->ucJoinFailureCount++;
+					if (prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) {
+						GET_CURRENT_SYSTIME(&prBssDesc->rJoinFailTime);
+						DBGLOG(AIS, INFO,
+							"Bss %pM join fail %d times,temp disable it at time:%u\n",
+							prBssDesc->aucBSSID,
+							SCN_BSS_JOIN_FAIL_THRESOLD, prBssDesc->rJoinFailTime);
+					}
+
+					if (prBssDesc)
+						prBssDesc->fgIsConnecting = FALSE;
+
+					/* 3.3 Free STA-REC */
+					if (prStaRec != prAisBssInfo->prStaRecOfAP)
+						cnmStaRecFree(prAdapter, prStaRec, FALSE);
+
+					if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+#if CFG_SUPPORT_ROAMING
+						eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN;
+#endif /* CFG_SUPPORT_ROAMING */
+					} else if (CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime,
+						 SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) {
+						/* abort connection trial */
+						prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE;
+
+						kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+								     WLAN_STATUS_CONNECT_INDICATION, NULL, 0);
+
+						eNextState = AIS_STATE_IDLE;
+					} else {
+						/* 4.b send reconnect request */
+						aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT);
+
+						eNextState = AIS_STATE_IDLE;
+					}
+				}
+			}
+		}
+#if DBG
+		else
+			DBGLOG(AIS, WARN, "SEQ NO of AIS JOIN COMP MSG is not matched.\n");
+#endif /* DBG */
+
+		if (eNextState != prAisFsmInfo->eCurrentState)
+			aisFsmSteps(prAdapter, eNextState);
+	} while (FALSE);
+
+	if (prAssocRspSwRfb)
+		nicRxReturnRFB(prAdapter, prAssocRspSwRfb);
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* end of aisFsmRunEventJoinComplete() */
+
+#if CFG_SUPPORT_ADHOC
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Grant Msg of IBSS Create which was sent by
+*        CNM to indicate that channel was changed for creating IBSS.
+*
+* @param[in] prAdapter  Pointer of ADAPTER_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+
+	ASSERT(prAdapter);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	do {
+		/* Check State */
+		if (prAisFsmInfo->eCurrentState == AIS_STATE_IBSS_ALONE)
+			aisUpdateBssInfoForCreateIBSS(prAdapter);
+	} while (FALSE);
+
+}				/* end of aisFsmCreateIBSS() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Grant Msg of IBSS Merge which was sent by
+*        CNM to indicate that channel was changed for merging IBSS.
+*
+* @param[in] prAdapter  Pointer of ADAPTER_T
+* @param[in] prStaRec   Pointer of STA_RECORD_T for merge
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+	P_BSS_INFO_T prAisBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	do {
+
+		eNextState = prAisFsmInfo->eCurrentState;
+
+		switch (prAisFsmInfo->eCurrentState) {
+		case AIS_STATE_IBSS_MERGE:
+			{
+				P_BSS_DESC_T prBssDesc;
+
+				/* 4 <1.1> Change FW's Media State immediately. */
+				aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+
+				/* 4 <1.2> Deactivate previous Peers' STA_RECORD_T in Driver if have. */
+				bssClearClientList(prAdapter, prAisBssInfo);
+
+				/* 4 <1.3> Unmark connection flag of previous BSS_DESC_T. */
+				prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
+				if (prBssDesc != NULL) {
+					prBssDesc->fgIsConnecting = FALSE;
+					prBssDesc->fgIsConnected = FALSE;
+				}
+				/* 4 <1.4> Update BSS_INFO_T */
+				aisUpdateBssInfoForMergeIBSS(prAdapter, prStaRec);
+
+				/* 4 <1.5> Add Peers' STA_RECORD_T to Client List */
+				bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec);
+
+				/* 4 <1.6> Activate current Peer's STA_RECORD_T in Driver. */
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+				prStaRec->fgIsMerging = FALSE;
+
+				/* 4 <1.7> Enable other features */
+
+				/* 4 <1.8> Indicate Connected Event to Host immediately. */
+				aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE);
+
+				/* 4 <1.9> Set the Next State of AIS FSM */
+				eNextState = AIS_STATE_NORMAL_TR;
+
+				/* 4 <1.10> Release channel privilege */
+				aisFsmReleaseCh(prAdapter);
+
+#if CFG_SLT_SUPPORT
+				prAdapter->rWifiVar.rSltInfo.prPseudoStaRec = prStaRec;
+#endif
+			}
+			break;
+
+		default:
+			break;
+		}
+
+		if (eNextState != prAisFsmInfo->eCurrentState)
+			aisFsmSteps(prAdapter, eNextState);
+
+	} while (FALSE);
+
+}				/* end of aisFsmMergeIBSS() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Notification of existing IBSS was found
+*        from SCN.
+*
+* @param[in] prMsgHdr   Message of Notification of an IBSS was present.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+	P_STA_RECORD_T prStaRec;
+	P_BSS_INFO_T prAisBssInfo;
+	P_BSS_DESC_T prBssDesc;
+	BOOLEAN fgIsMergeIn;
+
+	ASSERT(prMsgHdr);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) prMsgHdr;
+
+	ASSERT(prAisIbssPeerFoundMsg->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX);
+
+	prStaRec = prAisIbssPeerFoundMsg->prStaRec;
+	ASSERT(prStaRec);
+
+	fgIsMergeIn = prAisIbssPeerFoundMsg->fgIsMergeIn;
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+	eNextState = prAisFsmInfo->eCurrentState;
+	switch (prAisFsmInfo->eCurrentState) {
+	case AIS_STATE_IBSS_ALONE:
+		{
+			/* 4 <1> An IBSS Peer 'merged in'. */
+			if (fgIsMergeIn) {
+
+				/* 4 <1.1> Change FW's Media State immediately. */
+				aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+
+				/* 4 <1.2> Add Peers' STA_RECORD_T to Client List */
+				bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec);
+
+#if CFG_SLT_SUPPORT
+				/* 4 <1.3> Mark connection flag of BSS_DESC_T. */
+				prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr);
+				if (prBssDesc != NULL) {
+					prBssDesc->fgIsConnecting = FALSE;
+					prBssDesc->fgIsConnected = TRUE;
+				} else {
+					ASSERT(0);	/* Should be able to find a BSS_DESC_T here. */
+				}
+
+				/* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */
+				prStaRec->fgIsQoS = TRUE;	/* TODO(Kevin): TBD */
+#else
+				/* 4 <1.3> Mark connection flag of BSS_DESC_T. */
+				prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
+				if (prBssDesc != NULL) {
+					prBssDesc->fgIsConnecting = FALSE;
+					prBssDesc->fgIsConnected = TRUE;
+				} else {
+					ASSERT(0);	/* Should be able to find a BSS_DESC_T here. */
+				}
+
+				/* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */
+				prStaRec->fgIsQoS = FALSE;	/* TODO(Kevin): TBD */
+
+#endif
+
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+				prStaRec->fgIsMerging = FALSE;
+
+				/* 4 <1.6> sync. to firmware */
+				nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+				/* 4 <1.7> Indicate Connected Event to Host immediately. */
+				aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE);
+
+				/* 4 <1.8> indicate PM for connected */
+				nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+				/* 4 <1.9> Set the Next State of AIS FSM */
+				eNextState = AIS_STATE_NORMAL_TR;
+
+				/* 4 <1.10> Release channel privilege */
+				aisFsmReleaseCh(prAdapter);
+			}
+			/* 4 <2> We need 'merge out' to this IBSS */
+			else {
+
+				/* 4 <2.1> Get corresponding BSS_DESC_T */
+				prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr);
+
+				prAisFsmInfo->prTargetBssDesc = prBssDesc;
+
+				/* 4 <2.2> Set the Next State of AIS FSM */
+				eNextState = AIS_STATE_IBSS_MERGE;
+			}
+		}
+		break;
+
+	case AIS_STATE_NORMAL_TR:
+		{
+
+			/* 4 <3> An IBSS Peer 'merged in'. */
+			if (fgIsMergeIn) {
+
+				/* 4 <3.1> Add Peers' STA_RECORD_T to Client List */
+				bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec);
+
+#if CFG_SLT_SUPPORT
+				/* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */
+				prStaRec->fgIsQoS = TRUE;	/* TODO(Kevin): TBD */
+#else
+				/* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */
+				prStaRec->fgIsQoS = FALSE;	/* TODO(Kevin): TBD */
+#endif
+
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+				prStaRec->fgIsMerging = FALSE;
+
+			}
+			/* 4 <4> We need 'merge out' to this IBSS */
+			else {
+
+				/* 4 <4.1> Get corresponding BSS_DESC_T */
+				prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr);
+
+				prAisFsmInfo->prTargetBssDesc = prBssDesc;
+
+				/* 4 <4.2> Set the Next State of AIS FSM */
+				eNextState = AIS_STATE_IBSS_MERGE;
+
+			}
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	if (eNextState != prAisFsmInfo->eCurrentState)
+		aisFsmSteps(prAdapter, eNextState);
+
+}				/* end of aisFsmRunEventFoundIBSSPeer() */
+#endif /* CFG_SUPPORT_ADHOC */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate the Media State to HOST
+*
+* @param[in] eConnectionState   Current Media State
+* @param[in] fgDelayIndication  Set TRUE for postponing the Disconnect Indication.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter,
+				ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication)
+{
+	EVENT_CONNECTION_STATUS rEventConnStatus;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_INFO_T prAisBssInfo;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+
+	DEBUGFUNC("aisIndicationOfMediaStateToHost()");
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	/* NOTE(Kevin): Move following line to aisChangeMediaState() macro per CM's request. */
+	/* prAisBssInfo->eConnectionState = eConnectionState; */
+
+	/* For indicating the Disconnect Event only if current media state is
+	 * disconnected and we didn't do indication yet.
+	 */
+	if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
+		if (prAisBssInfo->eConnectionStateIndicated == eConnectionState)
+			return;
+	}
+
+	if (!fgDelayIndication) {
+		/* 4 <0> Cancel Delay Timer */
+		cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer);
+
+		/* 4 <1> Fill EVENT_CONNECTION_STATUS */
+		rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState;
+
+		if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+			rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED;
+
+			if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) {
+				rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA;
+				rEventConnStatus.u2AID = prAisBssInfo->u2AssocId;
+				rEventConnStatus.u2ATIMWindow = 0;
+			} else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
+				rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS;
+				rEventConnStatus.u2AID = 0;
+				rEventConnStatus.u2ATIMWindow = prAisBssInfo->u2ATIMWindow;
+			} else {
+				ASSERT(0);
+			}
+
+			COPY_SSID(rEventConnStatus.aucSsid,
+				  rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+
+			COPY_MAC_ADDR(rEventConnStatus.aucBssid, prAisBssInfo->aucBSSID);
+
+			rEventConnStatus.u2BeaconPeriod = prAisBssInfo->u2BeaconInterval;
+			rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prAisBssInfo->ucPrimaryChannel);
+
+			switch (prAisBssInfo->ucNonHTBasicPhyType) {
+			case PHY_TYPE_HR_DSSS_INDEX:
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS;
+				break;
+
+			case PHY_TYPE_ERP_INDEX:
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24;
+				break;
+
+			case PHY_TYPE_OFDM_INDEX:
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5;
+				break;
+
+			default:
+				ASSERT(0);
+				rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS;
+				break;
+			}
+		} else {
+			/* Deactivate previous Peers' STA_RECORD_T in Driver if have. */
+			bssClearClientList(prAdapter, prAisBssInfo);
+
+#if CFG_PRIVACY_MIGRATION
+			/* Clear the pmkid cache while media disconnect */
+			secClearPmkid(prAdapter);
+#endif
+
+			rEventConnStatus.ucReasonOfDisconnect = prAisBssInfo->ucReasonOfDisconnect;
+		}
+
+		/* 4 <2> Indication */
+		nicMediaStateChange(prAdapter, NETWORK_TYPE_AIS_INDEX, &rEventConnStatus);
+		prAisBssInfo->eConnectionStateIndicated = eConnectionState;
+	} else {
+		/* NOTE: Only delay the Indication of Disconnect Event */
+		ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED);
+
+		DBGLOG(AIS, INFO, "Postpone the indication of Disconnect for %d seconds\n",
+				   prConnSettings->ucDelayTimeOfDisconnectEvent);
+
+		cnmTimerStartTimer(prAdapter,
+				   &prAisFsmInfo->rIndicationOfDisconnectTimer,
+				   SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent));
+	}
+
+}				/* end of aisIndicationOfMediaStateToHost() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "Media Disconnect" to HOST
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	P_BSS_INFO_T prAisBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	/* 4 <1> Deactivate previous AP's STA_RECORD_T in Driver if have. */
+	if (prAisBssInfo->prStaRecOfAP) {
+		/* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */
+
+		prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+	}
+	/* 4 <2> Remove pending connection request */
+	aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE);
+	prConnSettings->fgIsDisconnectedByNonRequest = TRUE;
+	prAisBssInfo->u2DeauthReason = REASON_CODE_BEACON_TIMEOUT;
+	/* 4 <3> Indicate Disconnected Event to Host immediately. */
+	aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE);
+
+}				/* end of aisPostponedEventOfDisconnTimeout() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will update the contain of BSS_INFO_T for AIS network once
+*        the association was completed.
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+* @param[in] prAssocRspSwRfb        Pointer to SW RFB of ASSOC RESP FRAME.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame;
+	P_BSS_DESC_T prBssDesc;
+	UINT_16 u2IELength;
+	PUINT_8 pucIE;
+
+	DEBUGFUNC("aisUpdateBssInfoForJOIN()");
+
+	ASSERT(prStaRec);
+	ASSERT(prAssocRspSwRfb);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader;
+
+	DBGLOG(AIS, TRACE, "Update AIS_BSS_INFO_T and apply settings to MAC\n");
+
+	/* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */
+	/* 4 <1.1> Setup Operation Mode */
+	prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE;
+
+	/* 4 <1.2> Setup SSID */
+	COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+
+	/* 4 <1.3> Setup Channel, Band */
+	prAisBssInfo->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum;
+	prAisBssInfo->eBand = prAisFsmInfo->prTargetBssDesc->eBand;
+
+	/* 3 <2> Update BSS_INFO_T from STA_RECORD_T */
+	/* 4 <2.1> Save current AP's STA_RECORD_T and current AID */
+	prAisBssInfo->prStaRecOfAP = prStaRec;
+	prAisBssInfo->u2AssocId = prStaRec->u2AssocId;
+
+	/* 4 <2.2> Setup Capability */
+	prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo;	/* Use AP's Cap Info as BSS Cap Info */
+
+	if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)
+		prAisBssInfo->fgIsShortPreambleAllowed = TRUE;
+	else
+		prAisBssInfo->fgIsShortPreambleAllowed = FALSE;
+
+#if (CFG_SUPPORT_TDLS == 1)
+	/* init the TDLS flags */
+	prAisBssInfo->fgTdlsIsProhibited = prStaRec->fgTdlsIsProhibited;
+	prAisBssInfo->fgTdlsIsChSwProhibited = prStaRec->fgTdlsIsChSwProhibited;
+#endif /* CFG_SUPPORT_TDLS */
+
+	/* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */
+	prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
+
+	prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType;
+
+	prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet;
+	prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
+
+	/* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */
+	/* 4 <3.1> Setup BSSID */
+	COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prAssocRspFrame->aucBSSID);
+
+	u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) -
+				(OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN));
+	pucIE = prAssocRspFrame->aucInfoElem;
+
+	/* 4 <3.2> Parse WMM and setup QBSS flag */
+	/* Parse WMM related IEs and configure HW CRs accordingly */
+	mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
+
+	prAisBssInfo->fgIsQBSS = prStaRec->fgIsQoS;
+
+	/* 3 <4> Update BSS_INFO_T from BSS_DESC_T */
+	prBssDesc = scanSearchBssDescByBssid(prAdapter, prAssocRspFrame->aucBSSID);
+	if (prBssDesc) {
+		prBssDesc->fgIsConnecting = FALSE;
+		prBssDesc->fgIsConnected = TRUE;
+		prBssDesc->ucJoinFailureCount = 0;
+
+		/* 4 <4.1> Setup MIB for current BSS */
+		prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
+	} else {
+		/* should never happen */
+		ASSERT(0);
+	}
+
+	/* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */
+	prAisBssInfo->ucDTIMPeriod = 0;
+	prAisBssInfo->u2ATIMWindow = 0;
+
+	prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA;
+
+	/* 4 <4.2> Update HT information and set channel */
+	/* Record HT related parameters in rStaRec and rBssInfo
+	 * Note: it shall be called before nicUpdateBss()
+	 */
+	rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
+
+	/* 4 <4.3> Sync with firmware for BSS-INFO */
+	nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */
+	/* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */
+
+}				/* end of aisUpdateBssInfoForJOIN() */
+
+#if CFG_SUPPORT_ADHOC
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will create an Ad-Hoc network and start sending Beacon Frames.
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	if (prAisBssInfo->fgIsBeaconActivated)
+		return;
+	/* 3 <1> Update BSS_INFO_T per Network Basis */
+	/* 4 <1.1> Setup Operation Mode */
+	prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS;
+
+	/* 4 <1.2> Setup SSID */
+	COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+
+	/* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */
+	prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+	prAisBssInfo->u2AssocId = 0;
+
+	/* 4 <1.4> Setup Channel, Band and Phy Attributes */
+	prAisBssInfo->ucPrimaryChannel = prConnSettings->ucAdHocChannelNum;
+	prAisBssInfo->eBand = prConnSettings->eAdHocBand;
+
+	if (prAisBssInfo->eBand == BAND_2G4) {
+		/* Depend on eBand */
+		prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN;
+		/* Depend on eCurrentOPMode and ucPhyTypeSet */
+		prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG;
+	} else {
+		/* Depend on eBand */
+		prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN;
+		/* Depend on eCurrentOPMode and ucPhyTypeSet */
+		prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A;
+	}
+
+	/* 4 <1.5> Setup MIB for current BSS */
+	prAisBssInfo->u2BeaconInterval = prConnSettings->u2BeaconPeriod;
+	prAisBssInfo->ucDTIMPeriod = 0;
+	prAisBssInfo->u2ATIMWindow = prConnSettings->u2AtimWindow;
+
+	prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC;
+
+#if CFG_PRIVACY_MIGRATION
+	if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED ||
+	    prConnSettings->eEncStatus == ENUM_ENCRYPTION2_ENABLED ||
+	    prConnSettings->eEncStatus == ENUM_ENCRYPTION3_ENABLED) {
+		prAisBssInfo->fgIsProtection = TRUE;
+	} else {
+		prAisBssInfo->fgIsProtection = FALSE;
+	}
+#else
+	prAisBssInfo->fgIsProtection = FALSE;
+#endif
+
+	/* 3 <2> Update BSS_INFO_T common part */
+	ibssInitForAdHoc(prAdapter, prAisBssInfo);
+
+	/* 3 <3> Set MAC HW */
+	/* 4 <3.1> Setup channel and bandwidth */
+	rlmBssInitForAPandIbss(prAdapter, prAisBssInfo);
+
+	/* 4 <3.2> use command packets to inform firmware */
+	nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 4 <3.3> enable beaconing */
+	bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 4 <3.4> Update AdHoc PM parameter */
+	nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 3 <4> Set ACTIVE flag. */
+	prAisBssInfo->fgIsBeaconActivated = TRUE;
+	prAisBssInfo->fgHoldSameBssidForIBSS = TRUE;
+
+	/* 3 <5> Start IBSS Alone Timer */
+	cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC));
+
+	return;
+
+}				/* end of aisCreateIBSS() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will update the contain of BSS_INFO_T for AIS network once
+*        the existing IBSS was found.
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_DESC_T prBssDesc;
+	/* UINT_16 u2IELength; */
+	/* PUINT_8 pucIE; */
+
+	ASSERT(prStaRec);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer);
+
+	if (!prAisBssInfo->fgIsBeaconActivated) {
+
+		/* 3 <1> Update BSS_INFO_T per Network Basis */
+		/* 4 <1.1> Setup Operation Mode */
+		prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS;
+
+		/* 4 <1.2> Setup SSID */
+		COPY_SSID(prAisBssInfo->aucSSID,
+			  prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+
+		/* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */
+		prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+		prAisBssInfo->u2AssocId = 0;
+	}
+	/* 3 <2> Update BSS_INFO_T from STA_RECORD_T */
+	/* 4 <2.1> Setup Capability */
+	prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo;	/* Use Peer's Cap Info as IBSS Cap Info */
+
+	if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) {
+		prAisBssInfo->fgIsShortPreambleAllowed = TRUE;
+		prAisBssInfo->fgUseShortPreamble = TRUE;
+	} else {
+		prAisBssInfo->fgIsShortPreambleAllowed = FALSE;
+		prAisBssInfo->fgUseShortPreamble = FALSE;
+	}
+
+	/* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */
+	prAisBssInfo->fgUseShortSlotTime = FALSE;	/* Set to FALSE for AdHoc */
+	prAisBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME;
+
+	if (prAisBssInfo->u2CapInfo & CAP_INFO_PRIVACY)
+		prAisBssInfo->fgIsProtection = TRUE;
+	else
+		prAisBssInfo->fgIsProtection = FALSE;
+
+	/* 4 <2.2> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */
+	prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
+
+	prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType;
+
+	prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet;
+	prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
+
+	rateGetDataRatesFromRateSet(prAisBssInfo->u2OperationalRateSet,
+				    prAisBssInfo->u2BSSBasicRateSet,
+				    prAisBssInfo->aucAllSupportedRates, &prAisBssInfo->ucAllSupportedRatesLen);
+
+	/* 3 <3> X Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */
+
+	/* 3 <4> Update BSS_INFO_T from BSS_DESC_T */
+	prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr);
+	if (prBssDesc) {
+		prBssDesc->fgIsConnecting = FALSE;
+		prBssDesc->fgIsConnected = TRUE;
+
+		/* 4 <4.1> Setup BSSID */
+		COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prBssDesc->aucBSSID);
+
+		/* 4 <4.2> Setup Channel, Band */
+		prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum;
+		prAisBssInfo->eBand = prBssDesc->eBand;
+
+		/* 4 <4.3> Setup MIB for current BSS */
+		prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
+		prAisBssInfo->ucDTIMPeriod = 0;
+		prAisBssInfo->u2ATIMWindow = 0;	/* TBD(Kevin) */
+
+		prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC;
+	} else {
+		/* should never happen */
+		ASSERT(0);
+	}
+
+	/* 3 <5> Set MAC HW */
+	/* 4 <5.1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
+	{
+		UINT_8 ucLowestBasicRateIndex;
+
+		if (!rateGetLowestRateIndexFromRateSet(prAisBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) {
+
+			if (prAisBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_OFDM)
+				ucLowestBasicRateIndex = RATE_6M_INDEX;
+			else
+				ucLowestBasicRateIndex = RATE_1M_INDEX;
+		}
+
+		prAisBssInfo->ucHwDefaultFixedRateCode =
+		    aucRateIndex2RateCode[prAisBssInfo->fgUseShortPreamble][ucLowestBasicRateIndex];
+	}
+
+	/* 4 <5.2> Setup channel and bandwidth */
+	rlmBssInitForAPandIbss(prAdapter, prAisBssInfo);
+
+	/* 4 <5.3> use command packets to inform firmware */
+	nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 4 <5.4> enable beaconing */
+	bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 4 <5.5> Update AdHoc PM parameter */
+	nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* 3 <6> Set ACTIVE flag. */
+	prAisBssInfo->fgIsBeaconActivated = TRUE;
+	prAisBssInfo->fgHoldSameBssidForIBSS = TRUE;
+
+}				/* end of aisUpdateBssInfoForMergeIBSS() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Probe Request Frame and then return
+*        result to BSS to indicate if need to send the corresponding Probe Response
+*        Frame if the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu4ControlFlags   Control flags for replying the Probe Response
+*
+* @retval TRUE      Reply the Probe Response
+* @retval FALSE     Don't reply the Probe Response
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags)
+{
+	P_WLAN_MAC_MGMT_HEADER_T prMgtHdr;
+	P_BSS_INFO_T prBssInfo;
+	P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
+	PUINT_8 pucIE;
+	UINT_16 u2IELength;
+	UINT_16 u2Offset = 0;
+	BOOLEAN fgReplyProbeResp = FALSE;
+
+	ASSERT(prSwRfb);
+	ASSERT(pu4ControlFlags);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	/* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */
+	prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader;
+
+	u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen;
+	pucIE = (PUINT_8) prSwRfb->pvHeader + prSwRfb->u2HeaderLen;
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		if (ELEM_ID_SSID == IE_ID(pucIE)) {
+			if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID))
+				prIeSsid = (P_IE_SSID_T) pucIE;
+			break;
+		}
+	}			/* end of IE_FOR_EACH */
+
+	/* 4 <2> Check network conditions */
+
+	if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
+
+		if ((prIeSsid) && ((prIeSsid->ucLength == BC_SSID_LEN) ||	/* WILDCARD SSID */
+				   EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen,	/* CURRENT SSID */
+					      prIeSsid->aucSSID, prIeSsid->ucLength))) {
+			fgReplyProbeResp = TRUE;
+		}
+	}
+
+	return fgReplyProbeResp;
+
+}				/* end of aisValidateProbeReq() */
+
+#endif /* CFG_SUPPORT_ADHOC */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will modify and update necessary information to firmware
+*        for disconnection handling
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+*
+* @retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication)
+{
+	P_BSS_INFO_T prAisBssInfo;
+
+	ASSERT(prAdapter);
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+#if CFG_SUPPORT_ADHOC
+	if (prAisBssInfo->fgIsBeaconActivated) {
+		nicUpdateBeaconIETemplate(prAdapter, IE_UPD_METHOD_DELETE_ALL, NETWORK_TYPE_AIS_INDEX, 0, NULL, 0);
+
+		prAisBssInfo->fgIsBeaconActivated = FALSE;
+	}
+#endif
+
+	rlmBssAborted(prAdapter, prAisBssInfo);
+
+	/* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */
+	if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) {
+		/* add for ctia mode */
+		{
+			UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID;
+
+			if (EQUAL_SSID(aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen))
+				nicEnterCtiaMode(prAdapter, FALSE, FALSE);
+		}
+
+		if (prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_RADIO_LOST) {
+			scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
+
+			/* remove from scanning results as well */
+			wlanClearBssInScanningResult(prAdapter, prAisBssInfo->aucBSSID);
+
+			/* trials for re-association */
+			if (fgDelayIndication) {
+				DBGLOG(AIS, INFO, "try to do re-association due to radio lost!\n");
+				aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE);
+				aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT);
+			}
+		} else {
+			scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
+		}
+
+		if (fgDelayIndication) {
+			if (OP_MODE_IBSS != prAisBssInfo->eCurrentOPMode)
+				prAisBssInfo->fgHoldSameBssidForIBSS = FALSE;
+		} else {
+			prAisBssInfo->fgHoldSameBssidForIBSS = FALSE;
+		}
+	} else {
+		prAisBssInfo->fgHoldSameBssidForIBSS = FALSE;
+	}
+
+	/* 4 <4> Change Media State immediately. */
+	if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION) {
+		aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+
+		/* 4 <4.1> sync. with firmware */
+		nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX);
+	}
+
+	if (!fgDelayIndication) {
+		/* 4 <5> Deactivate previous AP's STA_RECORD_T or all Clients in Driver if have. */
+		if (prAisBssInfo->prStaRecOfAP) {
+			/* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */
+
+			prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+		}
+	}
+#if CFG_SUPPORT_ROAMING
+	roamingFsmRunEventAbort(prAdapter);
+
+	/* clear pending roaming connection request */
+	aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE);
+	aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE);
+#endif /* CFG_SUPPORT_ROAMING */
+
+	/* 4 <6> Indicate Disconnected Event to Host */
+	aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, fgDelayIndication);
+
+	/* 4 <7> Trigger AIS FSM */
+	aisFsmSteps(prAdapter, AIS_STATE_IDLE);
+
+}				/* end of aisFsmDisconnect() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of Scan done Time-Out to AIS FSM.
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 IsrCnt = 0, IsrPassCnt = 0, TaskIsrCnt = 0;
+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+#define SCAN_DONE_TIMEOUT_TIMES_LIMIT		20
+
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	GL_HIF_INFO_T *HifInfo;
+	UINT_32 u4FwCnt;
+	P_GLUE_INFO_T prGlueInfo;
+
+	DEBUGFUNC("aisFsmRunEventScanDoneTimeOut()");
+
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	HifInfo = &prAdapter->prGlueInfo->rHifInfo;
+
+	DBGLOG(AIS, WARN, "aisFsmRunEventScanDoneTimeOut Current[%d], ucScanTimeoutTimes=%d\n",
+		prAisFsmInfo->eCurrentState, ucScanTimeoutTimes);
+	DBGLOG(AIS, WARN, "Isr/task %u %u %u (0x%x)\n", prGlueInfo->IsrCnt, prGlueInfo->IsrPassCnt,
+			prGlueInfo->TaskIsrCnt, prAdapter->fgIsIntEnable);
+
+	/* dump firmware program counter */
+	DBGLOG(AIS, WARN, "CONNSYS FW CPUINFO:\n");
+	for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++)
+		DBGLOG(AIS, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR));
+
+	ucScanTimeoutTimes++;
+	if (ucScanTimeoutTimes > SCAN_DONE_TIMEOUT_TIMES_LIMIT) {
+		kalSendAeeWarning("[Scan done timeout more than 20 times!]", __func__);
+		glDoChipReset();
+	}
+#if 0 /* ALPS02018734: remove trigger assert */
+	if (prAdapter->fgTestMode == FALSE) {
+		/* Titus - xxx */
+		/* assert if and only if in normal mode */
+		mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40);
+	}
+#endif
+	/* report all scanned frames to upper layer to avoid scanned frame is timeout */
+	/* must be put before kalScanDone */
+/* scanReportBss2Cfg80211(prAdapter,BSS_TYPE_INFRASTRUCTURE,NULL); */
+
+	prConnSettings->fgIsScanReqIssued = FALSE;
+	kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS);
+	eNextState = prAisFsmInfo->eCurrentState;
+
+	switch (prAisFsmInfo->eCurrentState) {
+	case AIS_STATE_SCAN:
+		prAisFsmInfo->u4ScanIELength = 0;
+		eNextState = AIS_STATE_IDLE;
+		break;
+	case AIS_STATE_ONLINE_SCAN:
+		/* reset scan IE buffer */
+		prAisFsmInfo->u4ScanIELength = 0;
+#if CFG_SUPPORT_ROAMING
+		eNextState = aisFsmRoamingScanResultsUpdate(prAdapter);
+#else
+		eNextState = AIS_STATE_NORMAL_TR;
+#endif /* CFG_SUPPORT_ROAMING */
+		break;
+	default:
+		break;
+	}
+
+	/* try to stop scan in CONNSYS */
+	aisFsmStateAbort_SCAN(prAdapter);
+
+	/* wlanQueryDebugCode(prAdapter); */ /* display current SCAN FSM in FW, debug use */
+
+	if (eNextState != prAisFsmInfo->eCurrentState)
+		aisFsmSteps(prAdapter, eNextState);
+
+}				/* end of aisFsmBGSleepTimeout() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "Background Scan Time-Out" to AIS FSM.
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+
+	DEBUGFUNC("aisFsmRunEventBGSleepTimeOut()");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	eNextState = prAisFsmInfo->eCurrentState;
+
+	switch (prAisFsmInfo->eCurrentState) {
+	case AIS_STATE_WAIT_FOR_NEXT_SCAN:
+		DBGLOG(AIS, LOUD, "EVENT - SCAN TIMER: Idle End - Current Time = %u\n", kalGetTimeTick());
+
+		eNextState = AIS_STATE_LOOKING_FOR;
+
+		SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+		break;
+
+	default:
+		break;
+	}
+
+	/* Call aisFsmSteps() when we are going to change AIS STATE */
+	if (eNextState != prAisFsmInfo->eCurrentState)
+		aisFsmSteps(prAdapter, eNextState);
+
+}				/* end of aisFsmBGSleepTimeout() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "IBSS ALONE Time-Out" to AIS FSM.
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+
+	DEBUGFUNC("aisFsmRunEventIbssAloneTimeOut()");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	eNextState = prAisFsmInfo->eCurrentState;
+
+	switch (prAisFsmInfo->eCurrentState) {
+	case AIS_STATE_IBSS_ALONE:
+
+		/* There is no one participate in our AdHoc during this TIMEOUT Interval
+		 * so go back to search for a valid IBSS again.
+		 */
+
+		DBGLOG(AIS, LOUD, "EVENT-IBSS ALONE TIMER: Start pairing\n");
+
+		prAisFsmInfo->fgTryScan = TRUE;
+
+		/* abort timer */
+		aisFsmReleaseCh(prAdapter);
+
+		/* Pull back to SEARCH to find candidate again */
+		eNextState = AIS_STATE_SEARCH;
+
+		break;
+
+	default:
+		break;
+	}
+
+	/* Call aisFsmSteps() when we are going to change AIS STATE */
+	if (eNextState != prAisFsmInfo->eCurrentState)
+		aisFsmSteps(prAdapter, eNextState);
+
+}				/* end of aisIbssAloneTimeOut() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "Join Time-Out" to AIS FSM.
+*
+* @param[in] u4Param  Unused timer parameter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	P_BSS_INFO_T prAisBssInfo;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+	OS_SYSTIME rCurrentTime;
+
+	DEBUGFUNC("aisFsmRunEventJoinTimeout()");
+	prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	eNextState = prAisFsmInfo->eCurrentState;
+
+	GET_CURRENT_SYSTIME(&rCurrentTime);
+	switch (prAisFsmInfo->eCurrentState) {
+	case AIS_STATE_JOIN:
+		DBGLOG(AIS, LOUD, "EVENT- JOIN TIMEOUT\n");
+
+		/* 1. Do abort JOIN */
+		aisFsmStateAbort_JOIN(prAdapter);
+
+		/* 2. Increase Join Failure Count */
+		prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount++;
+/* For JB nl802.11 */
+		if (prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) {
+			/* 3.1 Retreat to AIS_STATE_SEARCH state for next try */
+			eNextState = AIS_STATE_SEARCH;
+		} else if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+			/* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */
+			eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN;
+		} else if (!CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime,
+				SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) {
+			/* 3.3 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */
+			eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN;
+		} else {
+			/* 3.4 Retreat to AIS_STATE_JOIN_FAILURE to terminate join operation */
+			kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_CONNECT_INDICATION, NULL, 0);
+			eNextState = AIS_STATE_IDLE;
+		}
+		break;
+
+	case AIS_STATE_NORMAL_TR:
+		/* 1. release channel */
+		aisFsmReleaseCh(prAdapter);
+		prAisFsmInfo->fgIsInfraChannelFinished = TRUE;
+
+		/* 2. process if there is pending scan */
+		if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) {
+			wlanClearScanningResult(prAdapter);
+			eNextState = AIS_STATE_ONLINE_SCAN;
+		}
+
+		break;
+
+	default:
+		/* release channel */
+		aisFsmReleaseCh(prAdapter);
+		break;
+
+	}
+
+	/* Call aisFsmSteps() when we are going to change AIS STATE */
+	if (eNextState != prAisFsmInfo->eCurrentState)
+		aisFsmSteps(prAdapter, eNextState);
+
+}				/* end of aisFsmRunEventJoinTimeout() */
+
+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	aisDeauthXmitComplete(prAdapter, NULL, TX_RESULT_LIFE_TIMEOUT);
+}
+
+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0)
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisTest(VOID)
+{
+	P_MSG_AIS_ABORT_T prAisAbortMsg;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	UINT_8 aucSSID[] = "pci-11n";
+	UINT_8 ucSSIDLen = 7;
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	/* Set Connection Request Issued Flag */
+	prConnSettings->fgIsConnReqIssued = TRUE;
+	prConnSettings->ucSSIDLen = ucSSIDLen;
+	kalMemCopy(prConnSettings->aucSSID, aucSSID, ucSSIDLen);
+
+	prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
+	if (!prAisAbortMsg) {
+
+		ASSERT(0);	/* Can't trigger SCAN FSM */
+		return;
+	}
+
+	prAisAbortMsg->rMsgHdr.eMsgId = MID_HEM_AIS_FSM_ABORT;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
+
+	wifi_send_msg(INDX_WIFI, MSG_ID_WIFI_IST, 0);
+
+}
+#endif /* CFG_TEST_MGMT_FSM */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is used to handle OID_802_11_BSSID_LIST_SCAN
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[in] prSsid     Pointer of SSID_T if specified
+* \param[in] pucIe      Pointer to buffer of extra information elements to be attached
+* \param[in] u4IeLength Length of information elements
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_INFO_T prAisBssInfo;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+
+	DEBUGFUNC("aisFsmScanRequest()");
+
+	ASSERT(prAdapter);
+	ASSERT(u4IeLength <= MAX_IE_LENGTH);
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	if (!prConnSettings->fgIsScanReqIssued) {
+		prConnSettings->fgIsScanReqIssued = TRUE;
+
+		if (prSsid == NULL) {
+			prAisFsmInfo->ucScanSSIDLen = 0;
+		} else {
+			COPY_SSID(prAisFsmInfo->aucScanSSID,
+				  prAisFsmInfo->ucScanSSIDLen, prSsid->aucSsid, (UINT_8) prSsid->u4SsidLen);
+		}
+
+		if (u4IeLength > 0 && u4IeLength <= MAX_IE_LENGTH) {
+			prAisFsmInfo->u4ScanIELength = u4IeLength;
+			kalMemCopy(prAisFsmInfo->aucScanIEBuf, pucIe, u4IeLength);
+		} else {
+			prAisFsmInfo->u4ScanIELength = 0;
+		}
+
+		if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) {
+			if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE
+			    && prAisFsmInfo->fgIsInfraChannelFinished == FALSE) {
+				/* 802.1x might not finished yet, pend it for later handling .. */
+				aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN);
+			} else {
+				if (prAisFsmInfo->fgIsChannelGranted == TRUE) {
+					DBGLOG(AIS, WARN,
+					       "Scan Request with channel granted for join operation: %d, %d",
+						prAisFsmInfo->fgIsChannelGranted, prAisFsmInfo->fgIsChannelRequested);
+				}
+
+				/* start online scan */
+				wlanClearScanningResult(prAdapter);
+				aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN);
+			}
+		} else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) {
+			wlanClearScanningResult(prAdapter);
+			aisFsmSteps(prAdapter, AIS_STATE_SCAN);
+		} else {
+			aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN);
+		}
+	} else {
+		DBGLOG(AIS, WARN, "Scan Request dropped. (state: %d)\n", prAisFsmInfo->eCurrentState);
+	}
+
+}				/* end of aisFsmScanRequest() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is invoked when CNM granted channel privilege
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_BSS_INFO_T prAisBssInfo;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_MSG_CH_GRANT_T prMsgChGrant;
+	UINT_8 ucTokenID;
+	UINT_32 u4GrantInterval;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr;
+
+	ucTokenID = prMsgChGrant->ucTokenID;
+	u4GrantInterval = prMsgChGrant->u4GrantInterval;
+
+	/* 1. free message */
+	cnmMemFree(prAdapter, prMsgHdr);
+
+	if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) {
+		/* 2. channel privilege has been approved */
+		prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval;
+
+		/* 3. state transition to join/ibss-alone/ibss-merge */
+		/* 3.1 set timeout timer in cases join could not be completed */
+		cnmTimerStartTimer(prAdapter,
+				   &prAisFsmInfo->rJoinTimeoutTimer,
+				   prAisFsmInfo->u4ChGrantedInterval - AIS_JOIN_CH_GRANT_THRESHOLD);
+		/* 3.2 set local variable to indicate join timer is ticking */
+		prAisFsmInfo->fgIsInfraChannelFinished = FALSE;
+
+		/* 3.3 switch to join state */
+		aisFsmSteps(prAdapter, AIS_STATE_JOIN);
+
+		prAisFsmInfo->fgIsChannelGranted = TRUE;
+	} else if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL &&
+		   prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) {
+		/* 2. channel privilege has been approved */
+		prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval;
+
+		/* 3.1 set timeout timer in cases upper layer cancel_remain_on_channel never comes */
+		cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer, prAisFsmInfo->u4ChGrantedInterval);
+
+		/* 3.2 switch to remain_on_channel state */
+		aisFsmSteps(prAdapter, AIS_STATE_REMAIN_ON_CHANNEL);
+
+		/* 3.3. indicate upper layer for channel ready */
+		kalReadyOnChannel(prAdapter->prGlueInfo,
+				  prAisFsmInfo->rChReqInfo.u8Cookie,
+				  prAisFsmInfo->rChReqInfo.eBand,
+				  prAisFsmInfo->rChReqInfo.eSco,
+				  prAisFsmInfo->rChReqInfo.ucChannelNum, prAisFsmInfo->rChReqInfo.u4DurationMs);
+
+		prAisFsmInfo->fgIsChannelGranted = TRUE;
+	} else {		/* mismatched grant */
+		/* 2. return channel privilege to CNM immediately */
+		aisFsmReleaseCh(prAdapter);
+	}
+
+}				/* end of aisFsmRunEventChGrant() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is to inform CNM that channel privilege
+*           has been released
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_MSG_CH_ABORT_T prMsgChAbort;
+
+	ASSERT(prAdapter);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	if (prAisFsmInfo->fgIsChannelGranted == TRUE || prAisFsmInfo->fgIsChannelRequested == TRUE) {
+
+		prAisFsmInfo->fgIsChannelRequested = FALSE;
+		prAisFsmInfo->fgIsChannelGranted = FALSE;
+
+		/* 1. return channel privilege to CNM immediately */
+		prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T));
+		if (!prMsgChAbort) {
+			ASSERT(0);	/* Can't release Channel to CNM */
+			return;
+		}
+
+		prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT;
+		prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+		prMsgChAbort->ucTokenID = prAisFsmInfo->ucSeqNumOfChReq;
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF);
+	}
+
+}				/* end of aisFsmReleaseCh() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is to inform AIS that corresponding beacon has not
+*           been received for a while and probing is not successful
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter)
+{
+	P_BSS_INFO_T prAisBssInfo;
+	BOOLEAN fgDoAbortIndication = FALSE;
+
+	ASSERT(prAdapter);
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	/* 4 <1> Diagnose Connection for Beacon Timeout Event */
+	if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) {
+		if (OP_MODE_INFRASTRUCTURE == prAisBssInfo->eCurrentOPMode) {
+			P_STA_RECORD_T prStaRec = prAisBssInfo->prStaRecOfAP;
+
+			if (prStaRec)
+				fgDoAbortIndication = TRUE;
+		} else if (OP_MODE_IBSS == prAisBssInfo->eCurrentOPMode) {
+			fgDoAbortIndication = TRUE;
+		}
+	}
+	/* 4 <2> invoke abort handler */
+	if (fgDoAbortIndication) {
+#if 0
+		P_CONNECTION_SETTINGS_T prConnSettings;
+
+		prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+		prConnSettings->fgIsDisconnectedByNonRequest = TRUE;
+#endif
+
+		DBGLOG(AIS, INFO, "Beacon Timeout, Remove BSS [%pM]\n", prAisBssInfo->aucBSSID);
+		scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
+
+		/*
+		   Note: Cannot change TRUE to FALSE; or you will suffer the problem in
+		   ALPS01270257/ ALPS01804173
+		 */
+		aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, TRUE);
+	}
+
+}				/* end of aisBssBeaconTimeout() */
+
+VOID aisBssSecurityChanged(P_ADAPTER_T prAdapter)
+{
+	P_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	prAdapter->rWifiVar.rConnSettings.fgIsDisconnectedByNonRequest = TRUE;
+	prAisBssInfo->u2DeauthReason = REASON_CODE_BSS_SECURITY_CHANGE;
+	aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_DEAUTHENTICATED, FALSE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is to inform AIS that DEAUTH frame has been
+*           sent and thus state machine could go ahead
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[in] prMsduInfo Pointer of MSDU_INFO_T for DEAUTH frame
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+
+	ASSERT(prAdapter);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	if (rTxDoneStatus == TX_RESULT_SUCCESS)
+		cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer);
+
+	if (prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) {
+		if (rTxDoneStatus != TX_RESULT_DROPPED_IN_DRIVER)
+			aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_NEW_CONNECTION, FALSE);
+	} else {
+		DBGLOG(AIS, WARN, "DEAUTH frame transmitted without further handling");
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of aisDeauthXmitComplete() */
+
+#if CFG_SUPPORT_ROAMING
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate an Event of "Looking for a candidate due to weak signal" to AIS FSM.
+*
+* @param[in] u4ReqScan  Requesting Scan or not
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	ENUM_AIS_REQUEST_TYPE_T eAisRequest;
+
+	DBGLOG(AIS, LOUD, "aisFsmRunEventRoamingDiscovery()\n");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	/* search candidates by best rssi */
+	prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI;
+
+#if CFG_SUPPORT_WFD
+#if CFG_ENABLE_WIFI_DIRECT
+	{
+		/* Check WFD is running */
+		P_BSS_INFO_T prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+		if (prAdapter->fgIsP2PRegistered &&
+		    IS_BSS_ACTIVE(prP2pBssInfo) &&
+		    (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT ||
+		     prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)) {
+			DBGLOG(ROAMING, INFO, "Handle roaming when P2P is GC or GO.\n");
+			if (prAdapter->rWifiVar.prP2pFsmInfo) {
+				prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+				if ((prWfdCfgSettings->ucWfdEnable == 1) &&
+				    ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) {
+					DBGLOG(ROAMING, INFO, "WFD is running. Stop roaming.\n");
+					roamingFsmRunEventRoam(prAdapter);
+					roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE);
+					return;
+				}
+			} else {
+				ASSERT(0);
+			}
+		}		/* fgIsP2PRegistered */
+	}
+#endif
+#endif
+
+	/* results are still new */
+	if (!u4ReqScan) {
+		roamingFsmRunEventRoam(prAdapter);
+		eAisRequest = AIS_REQUEST_ROAMING_CONNECT;
+	} else {
+		if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN
+		    || prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) {
+			eAisRequest = AIS_REQUEST_ROAMING_CONNECT;
+		} else {
+			eAisRequest = AIS_REQUEST_ROAMING_SEARCH;
+		}
+	}
+
+	if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && prAisFsmInfo->fgIsInfraChannelFinished == TRUE) {
+		if (eAisRequest == AIS_REQUEST_ROAMING_SEARCH)
+			aisFsmSteps(prAdapter, AIS_STATE_LOOKING_FOR);
+		else
+			aisFsmSteps(prAdapter, AIS_STATE_SEARCH);
+	} else {
+		aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE);
+		aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE);
+
+		aisFsmInsertRequest(prAdapter, eAisRequest);
+	}
+
+}				/* end of aisFsmRunEventRoamingDiscovery() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Update the time of ScanDone for roaming and transit to Roam state.
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	ENUM_AIS_STATE_T eNextState;
+
+	DBGLOG(AIS, LOUD, "->aisFsmRoamingScanResultsUpdate()\n");
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	roamingFsmScanResultsUpdate(prAdapter);
+
+	eNextState = prAisFsmInfo->eCurrentState;
+	if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) {
+		roamingFsmRunEventRoam(prAdapter);
+		eNextState = AIS_STATE_SEARCH;
+	} else if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) {
+		eNextState = AIS_STATE_SEARCH;
+	} else if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) {
+		eNextState = AIS_STATE_NORMAL_TR;
+	}
+
+	return eNextState;
+}				/* end of aisFsmRoamingScanResultsUpdate() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will modify and update necessary information to firmware
+*        for disconnection of last AP before switching to roaming bss.
+*
+* @param IN prAdapter          Pointer to the Adapter structure.
+*           prTargetStaRec     Target of StaRec of roaming
+*
+* @retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec)
+{
+	P_BSS_INFO_T prAisBssInfo;
+
+	DBGLOG(AIS, LOUD, "aisFsmRoamingDisconnectPrevAP()");
+
+	ASSERT(prAdapter);
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	/* Not invoke rlmBssAborted() here to avoid prAisBssInfo->fg40mBwAllowed
+	 * to be reset. RLM related parameters will be reset again when handling
+	 * association response in rlmProcessAssocRsp(). 20110413
+	 */
+	/* rlmBssAborted(prAdapter, prAisBssInfo); */
+
+	/* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */
+	if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState)
+		scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
+	/* 4 <4> Change Media State immediately. */
+	aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+
+	/* 4 <4.1> sync. with firmware */
+	prTargetStaRec->ucNetTypeIndex = 0xff;	/* Virtial NetType */
+	nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX);
+	prTargetStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;	/* Virtial NetType */
+
+#if (CFG_SUPPORT_TDLS == 1)
+	TdlsexLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, prAisBssInfo->aucBSSID,
+				TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING);
+#endif /* CFG_SUPPORT_TDLS */
+
+}				/* end of aisFsmRoamingDisconnectPrevAP() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will update the contain of BSS_INFO_T for AIS network once
+*        the roaming was completed.
+*
+* @param IN prAdapter          Pointer to the Adapter structure.
+*           prStaRec           StaRec of roaming AP
+*           prAssocRspSwRfb
+*
+* @retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb)
+{
+	P_BSS_INFO_T prAisBssInfo;
+
+	DBGLOG(AIS, LOUD, "aisUpdateBssInfoForRoamingAP()");
+
+	ASSERT(prAdapter);
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	/* 4 <1.1> Change FW's Media State immediately. */
+	aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+
+	/* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */
+	if ((prAisBssInfo->prStaRecOfAP) &&
+	    (prAisBssInfo->prStaRecOfAP != prStaRec) && (prAisBssInfo->prStaRecOfAP->fgIsInUse)) {
+		cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1);
+	}
+	/* 4 <1.3> Update BSS_INFO_T */
+	aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb);
+
+	/* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */
+	cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+
+	/* 4 <1.6> Indicate Connected Event to Host immediately. */
+	/* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */
+	aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE);
+
+}				/* end of aisFsmRoamingUpdateBss() */
+
+#endif /* CFG_SUPPORT_ROAMING */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Check if there is any pending request and remove it (optional)
+*
+* @param prAdapter
+*        eReqType
+*        bRemove
+*
+* @return TRUE
+*         FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_AIS_REQ_HDR_T prPendingReqHdr, prPendingReqHdrNext;
+
+	ASSERT(prAdapter);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	/* traverse through pending request list */
+	LINK_FOR_EACH_ENTRY_SAFE(prPendingReqHdr,
+				 prPendingReqHdrNext, &(prAisFsmInfo->rPendingReqList), rLinkEntry, AIS_REQ_HDR_T) {
+		/* check for specified type */
+		if (prPendingReqHdr->eReqType == eReqType) {
+			/* check if need to remove */
+			if (bRemove == TRUE) {
+				LINK_REMOVE_KNOWN_ENTRY(&(prAisFsmInfo->rPendingReqList),
+							&(prPendingReqHdr->rLinkEntry));
+
+				cnmMemFree(prAdapter, prPendingReqHdr);
+			}
+
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Get next pending request
+*
+* @param prAdapter
+*
+* @return P_AIS_REQ_HDR_T
+*/
+/*----------------------------------------------------------------------------*/
+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_AIS_REQ_HDR_T prPendingReqHdr;
+
+	ASSERT(prAdapter);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	LINK_REMOVE_HEAD(&(prAisFsmInfo->rPendingReqList), prPendingReqHdr, P_AIS_REQ_HDR_T);
+
+	return prPendingReqHdr;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Insert a new request
+*
+* @param prAdapter
+*        eReqType
+*
+* @return TRUE
+*         FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType)
+{
+	P_AIS_REQ_HDR_T prAisReq;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+
+	ASSERT(prAdapter);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+	prAisReq = (P_AIS_REQ_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(AIS_REQ_HDR_T));
+
+	if (!prAisReq) {
+		ASSERT(0);	/* Can't generate new message */
+		return FALSE;
+	}
+
+	prAisReq->eReqType = eReqType;
+
+	/* attach request into pending request list */
+	LINK_INSERT_TAIL(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry);
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Flush all pending requests
+*
+* @param prAdapter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_REQ_HDR_T prAisReq;
+
+	ASSERT(prAdapter);
+
+	while ((prAisReq = aisFsmGetNextRequest(prAdapter)) != NULL)
+		cnmMemFree(prAdapter, prAisReq);
+
+}
+
+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_REMAIN_ON_CHANNEL_T prRemainOnChannel;
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	DEBUGFUNC("aisFsmRunEventRemainOnChannel()");
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	prRemainOnChannel = (P_MSG_REMAIN_ON_CHANNEL_T) prMsgHdr;
+
+	/* record parameters */
+	prAisFsmInfo->rChReqInfo.eBand = prRemainOnChannel->eBand;
+	prAisFsmInfo->rChReqInfo.eSco = prRemainOnChannel->eSco;
+	prAisFsmInfo->rChReqInfo.ucChannelNum = prRemainOnChannel->ucChannelNum;
+	prAisFsmInfo->rChReqInfo.u4DurationMs = prRemainOnChannel->u4DurationMs;
+	prAisFsmInfo->rChReqInfo.u8Cookie = prRemainOnChannel->u8Cookie;
+
+	if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE || prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) {
+		/* transit to next state */
+		aisFsmSteps(prAdapter, AIS_STATE_REQ_REMAIN_ON_CHANNEL);
+	} else {
+		aisFsmInsertRequest(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL);
+	}
+
+	/* free messages */
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}
+
+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+	P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prCancelRemainOnChannel;
+
+	ASSERT(prAdapter);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	prCancelRemainOnChannel = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) prMsgHdr;
+
+	/* 1. Check the cookie first */
+	if (prCancelRemainOnChannel->u8Cookie == prAisFsmInfo->rChReqInfo.u8Cookie) {
+
+		/* 2. release channel privilege/request */
+		if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL) {
+			/* 2.1 elease channel */
+			aisFsmReleaseCh(prAdapter);
+		} else if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) {
+			/* 2.1 release channel */
+			aisFsmReleaseCh(prAdapter);
+
+			/* 2.2 stop channel timeout timer */
+			cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer);
+		}
+
+		/* 3. clear pending request of remain_on_channel */
+		aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE);
+
+		/* 4. decide which state to retreat */
+		if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED)
+			aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR);
+		else
+			aisFsmSteps(prAdapter, AIS_STATE_IDLE);
+	}
+
+	/* 5. free message */
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}
+
+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_MSG_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+		/* prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); */
+
+		if (prAisFsmInfo == NULL)
+			break;
+		prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) prMsgHdr;
+
+		aisFuncTxMgmtFrame(prAdapter,
+				   &prAisFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* aisFsmRunEventMgmtFrameTx */
+
+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_BSS_INFO_T prAisBssInfo;
+
+	DEBUGFUNC("aisFsmRunEventRemainOnChannel()");
+
+	ASSERT(prAdapter);
+	prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) {
+		/* 1. release channel */
+		aisFsmReleaseCh(prAdapter);
+
+		/* 2. stop channel timeout timer */
+		cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer);
+
+		/* 3. expiration indication to upper layer */
+		kalRemainOnChannelExpired(prAdapter->prGlueInfo,
+					  prAisFsmInfo->rChReqInfo.u8Cookie,
+					  prAisFsmInfo->rChReqInfo.eBand,
+					  prAisFsmInfo->rChReqInfo.eSco, prAisFsmInfo->rChReqInfo.ucChannelNum);
+
+		/* 4. decide which state to retreat */
+		if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED)
+			aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR);
+		else
+			aisFsmSteps(prAdapter, AIS_STATE_IDLE);
+	} else {
+		DBGLOG(AIS, WARN, "Unexpected remain_on_channel timeout event\n");
+#if DBG
+		DBGLOG(AIS, STATE, "CURRENT State: [%s]\n", apucDebugAisState[prAisFsmInfo->eCurrentState]);
+#else
+		DBGLOG(AIS, STATE, "[%d] CURRENT State: [%d]\n", DBG_AIS_IDX, prAisFsmInfo->eCurrentState);
+#endif
+	}
+
+}
+
+WLAN_STATUS
+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter,
+			      IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+	P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_AIS_MGMT_TX_REQ_INFO_T) NULL;
+	BOOLEAN fgIsSuccess = FALSE;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+		prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo);
+
+		if (rTxDoneStatus != TX_RESULT_SUCCESS) {
+			DBGLOG(AIS, ERROR, "Mgmt Frame TX Fail, Status:%d.\n", rTxDoneStatus);
+		} else {
+			fgIsSuccess = TRUE;
+			/* printk("Mgmt Frame TX Done.\n"); */
+		}
+
+		if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) {
+			kalIndicateMgmtTxStatus(prAdapter->prGlueInfo,
+						prMgmtTxReqInfo->u8Cookie,
+						fgIsSuccess, prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength);
+
+			prMgmtTxReqInfo->prMgmtTxMsdu = NULL;
+		}
+
+	} while (FALSE);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* aisFsmRunEventMgmtFrameTxDone */
+
+WLAN_STATUS
+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter,
+		   IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL;
+	P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL));
+
+		if (prMgmtTxReqInfo->fgIsMgmtTxRequested) {
+
+			/* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */
+			/* Packet on driver, not done yet, drop it. */
+			prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu;
+			if (prTxMsduInfo != NULL) {
+
+				kalIndicateMgmtTxStatus(prAdapter->prGlueInfo,
+							prMgmtTxReqInfo->u8Cookie,
+							FALSE,
+							prTxMsduInfo->prPacket, (UINT_32) prTxMsduInfo->u2FrameLength);
+
+				/* Leave it to TX Done handler. */
+				/* cnmMgtPktFree(prAdapter, prTxMsduInfo); */
+				prMgmtTxReqInfo->prMgmtTxMsdu = NULL;
+			}
+			/* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */
+			/* Packet transmitted, wait tx done. (cookie issue) */
+		}
+
+		ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL);
+
+		prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD);
+		prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanHdr->aucAddr1);
+		prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_AIS_INDEX;
+
+		prMgmtTxReqInfo->u8Cookie = u8Cookie;
+		prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu;
+		prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE;
+
+		prMgmtTxMsdu->eSrc = TX_PACKET_MGMT;
+		prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+		prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF);
+		if (prStaRec != NULL) {
+			/* Do nothing */
+			/* printk("Mgmt with station record: %pM .\n", prStaRec->aucMacAddr); */
+		}
+
+		prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;	/* TODO: undcertain. */
+		prMgmtTxMsdu->fgIs802_1x = FALSE;
+		prMgmtTxMsdu->fgIs802_11 = TRUE;
+		prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+		prMgmtTxMsdu->pfTxDoneHandler = aisFsmRunEventMgmtFrameTxDone;
+		prMgmtTxMsdu->fgIsBasicRate = TRUE;
+		DBGLOG(AIS, TRACE, "Mgmt seq NO. %d .\n", prMgmtTxMsdu->ucTxSeqNum);
+
+		nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu);
+
+	} while (FALSE);
+
+	return rWlanStatus;
+}				/* aisFuncTxMgmtFrame */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Action Frame and indicate to uppoer layer
+*           if the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu4ControlFlags   Control flags for replying the Probe Response
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL;
+
+	DEBUGFUNC("aisFuncValidateRxActionFrame");
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
+
+		prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo);
+
+		if (1 /* prAisFsmInfo->u4AisPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME */) {
+			/* Leave the action frame to wpa_supplicant. */
+			kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb);
+		}
+
+	} while (FALSE);
+
+	return;
+
+}				/* aisFuncValidateRxActionFrame */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c
new file mode 100644
index 0000000000000..f02d7c3bb5b27
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c
@@ -0,0 +1,1932 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#3
+*/
+
+/*! \file   "assoc.c"
+    \brief  This file includes the association-related functions.
+
+    This file includes the association-related functions.
+*/
+
+/*\
+** Log: assoc.c
+**
+** 07 27 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Fix wifi direct connection issue.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 06 08 2012 cp.wu
+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development
+ * add a pair of brace for compilation success.
+ *
+ * 06 04 2012 cp.wu
+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development
+ * discussed with WH, privacy bit in associate response is not necessary to be checked,
+ * and identified as association failure when mismatching with beacon/probe response
+ *
+ * 03 14 2012 wh.su
+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
+ * Add code from 2.2
+ *
+ * 03 09 2012 terry.wu
+ * NULL
+ * Fix build error.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 16 2012 yuche.tsai
+ * NULL
+ * Update Driver for wifi driect gc join IE update issue.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the debug module level.
+ *
+ * 10 25 2011 cm.chang
+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
+ * Fix PhyTypeSet in STA_REC in AP mode
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 19 2011 yuche.tsai
+ * NULL
+ * Fix KE when enable hot-spot & any one client connect to this hot-spot.
+ *
+ * 09 14 2011 yuche.tsai
+ * NULL
+ * Add P2P IE in assoc response.
+ *
+ * 07 15 2011 terry.wu
+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment
+ * Update workaround for Kingnet AP.
+ *
+ * 07 15 2011 terry.wu
+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment
+ * Workaround for Kingnet 710 AP wrong AID assignment.
+ *
+ * 05 02 2011 eddie.chen
+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning[WCXRP00000672] [MT6620 Wi-Fi][FW]
+ * Fix the PS event allocation
+ * Check STA when rx assoc.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue
+ * Make assoc req to append P2P IE if wifi direct is enabled.
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 16 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * enable the protected while at P2P start GO, and skip some security check .
+ *
+ * 03 14 2011 wh.su
+ * [WCXRP00000545] [MT6620 Wi-Fi] [Driver] Fixed the p2p not enable, received a assoc rsp
+ * cause the rx assoc execute a null function
+ * Modify file for avoid assert at BOW receive a assoc response frame but no p2p function.
+ *
+ * 03 08 2011 terry.wu
+ * [WCXRP00000524] [MT6620 Wi-Fi][Driver] Fix p2p assoc request containing wrong IE format
+ * Fix p2p assoc request containing wrong IE format.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add code to let the beacon and probe response for Auto GO WSC .
+ *
+ * 02 15 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Fix RX disassoc issue under Hot-spot mode.
+ *
+ * 02 09 2011 wh.su
+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
+ * adding the code for check STA privacy bit at AP mode, .
+ *
+ * 02 08 2011 eddie.chen
+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
+ * Add event STA agint timeout
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update
+ * when STA record is created under AP Mode.
+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate,
+ * but if the P2P device is connected, 11b rate is not allowed.
+ *
+ * 01 11 2011 yuche.tsai
+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update
+ * when STA record is created under AP Mode.
+ * Update Desired Non-HT Rate Set.
+ *
+ * 12 30 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * Recover the code that was coverwritted..
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * use definition macro to replace hard-coded constant
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 27 2010 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
+ * Update BCM/BoW design and settings.
+ *
+ * 09 16 2010 cm.chang
+ * NULL
+ * Change conditional compiling options for BOW
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Add SSID IE in assoc req frame which is sent by P2P GC.
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 07 20 2010 wh.su
+ *
+ * adding the wapi code.
+ *
+ * 07 09 2010 yarco.yang
+ *
+ * [MT6620 and MT5931] SW Migration: Add ADDBA support
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * take use of RLM module for parsing/generating HT IEs for 11n capability
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * comment out RSN IE generation by CFG_RSN_MIGRATION compilation flag.
+ *
+ * 06 28 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * send MMPDU in basic rate.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan_fsm into building.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * specify correct value for management frames.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration from MT6620 firmware.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * revised.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 05 24 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Update assocProcessRxAssocReqFrame() to avoid redundant SSID IE {0,0} for IOT.
+ *
+ * 05 14 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Fix compile warning - macro > 10 line, initial value of an array
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft code to support protection in AP mode
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support
+ *  *  *  *  *  *  *  *  and will send Null frame to diagnose connection
+ *
+ * 04 16 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * adding the wpa-none for ibss beacon.
+ *
+ * 03 25 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Remove compiling warning
+ *
+ * 03 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Not carry  HT cap when being associated with b/g only AP
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 28 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * fixed the compiling warning.u1rwduu`wvpghlqg|rm+vp
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 07 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Update Assoc ID for PS
+ *
+ * 01 04 2010 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * For working out the first connection Chariot-verified version
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 12 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Use new constant definition ELEM_MAX_LEN_EXT_CAP
+ *
+ * Dec 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Modify assoc req IE talbe for HT cap IE
+ *
+ * Dec 7 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * update the assocComposeReAssocReqFrameHeader() and fix the u2EstimatedFrameLen in assocSendReAssocReqFrame()
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * remove some space line
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the sending disassoc frame function
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the txassocReq IE table, adding for WPA/RSN
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix eNetType not init in send AssocReq function
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Integrate the send Assoc with TXM
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the code to indicate the assoc request and assoc response (now disable)
+ *
+ * Nov 24 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Remove unused variables
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+APPEND_VAR_IE_ENTRY_T txAssocReqIETable[] = {
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmReqGenerateHtCapIE}
+	,			/* 45 */
+#if CFG_SUPPORT_WPS2
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WSC), NULL, rsnGenerateWSCIE}
+	,			/* 221 */
+#endif
+#if CFG_RSN_MIGRATION
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}
+	,			/* 48 */
+#endif
+#if CFG_SUPPORT_WAPI
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI), NULL, wapiGenerateWAPIIE}
+	,			/* 68 */
+#endif
+#if CFG_SUPPORT_HOTSPOT_2_0
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_INTERWORKING), NULL, hs20GenerateInterworkingIE}
+	,			/* 107 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_ROAMING_CONSORTIUM), NULL, hs20GenerateRoamingConsortiumIE}
+	,			/* 111 */
+#endif
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE}
+	,			/* 127 */
+#if CFG_SUPPORT_HOTSPOT_2_0
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HS20_INDICATION), NULL, hs20GenerateHS20IE}
+	,			/* 221 */
+#endif
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE}
+	,			/* 221 */
+#if CFG_RSN_MIGRATION
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE}
+	,			/* 221 */
+#endif
+};
+
+#if CFG_SUPPORT_AAA
+VERIFY_IE_ENTRY_T rxAssocReqIETable[] = {
+	{ELEM_ID_RESERVED, NULL}	/* 255 */
+};
+
+APPEND_VAR_IE_ENTRY_T txAssocRespIETable[] = {
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}
+	,			/* 42 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}
+	,			/* 45 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}
+	,			/* 61 */
+#if CFG_ENABLE_WIFI_DIRECT
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}
+	,			/* 74 */
+	{(0), p2pFuncCalculateP2p_IELenForAssocRsp, p2pFuncGenerateP2p_IEForAssocRsp}
+	,			/* 221 */
+#if CFG_SUPPORT_WFD
+	{(0), wfdFuncCalculateWfdIELenForAssocRsp, wfdFuncGenerateWfdIEForAssocRsp}
+	,			/* 221 */
+#endif
+#endif
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}
+	,			/* 127 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}
+	,			/* 221 */
+
+	{(0), p2pFuncCalculateWSC_IELenForAssocRsp, p2pFuncGenerateWSC_IEForAssocRsp}	/* 221 */
+
+};
+#endif
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to compose the Capability Info Field.
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+*
+* @retval Capability Info Field
+*/
+/*----------------------------------------------------------------------------*/
+UINT_16
+assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	UINT_32 u4NonHTPhyType;
+	UINT_16 u2CapInfo;
+
+	/* Set up our requested capabilities. */
+	u2CapInfo = CAP_INFO_ESS;
+	u2CapInfo |= CAP_CF_STA_NOT_POLLABLE;
+
+	if (prStaRec == NULL)
+		u2CapInfo |= CAP_INFO_PRIVACY;
+	else {
+		if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY)
+			u2CapInfo |= CAP_INFO_PRIVACY;
+	}
+
+	/* 7.3.1.4 */
+	if (prStaRec == NULL) {
+		if ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||/* ShortPreambleOptionEnable is TRUE */
+		    (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))
+			u2CapInfo |= CAP_INFO_SHORT_PREAMBLE;
+		if (prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable)
+			u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
+	} else if (prStaRec->fgHasBasicPhyType) {
+		u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
+
+		if ((rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) &&
+			/* Short Preamble Option Enable is TRUE */
+			((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||
+			((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) &&
+			(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) {
+
+			/* Case I: Implemented == TRUE and Short Preamble Option Enable == TRUE.
+			 * Case II: Implemented == TRUE and Short Preamble == AUTO (depends on
+			 *          BSS_DESC_T's capability)
+			 */
+			u2CapInfo |= CAP_INFO_SHORT_PREAMBLE;
+		}
+#if CFG_SUPPORT_SPEC_MGMT	/*Add by Enlai */
+		/* Support 802.11h */
+		if (prStaRec->u2CapInfo & CAP_INFO_SPEC_MGT) {
+			/*
+			   1.   The Power Capability element shall be present if
+			   dot11SpectrumManagementRequired is true.
+
+			   2.   A STA shall set dot11SpectrumManagementRequired to TRUE before
+			   associating with a BSS or IBSS in which the Spectrum Management
+			   bit is set to 1 in the Capability Information field in Beacon frames
+			   and Probe Response frames received from the BSS or IBSS.
+			 */
+			if (prAdapter->fgEnable5GBand == TRUE)
+				u2CapInfo |= CAP_INFO_SPEC_MGT;
+		}
+#endif
+
+		if (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented &&
+		    prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) {
+			u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
+		}
+	}
+
+	if (prStaRec) {
+		DBGLOG(SAA, LOUD, "ASSOC REQ: Compose Capability = 0x%04x for Target BSS [%pM].\n",
+				   u2CapInfo, prStaRec->aucMacAddr);
+	}
+
+	return u2CapInfo;
+
+}				/* end of assocBuildCapabilityInfo() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to compose Common Information Elements for Association
+*        Request Frame.
+*
+* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID assocBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_STA_RECORD_T prStaRec;
+	PUINT_8 pucBuffer;
+	UINT_16 u2SupportedRateSet;
+	UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 };
+	UINT_8 ucAllSupportedRatesLen;
+	UINT_8 ucSupRatesLen;
+	UINT_8 ucExtSupRatesLen;
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	ASSERT(prMsduInfo);
+	ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return;
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength);
+	ASSERT(pucBuffer);
+
+	if (IS_STA_IN_AIS(prStaRec)) {
+
+		/* Fill the SSID element. */
+		SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID;
+
+		/* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of
+		 * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame.
+		 */
+
+		COPY_SSID(SSID_IE(pucBuffer)->aucSSID,
+			  SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+		pucBuffer += IE_SIZE(pucBuffer);
+
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec)))
+		pucBuffer = p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, pucBuffer);
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+	else if (IS_STA_IN_BOW(prStaRec)) {
+
+		SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID;
+
+		/* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of
+		 * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame.
+		 */
+
+		COPY_SSID(SSID_IE(pucBuffer)->aucSSID,
+			  SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen);
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+		pucBuffer += IE_SIZE(pucBuffer);
+	}
+#endif
+	else {
+		/* Do nothing */
+		/* TODO(Kevin): For other network */
+	}
+
+	/* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication -
+	 * SupportedRates - The set of data rates that are supported by the STA
+	 * that is requesting association.
+	 * Original(Portable Driver): Only send the Rates that we'll support.
+	 * New: Send the Phy Rates if the result of following & operation == NULL.
+	 */
+	/* rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet & */
+	/* rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet), */
+
+	if (prStaRec->fgHasBasicPhyType) {
+		UINT_32 u4NonHTPhyType;
+
+		u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
+
+		u2SupportedRateSet = (prStaRec->u2OperationalRateSet &
+				      rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet);
+
+		ASSERT(u2SupportedRateSet);
+
+		if (!u2SupportedRateSet)
+			u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
+
+		/* TODO(Kevin): For P2P, we shouldn't send support rate set which contains 11b rate */
+
+		rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen);
+
+		ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ?
+				 ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen);
+
+		ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen;
+
+		/* Fill the Supported Rates element. */
+		if (ucSupRatesLen) {
+			SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES;
+			SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen;
+			kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen);
+
+			prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+			pucBuffer += IE_SIZE(pucBuffer);
+		}
+
+		/* Fill the Extended Supported Rates element. */
+		if (ucExtSupRatesLen) {
+
+			EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
+			EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen;
+
+			kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates,
+				   &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen);
+
+			prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+			pucBuffer += IE_SIZE(pucBuffer);
+		}
+
+		/* 7.3.2.19 Supported Channels element */
+#if CFG_SUPPORT_DFS		/* Add by Enlai */
+		if (prAdapter->fgEnable5GBand == TRUE) {
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS;
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucLength = 8;
+
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[0] = 36;
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[1] = 4;
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[2] = 52;
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[3] = 4;
+/* Not China --- Start */
+			/* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 100; */
+			/* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 11; */
+/* Not China --- End */
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 149;
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 4;
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[6] = 165;
+			SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[7] = 1;
+
+			prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+			pucBuffer += IE_SIZE(pucBuffer);
+		}
+#endif
+	}
+
+}				/* end of assocBuildReAssocReqFrameCommonIEs() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the (Re)Association Request frame header and
+*        its fixed fields
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] aucMACAddress          Given Our MAC Address.
+* @param[in out] pu2PayloadLen      Return the length of the composed fixed fields
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID
+assocComposeReAssocReqFrameHeaderAndFF(IN P_ADAPTER_T prAdapter,
+				       IN P_STA_RECORD_T prStaRec,
+				       IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN OUT PUINT_16 pu2PayloadLen)
+{
+	P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame;
+	BOOLEAN fgIsReAssoc;
+
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2CapInfo;
+	UINT_16 u2ListenInterval;
+
+	ASSERT(prStaRec);
+	ASSERT(pucBuffer);
+	ASSERT(aucMACAddress);
+	ASSERT(pu2PayloadLen);
+
+	prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) pucBuffer;
+	fgIsReAssoc = prStaRec->fgIsReAssoc;
+
+	/* 4 <1> Compose the frame header of the (Re)Association Request  frame. */
+	/* Fill the Frame Control field. */
+	if (fgIsReAssoc)
+		u2FrameCtrl = MAC_FRAME_REASSOC_REQ;
+	else
+		u2FrameCtrl = MAC_FRAME_ASSOC_REQ;
+	WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl);
+
+	/* Fill the DA field with Target BSSID. */
+	COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr);
+
+	/* Fill the SA field with our MAC Address. */
+	COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress);
+
+	/* Fill the BSSID field with Target BSSID. */
+	COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr);
+
+	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
+	prAssocFrame->u2SeqCtrl = 0;
+
+	/* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request  frame. */
+	u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
+
+	/* Fill the Capability Information field. */
+	WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo);
+
+	/* Calculate the listen interval for the maximum power mode. Currently, we
+	   set it to the value 2 times DTIM period. */
+	if (prStaRec->ucDTIMPeriod) {
+		u2ListenInterval = prStaRec->ucDTIMPeriod * DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD;
+	} else {
+		DBGLOG(SAA, TRACE, "Use default listen interval\n");
+		u2ListenInterval = DEFAULT_LISTEN_INTERVAL;
+	}
+	prStaRec->u2ListenInterval = u2ListenInterval;
+
+	/* Fill the Listen Interval field. */
+	WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval);
+
+	/* 4 <3> Compose the Current AP Address field for ReAssociation Request  frame. */
+	/* Fill the Current AP Address field. */
+	if (prStaRec->fgIsReAssoc) {
+		if (IS_STA_IN_AIS(prStaRec)) {
+
+			P_AIS_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+			P_WLAN_REASSOC_REQ_FRAME_T prReAssocFrame = (P_WLAN_REASSOC_REQ_FRAME_T) prAssocFrame;
+
+			COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, prAisBssInfo->aucBSSID);
+		} else {
+			ASSERT(0);	/* We don't support ReAssociation for other network */
+		}
+
+		*pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + CURR_AP_ADDR_FIELD_LEN);
+	} else {
+		*pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN);
+	}
+
+}				/* end of assocComposeReAssocReqFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send the (Re)Association Request frame
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
+* @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	P_BSS_INFO_T prBssInfo;
+
+	UINT_16 u2PayloadLen;
+	UINT_16 u2EstimatedFrameLen;
+	UINT_16 u2EstimatedExtraIELen;
+	BOOLEAN fgIsReAssoc;
+	UINT_32 i;
+
+	ASSERT(prStaRec);
+
+	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
+	fgIsReAssoc = prStaRec->fgIsReAssoc;
+
+	/* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */
+	if (fgIsReAssoc) {
+		u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD +
+		    WLAN_MAC_MGMT_HEADER_LEN +
+		    CAP_INFO_FIELD_LEN +
+		    LISTEN_INTERVAL_FIELD_LEN +
+		    CURR_AP_ADDR_FIELD_LEN +
+		    (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) +
+		    (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES));
+	} else {
+		u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD +
+		    WLAN_MAC_MGMT_HEADER_LEN +
+		    CAP_INFO_FIELD_LEN +
+		    LISTEN_INTERVAL_FIELD_LEN +
+		    (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) +
+		    (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES));
+	}
+
+	/* + Extra IE Length */
+	u2EstimatedExtraIELen = 0;
+
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT
+	if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
+		if ((prAdapter->fgIsP2PRegistered)) {
+			u2EstimatedExtraIELen = p2pCalculate_IEForAssocReq(prAdapter,
+									   prStaRec->ucNetTypeIndex, prStaRec);
+		} else {
+			DBGLOG(P2P, TRACE, "Function Linker Lost.\n");
+			ASSERT(FALSE);
+		}
+	} else {
+		for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
+			if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) {
+				u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen;
+			} else {
+				u2EstimatedExtraIELen +=
+				    (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter,
+											     prStaRec->ucNetTypeIndex,
+											     prStaRec);
+			}
+		}
+	}
+#else
+	for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
+		if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) {
+			u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen;
+		} else {
+			u2EstimatedExtraIELen += (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter,
+											  prStaRec->ucNetTypeIndex,
+											  prStaRec);
+		}
+	}
+#endif
+
+	u2EstimatedFrameLen += u2EstimatedExtraIELen;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(SAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Request.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	/* Compose Header and Fixed Field */
+	assocComposeReAssocReqFrameHeaderAndFF(prAdapter,
+					       prStaRec,
+					       (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+					       prBssInfo->aucOwnMacAddr, &u2PayloadLen);
+
+	/* 4 <3> Update information of MSDU_INFO_T */
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone;
+	prMsduInfo->fgIsBasicRate = TRUE;
+
+	/* 4 <4> Compose the frame body's IEs of the (Re)Association Request  frame. */
+	assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo);
+
+	/* 4 <5> Compose IEs in MSDU_INFO_T */
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT
+	if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
+		if ((prAdapter->fgIsP2PRegistered)) {
+			p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo);
+		} else {
+			DBGLOG(P2P, TRACE, "Function Linker Lost.\n");
+			ASSERT(FALSE);
+		}
+	} else {
+		/* Append IE */
+		for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
+			if (txAssocReqIETable[i].pfnAppendIE)
+				txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
+		}
+	}
+#else
+	/* Append IE */
+	for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
+		if (txAssocReqIETable[i].pfnAppendIE)
+			txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
+	}
+#endif
+
+	/* 4 <6> Update the (Re)association request information */
+	if (IS_STA_IN_AIS(prStaRec)) {
+		P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame;
+
+		prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+#if CFG_RSN_MIGRATION
+		kalUpdateReAssocReqInfo(prAdapter->prGlueInfo,
+					(PUINT_8) &prAssocFrame->u2CapInfo,
+					prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo),
+					fgIsReAssoc);
+#endif
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {
+		P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame;
+
+		prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+		kalP2PUpdateAssocInfo(prAdapter->prGlueInfo,
+				      (PUINT_8) &prAssocFrame->u2CapInfo,
+				      prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo),
+				      fgIsReAssoc);
+	}
+#endif
+
+	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
+
+	/* 4 <6> Enqueue the frame to send this (Re)Association request frame. */
+	DBGLOG(SAA, INFO, "Sending (Re)Assoc Request, network: %d seqNo: %d\n",
+		prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum);
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of assocSendReAssocReqFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will strictly check the TX (Re)Association Request frame for
+*        SAA event handling.
+*
+* @param[in] prMsduInfo         Pointer of MSDU_INFO_T
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2TxFrameCtrl;
+
+	ASSERT(prMsduInfo);
+	ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
+
+	prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) (prMsduInfo->prPacket);
+	ASSERT(prAssocReqFrame);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return WLAN_STATUS_INVALID_PACKET;
+	/* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl) */
+	u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+	u2TxFrameCtrl &= MASK_FRAME_TYPE;
+	if (prStaRec->fgIsReAssoc) {
+		if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ)
+			return WLAN_STATUS_FAILURE;
+	} else {
+		if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ)
+			return WLAN_STATUS_FAILURE;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of assocCheckTxReAssocReqFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will strictly check the TX (Re)Association Response frame for
+*        AAA event handling.
+*
+* @param[in] prMsduInfo         Pointer of MSDU_INFO_T
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame;
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2TxFrameCtrl;
+
+	ASSERT(prMsduInfo);
+	ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
+
+	prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) (prMsduInfo->prPacket);
+	ASSERT(prAssocRspFrame);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return WLAN_STATUS_INVALID_PACKET;
+	/* WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl) */
+	u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+	u2TxFrameCtrl &= MASK_FRAME_TYPE;
+	if (prStaRec->fgIsReAssoc) {
+		if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP)
+			return WLAN_STATUS_FAILURE;
+	} else {
+		if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP)
+			return WLAN_STATUS_FAILURE;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of assocCheckTxReAssocRespFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the incoming (Re)Association Frame and take out
+*        the status code.
+*
+* @param[in] prSwRfb                Pointer to SW RFB data structure.
+* @param[out] pu2StatusCode         Pointer to store the Status Code from Authentication.
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode)
+{
+	P_STA_RECORD_T prStaRec;
+	P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame;
+	UINT_16 u2RxFrameCtrl;
+	UINT_16 u2RxCapInfo;
+	UINT_16 u2RxStatusCode;
+	UINT_16 u2RxAssocId;
+
+	ASSERT(prSwRfb);
+	ASSERT(pu2StatusCode);
+
+	if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN +
+							     STATUS_CODE_FIELD_LEN + AID_FIELD_LEN)) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	DBGLOG(SAA, LOUD, "prSwRfb->u2PayloadLength = %d\n", prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return WLAN_STATUS_INVALID_PACKET;
+	/* 4 <1> locate the (Re)Association Resp Frame. */
+	prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader;
+
+	/* 4 <2> Parse the Header of (Re)Association Resp Frame. */
+	/* WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl); */
+	u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+	u2RxFrameCtrl &= MASK_FRAME_TYPE;
+	if (prStaRec->fgIsReAssoc) {
+		if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP)
+			return WLAN_STATUS_FAILURE;
+	} else {
+		if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP)
+			return WLAN_STATUS_FAILURE;
+	}
+
+	/* 4 <3> Parse the Fixed Fields of (Re)Association Resp Frame Body. */
+	/* WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo); */
+	u2RxCapInfo = prAssocRspFrame->u2CapInfo;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode); */
+	u2RxStatusCode = prAssocRspFrame->u2StatusCode;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* 4 <4> Check CAP_INFO */
+	/* NOTE(Kevin): CM suggest to add MGMT workaround for those APs didn't check
+	 * the CAP Privacy Bit to overcome a corner case that the Privacy Bit
+	 * of our SCAN result didn't consist with AP's Association Resp.
+	 */
+	if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) {
+#if CFG_SUPPORT_WAPI
+		if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
+			/* WAPI AP allow the customer use WZC to join mode, the privacy bit is 0 */
+			/* even at WAI & WAPI_PSK mode, but the assoc respose set the privacy bit set 1 */
+			DBGLOG(SEC, TRACE, "Workaround the WAPI AP allow the customer to use WZC to join\n");
+		} else
+#endif
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered && 1) {
+			/* Todo:: Fixed this */
+		} else
+#endif
+		{
+		}
+
+#if CFG_STRICT_CHECK_CAPINFO_PRIVACY
+		if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY))
+			u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED;
+#endif
+	}
+
+	if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) {
+#if CFG_RSN_MIGRATION
+		/* Update the information in the structure used to query and set
+		   OID_802_11_ASSOCIATION_INFORMATION. */
+		kalUpdateReAssocRspInfo(prAdapter->prGlueInfo,
+					(PUINT_8) &prAssocRspFrame->u2CapInfo, (UINT_32) (prSwRfb->u2PacketLen));
+#endif
+	}
+	/* 4 <5> Update CAP_INFO and ASSOC_ID */
+	if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) {
+		prStaRec->u2CapInfo = u2RxCapInfo;
+
+		/* WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, &u2RxAssocId); */
+		u2RxAssocId = prAssocRspFrame->u2AssocId;	/* NOTE(Kevin): Optimized for ARM */
+
+		/*  20110715 Workaround for Kingnet 710 AP (Realtek 8186)
+		 *   This AP raises the bit 6&7 not bit 14&15 in AID field.
+		 *   It cause wrong AID assignment.
+		 *   For AID = 2
+		 *     Normal case: 0xC002(1100 0000 0000 0010) => 2
+		 *     Kingnet 710:  0x00C2(0000 0000 1100 0010) => 194
+		 *     workaround: mask bit 6&7 for this AP
+		 */
+		if ((u2RxAssocId & BIT(6)) && (u2RxAssocId & BIT(7)) && !(u2RxAssocId & BITS(8, 15))) {
+			prStaRec->u2AssocId = u2RxAssocId & ~BITS(6, 7);
+		} else {
+			prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB;
+#if CFG_SUPPORT_802_11W
+			if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
+				P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
+
+				prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+				ASSERT(prBssSpecInfo);
+
+				prBssSpecInfo->ucSaQueryTimedOut = 0;
+			}
+#endif
+		}
+	}
+#if CFG_SUPPORT_802_11W
+	if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) {
+		DBGLOG(SAA, INFO, "AP rejected due the authentication algorithm not support\n");
+	} else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) {
+		PUINT_8 pucIE, pucTime;
+		UINT_16 u2IELength;
+		UINT_16 u2Offset = 0;
+
+		u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen;
+		pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen);
+
+		IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+			if (ELEM_ID_TIMEOUT_INTERVAL == IE_ID(pucIE) && IE_LEN(pucIE) == 5) {
+				pucTime = ((P_IE_HDR_T) pucIE)->aucInfo;
+				if (pucTime[0] == ACTION_SA_TIMEOUT_ASSOC_COMEBACK) {
+					UINT_32 tu;
+
+					WLAN_GET_FIELD_32(pucTime + 1, &tu);
+					DBGLOG(SAA, INFO,
+					       "AP rejected association temporarily;comeback duration %u TU (%u ms)\n",
+						tu, TU_TO_MSEC(tu));
+					if (tu > TX_ASSOCIATION_RETRY_TIMEOUT_TU) {
+						DBGLOG(SAA, INFO, "Update timer based on comeback duration\n");
+						/* ieee80211_reschedule_timer(wpa_s, ms); */
+					}
+				}
+				break;
+			}
+		}		/* end of IE_FOR_EACH */
+	}
+#endif
+	*pu2StatusCode = u2RxStatusCode;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of assocCheckRxReAssocRspFrameStatus() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will compose the Disassociation frame
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] aucMACAddress     Given Our MAC Address.
+* @param[in] u2ReasonCode      The reason code of disassociation
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID
+assocComposeDisassocFrame(IN P_STA_RECORD_T prStaRec,
+			  IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN UINT_16 u2ReasonCode)
+{
+	P_WLAN_DISASSOC_FRAME_T prDisAssocFrame;
+	UINT_16 u2FrameCtrl;
+
+	ASSERT(pucBuffer);
+	ASSERT(pucBuffer);
+	ASSERT(aucMACAddress);
+
+	prDisAssocFrame = (P_WLAN_DISASSOC_FRAME_T) pucBuffer;
+
+	/* 4 <1> Compose the frame header of the DisAssociation  frame. */
+	/* Fill the Frame Control field. */
+	u2FrameCtrl = MAC_FRAME_DISASSOC;
+
+	WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl);
+
+	/* Fill the DA field with Target BSSID. */
+	COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr);
+
+	/* Fill the SA field with our MAC Address. */
+	COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress);
+
+	/* Fill the BSSID field with Target BSSID. */
+	COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr);
+
+	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
+	prDisAssocFrame->u2SeqCtrl = 0;
+
+	/* 4 <2> Compose the frame body's fixed field part of the Disassociation frame. */
+	/* Fill the Reason Code field. */
+	WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode);
+
+}				/* end of assocComposeDisassocFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send the Disassociation frame
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+* @param[in] u2ReasonCode  The reason code of disassociation
+*
+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
+* @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode)
+{
+	PUINT_8 pucMacAddress;
+	P_MSDU_INFO_T prMsduInfo;
+	UINT_16 u2PayloadLen;
+	UINT_16 u2EstimatedFrameLen;
+	/* UINT_32 u4Status = WLAN_STATUS_SUCCESS; */
+
+	ASSERT(prStaRec);
+
+	/* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */
+	/* Init with MGMT Header Length + Length of Fixed Fields + IE Length */
+	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(SAA, WARN, "No PKT_INFO_T for sending DisAssoc.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose Disassociation  frame header and fixed fields in MSDU_INfO_T. */
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	pucMacAddress = prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].aucOwnMacAddr;
+
+	/* Compose Header and Fixed Field */
+	assocComposeDisassocFrame(prStaRec,
+				  (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+				  pucMacAddress, u2ReasonCode);
+
+#if CFG_SUPPORT_802_11W
+	if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+		P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
+
+		prDisassocFrame =
+		    (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+		prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+		DBGLOG(TX, WARN, "assocSendDisAssocFrame with protection\n");
+	}
+#endif
+
+	u2PayloadLen = REASON_CODE_FIELD_LEN;
+
+	/* 4 <3> Update information of MSDU_INFO_T */
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = NULL;
+	prMsduInfo->fgIsBasicRate = TRUE;
+
+	/* 4 <4> Enqueue the frame to send this (Re)Association request frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of assocSendDisAssocFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will parse and process the incoming Disassociation frame
+*        if the given BSSID is matched.
+*
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[in] aucBSSID           Given BSSID
+* @param[out] pu2ReasonCode     Pointer to store the Reason Code from Deauthentication.
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter,
+			    IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode)
+{
+	P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
+	UINT_16 u2RxReasonCode;
+
+	ASSERT(prSwRfb);
+	ASSERT(aucBSSID);
+	ASSERT(pu2ReasonCode);
+
+	/* 4 <1> locate the Disassociation Frame. */
+	prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader;
+
+	/* 4 <2> Parse the Header of Disassociation Frame. */
+	if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	/* Check if this Disassoc Frame is coming from Target BSSID */
+	if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) {
+		DBGLOG(SAA, LOUD, "Ignore Disassoc Frame from other BSS [ %pM ]\n",
+				   prDisassocFrame->aucSrcAddr);
+		return WLAN_STATUS_FAILURE;
+	}
+	/* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */
+	WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode);
+	*pu2ReasonCode = u2RxReasonCode;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of assocProcessRxDisassocFrame() */
+
+#if CFG_SUPPORT_AAA
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will parse and process the incoming Association Req frame
+*        and return a Status Code.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu2StatusCode     Pointer to store the Status Code for carried in Association Response.
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode)
+{
+	P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
+	P_STA_RECORD_T prStaRec;
+	P_BSS_INFO_T prBssInfo;
+	P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
+	P_RSN_INFO_ELEM_T prIeRsn = (P_RSN_INFO_ELEM_T) NULL;
+	P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL;
+	P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL;
+	PUINT_8 pucIE, pucIEStart;
+	UINT_16 u2IELength;
+	UINT_16 u2Offset = 0;
+	UINT_16 u2StatusCode = STATUS_CODE_SUCCESSFUL;
+	UINT_16 u2RxFrameCtrl;
+	UINT_16 u2BSSBasicRateSet;
+	BOOLEAN fgIsUnknownBssBasicRate;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+	ASSERT(pu2StatusCode);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+	if (prStaRec == NULL)
+		return WLAN_STATUS_FAILURE;
+	/* 4 <1> locate the Association Req Frame. */
+	prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
+
+	/* 4 <2> Parse the Header of Association Req Frame. */
+	if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN)) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	/* Check if this Disassoc Frame is coming from Target BSSID */
+	if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID))
+		return WLAN_STATUS_FAILURE;	/* Just Ignore this MMPDU */
+	/* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2RxFrameCtrl); */
+	u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+	u2RxFrameCtrl &= MASK_FRAME_TYPE;
+	if (MAC_FRAME_REASSOC_REQ == u2RxFrameCtrl) {
+		prStaRec->fgIsReAssoc = TRUE;
+
+		u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
+		    (UINT_16) (OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN);
+
+		pucIEStart = pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem;
+	} else {
+		prStaRec->fgIsReAssoc = FALSE;
+
+		u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
+		    (UINT_16) (OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN);
+
+		pucIEStart = pucIE = prAssocReqFrame->aucInfoElem;
+	}
+
+	/* 4 <3> Parse the Fixed Fields of Assoc Req Frame Body. */
+	prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo;
+
+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK
+	if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
+		if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) && !kalP2PGetCipher(prAdapter->prGlueInfo))) {
+			u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED;
+			DBGLOG(RSN, TRACE, "STA Assoc req privacy bit check fail\n");
+			return WLAN_STATUS_SUCCESS;
+		}
+	}
+#endif
+
+	prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval;
+	prStaRec->ucPhyTypeSet = 0;
+
+	/* Might be legacy client or p2p gc. */
+	prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT;
+
+	/* 4 <4> Parse the IE of Assoc Req Frame Body. */
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_SSID:
+			if ((!prIeSsid) &&	/* NOTE(Kevin): Get SSID once */
+			    (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
+				prIeSsid = (P_IE_SSID_T) pucIE;
+			}
+			break;
+
+		case ELEM_ID_SUP_RATES:
+			if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM))
+				prIeSupportedRate = SUP_RATES_IE(pucIE);
+			break;
+
+		case ELEM_ID_EXTENDED_SUP_RATES:
+			if (!prIeExtSupportedRate)
+				prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
+			break;
+		case ELEM_ID_HT_CAP:
+			prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
+			kalMemCopy(&prStaRec->u2HtCapInfo, &(HT_CAP_IE(pucIE)->u2HtCapInfo), 2);
+			break;
+		case ELEM_ID_RSN:
+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK
+			if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
+				prIeRsn = RSN_IE(pucIE);
+				rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode);
+				if (u2StatusCode != STATUS_CODE_SUCCESSFUL) {
+					*pu2StatusCode = u2StatusCode;
+					return WLAN_STATUS_SUCCESS;
+				}
+			}
+#endif
+			break;
+		case ELEM_ID_VENDOR:
+#if CFG_ENABLE_WIFI_DIRECT
+			{
+				if ((prAdapter->fgIsP2PRegistered)) {
+					UINT_8 ucOuiType = 0;
+
+					p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType);
+
+					if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
+						DBGLOG(P2P, TRACE, "Target Client is a P2P group client\n");
+						prStaRec->eStaType = STA_TYPE_P2P_GC;
+					}
+				}
+			}
+#endif
+			break;
+		default:
+			for (i = 0; i < (sizeof(rxAssocReqIETable) / sizeof(VERIFY_IE_ENTRY_T)); i++) {
+
+				if ((IE_ID(pucIE)) == rxAssocReqIETable[i].ucElemID) {
+					rxAssocReqIETable[i].pfnVarifyIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIE,
+									 &u2StatusCode);
+
+					if (u2StatusCode != STATUS_CODE_SUCCESSFUL) {
+						*pu2StatusCode = u2StatusCode;
+						return WLAN_STATUS_SUCCESS;
+					}
+				}
+			}
+
+			break;
+		}
+	}			/* end of IE_FOR_EACH */
+
+	/* parsing for WMM related information (2010/12/21) */
+	mqmProcessAssocReq(prAdapter, prSwRfb, pucIEStart, u2IELength);
+
+	do {
+		if (prIeSsid) {
+			if (UNEQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen,
+					 prIeSsid->aucSSID, prIeSsid->ucLength)) {
+
+				u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE;
+				break;
+			}
+		} else {
+			u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE;
+			break;
+		}
+
+		prStaRec->u2OperationalRateSet = 0;
+		prStaRec->u2BSSBasicRateSet = 0;
+
+		if (prIeSupportedRate || prIeExtSupportedRate) {
+			rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, &prStaRec->u2OperationalRateSet,
+						&u2BSSBasicRateSet,	/* Ignore any Basic Bit */
+						&fgIsUnknownBssBasicRate);
+
+			if ((prBssInfo->u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) !=
+			    prBssInfo->u2BSSBasicRateSet) {
+
+				u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED;
+				break;
+			}
+
+			/* Accpet the Sta, update BSSBasicRateSet from Bss */
+
+			prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet;
+
+			prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG);
+
+			if (BAND_2G4 == HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr)) {
+#if 0				/* Marked by CMC 20111024 */
+				/* check if support 11n */
+				if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
+
+					if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM)
+						prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
+
+					if ((!(u2BSSBasicRateSet & RATE_SET_OFDM)) &&
+						(prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS)) {
+							prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
+
+					}
+
+				}
+#else
+				if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM)
+					prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
+				if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS)
+					prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
+#endif
+			} else {	/* (BAND_5G == prBssDesc->eBande) */
+#if 0				/* Marked by CMC 20111024 */
+				if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY))
+					prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
+				ASSERT((prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) == 0);
+#else
+				if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM)
+					prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
+#endif
+			}
+
+		} else {
+			ASSERT(0);
+			u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED;
+			break;
+		}
+
+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK
+		if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
+			if (prIeRsn) {
+				if (!kalP2PGetCipher(prAdapter->prGlueInfo)) {
+					u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED;
+					break;
+				}
+			} else {
+				prStaRec->rSecInfo.fgAllowOnly1x = FALSE;
+				if (kalP2PGetCipher(prAdapter->prGlueInfo)) {
+					/* Only Allow 1x */
+					prStaRec->rSecInfo.fgAllowOnly1x = TRUE;
+					break;
+				}
+			}
+		}
+#endif
+
+	} while (FALSE);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
+#if 1				/* ICS */
+		{
+			PUINT_8 cp = (PUINT_8) &prAssocReqFrame->u2CapInfo;
+			P_UINT_8 prNewAssocReqIe = NULL;
+
+			if (u2IELength) {
+				prNewAssocReqIe = kalMemAlloc(u2IELength, VIR_MEM_TYPE);
+				if (NULL == prNewAssocReqIe) {
+					DBGLOG(AIS, WARN, "allocate memory for (Re)assocReqIe fail!\n");
+					u2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
+					return WLAN_STATUS_FAILURE;
+				}
+			}
+
+			if (prStaRec->fgIsReAssoc)
+				cp += 10;
+			else
+				cp += 4;
+			if (prStaRec->pucAssocReqIe) {
+				kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
+				prStaRec->pucAssocReqIe = NULL;
+			}
+			prStaRec->u2AssocReqIeLen = u2IELength;
+			if (u2IELength) {
+				prStaRec->pucAssocReqIe = prNewAssocReqIe; /* kalMemAlloc(u2IELength, VIR_MEM_TYPE); */
+				kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength);
+			}
+		}
+#endif
+		kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8) &prAssocReqFrame->u2CapInfo,
+				      u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc);
+	}
+#endif
+
+	*pu2StatusCode = u2StatusCode;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of assocProcessRxAssocReqFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to compose Common Information Elements for Association
+*        Response Frame.
+*
+* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
+* @param[in] prBssInfo      Pointer to the BSS_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID
+assocBuildReAssocRespFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo)
+{
+	PUINT_8 pucBuffer;
+	P_STA_RECORD_T prStaRec;
+	UINT_8 ucSupRatesLen;
+	UINT_8 ucExtSupRatesLen;
+
+	ASSERT(prMsduInfo);
+	ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	ASSERT(prStaRec);
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+	ASSERT(pucBuffer);
+
+	if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) {
+
+		ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES;
+		ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES;
+	} else {
+		ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen;
+		ucExtSupRatesLen = 0;
+	}
+
+	/* Fill the Supported Rates element. */
+	if (ucSupRatesLen) {
+		SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES;
+		SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen;
+		kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen);
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+		pucBuffer += IE_SIZE(pucBuffer);
+	}
+
+	/* Fill the Extended Supported Rates element. */
+	if (ucExtSupRatesLen) {
+
+		EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
+		EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen;
+
+		kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates,
+			   &prBssInfo->aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen);
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+	}
+
+}				/* end of assocBuildReAssocRespFrameCommonIEs() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the (Re)Association Response frame
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] aucBssid               Given BSSID.
+* @param[in] u2CapInfo              Capability Field of current BSS.
+* @param[in out] pu2PayloadLen      Return the length of the composed fixed fields
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID
+assocComposeReAssocRespFrameHeaderAndFF(IN P_STA_RECORD_T prStaRec,
+					IN PUINT_8 pucBuffer,
+					IN UINT_8 aucBSSID[], IN UINT_16 u2CapInfo, IN OUT PUINT_16 pu2PayloadLen)
+{
+	P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame;
+	BOOLEAN fgIsReAssoc;
+
+	UINT_16 u2FrameCtrl;
+
+	ASSERT(prStaRec);
+	ASSERT(pucBuffer);
+	ASSERT(aucBSSID);
+	ASSERT(pu2PayloadLen);
+
+	prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) pucBuffer;
+	fgIsReAssoc = prStaRec->fgIsReAssoc;
+
+	/* 4 <1> Compose the frame header of the (Re)Association Request  frame. */
+	/* Fill the Frame Control field. */
+	if (fgIsReAssoc)
+		u2FrameCtrl = MAC_FRAME_REASSOC_RSP;
+	else
+		u2FrameCtrl = MAC_FRAME_ASSOC_RSP;
+	/* WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); */
+	prAssocRspFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the DA field with Target MAC Address. */
+	COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr);
+
+	/* Fill the SA field with current BSSID. */
+	COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID);
+
+	/* Fill the BSSID field with current BSSID. */
+	COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID);
+
+	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
+	prAssocRspFrame->u2SeqCtrl = 0;
+
+	/* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request  frame. */
+	/* Fill the Capability Information field. */
+	/* WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); */
+	prAssocRspFrame->u2CapInfo = u2CapInfo;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, prStaRec->u2StatusCode); */
+	prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, ((prStaRec->u2AssocId & AID_MASK) | AID_MSB)); */
+	prAssocRspFrame->u2AssocId = ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); /* NOTE(Kevin): Optimized for ARM */
+
+	*pu2PayloadLen = (CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN);
+
+}				/* end of assocComposeReAssocRespFrameHeaderAndFF() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send the (Re)Association Resp frame
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
+* @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_MSDU_INFO_T prMsduInfo;
+
+	UINT_16 u2PayloadLen;
+	UINT_16 u2EstimatedFrameLen;
+	UINT_16 u2EstimatedExtraIELen;
+	BOOLEAN fgIsReAssoc;
+	UINT_32 i;
+
+	ASSERT(prStaRec);
+
+	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
+	fgIsReAssoc = prStaRec->fgIsReAssoc;
+
+	/* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */
+	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD +
+	    WLAN_MAC_MGMT_HEADER_LEN +
+	    CAP_INFO_FIELD_LEN +
+	    STATUS_CODE_FIELD_LEN +
+	    AID_FIELD_LEN +
+	    (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES));
+
+	/* + Extra IE Length */
+	u2EstimatedExtraIELen = 0;
+
+	for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
+		if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) {
+			u2EstimatedExtraIELen += txAssocRespIETable[i].u2EstimatedFixedIELen;
+		} else if (txAssocRespIETable[i].pfnCalculateVariableIELen != NULL) {
+			u2EstimatedExtraIELen += (UINT_16) txAssocRespIETable[i].pfnCalculateVariableIELen(prAdapter,
+											   prStaRec->ucNetTypeIndex,
+											   prStaRec);
+		}
+
+	}
+
+	u2EstimatedFrameLen += u2EstimatedExtraIELen;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(AAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Response.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */
+	ASSERT(prStaRec->ucNetTypeIndex != NETWORK_TYPE_AIS_INDEX);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	/* Compose Header and Fixed Field */
+	assocComposeReAssocRespFrameHeaderAndFF(prStaRec,
+						(PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+						prBssInfo->aucBSSID, prBssInfo->u2CapInfo, &u2PayloadLen);
+
+	/* 4 <3> Update information of MSDU_INFO_T */
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = aaaFsmRunEventTxDone;
+	prMsduInfo->fgIsBasicRate = TRUE;
+
+	/* 4 <4> Compose the frame body's IEs of the (Re)Association Request  frame. */
+	assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo);
+
+	/* 4 <5> Compose IEs in MSDU_INFO_T */
+
+	/* Append IE */
+	for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
+		if (txAssocRespIETable[i].pfnAppendIE)
+			txAssocRespIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
+	}
+
+	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
+
+	/* 4 <6> Enqueue the frame to send this (Re)Association request frame. */
+	DBGLOG(SAA, INFO, "Sending (Re)Assoc Response, network: %d seqNo: %d\n",
+			prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum);
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of assocSendReAssocRespFrame() */
+#endif /* CFG_SUPPORT_AAA */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c
new file mode 100644
index 0000000000000..43b91d72bd431
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c
@@ -0,0 +1,1211 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1
+*/
+
+/*! \file   "auth.c"
+    \brief  This file includes the authentication-related functions.
+
+    This file includes the authentication-related functions.
+*/
+
+/*
+** Log: auth.c
+ *
+ * 02 13 2012 cp.wu
+ * NULL
+ * show error message only instead of raise assertion when
+ * received authentication frame is carrying illegal parameters.
+ *
+ * 11 09 2011 yuche.tsai
+ * NULL
+ * Fix a network index & station record index issue when TX deauth frame.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 06 22 2011 yuche.tsai
+ * NULL
+ * Fix coding error.
+ *
+ * 06 20 2011 yuche.tsai
+ * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature.
+ * BC deauth support.
+ *
+ * 04 21 2011 terry.wu
+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
+ * Add network type parameter to authSendAuthFrame.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW short range mode.
+ *
+ * 02 08 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * 1. Fix Service Disocvery Logical issue.
+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station.
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 21 2011 terry.wu
+ * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode
+ * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * use definition macro to replace hard-coded constant
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
+ * There is no CFG_SUPPORT_BOW in driver domain source.
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 28 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * send MMPDU in basic rate.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * specify correct value for management frames.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 05 28 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T
+ *
+ * 05 24 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Check Net is active before sending Deauth frame.
+ *
+ * 05 24 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval.
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Send Deauth for Class 3 Error and Leave Network Support
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Fix compile warning
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add debug message for abnormal authentication frame from AP
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 07 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ * Fix the Debug Label
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 7 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Update the authComposeAuthFrameHeader()
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the send deauth frame function
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Integrate send Auth with TXM
+ *
+ * Nov 24 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Revise MGMT Handler with Retain Status
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+APPEND_IE_ENTRY_T txAuthIETable[] = {
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText}
+};
+
+HANDLE_IE_ENTRY_T rxAuthIETable[] = {
+	{ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText}
+};
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the Authentication frame header and fixed fields.
+*
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] aucPeerMACAddress      Given Peer MAC Address.
+* @param[in] aucMACAddress          Given Our MAC Address.
+* @param[in] u2AuthAlgNum           Authentication Algorithm Number
+* @param[in] u2TransactionSeqNum    Transaction Sequence Number
+* @param[in] u2StatusCode           Status Code
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID
+authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer,
+				IN UINT_8 aucPeerMACAddress[],
+				IN UINT_8 aucMACAddress[],
+				IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode)
+{
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	UINT_16 u2FrameCtrl;
+
+	ASSERT(pucBuffer);
+	ASSERT(aucPeerMACAddress);
+	ASSERT(aucMACAddress);
+
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer;
+
+	/* 4 <1> Compose the frame header of the Authentication frame. */
+	/* Fill the Frame Control field. */
+	u2FrameCtrl = MAC_FRAME_AUTH;
+
+	/* If this frame is the third frame in the shared key authentication
+	 * sequence, it shall be encrypted.
+	 */
+	if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3))
+		u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;	/* HW will also detect this bit for applying encryption */
+	/* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */
+	prAuthFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the DA field with Target BSSID. */
+	COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress);
+
+	/* Fill the SA field with our MAC Address. */
+	COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress);
+
+	switch (u2TransactionSeqNum) {
+	case AUTH_TRANSACTION_SEQ_1:
+	case AUTH_TRANSACTION_SEQ_3:
+
+		/* Fill the BSSID field with Target BSSID. */
+		COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress);
+		break;
+
+	case AUTH_TRANSACTION_SEQ_2:
+	case AUTH_TRANSACTION_SEQ_4:
+
+		/* Fill the BSSID field with Current BSSID. */
+		COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress);
+		break;
+
+	default:
+		ASSERT(0);
+	}
+
+	/* Clear the SEQ/FRAG_NO field. */
+	prAuthFrame->u2SeqCtrl = 0;
+
+	/* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */
+	/* Fill the Authentication Algorithm Number field. */
+	/* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */
+	prAuthFrame->u2AuthAlgNum = u2AuthAlgNum;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the Authentication Transaction Sequence Number field. */
+	/* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */
+	prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the Status Code field. */
+	/* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */
+	prAuthFrame->u2StatusCode = u2StatusCode;	/* NOTE(Kevin): Optimized for ARM */
+
+}				/* end of authComposeAuthFrameHeaderAndFF() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will append Challenge Text IE to the Authentication frame
+*
+* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo)
+{
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2TransactionSeqNum;
+
+	ASSERT(prMsduInfo);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if (!prStaRec)
+		return;
+
+	ASSERT(prStaRec);
+
+	/* For Management, frame header and payload are in a continuous buffer */
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket;
+
+	WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum)
+
+	    /* Only consider SEQ_3 for Challenge Text */
+	    if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) &&
+		(prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) {
+
+		COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText));
+
+		prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText);
+	}
+
+	return;
+
+}				/* end of authAddIEChallengeText() */
+
+#if !CFG_SUPPORT_AAA
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send the Authenticiation frame
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+* @param[in] u2TransactionSeqNum    Transaction Sequence Number
+*
+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
+* @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	P_BSS_INFO_T prBssInfo;
+	UINT_16 u2EstimatedFrameLen;
+	UINT_16 u2EstimatedExtraIELen;
+	UINT_16 u2PayloadLen;
+	UINT_32 i;
+
+	DBGLOG(SAA, LOUD, "Send Auth Frame\n");
+
+	ASSERT(prStaRec);
+
+	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
+	/* Init with MGMT Header Length + Length of Fixed Fields */
+	u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
+			       WLAN_MAC_MGMT_HEADER_LEN +
+			       AUTH_ALGORITHM_NUM_FIELD_LEN +
+			       AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
+
+	/* + Extra IE Length */
+	u2EstimatedExtraIELen = 0;
+
+	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++)
+		u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
+
+	u2EstimatedFrameLen += u2EstimatedExtraIELen;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	/* Compose Header and some Fixed Fields */
+	authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+					prStaRec->aucMacAddr,
+					prBssInfo->aucOwnMacAddr,
+					prStaRec->ucAuthAlgNum, u2TransactionSeqNum, STATUS_CODE_RESERVED);
+
+	u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
+
+	/* 4 <3> Update information of MSDU_INFO_T */
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone;
+	prMsduInfo->fgIsBasicRate = TRUE;
+
+	/* 4 <4> Compose IEs in MSDU_INFO_T */
+	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
+		if (txAuthIETable[i].pfnAppendIE)
+			txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
+	}
+
+	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
+
+	/* 4 <6> Inform TXM  to send this Authentication frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of authSendAuthFrame() */
+
+#else
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send the Authenticiation frame
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+* @param[in] u2TransactionSeqNum    Transaction Sequence Number
+*
+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
+* @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+authSendAuthFrame(IN P_ADAPTER_T prAdapter,
+		  IN P_STA_RECORD_T prStaRec,
+		  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+		  IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode)
+{
+	PUINT_8 pucReceiveAddr;
+	PUINT_8 pucTransmitAddr;
+	P_MSDU_INFO_T prMsduInfo;
+	P_BSS_INFO_T prBssInfo;
+	/*get from input parameter */
+	/* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */
+	PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL;
+	UINT_16 u2EstimatedFrameLen;
+	UINT_16 u2EstimatedExtraIELen;
+	UINT_16 u2PayloadLen;
+	UINT_16 ucAuthAlgNum;
+	UINT_32 i;
+
+	DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode);
+
+	/* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
+	/* Init with MGMT Header Length + Length of Fixed Fields */
+	u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
+			       WLAN_MAC_MGMT_HEADER_LEN +
+			       AUTH_ALGORITHM_NUM_FIELD_LEN +
+			       AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
+
+	/* + Extra IE Length */
+	u2EstimatedExtraIELen = 0;
+
+	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++)
+		u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
+
+	u2EstimatedFrameLen += u2EstimatedExtraIELen;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
+	if (prStaRec) {
+		ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+		pucTransmitAddr = prBssInfo->aucOwnMacAddr;
+
+		pucReceiveAddr = prStaRec->aucMacAddr;
+
+		ucAuthAlgNum = prStaRec->ucAuthAlgNum;
+
+		switch (u2TransactionSeqNum) {
+		case AUTH_TRANSACTION_SEQ_1:
+		case AUTH_TRANSACTION_SEQ_3:
+			pfTxDoneHandler = saaFsmRunEventTxDone;
+			break;
+
+		case AUTH_TRANSACTION_SEQ_2:
+		case AUTH_TRANSACTION_SEQ_4:
+			pfTxDoneHandler = aaaFsmRunEventTxDone;
+			break;
+		}
+
+	} else {		/* For Error Status Code */
+		P_WLAN_AUTH_FRAME_T prFalseAuthFrame;
+
+		ASSERT(prFalseAuthSwRfb);
+		prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader;
+
+		ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL);
+
+		pucTransmitAddr = prFalseAuthFrame->aucDestAddr;
+
+		pucReceiveAddr = prFalseAuthFrame->aucSrcAddr;
+
+		ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum;
+
+		u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1);
+	}
+
+	/* Compose Header and some Fixed Fields */
+	authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+					pucReceiveAddr,
+					pucTransmitAddr, ucAuthAlgNum, u2TransactionSeqNum, u2StatusCode);
+
+	u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
+
+	/* 4 <3> Update information of MSDU_INFO_T */
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	if (prStaRec)
+		prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	else
+		prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND;	/* false Auth frame */
+	prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
+	prMsduInfo->fgIsBasicRate = TRUE;
+
+	/* 4 <4> Compose IEs in MSDU_INFO_T */
+	for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
+		if (txAuthIETable[i].pfnAppendIE)
+			txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
+	}
+
+	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
+
+	/* 4 <6> Inform TXM  to send this Authentication frame. */
+	DBGLOG(SAA, INFO, "network: %d Send Auth Frame %d, Status Code = %d seq num %d\n",
+		eNetTypeIndex, u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum);
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of authSendAuthFrame() */
+
+#endif /* CFG_SUPPORT_AAA */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will strictly check the TX Authentication frame for SAA/AAA event
+*        handling.
+*
+* @param[in] prMsduInfo             Pointer of MSDU_INFO_T
+* @param[in] u2TransactionSeqNum    Transaction Sequence Number
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum)
+{
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2TxFrameCtrl;
+	UINT_16 u2TxAuthAlgNum;
+	UINT_16 u2TxTransactionSeqNum;
+
+	ASSERT(prMsduInfo);
+
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) (prMsduInfo->prPacket);
+	ASSERT(prAuthFrame);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return WLAN_STATUS_INVALID_PACKET;
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */
+	u2TxFrameCtrl = prAuthFrame->u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+	u2TxFrameCtrl &= MASK_FRAME_TYPE;
+	if (u2TxFrameCtrl != MAC_FRAME_AUTH)
+		return WLAN_STATUS_FAILURE;
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */
+	u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum;	/* NOTE(Kevin): Optimized for ARM */
+	if (u2TxAuthAlgNum != (UINT_16) (prStaRec->ucAuthAlgNum))
+		return WLAN_STATUS_FAILURE;
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum) */
+	u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo;	/* NOTE(Kevin): Optimized for ARM */
+	if (u2TxTransactionSeqNum != u2TransactionSeqNum)
+		return WLAN_STATUS_FAILURE;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of authCheckTxAuthFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will check the incoming Auth Frame's Transaction Sequence
+*        Number before delivering it to the corresponding SAA or AAA Module.
+*
+* @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Always not retain authentication frames
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	UINT_16 u2RxTransactionSeqNum;
+
+	ASSERT(prSwRfb);
+
+	/* 4 <1> locate the Authentication Frame. */
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
+
+	/* 4 <2> Parse the Header of Authentication Frame. */
+	if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN +
+							     AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
+							     STATUS_CODE_FIELD_LEN)) {
+		ASSERT(0);
+		return WLAN_STATUS_SUCCESS;
+	}
+	/* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */
+	u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo;	/* NOTE(Kevin): Optimized for ARM */
+
+	switch (u2RxTransactionSeqNum) {
+	case AUTH_TRANSACTION_SEQ_2:
+	case AUTH_TRANSACTION_SEQ_4:
+		saaFsmRunEventRxAuth(prAdapter, prSwRfb);
+		break;
+
+	case AUTH_TRANSACTION_SEQ_1:
+	case AUTH_TRANSACTION_SEQ_3:
+#if CFG_SUPPORT_AAA
+		aaaFsmRunEventRxAuth(prAdapter, prSwRfb);
+#endif /* CFG_SUPPORT_AAA */
+		break;
+
+	default:
+		DBGLOG(SAA, WARN, "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n",
+				   u2RxTransactionSeqNum, prAuthFrame->u2StatusCode);
+		break;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of authCheckRxAuthFrameTransSeq() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the incoming Authentication Frame and take
+*        the status code out.
+*
+* @param[in] prSwRfb                Pointer to SW RFB data structure.
+* @param[in] u2TransactionSeqNum    Transaction Sequence Number
+* @param[out] pu2StatusCode         Pointer to store the Status Code from Authentication.
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter,
+			   IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode)
+{
+	P_STA_RECORD_T prStaRec;
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	UINT_16 u2RxAuthAlgNum;
+	UINT_16 u2RxTransactionSeqNum;
+	/* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */
+
+	ASSERT(prSwRfb);
+	ASSERT(pu2StatusCode);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return WLAN_STATUS_INVALID_PACKET;
+	/* 4 <1> locate the Authentication Frame. */
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
+
+	/* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */
+	u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum;	/* NOTE(Kevin): Optimized for ARM */
+	if (u2RxAuthAlgNum != (UINT_16) prStaRec->ucAuthAlgNum) {
+		DBGLOG(SAA, WARN, "Discard Auth frame with auth type = %d, current = %d\n",
+				   u2RxAuthAlgNum, prStaRec->ucAuthAlgNum);
+		*pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED;
+		return WLAN_STATUS_SUCCESS;
+	}
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */
+	u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo;	/* NOTE(Kevin): Optimized for ARM */
+	if (u2RxTransactionSeqNum != u2TransactionSeqNum) {
+		DBGLOG(SAA, WARN, "Discard Auth frame with Transaction Seq No = %d\n", u2RxTransactionSeqNum);
+		*pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ;
+		return WLAN_STATUS_SUCCESS;
+	}
+	/* 4 <3> Get the Status code */
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */
+	/* *pu2StatusCode = u2RxStatusCode; */
+	*pu2StatusCode = prAuthFrame->u2StatusCode;	/* NOTE(Kevin): Optimized for ARM */
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of authCheckRxAuthFrameStatus() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Challenge Text IE from the Authentication frame
+*
+* @param[in] prSwRfb                Pointer to SW RFB data structure.
+* @param[in] prIEHdr                Pointer to start address of IE
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr)
+{
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2TransactionSeqNum;
+
+	ASSERT(prSwRfb);
+	ASSERT(prIEHdr);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return;
+
+	/* For Management, frame header and payload are in a continuous buffer */
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
+
+	/* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) */
+	u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Only consider SEQ_2 for Challenge Text */
+	if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) &&
+	    (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) {
+
+		/* Free previous allocated TCM memory */
+		if (prStaRec->prChallengeText) {
+			ASSERT(0);
+			cnmMemFree(prAdapter, prStaRec->prChallengeText);
+			prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL;
+		}
+
+		prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr));
+		if (prStaRec->prChallengeText == NULL)
+			return;
+
+		/* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */
+		COPY_IE(prStaRec->prChallengeText, prIEHdr);
+	}
+
+	return;
+
+}				/* end of authAddIEChallengeText() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will parse and process the incoming Authentication frame.
+*
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+*
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	PUINT_8 pucIEsBuffer;
+	UINT_16 u2IEsLen;
+	UINT_16 u2Offset;
+	UINT_8 ucIEID;
+	UINT_32 i;
+
+	ASSERT(prSwRfb);
+
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
+
+	pucIEsBuffer = &prAuthFrame->aucInfoElem[0];
+	u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
+	    (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
+
+	IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) {
+		ucIEID = IE_ID(pucIEsBuffer);
+
+		for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) {
+
+			if (ucIEID == rxAuthIETable[i].ucElemID)
+				rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIEsBuffer);
+		}
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of authProcessRxAuth2_Auth4Frame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the Deauthentication frame
+*
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] aucPeerMACAddress      Given Peer MAC Address.
+* @param[in] aucMACAddress          Given Our MAC Address.
+* @param[in] u2StatusCode           Status Code
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID
+authComposeDeauthFrameHeaderAndFF(IN PUINT_8 pucBuffer,
+				  IN UINT_8 aucPeerMACAddress[],
+				  IN UINT_8 aucMACAddress[], IN UINT_8 aucBssid[], IN UINT_16 u2ReasonCode)
+{
+	P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
+	UINT_16 u2FrameCtrl;
+
+	ASSERT(pucBuffer);
+	ASSERT(aucPeerMACAddress);
+	ASSERT(aucMACAddress);
+	ASSERT(aucBssid);
+
+	prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) pucBuffer;
+
+	/* 4 <1> Compose the frame header of the Deauthentication frame. */
+	/* Fill the Frame Control field. */
+	u2FrameCtrl = MAC_FRAME_DEAUTH;
+
+	/* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */
+	prDeauthFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the DA field with Target BSSID. */
+	COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress);
+
+	/* Fill the SA field with our MAC Address. */
+	COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress);
+
+	/* Fill the BSSID field with Target BSSID. */
+	COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid);
+
+	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
+	prDeauthFrame->u2SeqCtrl = 0;
+
+	/* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */
+	/* Fill the Status Code field. */
+	/* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */
+	prDeauthFrame->u2ReasonCode = u2ReasonCode;	/* NOTE(Kevin): Optimized for ARM */
+
+}				/* end of authComposeDeauthFrameHeaderAndFF() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send the Deauthenticiation frame
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+* @param[in] prClassErrSwRfb    Pointer to the SW_RFB_T which is Class Error.
+* @param[in] u2ReasonCode       A reason code to indicate why to leave BSS.
+* @param[in] pfTxDoneHandler    TX Done call back function
+*
+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
+* @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
+* @retval WLAN_STATUS_FAILURE   Didn't send Deauth frame for various reasons.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+authSendDeauthFrame(IN P_ADAPTER_T prAdapter,
+		    IN P_STA_RECORD_T prStaRec,
+		    IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
+{
+	P_WLAN_MAC_HEADER_A4_T prWlanMacHeader = NULL;
+	PUINT_8 pucReceiveAddr;
+	PUINT_8 pucTransmitAddr;
+	PUINT_8 pucBssid = NULL;
+
+	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+	P_MSDU_INFO_T prMsduInfo;
+	UINT_16 u2EstimatedFrameLen;
+	UINT_16 u2RxFrameCtrl;
+	P_BSS_INFO_T prBssInfo;
+
+	P_DEAUTH_INFO_T prDeauthInfo;
+	OS_SYSTIME rCurrentTime;
+	INT_32 i4NewEntryIndex, i;
+	UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND;
+
+#if CFG_ENABLE_WIFI_DIRECT
+	UINT_8 aucBMC[] = BC_MAC_ADDR;
+#endif
+
+	/* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data
+	 * frame
+	 */
+	/* 4 <1> Find the Receiver Address first. */
+	if (prClassErrSwRfb) {
+		BOOLEAN fgIsAbleToSendDeauth = FALSE;
+
+		prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader;
+
+		/* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl); */
+		u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+
+		/* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */
+		if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0)
+			return WLAN_STATUS_FAILURE;
+
+		/* Check if corresponding BSS is able to send Deauth */
+		for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) {
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]);
+
+			if (IS_NET_ACTIVE(prAdapter, i) &&
+			    (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) {
+				{
+					fgIsAbleToSendDeauth = TRUE;
+					eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) i;
+					break;
+				}
+			}
+		}
+
+		if (!fgIsAbleToSendDeauth)
+			return WLAN_STATUS_FAILURE;
+
+		pucReceiveAddr = prWlanMacHeader->aucAddr2;
+
+	} else if (prStaRec) {
+
+		pucReceiveAddr = prStaRec->aucMacAddr;
+	} else {
+#if CFG_ENABLE_WIFI_DIRECT
+		pucReceiveAddr = aucBMC;
+#else
+		return WLAN_STATUS_FAILURE;
+#endif
+	}
+
+	/* 4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC */
+	GET_CURRENT_SYSTIME(&rCurrentTime);
+
+	i4NewEntryIndex = -1;
+	for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) {
+		prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]);
+
+		/* For continuously sending Deauth frame, the minimum interval is
+		 * MIN_DEAUTH_INTERVAL_MSEC.
+		 */
+		if (CHECK_FOR_TIMEOUT(rCurrentTime,
+				      prDeauthInfo->rLastSendTime, MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) {
+
+			i4NewEntryIndex = i;
+		} else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) && (!pfTxDoneHandler)) {
+
+			return WLAN_STATUS_FAILURE;
+		}
+	}
+
+	/* 4 <3> Update information. */
+	if (i4NewEntryIndex > 0) {
+
+		prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]);
+
+		COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr);
+		prDeauthInfo->rLastSendTime = rCurrentTime;
+	} else {
+		/* NOTE(Kevin): for the case of AP mode, we may encounter this case
+		 * if deauth all the associated clients.
+		 */
+		DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n");
+	}
+
+	/* 4 <4> Allocate a PKT_INFO_T for Deauthentication Frame */
+	/* Init with MGMT Header Length + Length of Fixed Fields + IE Length */
+	u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN);
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Deauth Request.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <5> Find the Transmitter Address and BSSID. */
+	if (prClassErrSwRfb) {
+
+		/* The TA of Deauth is the A1 of RX frame */
+		pucTransmitAddr = prWlanMacHeader->aucAddr1;
+
+		switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) {
+
+		case MASK_FC_FROM_DS:
+			/* The BSSID of Deauth is the A2 of RX frame */
+			pucBssid = prWlanMacHeader->aucAddr2;
+			break;
+
+		case MASK_FC_TO_DS:
+			/* The BSSID of Deauth is the A1 of RX frame */
+			pucBssid = prWlanMacHeader->aucAddr1;
+			break;
+
+		case MASK_TO_DS_FROM_DS:
+			/* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth
+			 * to the A2 of RX frame for temporary solution.
+			 */
+			pucBssid = prWlanMacHeader->aucAddr2;
+			break;
+
+			/* No Default */
+		}
+
+	} else if (prStaRec) {
+		eNetTypeIndex = prStaRec->ucNetTypeIndex;
+
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+		pucTransmitAddr = prBssInfo->aucOwnMacAddr;
+
+		pucBssid = prBssInfo->aucBSSID;
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	else {
+		if (prAdapter->fgIsP2PRegistered) {
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+			ucStaRecIdx = STA_REC_INDEX_BMCAST;
+
+			pucTransmitAddr = prBssInfo->aucOwnMacAddr;
+
+			pucBssid = prBssInfo->aucBSSID;
+
+			eNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+		} else {
+			/* 20130122: free packet by samplin */
+			cnmMgtPktFree(prAdapter, prMsduInfo);
+			return WLAN_STATUS_FAILURE;
+		}
+	}
+
+#endif
+
+	/* 4 <6> compose Deauthentication frame header and some fixed fields */
+	authComposeDeauthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+					  pucReceiveAddr, pucTransmitAddr, pucBssid, u2ReasonCode);
+
+#if CFG_SUPPORT_802_11W
+	if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+		P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
+
+		prDeauthFrame =
+		    (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+		prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+		DBGLOG(TX, WARN, "authSendDeauthFrame with protection\n");
+	}
+#endif
+
+	/* 4 <7> Update information of MSDU_INFO_T */
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = ((prStaRec == NULL) ? ucStaRecIdx : prStaRec->ucIndex);
+	prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
+	prMsduInfo->fgIsBasicRate = TRUE;
+	DBGLOG(SAA, INFO, "Sending Deauth, network: %d, seqNo %d\n",
+		eNetTypeIndex, prMsduInfo->ucTxSeqNum);
+
+	/* 4 <8> Inform TXM to send this Deauthentication frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of authSendDeauthFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will parse and process the incoming Deauthentication frame
+*        if the given BSSID is matched.
+*
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[in] aucBSSID           Given BSSID
+* @param[out] pu2ReasonCode     Pointer to store the Reason Code from Deauthentication.
+*
+* @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode)
+{
+	P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
+	UINT_16 u2RxReasonCode;
+
+	ASSERT(prSwRfb);
+	ASSERT(aucBSSID);
+	ASSERT(pu2ReasonCode);
+
+	/* 4 <1> locate the Deauthentication Frame. */
+	prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
+
+	/* 4 <2> Parse the Header of Deauthentication Frame. */
+#if 0				/* Kevin: Seems redundant */
+	WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl)
+	    u2RxFrameCtrl &= MASK_FRAME_TYPE;
+	if (u2RxFrameCtrl != MAC_FRAME_DEAUTH)
+		return WLAN_STATUS_FAILURE;
+#endif
+
+	if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	/* Check if this Deauth Frame is coming from Target BSSID */
+	if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) {
+		DBGLOG(SAA, LOUD, "Ignore Deauth Frame from other BSS [ %pM ]\n",
+				   prDeauthFrame->aucSrcAddr);
+		return WLAN_STATUS_FAILURE;
+	}
+	/* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */
+	WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode);
+	*pu2ReasonCode = u2RxReasonCode;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of authProcessRxDeauthFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will parse and process the incoming Authentication frame.
+*
+* @param[in] prSwRfb                Pointer to SW RFB data structure.
+* @param[in] aucExpectedBSSID       Given Expected BSSID.
+* @param[in] u2ExpectedAuthAlgNum   Given Expected Authentication Algorithm Number
+* @param[in] u2ExpectedTransSeqNum  Given Expected Transaction Sequence Number.
+* @param[out] pu2ReturnStatusCode   Return Status Code.
+*
+* @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
+* @retval WLAN_STATUS_FAILURE   The frame we will ignore.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter,
+			IN P_SW_RFB_T prSwRfb,
+			IN UINT_8 aucExpectedBSSID[],
+			IN UINT_16 u2ExpectedAuthAlgNum,
+			IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode)
+{
+	P_WLAN_AUTH_FRAME_T prAuthFrame;
+	UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL;
+
+	ASSERT(prSwRfb);
+	ASSERT(aucExpectedBSSID);
+	ASSERT(pu2ReturnStatusCode);
+
+	/* 4 <1> locate the Authentication Frame. */
+	prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
+
+	/* 4 <2> Check the BSSID */
+	if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID))
+		return WLAN_STATUS_FAILURE;	/* Just Ignore this MMPDU */
+	/* 4 <3> Check the SA, which should not be MC/BC */
+	if (prAuthFrame->aucSrcAddr[0] & BIT(0)) {
+		DBGLOG(P2P, WARN, "Invalid STA MAC with MC/BC bit set: %pM\n",
+				   prAuthFrame->aucSrcAddr);
+		return WLAN_STATUS_FAILURE;
+	}
+	/* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */
+	if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum)
+		u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED;
+
+	if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum)
+		u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ;
+
+	*pu2ReturnStatusCode = u2ReturnStatusCode;
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of authProcessRxAuth1Frame() */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c
new file mode 100644
index 0000000000000..160779583655f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c
@@ -0,0 +1,2521 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/bss.c#3
+*/
+
+/*! \file   "bss.c"
+    \brief  This file contains the functions for creating BSS(AP)/IBSS(AdHoc).
+
+    This file contains the functions for BSS(AP)/IBSS(AdHoc). We may create a BSS/IBSS
+    network, or merge with exist IBSS network and sending Beacon Frame or reply
+    the Probe Response Frame for received Probe Request Frame.
+*/
+
+/*
+** Log: bss.c
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+**
+** 08 30 2012 chinglan.wang
+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
+** .
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 14 2012 chinglan.wang
+ * NULL
+ * Fix the losing of the HT IE in assoc request..
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 03 08 2012 yuche.tsai
+ * NULL
+ * Fix FW assert when start Hot-Spot.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 01 20 2012 chinglan.wang
+ * 03 02 2012 terry.wu
+ * NULL
+ * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug.
+ *
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 15 2012 yuche.tsai
+ * NULL
+ * Fix wrong basic rate issue.
+ *
+ * 01 13 2012 yuche.tsai
+ * NULL
+ * WiFi Hot Spot Tethering for ICS ALPHA testing version.
+ *
+ * 11 03 2011 cm.chang
+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
+ * Always set short slot time to TRUE initially in AP mode
+ *
+ * 11 03 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG
+ *
+ * 09 14 2011 yuche.tsai
+ * NULL
+ * Add P2P IE in assoc response.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 12 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix the sta index in processing security frame
+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
+ * Add debug message.
+ *
+ * 04 08 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix for sigma
+ *
+ * 03 29 2011 eddie.chen
+ * [WCXRP00000608] [MT6620 Wi-Fi][DRV] Change wmm parameters in beacon
+ * Change wmm parameters in beacon.
+ *
+ * 03 29 2011 yuche.tsai
+ * [WCXRP00000607] [Volunteer Patch][MT6620][Driver] Coding Style Fix for klocwork scan.
+ * Fix klocwork issue.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue
+ * Make assoc req to append P2P IE if wifi direct is enabled.
+ *
+ * 03 11 2011 chinglan.wang
+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security.
+ * .
+ *
+ * 03 03 2011 george.huang
+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated
+ * .
+ *
+ * 03 03 2011 george.huang
+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated
+ * modify to handle if beacon MSDU been released when BSS deactivated
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add code to let the beacon and probe response for Auto GO WSC .
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
+ * Add code to send beacon and probe response WSC IE at Auto GO.
+ *
+ * 02 17 2011 eddie.chen
+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel
+ * 1) Change GetFrameAction decision when BSS is absent.
+ * 2) Check channel and resource in processing ProbeRequest
+ *
+ * 02 12 2011 yuche.tsai
+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled.
+ * bss should create station record type according to callers input.
+ *
+ * 02 11 2011 terry.wu
+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
+ * In p2p link function, check networktype before calling p2p function.
+ *
+ * 02 11 2011 terry.wu
+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
+ * Modify p2p link function to avoid assert.
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 01 25 2011 eddie.chen
+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
+ * Fix the compile error in windows.
+ *
+ * 01 24 2011 eddie.chen
+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
+ * Add destination decision in AP mode.
+ *
+ * 01 24 2011 terry.wu
+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
+ * .Fix typo and missing entry
+ *
+ * 12 30 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * Fix  prBssInfo->aucCWminLog to  prBssInfo->aucCWminLogForBcast
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+
+Add per station flow control when STA is in PS
+
+ * Add WMM parameter for broadcast.
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 11 29 2010 cp.wu
+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC
+ * for initial TX rate selection of auto-rate algorithm
+ * update ucRcpi of STA_RECORD_T for AIS when
+ * 1) Beacons for IBSS merge is received
+ * 2) Associate Response for a connecting peer is received
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * use definition macro to replace hard-coded constant
+ *
+ * 10 08 2010 wh.su
+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
+ * update the frog's new p2p state machine.
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 27 2010 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
+ * Update BCM/BoW design and settings.
+ *
+ * 09 16 2010 cm.chang
+ * NULL
+ * Change conditional compiling options for BOW
+ *
+ * 09 10 2010 cm.chang
+ * NULL
+ * Always update Beacon content if FW sync OBSS info
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * Finish SLT TX/RX & Rate Changing Support.
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Before composing Beacon IE, assign network type index for msdu info,
+ * this information is needed by RLM module while composing some RLM related IE field.
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
+ * There is no CFG_SUPPORT_BOW in driver domain source.
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Fix undefined pucDestAddr in bssUpdateBeaconContent()
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse()
+ *
+ * 08 11 2010 cp.wu
+ * NULL
+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting)
+ * 2) extending scanning result to 64 instead of 48
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 08 02 2010 george.huang
+ * NULL
+ * add WMM-PS test related OID/ CMD handlers
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Add support to RX probe response for P2P.
+ *
+ * 07 20 2010 cp.wu
+ *
+ * 1) bugfix: do not stop timer for join after switched into normal_tr state, for providing chance for DHCP handshasking
+ * 2) modify rsnPerformPolicySelection() invoking
+ *
+ * 07 19 2010 wh.su
+ *
+ * update for security supporting.
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * when IBSS is being merged-in, send command packet to PM for connected indication
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Add Ad-Hoc support to AIS-FSM
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 06 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Update arguments for nicUpdateBeaconIETemplate()
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) sync to. CMD/EVENT document v0.03
+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
+ * 3) send command packet to indicate FW-PM after
+ *     a) 1st beacon is received after AIS has connected to an AP
+ *     b) IBSS-ALONE has been created
+ *     c) IBSS-MERGE has occurred
+ *
+ * 06 28 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * send MMPDU in basic rate.
+ *
+ * 06 25 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Create beacon update path, with expose bssUpdateBeaconContent()
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Fix compile error while enable WIFI_DIRECT support.
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Support CFG_MQM_MIGRATION flag
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * enable RX management frame handling.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * specify correct value for management frames.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * correct when ADHOC support is turned on.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan.c.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * auth.c is migrated.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * fix compilation error when WIFI_DIRECT is turned on
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add bss.c.
+ *
+ * 06 04 2010 george.huang
+ * [BORA00000678][MT6620]WiFi LP integration
+ * [PM] Support U-APSD for STA mode
+ *
+ * 05 28 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList
+ *
+ * 05 24 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Update bssProcessProbeRequest() to avoid redundant SSID IE {0,0} for IOT.
+ *
+ * 05 21 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set
+ *
+ * 05 18 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs
+ *
+ * 05 14 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Use TX MGMT Frame API for sending PS NULL frame to avoid the TX Burst Mechanism in TX FW Frame API
+ *
+ * 05 14 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Separate Beacon and ProbeResp IE array
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 28 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Removed the use of compiling flag MQM_WMM_PARSING
+ *
+ * 04 27 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft code to support protection in AP mode
+ *
+ * 04 20 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Fix restart Beacon Timeout Func after connection diagnosis
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support and will send Null frame to diagnose connection
+ *
+ * 04 16 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * adding the wpa-none for ibss beacon.
+ *
+ * 04 15 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * fixed the protected bit at cap info for ad-hoc.
+ *
+ * 03 18 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Rename the CFG flags
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Update outgoing beacon's TX data rate
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add DTIM count update while TX Beacon
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Modify code due to define - BAND_24G and specific BSS_INFO_T was changed
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA)
+APPEND_VAR_IE_ENTRY_T txBcnIETable[] = {
+	{(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE},	/* 50 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE},	/* 42 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE},	/* 45 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE},	/* 61 */
+#if CFG_ENABLE_WIFI_DIRECT
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE},	/* 74 */
+#endif
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE},	/* 127 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE},	/* 221 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE},	/* 221 */
+#if CFG_ENABLE_WIFI_DIRECT
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE},	/* 221 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE},	/* 48 */
+#if 0				/* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */
+	{0, p2pFuncCalculateExtra_IELenForBeacon, p2pFuncGenerateExtra_IEForBeacon},	/* 221 */
+#else
+	{0, p2pFuncCalculateP2p_IELenForBeacon, p2pFuncGenerateP2p_IEForBeacon},	/* 221 */
+	{0, p2pFuncCalculateWSC_IELenForBeacon, p2pFuncGenerateWSC_IEForBeacon},	/* 221 */
+	{0, p2pFuncCalculateP2P_IE_NoA, p2pFuncGenerateP2P_IE_NoA},	/* 221 */
+#endif
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+};
+
+APPEND_VAR_IE_ENTRY_T txProbRspIETable[] = {
+	{(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE},	/* 50 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE},	/* 42 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE},	/* 45 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE},	/* 61 */
+#if CFG_ENABLE_WIFI_DIRECT
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE},	/* 48 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE},	/* 74 */
+#endif
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE},	/* 127 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE},	/* 221 */
+	{(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}	/* 221 */
+};
+
+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines for all Operation Modes                                           */
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T for
+*        Infrastructure or AdHoc Mode.
+*
+* @param[in] prAdapter              Pointer to the Adapter structure.
+* @param[in] eStaType               Assign STA Type for this STA_RECORD_T
+* @param[in] eNetTypeIndex          Assign Net Type Index for this STA_RECORD_T
+* @param[in] prBssDesc              Received Beacon/ProbeResp from this STA
+*
+* @retval   Pointer to STA_RECORD_T
+*/
+/*----------------------------------------------------------------------------*/
+P_STA_RECORD_T
+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter,
+			   IN ENUM_STA_TYPE_T eStaType,
+			   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_8 ucNonHTPhyTypeSet;
+
+	ASSERT(prBssDesc);
+
+	/* 4 <1> Get a valid STA_RECORD_T */
+	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr);
+	if (!prStaRec) {
+
+		prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) eNetTypeIndex);
+
+		/* TODO(Kevin): Error handling of allocation of STA_RECORD_T for
+		 * exhausted case and do removal of unused STA_RECORD_T.
+		 */
+
+		if (!prStaRec) {
+			ASSERT(FALSE);
+			return NULL;
+		}
+
+		ASSERT(prStaRec);
+
+		prStaRec->ucStaState = STA_STATE_1;
+		prStaRec->ucJoinFailureCount = 0;
+		/* TODO(Kevin): If this is an old entry, we may also reset the ucJoinFailureCount to 0.
+		 */
+
+		COPY_MAC_ADDR(prStaRec->aucMacAddr, prBssDesc->aucSrcAddr);
+	}
+	/* 4 <2> Setup STA TYPE and NETWORK */
+	prStaRec->eStaType = eStaType;
+
+	prStaRec->ucNetTypeIndex = eNetTypeIndex;
+
+	/* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */
+	prStaRec->u2CapInfo = prBssDesc->u2CapInfo;
+
+	prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet;
+	prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet;
+
+	prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet;
+	if (IS_STA_IN_AIS(prStaRec)) {
+		if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) ||
+		      (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) ||
+		      (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED) ||
+		      (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz))) {
+			DBGLOG(BSS, TRACE, "Ignore the HT Bit for TKIP as pairwise cipher configured!\n");
+			prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT;
+		}
+	} else {
+		DBGLOG(BSS, TRACE, "P2P skip TKIP limitation for HT Hit!\n");
+	}
+	prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet;
+
+	ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG;
+
+	/* Check for Target BSS's non HT Phy Types */
+	if (ucNonHTPhyTypeSet) {
+
+		if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) {
+			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX;
+		} else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) {
+			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX;
+		} else {	/* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */
+
+			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX;
+		}
+
+		prStaRec->fgHasBasicPhyType = TRUE;
+	} else {
+		/* Use mandatory for 11N only BSS */
+		ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N);
+
+		{
+			/* TODO(Kevin): which value should we set for 11n ? ERP ? */
+			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX;
+		}
+
+		prStaRec->fgHasBasicPhyType = FALSE;
+	}
+
+	/* Update non HT Desired Rate Set */
+	{
+		P_CONNECTION_SETTINGS_T prConnSettings;
+
+		prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+		prStaRec->u2DesiredNonHTRateSet =
+		    (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet);
+	}
+
+	/* 4 <4> Update information from BSS_DESC_T to current P_STA_RECORD_T */
+	if (IS_AP_STA(prStaRec)) {
+		/* do not need to parse IE for DTIM,
+		 * which have been parsed before inserting into BSS_DESC_T
+		 */
+		if (prBssDesc->ucDTIMPeriod)
+			prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
+		else
+			prStaRec->ucDTIMPeriod = 0;	/* Means that TIM was not parsed. */
+	}
+	/* 4 <5> Update default value */
+	prStaRec->fgDiagnoseConnection = FALSE;
+
+	/* 4 <6> Update default value for other Modules */
+	/* Determine fgIsWmmSupported and fgIsUapsdSupported in STA_REC */
+	mqmProcessScanResult(prAdapter, prBssDesc, prStaRec);
+
+	return prStaRec;
+
+}				/* end of bssCreateStaRecFromBssDesc() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the Null Data frame.
+*
+* @param[in] prAdapter              Pointer to the Adapter structure.
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] prStaRec               Pointer to the STA_RECORD_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec)
+{
+	P_WLAN_MAC_HEADER_T prNullFrame;
+	P_BSS_INFO_T prBssInfo;
+	UINT_16 u2FrameCtrl;
+
+	ASSERT(pucBuffer);
+	ASSERT(prStaRec);
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	ASSERT(prBssInfo);
+
+	prNullFrame = (P_WLAN_MAC_HEADER_T) pucBuffer;
+
+	/* 4 <1> Decide the Frame Control Field */
+	u2FrameCtrl = MAC_FRAME_NULL;
+
+	if (IS_AP_STA(prStaRec)) {
+		u2FrameCtrl |= MASK_FC_TO_DS;
+
+		if (prStaRec->fgSetPwrMgtBit)
+			u2FrameCtrl |= MASK_FC_PWR_MGT;
+	} else if (IS_CLIENT_STA(prStaRec)) {
+		u2FrameCtrl |= MASK_FC_FROM_DS;
+	} else if (IS_DLS_STA(prStaRec)) {
+		/* TODO(Kevin) */
+	} else {
+		/* NOTE(Kevin): We won't send Null frame for IBSS */
+		ASSERT(0);
+		return;
+	}
+
+	/* 4 <2> Compose the Null frame */
+	/* Fill the Frame Control field. */
+	/* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */
+	prNullFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the Address 1 field with Target Peer Address. */
+	COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr);
+
+	/* Fill the Address 2 field with our MAC Address. */
+	COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr);
+
+	/* Fill the Address 3 field with Target BSSID. */
+	COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID);
+
+	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
+	prNullFrame->u2SeqCtrl = 0;
+
+	return;
+
+}				/* end of bssComposeNullFrameHeader() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the QoS Null Data frame.
+*
+* @param[in] prAdapter              Pointer to the Adapter structure.
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] prStaRec               Pointer to the STA_RECORD_T.
+* @param[in] ucUP                   User Priority.
+* @param[in] fgSetEOSP              Set the EOSP bit.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter,
+		       IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP)
+{
+	P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame;
+	P_BSS_INFO_T prBssInfo;
+	UINT_16 u2FrameCtrl;
+	UINT_16 u2QosControl;
+
+	ASSERT(pucBuffer);
+	ASSERT(prStaRec);
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	ASSERT(prBssInfo);
+
+	prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) pucBuffer;
+
+	/* 4 <1> Decide the Frame Control Field */
+	u2FrameCtrl = MAC_FRAME_QOS_NULL;
+
+	if (IS_AP_STA(prStaRec)) {
+		u2FrameCtrl |= MASK_FC_TO_DS;
+
+		if (prStaRec->fgSetPwrMgtBit)
+			u2FrameCtrl |= MASK_FC_PWR_MGT;
+	} else if (IS_CLIENT_STA(prStaRec)) {
+		u2FrameCtrl |= MASK_FC_FROM_DS;
+	} else if (IS_DLS_STA(prStaRec)) {
+		/* TODO(Kevin) */
+	} else {
+		/* NOTE(Kevin): We won't send QoS Null frame for IBSS */
+		ASSERT(0);
+		return;
+	}
+
+	/* 4 <2> Compose the QoS Null frame */
+	/* Fill the Frame Control field. */
+	/* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */
+	prQoSNullFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the Address 1 field with Target Peer Address. */
+	COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr);
+
+	/* Fill the Address 2 field with our MAC Address. */
+	COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr);
+
+	/* Fill the Address 3 field with Target BSSID. */
+	COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID);
+
+	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
+	prQoSNullFrame->u2SeqCtrl = 0;
+
+	u2QosControl = (UINT_16) (ucUP & WMM_QC_UP_MASK);
+
+	if (fgSetEOSP)
+		u2QosControl |= WMM_QC_EOSP;
+	/* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */
+	prQoSNullFrame->u2QosCtrl = u2QosControl;	/* NOTE(Kevin): Optimized for ARM */
+
+	return;
+
+}				/* end of bssComposeQoSNullFrameHeader() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Send the Null Frame
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+* @param[in] pfTxDoneHandler    TX Done call back function
+*
+* @retval WLAN_STATUS_RESOURCE  No available resources to send frame.
+* @retval WLAN_STATUS_SUCCESS   Succe]ss.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	UINT_16 u2EstimatedFrameLen;
+
+	/* 4 <1> Allocate a PKT_INFO_T for Null Frame */
+	/* Init with MGMT Header Length */
+	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose Null frame in MSDU_INfO_T. */
+	bssComposeNullFrame(prAdapter, (PUINT_8) ((ULONG) prMsduInfo->prPacket + MAC_TX_RESERVED_FIELD), prStaRec);
+#if 0
+	/* 4 <3> Update information of MSDU_INFO_T */
+	TXM_SET_DATA_PACKET(
+				   /* STA_REC ptr */ prStaRec,
+				   /* MSDU_INFO ptr */ prMsduInfo,
+				   /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD),
+				   /* MAC HDR length */ WLAN_MAC_HEADER_LEN,
+				   /* PAYLOAD ptr */
+				   (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN),
+				   /* PAYLOAD length */ 0,
+				   /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex,
+				   /* TID */ 0 /* BE: AC1 */ ,
+				   /* Flag 802.11 */ TRUE,
+				   /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ ,
+				   /* Resource TC */ 0 /* Irrelevant */ ,
+				   /* Flag 802.1x */ FALSE,
+				   /* TX-done callback */ pfTxDoneHandler,
+				   /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS,
+				   /* PS Session ID */ 0 /* Irrelevant */ ,
+				   /* Flag fixed rate */ TRUE,
+				   /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode,
+				   /* Fixed-rate retry */ BSS_DEFAULT_CONN_TEST_NULL_FRAME_RETRY_LIMIT,
+				   /* PAL LLH */ 0 /* Irrelevant */ ,
+				   /* ACL SN */ 0 /* Irrelevant */ ,
+				   /* Flag No Ack */ FALSE
+	    );
+
+	/* Terminate with a NULL pointer */
+	NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL);
+
+	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
+
+	/* Indicate the packet to TXM */
+	/* 4 <4> Inform TXM to send this Null frame. */
+	txmSendFwDataPackets(prMsduInfo);
+#endif
+
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA;
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_LEN;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
+	prMsduInfo->fgIsBasicRate = FALSE;
+
+	/* 4 <4> Inform TXM  to send this Null frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of bssSendNullFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Send the QoS Null Frame
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+* @param[in] pfTxDoneHandler    TX Done call back function
+*
+* @retval WLAN_STATUS_RESOURCE  No available resources to send frame.
+* @retval WLAN_STATUS_SUCCESS   Success.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter,
+		    IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	UINT_16 u2EstimatedFrameLen;
+
+	/* 4 <1> Allocate a PKT_INFO_T for Null Frame */
+	/* Init with MGMT Header Length */
+	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n");
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose Null frame in MSDU_INfO_T. */
+	bssComposeQoSNullFrame(prAdapter,
+			       (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+			       prStaRec, ucUP, FALSE);
+#if 0
+	/* 4 <3> Update information of MSDU_INFO_T */
+	TXM_SET_DATA_PACKET(
+				   /* STA_REC ptr */ prStaRec,
+				   /* MSDU_INFO ptr */ prMsduInfo,
+				   /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD),
+				   /* MAC HDR length */ WLAN_MAC_HEADER_QOS_LEN,
+				   /* PAYLOAD ptr */
+				   (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN),
+				   /* PAYLOAD length */ 0,
+				   /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex,
+				   /* TID */ 0 /* BE: AC1 */ ,
+				   /* Flag 802.11 */ TRUE,
+				   /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ ,
+				   /* Resource TC */ 0 /* Irrelevant */ ,
+				   /* Flag 802.1x */ FALSE,
+				   /* TX-done callback */ pfTxDoneHandler,
+				   /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS,
+				   /* PS Session ID */ 0 /* Irrelevant */ ,
+				   /* Flag fixed rate */ TRUE,
+				   /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode,
+				   /* Fixed-rate retry */ TXM_DEFAULT_DATA_FRAME_RETRY_LIMIT,
+				   /* PAL LLH */ 0 /* Irrelevant */ ,
+				   /* ACL SN */ 0 /* Irrelevant */ ,
+				   /* Flag No Ack */ FALSE
+	    );
+
+	/* Terminate with a NULL pointer */
+	NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL);
+
+	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
+
+	/* Indicate the packet to TXM */
+	/* 4 <4> Inform TXM to send this Null frame. */
+	txmSendFwDataPackets(prMsduInfo);
+#endif
+
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
+	prMsduInfo->fgIsBasicRate = TRUE;
+
+	/* 4 <4> Inform TXM  to send this Null frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of bssSendQoSNullFrame() */
+
+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA)
+/*----------------------------------------------------------------------------*/
+/* Routines for both IBSS(AdHoc) and BSS(AP)                                  */
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to generate Information Elements of Extended
+*        Support Rate
+*
+* @param[in] prAdapter      Pointer to the Adapter structure.
+* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	PUINT_8 pucBuffer;
+	UINT_8 ucExtSupRatesLen;
+
+	ASSERT(prMsduInfo);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]);
+	ASSERT(prBssInfo);
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+	ASSERT(pucBuffer);
+
+	if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES)
+		ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES;
+	else
+		ucExtSupRatesLen = 0;
+
+	/* Fill the Extended Supported Rates element. */
+	if (ucExtSupRatesLen) {
+
+		EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
+		EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen;
+
+		kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates,
+			   &prBssInfo->aucAllSupportedRates[ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen);
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+	}
+
+}				/* end of bssGenerateExtSuppRate_IE() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to compose Common Information Elements for Beacon
+*        or Probe Response Frame.
+*
+* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
+* @param[in] prBssInfo      Pointer to the BSS_INFO_T.
+* @param[in] pucDestAddr    Pointer to the Destination Address, if NULL, means Beacon.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr)
+{
+	PUINT_8 pucBuffer;
+	UINT_8 ucSupRatesLen;
+
+	ASSERT(prMsduInfo);
+	ASSERT(prBssInfo);
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+	ASSERT(pucBuffer);
+
+	/* Compose the frame body of the Probe Response frame. */
+	/* 4 <1> Fill the SSID element. */
+	SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID;
+	if (prBssInfo->eHiddenSsidType == ENUM_HIDDEN_SSID_LEN) {
+		if ((!pucDestAddr) &&	/* For Beacon only */
+		    (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
+			SSID_IE(pucBuffer)->ucLength = 0;
+		} else {	/* Probe response */
+			SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen;
+			if (prBssInfo->ucSSIDLen)
+				kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
+		}
+	} else {
+		SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen;
+		if (prBssInfo->ucSSIDLen)
+			kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
+	}
+
+	prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+	pucBuffer += IE_SIZE(pucBuffer);
+
+	/* 4 <2> Fill the Supported Rates element. */
+	if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES)
+		ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES;
+	else
+		ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen;
+
+	if (ucSupRatesLen) {
+		SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES;
+		SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen;
+		kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen);
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+		pucBuffer += IE_SIZE(pucBuffer);
+	}
+	/* 4 <3> Fill the DS Parameter Set element. */
+	if (prBssInfo->eBand == BAND_2G4) {
+		DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET;
+		DS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_DS_PARAMETER_SET;
+		DS_PARAM_IE(pucBuffer)->ucCurrChnl = prBssInfo->ucPrimaryChannel;
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+		pucBuffer += IE_SIZE(pucBuffer);
+	}
+	/* 4 <4> IBSS Parameter Set element, ID: 6 */
+	if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
+		IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET;
+		IBSS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_IBSS_PARAMETER_SET;
+		WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), prBssInfo->u2ATIMWindow);
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+		pucBuffer += IE_SIZE(pucBuffer);
+	}
+	/* 4 <5> TIM element, ID: 5 */
+	if ((!pucDestAddr) &&	/* For Beacon only. */
+	    (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
+
+#if CFG_ENABLE_WIFI_DIRECT
+		/*no fgIsP2PRegistered protect */
+		if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
+#if 0
+			P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;
+			UINT_8 ucBitmapControl = 0;
+			UINT_32 u4N1, u4N2;
+
+			prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo);
+
+			/* Clear existing value. */
+			prP2pSpecificBssInfo->ucBitmapCtrl = 0;
+			kalMemZero(prP2pSpecificBssInfo->aucPartialVirtualBitmap,
+				   sizeof(prP2pSpecificBssInfo->aucPartialVirtualBitmap));
+
+			/* IEEE 802.11 2007 - 7.3.2.6 */
+			TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM;
+			TIM_IE(pucBuffer)->ucDTIMCount = prBssInfo->ucDTIMCount;
+			TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod;
+
+			/* Setup DTIM Count for next TBTT. */
+			if (prBssInfo->ucDTIMCount == 0) {
+				/*Do nothing*/
+				/* 3 *** pmQueryBufferedBCAST(); */
+			}
+			/* 3 *** pmQueryBufferedPSNode(); */
+			/* TODO(Kevin): Call PM Module here to loop all STA_RECORD_Ts and it
+			 * will call bssSetTIMBitmap to toggle the Bitmap.
+			 */
+
+			/* Set Virtual Bitmap for UCAST */
+			u4N1 = (prP2pSpecificBssInfo->u2SmallestAID >> 4) << 1;	/* Find the largest even number. */
+			u4N2 = prP2pSpecificBssInfo->u2LargestAID >> 3;	/* Find the smallest number. */
+
+			ASSERT(u4N2 >= u4N1);
+
+			kalMemCopy(TIM_IE(pucBuffer)->aucPartialVirtualMap,
+				   &prP2pSpecificBssInfo->aucPartialVirtualBitmap[u4N1], ((u4N2 - u4N1) + 1));
+
+			/* Set Virtual Bitmap for BMCAST */
+			/* BMC bit only indicated when DTIM count == 0. */
+			if (prBssInfo->ucDTIMCount == 0)
+				ucBitmapControl = prP2pSpecificBssInfo->ucBitmapCtrl;
+			TIM_IE(pucBuffer)->ucBitmapControl = ucBitmapControl | (UINT_8) u4N1;
+
+			TIM_IE(pucBuffer)->ucLength = ((u4N2 - u4N1) + 4);
+
+			prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+#else
+
+			/* IEEE 802.11 2007 - 7.3.2.6 */
+			TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM;
+			/* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */
+			TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP); /*((u4N2 - u4N1) + 4) */
+			/* will be overwrite by FW */
+			TIM_IE(pucBuffer)->ucDTIMCount = 0; /*prBssInfo->ucDTIMCount */
+			TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod;
+			/* will be overwrite by FW */
+			TIM_IE(pucBuffer)->ucBitmapControl = 0; /*ucBitmapControl | (UINT_8)u4N1 */
+
+			prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+
+#endif
+
+		} else
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+		{
+			/* NOTE(Kevin): 1. AIS - Didn't Support AP Mode.
+			 *              2. BOW - Didn't Support BCAST and PS.
+			 */
+		}
+
+	}
+
+}				/* end of bssBuildBeaconProbeRespFrameCommonIEs() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the Beacon/Probe Response frame header and
+*        its fixed fields.
+*
+* @param[in] pucBuffer              Pointer to the frame buffer.
+* @param[in] pucDestAddr            Pointer to the Destination Address, if NULL, means Beacon.
+* @param[in] pucOwnMACAddress       Given Our MAC Address.
+* @param[in] pucBSSID               Given BSSID of the BSS.
+* @param[in] u2BeaconInterval       Given Beacon Interval.
+* @param[in] u2CapInfo              Given Capability Info.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer,
+					  IN PUINT_8 pucDestAddr,
+					  IN PUINT_8 pucOwnMACAddress,
+					  IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo)
+{
+	P_WLAN_BEACON_FRAME_T prBcnProbRspFrame;
+	UINT_8 aucBCAddr[] = BC_MAC_ADDR;
+	UINT_16 u2FrameCtrl;
+
+	DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF");
+	/* DBGLOG(INIT, LOUD, ("\n")); */
+
+	ASSERT(pucBuffer);
+	ASSERT(pucOwnMACAddress);
+	ASSERT(pucBSSID);
+
+	prBcnProbRspFrame = (P_WLAN_BEACON_FRAME_T) pucBuffer;
+
+	/* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */
+	/* Fill the Frame Control field. */
+	if (pucDestAddr) {
+		u2FrameCtrl = MAC_FRAME_PROBE_RSP;
+	} else {
+		u2FrameCtrl = MAC_FRAME_BEACON;
+		pucDestAddr = aucBCAddr;
+	}
+	/* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */
+	prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */
+	COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr);
+
+	/* Fill the SA field with our MAC Address. */
+	COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress);
+
+	/* Fill the BSSID field with current BSSID. */
+	COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID);
+
+	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
+	prBcnProbRspFrame->u2SeqCtrl = 0;
+
+	/* 4 <2> Compose the frame body's common fixed field part of the Beacon /ProbeResp frame. */
+	/* MAC will update TimeStamp field */
+
+	/* Fill the Beacon Interval field. */
+	/* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, u2BeaconInterval); */
+	prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval;	/* NOTE(Kevin): Optimized for ARM */
+
+	/* Fill the Capability Information field. */
+	/* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */
+	prBcnProbRspFrame->u2CapInfo = u2CapInfo;	/* NOTE(Kevin): Optimized for ARM */
+
+}				/* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] eNetTypeIndex      Specify which network reply the Probe Response.
+*
+* @retval WLAN_STATUS_SUCCESS   Success.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_MSDU_INFO_T prMsduInfo;
+	P_WLAN_BEACON_FRAME_T prBcnFrame;
+	UINT_32 i;
+
+	DEBUGFUNC("bssUpdateBeaconContent");
+	DBGLOG(BSS, LOUD, "\n");
+
+	ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+	/* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */
+	/* Allocate a MSDU_INFO_T */
+	/* For Beacon */
+	prMsduInfo = prBssInfo->prBeacon;
+
+	/* beacon prMsduInfo will be NULLify once BSS deactivated, so skip if it is */
+	if (prMsduInfo == NULL)
+		return WLAN_STATUS_SUCCESS;
+	/* 4 <2> Compose header */
+	bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+						  NULL,
+						  prBssInfo->aucOwnMacAddr,
+						  prBssInfo->aucBSSID,
+						  prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo);
+
+	prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN +
+				     (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN));
+
+	prMsduInfo->ucNetworkType = eNetTypeIndex;
+
+	/* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */
+	bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL);
+
+	/* 4 <4> Compose IEs in MSDU_INFO_T */
+
+	/* Append IE for Beacon */
+	for (i = 0; i < sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
+		if (txBcnIETable[i].pfnAppendIE)
+			txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
+	}
+
+	prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket;
+
+	return nicUpdateBeaconIETemplate(prAdapter,
+					 IE_UPD_METHOD_UPDATE_ALL,
+					 eNetTypeIndex,
+					 prBssInfo->u2CapInfo,
+					 (PUINT_8) prBcnFrame->aucInfoElem,
+					 prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem));
+
+}				/* end of bssUpdateBeaconContent() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to the given
+*        Destination Address.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] eNetTypeIndex      Specify which network reply the Probe Response.
+* @param[in] pucDestAddr        Pointer to the Destination Address to reply
+* @param[in] u4ControlFlags     Control flags for information on Probe Response.
+*
+* @retval WLAN_STATUS_RESOURCE  No available resources to send frame.
+* @retval WLAN_STATUS_SUCCESS   Success.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter,
+			   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+			   IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_MSDU_INFO_T prMsduInfo;
+	UINT_16 u2EstimatedFrameLen;
+	UINT_16 u2EstimatedFixedIELen;
+	UINT_16 u2EstimatedExtraIELen;
+	P_APPEND_VAR_IE_ENTRY_T prIeArray = NULL;
+	UINT_32 u4IeArraySize = 0;
+	UINT_32 i;
+
+	ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+	if (!pucDestAddr) {	/* For Beacon */
+		prIeArray = &txBcnIETable[0];
+		u4IeArraySize = sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T);
+	} else {
+		prIeArray = &txProbRspIETable[0];
+		u4IeArraySize = sizeof(txProbRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T);
+	}
+
+	/* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */
+	/* Allocate a MSDU_INFO_T */
+
+	/* Init with MGMT Header Length + Length of Fixed Fields + Common IE Fields */
+	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD +
+	    WLAN_MAC_MGMT_HEADER_LEN +
+	    TIMESTAMP_FIELD_LEN +
+	    BEACON_INTERVAL_FIELD_LEN +
+	    CAP_INFO_FIELD_LEN +
+	    (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) +
+	    (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) +
+	    (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) +
+	    (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP));
+
+	/* + Extra IE Length */
+	u2EstimatedExtraIELen = 0;
+
+	for (i = 0; i < u4IeArraySize; i++) {
+		u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen;
+
+		if (u2EstimatedFixedIELen) {
+			u2EstimatedExtraIELen += u2EstimatedFixedIELen;
+		} else {
+			ASSERT(prIeArray[i].pfnCalculateVariableIELen);
+
+			u2EstimatedExtraIELen += (UINT_16)
+			    prIeArray[i].pfnCalculateVariableIELen(prAdapter, eNetTypeIndex, NULL);
+		}
+	}
+
+	u2EstimatedFrameLen += u2EstimatedExtraIELen;
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", ((!pucDestAddr) ? "Beacon" : "Probe Response"));
+		return WLAN_STATUS_RESOURCES;
+	}
+	/* 4 <2> Compose Beacon/Probe Response frame header and fixed fields in MSDU_INfO_T. */
+	/* Compose Header and Fixed Field */
+#if CFG_ENABLE_WIFI_DIRECT
+	if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) {
+		if (prAdapter->fgIsP2PRegistered) {
+			bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8)
+								  ((ULONG) (prMsduInfo->prPacket) +
+								   MAC_TX_RESERVED_FIELD), pucDestAddr,
+								  prAdapter->rWifiVar.aucDeviceAddress,
+								  prAdapter->rWifiVar.aucDeviceAddress,
+								  DOT11_BEACON_PERIOD_DEFAULT,
+								  (prBssInfo->u2CapInfo &
+								   ~(CAP_INFO_ESS | CAP_INFO_IBSS)));
+		}
+	} else
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+	{
+		bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8)
+							  ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+							  pucDestAddr, prBssInfo->aucOwnMacAddr, prBssInfo->aucBSSID,
+							  prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo);
+	}
+
+	/* 4 <3> Update information of MSDU_INFO_T */
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = 0xFF;
+	prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN +
+				     TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN);
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = NULL;
+	prMsduInfo->fgIsBasicRate = TRUE;
+
+	/* 4 <4> Compose the frame body's Common IEs of the Beacon/ProbeResp  frame. */
+	bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, pucDestAddr);
+
+	/* 4 <5> Compose IEs in MSDU_INFO_T */
+
+	/* Append IE */
+	for (i = 0; i < u4IeArraySize; i++) {
+		if (prIeArray[i].pfnAppendIE)
+			prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo);
+	}
+
+	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
+
+	/* 4 <6> Inform TXM  to send this Beacon /Probe Response frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of bssSendBeaconProbeResponse() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will process the Rx Probe Request Frame and then send
+*        back the corresponding Probe Response Frame if the specified conditions
+*        were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Always return success
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_WLAN_MAC_MGMT_HEADER_T prMgtHdr;
+	P_BSS_INFO_T prBssInfo;
+	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;
+	UINT_8 aucBCBSSID[] = BC_BSSID;
+	BOOLEAN fgIsBcBssid;
+	BOOLEAN fgReplyProbeResp;
+	UINT_32 u4CtrlFlagsForProbeResp = 0;
+	ENUM_BAND_T eBand;
+	UINT_8 ucHwChannelNum;
+
+	ASSERT(prSwRfb);
+
+	/* 4 <1> Parse Probe Req and Get BSSID */
+	prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader;
+
+	if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID))
+		fgIsBcBssid = TRUE;
+	else
+		fgIsBcBssid = FALSE;
+
+	/* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */
+	for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) {
+
+		if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex))
+			continue;
+
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+		if ((!fgIsBcBssid) && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID))
+			continue;
+
+		eBand = HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr);
+		ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr);
+
+		if (prBssInfo->eBand != eBand)
+			continue;
+
+		if (prBssInfo->ucPrimaryChannel != ucHwChannelNum)
+			continue;
+
+		fgReplyProbeResp = FALSE;
+
+		if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) {
+
+#if CFG_SUPPORT_ADHOC
+			fgReplyProbeResp = aisValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp);
+#endif
+		}
+#if CFG_ENABLE_WIFI_DIRECT
+		else if ((prAdapter->fgIsP2PRegistered) && (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex)) {
+			if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) {
+				/* Resource margin is enough */
+				fgReplyProbeResp =
+				    p2pFuncValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp);
+			}
+		}
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+		else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex)
+			fgReplyProbeResp = bowValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp);
+#endif
+
+		if (fgReplyProbeResp) {
+			if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) {
+				/* Resource margin is enough */
+				bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr,
+							   u4CtrlFlagsForProbeResp);
+			}
+		}
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of bssProcessProbeRequest() */
+
+#if 0				/* NOTE(Kevin): condition check should move to P2P_FSM.c */
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will process the Rx Probe Request Frame and then send
+*        back the corresponding Probe Response Frame if the specified conditions
+*        were matched.
+*
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Always return success
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_WLAN_MAC_MGMT_HEADER_T prMgtHdr;
+	P_BSS_INFO_T prBssInfo;
+	P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
+	P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL;
+	P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL;
+	PUINT_8 pucIE;
+	UINT_16 u2IELength;
+	UINT_16 u2Offset = 0;
+	UINT_8 aucBCBSSID[] = BC_BSSID;
+	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;
+	BOOLEAN fgReplyProbeResp;
+#if CFG_ENABLE_WIFI_DIRECT
+	BOOLEAN fgP2PTargetDeviceFound;
+	UINT_8 aucP2PWildcardSSID[] = P2P_WILDCARD_SSID;
+#endif
+
+	ASSERT(prSwRfb);
+
+	/* 4 <1> Parse Probe Req and Get SSID IE ptr */
+	prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader;
+
+	u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen;
+	pucIE = (PUINT_8) ((UINT_32) prSwRfb->pvHeader + prSwRfb->u2HeaderLen);
+
+	prIeSsid = (P_IE_SSID_T) NULL;
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_SSID:
+			if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID))
+				prIeSsid = (P_IE_SSID_T) pucIE;
+			break;
+
+		case ELEM_ID_SUP_RATES:
+			/* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
+			 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
+			 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
+			 */
+			/* if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SUP_RATES) { */
+			if (IE_LEN(pucIE) <= RATE_NUM)
+				prIeSupportedRate = SUP_RATES_IE(pucIE);
+			break;
+
+		case ELEM_ID_EXTENDED_SUP_RATES:
+			prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
+			break;
+
+#if CFG_ENABLE_WIFI_DIRECT
+			/* TODO: P2P IE & WCS IE parsing for P2P. */
+		case ELEM_ID_P2P:
+
+			break;
+#endif
+
+			/* no default */
+		}
+	}			/* end of IE_FOR_EACH */
+
+	/* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */
+	for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) {
+
+		if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex))
+			continue;
+
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+		if (UNEQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID) &&
+		    UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) {
+			/* BSSID not Wildcard BSSID. */
+			continue;
+		}
+
+		fgReplyProbeResp = FALSE;
+
+		if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) {
+
+			if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
+
+				/* TODO(Kevin): Check if we are IBSS Master. */
+				if (TRUE && prIeSsid) {
+					if ((prIeSsid->ucLength == BC_SSID_LEN) ||	/* WILDCARD SSID */
+					    EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen,
+						       prIeSsid->aucSSID, prIeSsid->ucLength)) {
+						fgReplyProbeResp = TRUE;
+					}
+				}
+			}
+		}
+#if CFG_ENABLE_WIFI_DIRECT
+		else if (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex) {
+
+			/* TODO(Kevin): Move following lines to p2p_fsm.c */
+
+			if ((prIeSsid) &&
+			    ((prIeSsid->ucLength == BC_SSID_LEN) ||
+			     (EQUAL_SSID(aucP2PWildcardSSID,
+					 P2P_WILDCARD_SSID_LEN, prIeSsid->aucSSID, prIeSsid->ucLength)))) {
+				/* if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prMgtHdr->aucSrcAddr,
+					pucIE, u2IELength)) { */
+				if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prSwRfb)) {
+					/* Extand channel request time & cancel scan request. */
+					P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+
+					/* TODO: RX probe request may not caused by LISTEN state. */
+					/* TODO: It can be GO. */
+					/* Generally speaking, cancel a non-exist scan request is fine.
+					 * We can check P2P FSM here for only LISTEN state.
+					 */
+
+					P_MSG_SCN_SCAN_CANCEL prScanCancelMsg;
+
+					prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+					/* Abort JOIN process. */
+					prScanCancelMsg =
+					    (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG,
+										sizeof(MSG_SCN_SCAN_CANCEL));
+					if (!prScanCancelMsg) {
+						ASSERT(0);	/* Can't abort SCN FSM */
+						continue;
+					}
+
+					prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL;
+					prScanCancelMsg->ucSeqNum = prP2pFsmInfo->ucSeqNumOfScnMsg;
+					prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX;
+					prScanCancelMsg->fgIsChannelExt = TRUE;
+
+					mboxSendMsg(prAdapter,
+						    MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF);
+				}
+			} else {
+				/* 1. Probe Request without SSID.
+				 * 2. Probe Request with SSID not Wildcard SSID & not P2P Wildcard SSID.
+				 */
+				continue;
+			}
+
+#if 0				/* Frog */
+			if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_LISTEN) {
+				/* P2P 2.4.1 - P2P Devices shall not respond to Probe Request frames
+				which only contain 11b rates only. */
+				if (prIeSupportedRate || prIeExtSupportedRate) {
+					UINT_16 u2OperationalRateSet, u2BSSBasicRateSet;
+					BOOLEAN fgIsUnknownBssBasicRate;
+
+					rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate,
+							      &u2OperationalRateSet,
+							      &u2BSSBasicRateSet,	/* Ignore any Basic Bit */
+							      &fgIsUnknownBssBasicRate);
+
+					if (u2OperationalRateSet & ~RATE_SET_HR_DSSS)
+						continue;
+				}
+			}
+			/* TODO: Check channel time before first check point to: */
+			/* If Target device is selected:
+			 *     1. Send XXXX request frame.
+			 * else
+			 *     1. Send Probe Response frame.
+			 */
+
+			if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
+				/* TODO(Kevin): During PROVISION state, can we reply Probe Response ? */
+
+				/* TODO(Kevin):
+				 * If we are GO, accept legacy client --> accept Wildcard SSID
+				 * If we are in Listen State, accept only P2P Device --> check P2P IE and WPS IE
+				 */
+				if (TRUE /* We are GO */ && prIeSsid) {
+					UINT_8 aucSSID[] = P2P_WILDCARD_SSID;
+
+					if ((prIeSsid->ucLength == BC_SSID_LEN) ||	/* WILDCARD SSID */
+					    EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen,
+						       prIeSsid->aucSSID, prIeSsid->ucLength) ||
+					    EQUAL_SSID(aucSSID, P2P_WILDCARD_SSID_LEN,
+						       prIeSsid->aucSSID, prIeSsid->ucLength)) {
+						fgReplyProbeResp = TRUE;
+					}
+				}
+/* else if (FALSE) { */ /* We are in Listen State */
+/* } */
+
+				/* TODO(Kevin): Check P2P IE and WPS IE */
+			}
+#endif
+		}
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+		else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) {
+
+			if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
+				/* Do nothing */
+				/* TODO(Kevin): TBD */
+			}
+		}
+#endif
+		else
+			ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+		if (fgReplyProbeResp)
+			bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr);
+
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of bssProcessProbeRequest() */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to clear the client list for AdHoc or AP Mode
+*
+* @param[in] prAdapter              Pointer to the Adapter structure.
+* @param[in] prBssInfo              Given related BSS_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
+{
+	P_LINK_T prStaRecOfClientList;
+
+	ASSERT(prBssInfo);
+
+	prStaRecOfClientList = &prBssInfo->rStaRecOfClientList;
+
+	if (!LINK_IS_EMPTY(prStaRecOfClientList)) {
+		P_STA_RECORD_T prPeerStaRec;
+
+		LINK_FOR_EACH_ENTRY(prPeerStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) {
+			cnmStaRecChangeState(prAdapter, prPeerStaRec, STA_STATE_1);
+		}
+
+		LINK_INITIALIZE(prStaRecOfClientList);
+	}
+
+}				/* end of bssClearClientList() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to Add a STA_RECORD_T to the client list for AdHoc or AP Mode
+*
+* @param[in] prAdapter              Pointer to the Adapter structure.
+* @param[in] prBssInfo              Given related BSS_INFO_T.
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec)
+{
+	P_LINK_T prStaRecOfClientList;
+
+	ASSERT(prBssInfo);
+
+	prStaRecOfClientList = &prBssInfo->rStaRecOfClientList;
+
+	if (!LINK_IS_EMPTY(prStaRecOfClientList)) {
+		P_STA_RECORD_T prCurrStaRec;
+
+		LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) {
+
+			if (prCurrStaRec == prStaRec) {
+				DBGLOG(BSS, WARN,
+				       "Current Client List already contains that STA_RECORD_T[%pM]\n",
+					prStaRec->aucMacAddr);
+				return;
+			}
+		}
+	}
+
+	LINK_INSERT_TAIL(prStaRecOfClientList, &prStaRec->rLinkEntry);
+
+}				/* end of bssAddStaRecToClientList() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to Remove a STA_RECORD_T from the client list for AdHoc or AP Mode
+*
+* @param[in] prAdapter              Pointer to the Adapter structure.
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec)
+{
+	P_LINK_T prStaRecOfClientList;
+
+	ASSERT(prBssInfo);
+
+	prStaRecOfClientList = &prBssInfo->rStaRecOfClientList;
+
+#if 0
+	if (!LINK_IS_EMPTY(prStaRecOfClientList)) {
+		P_STA_RECORD_T prCurrStaRec;
+
+		LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) {
+
+			if (prCurrStaRec == prStaRec) {
+
+				LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry);
+
+				return;
+			}
+		}
+	}
+#endif
+	if (!LINK_IS_EMPTY(prStaRecOfClientList)) {
+
+		P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+
+		LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
+			if ((ULONG) prStaRec == (ULONG) prLinkEntry) {
+				LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry);
+				return;
+			}
+		}
+	}
+
+	DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T[%pM] before removing.\n",
+			   prStaRec->aucMacAddr);
+
+}				/* end of bssRemoveStaRecFromClientList() */
+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Get station record by Address for AP mode
+*
+* @param[in] prBssInfo              Pointer to BSS_INFO_T.
+* @param[in] pucMacAddr               Pointer to target mac address
+*
+* @return pointer of STA_RECORD_T if found, otherwise, return NULL
+*/
+/*----------------------------------------------------------------------------*/
+
+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr)
+{
+	P_LINK_T prStaRecOfClientList;
+
+	ASSERT(prBssInfo);
+	ASSERT(pucMacAddr);
+
+	prStaRecOfClientList = &prBssInfo->rStaRecOfClientList;
+	if (!LINK_IS_EMPTY(prStaRecOfClientList)) {
+		P_STA_RECORD_T prCurrStaRec;
+
+		LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) {
+			if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMacAddr))
+				return prCurrStaRec;
+		}
+	}
+	return NULL;
+}
+
+#if CFG_SUPPORT_ADHOC
+/*----------------------------------------------------------------------------*/
+/* Routines for IBSS(AdHoc) only                                              */
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to process Beacons from current Ad-Hoc network peers.
+*        We also process Beacons from other Ad-Hoc network during SCAN. If it has
+*        the same SSID and we'll decide to merge into it if it has a larger TSF.
+*
+* @param[in] prAdapter  Pointer to the Adapter structure.
+* @param[in] prBssInfo  Pointer to the BSS_INFO_T.
+* @param[in] prBSSDesc  Pointer to the BSS Descriptor.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter,
+			 IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI)
+{
+	P_STA_RECORD_T prStaRec = NULL;
+
+	BOOLEAN fgIsCheckCapability = FALSE;
+	BOOLEAN fgIsCheckTSF = FALSE;
+	BOOLEAN fgIsGoingMerging = FALSE;
+	BOOLEAN fgIsSameBSSID;
+
+	ASSERT(prBssInfo);
+	ASSERT(prBssDesc);
+
+	/* 4 <1> Process IBSS Beacon only after we create or merge with other IBSS. */
+	if (!prBssInfo->fgIsBeaconActivated)
+		return;
+	/* 4 <2> Get the STA_RECORD_T of TA. */
+	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prBssDesc->aucSrcAddr);
+
+	fgIsSameBSSID = UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID) ? FALSE : TRUE;
+
+	/* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */
+	if (fgIsSameBSSID) {
+
+		/* Same BSSID:
+		 * Case I.  This is a new TA and it has decide to merged with us.
+		 *      a)  If fgIsMerging == FALSE - we will send msg to notify AIS.
+		 *      b)  If fgIsMerging == TRUE - already notify AIS.
+		 * Case II. This is an old TA and we've already merged together.
+		 */
+		if (!prStaRec) {
+
+			/* For Case I - Check this IBSS's capability first before adding this Sta Record. */
+			fgIsCheckCapability = TRUE;
+
+			/* If check is passed, then we perform merging with this new IBSS */
+			fgIsGoingMerging = TRUE;
+
+		} else {
+
+			ASSERT((prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) && IS_ADHOC_STA(prStaRec));
+
+			if (prStaRec->ucStaState != STA_STATE_3) {
+
+				if (!prStaRec->fgIsMerging) {
+
+					/* For Case I - Check this IBSS's capability first
+					 * before adding this Sta Record. */
+					fgIsCheckCapability = TRUE;
+
+					/* If check is passed, then we perform merging with this new IBSS */
+					fgIsGoingMerging = TRUE;
+				} else {
+					/* For Case II - Update rExpirationTime of Sta Record */
+					GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);
+				}
+			} else {
+				/* For Case II - Update rExpirationTime of Sta Record */
+				GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);
+			}
+
+		}
+	} else {
+
+		/* Unequal BSSID:
+		 * Case III. This is a new TA and we need to compare the TSF and get the winner.
+		 * Case IV.  This is an old TA and it merge into a new IBSS before we do the same thing.
+		 *           We need to compare the TSF to get the winner.
+		 * Case V.   This is an old TA and it restart a new IBSS. We also need to
+		 *           compare the TSF to get the winner.
+		 */
+
+		/* For Case III, IV & V - We'll always check this new IBSS's capability first
+		 * before merging into new IBSS.
+		 */
+		fgIsCheckCapability = TRUE;
+
+		/* If check is passed, we need to perform TSF check to decide the major BSSID */
+		fgIsCheckTSF = TRUE;
+
+		/* For Case IV & V - We won't update rExpirationTime of Sta Record */
+	}
+
+	/* 4 <7> Check this BSS_DESC_T's capability. */
+	if (fgIsCheckCapability) {
+		BOOLEAN fgIsCapabilityMatched = FALSE;
+
+		do {
+			if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
+				DBGLOG(BSS, LOUD,
+				       "IBSS MERGE: Ignore Peer MAC: %pM - Unsupported Phy.\n",
+					prBssDesc->aucSrcAddr);
+
+				break;
+			}
+
+			if (prBssDesc->fgIsUnknownBssBasicRate) {
+				DBGLOG(BSS, LOUD,
+				       "IBSS MERGE: Ignore Peer MAC: %pM - Unknown Basic Rate.\n",
+					prBssDesc->aucSrcAddr);
+
+				break;
+			}
+
+			if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
+				DBGLOG(BSS, LOUD,
+				       "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n",
+					prBssDesc->aucSrcAddr);
+
+				break;
+			}
+
+			fgIsCapabilityMatched = TRUE;
+		} while (FALSE);
+
+		if (!fgIsCapabilityMatched) {
+
+			if (prStaRec) {
+				/* For Case II - We merge this STA_RECORD in RX Path.
+				 *     Case IV & V - They change their BSSID after we merge with them.
+				 */
+
+				DBGLOG(BSS, LOUD,
+				       "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n",
+					prBssDesc->aucSrcAddr);
+			}
+
+			return;
+		}
+
+		DBGLOG(BSS, LOUD,
+		       "IBSS MERGE: Peer MAC: %pM - Check capability was passed.\n",
+			prBssDesc->aucSrcAddr);
+	}
+
+	if (fgIsCheckTSF) {
+#if CFG_SLT_SUPPORT
+		fgIsGoingMerging = TRUE;
+#else
+		if (prBssDesc->fgIsLargerTSF)
+			fgIsGoingMerging = TRUE;
+		else
+			return;
+#endif
+	}
+
+	if (fgIsGoingMerging) {
+		P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg;
+
+		/* 4 <1> We will merge with to this BSS immediately. */
+		prBssDesc->fgIsConnecting = TRUE;
+		prBssDesc->fgIsConnected = FALSE;
+
+		/* 4 <2> Setup corresponding STA_RECORD_T */
+		prStaRec = bssCreateStaRecFromBssDesc(prAdapter,
+						      STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc);
+
+		if (!prStaRec) {
+			/* no memory ? */
+			return;
+		}
+
+		prStaRec->fgIsMerging = TRUE;
+
+		/* update RCPI */
+		prStaRec->ucRCPI = ucRCPI;
+
+		/* 4 <3> Send Merge Msg to CNM to obtain the channel privilege. */
+		prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T)
+		    cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_IBSS_PEER_FOUND_T));
+
+		if (!prAisIbssPeerFoundMsg) {
+
+			ASSERT(0);	/* Can't send Merge Msg */
+			return;
+		}
+
+		prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS;
+		prAisIbssPeerFoundMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX;
+		prAisIbssPeerFoundMsg->prStaRec = prStaRec;
+
+		/* Inform AIS to do STATE TRANSITION
+		 * For Case I - If AIS in IBSS_ALONE, let it jump to NORMAL_TR after we know the new member.
+		 * For Case III, IV - Now this new BSSID wins the TSF, follow it.
+		 */
+		if (fgIsSameBSSID) {
+			prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE;
+		} else {
+#if CFG_SLT_SUPPORT
+			prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE;
+#else
+			prAisIbssPeerFoundMsg->fgIsMergeIn = (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE;
+#endif
+		}
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisIbssPeerFoundMsg, MSG_SEND_METHOD_BUF);
+
+	}
+
+}				/* end of ibssProcessMatchedBeacon() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will check the Capability for Ad-Hoc to decide if we are
+*        able to merge with(same capability).
+*
+* @param[in] prBSSDesc  Pointer to the BSS Descriptor.
+*
+* @retval WLAN_STATUS_FAILURE   Can't pass the check of Capability.
+* @retval WLAN_STATUS_SUCCESS   Pass the check of Capability.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+
+	ASSERT(prBssDesc);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	do {
+		/* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */
+		if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) &&
+		    (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) {
+			break;
+		} else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) &&
+			   (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) {
+			break;
+		}
+		/* 4 <2> Check the Short Slot Time. */
+#if 0				/* Do not check ShortSlotTime until Wi-Fi define such policy */
+		if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) {
+			if (((prConnSettings->fgIsShortSlotTimeOptionEnable) &&
+			     !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) ||
+			    (!(prConnSettings->fgIsShortSlotTimeOptionEnable) &&
+			     (prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))) {
+				break;
+			}
+		}
+#endif
+
+		/* 4 <3> Check the ATIM window setting. */
+		if (prBssDesc->u2ATIMWindow) {
+			DBGLOG(BSS, INFO, "AdHoc PS was not supported(ATIM Window: %d)\n", prBssDesc->u2ATIMWindow);
+			break;
+		}
+#if CFG_RSN_MIGRATION
+		/* 4 <4> Check the Security setting. */
+		if (!rsnPerformPolicySelection(prAdapter, prBssDesc))
+			break;
+#endif
+
+		rStatus = WLAN_STATUS_SUCCESS;
+	} while (FALSE);
+
+	return rStatus;
+
+}				/* end of ibssCheckCapabilityForAdHocMode() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will initial the BSS_INFO_T for IBSS Mode.
+*
+* @param[in] prBssInfo      Pointer to the BSS_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
+{
+	UINT_8 ucLowestBasicRateIndex;
+	UINT_8 aucBSSID[MAC_ADDR_LEN];
+	PUINT_16 pu2BSSID = (PUINT_16) &aucBSSID[0];
+	UINT_32 i;
+
+	ASSERT(prBssInfo);
+	ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_IBSS);
+
+	/* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */
+	prBssInfo->ucNonHTBasicPhyType = (UINT_8)
+	    rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
+	prBssInfo->u2BSSBasicRateSet = rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;
+
+	prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;
+
+	rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet,
+				    prBssInfo->u2BSSBasicRateSet,
+				    prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen);
+
+	/* 4 <2> Setup BSSID */
+	if (!prBssInfo->fgHoldSameBssidForIBSS) {
+
+		for (i = 0; i < sizeof(aucBSSID) / sizeof(UINT_16); i++)
+			pu2BSSID[i] = (UINT_16) (kalRandomNumber() & 0xFFFF);
+
+		aucBSSID[0] &= ~0x01;	/* 7.1.3.3.3 - The individual/group bit of the address is set to 0. */
+		aucBSSID[0] |= 0x02;	/* 7.1.3.3.3 - The universal/local bit of the address is set to 1. */
+
+		COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID);
+	}
+	/* 4 <3> Setup Capability - Short Preamble */
+	if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented &&
+	   ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */
+	    (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) {
+		prBssInfo->fgIsShortPreambleAllowed = TRUE;
+		prBssInfo->fgUseShortPreamble = TRUE;
+	} else {
+		prBssInfo->fgIsShortPreambleAllowed = FALSE;
+		prBssInfo->fgUseShortPreamble = FALSE;
+	}
+
+	/* 4 <4> Setup Capability - Short Slot Time */
+	/* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */
+	prBssInfo->fgUseShortSlotTime = FALSE;	/* Set to FALSE for AdHoc */
+
+	/* 4 <5> Compoase Capability */
+	prBssInfo->u2CapInfo = CAP_INFO_IBSS;
+
+	if (prBssInfo->fgIsProtection)
+		prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY;
+
+	if (prBssInfo->fgIsShortPreambleAllowed)
+		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE;
+
+	if (prBssInfo->fgUseShortSlotTime)
+		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
+	/* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
+	rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex);
+
+	prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex];
+
+}				/* end of ibssInitForAdHoc() */
+
+#endif /* CFG_SUPPORT_ADHOC */
+
+#if CFG_SUPPORT_AAA
+
+/*----------------------------------------------------------------------------*/
+/* Routines for BSS(AP) only                                                  */
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will initial the BSS_INFO_T for AP Mode.
+*
+* @param[in] prBssInfo              Given related BSS_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate)
+{
+	UINT_8 ucLowestBasicRateIndex;
+
+	P_AC_QUE_PARMS_T prACQueParms;
+
+	ENUM_WMM_ACI_T eAci;
+
+	UINT_8 auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ };
+	UINT_8 auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 };
+	UINT_8 auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 };
+	UINT_8 auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 };	/* If the AP is OFDM */
+
+	UINT_8 auCWminLog2[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ };
+	UINT_8 auCWmaxLog2[WMM_AC_INDEX_NUM] = { 7, 10, 4, 3 };
+	UINT_8 auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 };
+	UINT_8 auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 };	/* If the AP is OFDM */
+
+	DEBUGFUNC("bssInitForAP");
+	DBGLOG(BSS, LOUD, "\n");
+
+	ASSERT(prBssInfo);
+	ASSERT((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || (prBssInfo->eCurrentOPMode == OP_MODE_BOW));
+
+#if 0
+	prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE;
+	prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M;
+	prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M;
+#endif
+
+	/* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */
+	prBssInfo->ucNonHTBasicPhyType = (UINT_8)
+	    rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
+	prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;
+
+	prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;
+
+	if (fgIsRateUpdate) {
+		rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet,
+					    prBssInfo->u2BSSBasicRateSet,
+					    prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen);
+	}
+	/* 4 <2> Setup BSSID */
+	COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr);
+
+	/* 4 <3> Setup Capability - Short Preamble */
+	if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented &&
+	   ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */
+	    (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) {
+		prBssInfo->fgIsShortPreambleAllowed = TRUE;
+		prBssInfo->fgUseShortPreamble = TRUE;
+	} else {
+		prBssInfo->fgIsShortPreambleAllowed = FALSE;
+		prBssInfo->fgUseShortPreamble = FALSE;
+	}
+
+	/* 4 <4> Setup Capability - Short Slot Time */
+	prBssInfo->fgUseShortSlotTime = TRUE;
+
+	/* 4 <5> Compoase Capability */
+	prBssInfo->u2CapInfo = CAP_INFO_ESS;
+
+	if (prBssInfo->fgIsProtection)
+		prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY;
+
+	if (prBssInfo->fgIsShortPreambleAllowed)
+		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE;
+
+	if (prBssInfo->fgUseShortSlotTime)
+		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
+	/* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
+	rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex);
+
+	prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex];
+
+	/* 4 <7> Fill the EDCA */
+
+	prACQueParms = prBssInfo->arACQueParmsForBcast;
+
+	for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {
+
+		prACQueParms[eAci].fgIsACMSet = FALSE;
+		prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci];
+		prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1;
+		prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1;
+		prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci];
+
+		prBssInfo->aucCWminLog2ForBcast[eAci] = auCWminLog2ForBcast[eAci];	/* used to send WMM IE */
+		prBssInfo->aucCWmaxLog2ForBcast[eAci] = auCWmaxLog2ForBcast[eAci];
+
+		DBGLOG(BSS, INFO, "Bcast: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n",
+				   eAci, prACQueParms[eAci].fgIsACMSet,
+				   prACQueParms[eAci].u2Aifsn,
+				   prACQueParms[eAci].u2CWmin,
+				   prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit);
+
+	}
+
+	prACQueParms = prBssInfo->arACQueParms;
+
+	for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {
+
+		prACQueParms[eAci].fgIsACMSet = FALSE;
+		prACQueParms[eAci].u2Aifsn = auAifs[eAci];
+		prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1;
+		prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1;
+		prACQueParms[eAci].u2TxopLimit = auTxop[eAci];
+
+		DBGLOG(BSS, INFO, "eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n",
+				   eAci, prACQueParms[eAci].fgIsACMSet,
+				   prACQueParms[eAci].u2Aifsn,
+				   prACQueParms[eAci].u2CWmin,
+				   prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit);
+	}
+
+	/* Note: Caller should update the EDCA setting to HW by nicQmUpdateWmmParms() it there is no AIS network */
+	/* Note: In E2, only 4 HW queues. The the Edca parameters should be folow by AIS network */
+	/* Note: In E3, 8 HW queues.  the Wmm parameters should be updated to right queues  according to BSS */
+
+}				/* end of bssInitForAP() */
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Update DTIM Count
+*
+* @param[in] eNetTypeIndex      Specify which network to update
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+	if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
+
+		/* Setup DTIM Count for next TBTT. */
+		if (prBssInfo->ucDTIMCount > 0) {
+			prBssInfo->ucDTIMCount--;
+		} else {
+
+			ASSERT(prBssInfo->ucDTIMPeriod > 0);
+
+			prBssInfo->ucDTIMCount = prBssInfo->ucDTIMPeriod - 1;
+		}
+	}
+
+}				/* end of bssUpdateDTIMIE() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to set the Virtual Bitmap in TIM Information Elements
+*
+* @param[in] prBssInfo      Pointer to the BSS_INFO_T.
+* @param[in] u2AssocId      The association id to set in Virtual Bitmap.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId)
+{
+
+	ASSERT(prBssInfo);
+
+	if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
+		P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;
+
+		prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo);
+
+		/* Use Association ID == 0 for BMCAST indication */
+		if (u2AssocId == 0) {
+
+			prP2pSpecificBssInfo->ucBitmapCtrl |= (UINT_8) BIT(0);
+		} else {
+			PUINT_8 pucPartialVirtualBitmap;
+			UINT_8 ucBitmapToSet;
+
+			/* (u2AssocId / 8) */
+			pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)];
+			ucBitmapToSet = (UINT_8) BIT((u2AssocId % 8));
+
+			if (*pucPartialVirtualBitmap & ucBitmapToSet) {
+				/* The virtual bitmap has been set */
+				return;
+			}
+
+			*pucPartialVirtualBitmap |= ucBitmapToSet;
+
+			/* Update u2SmallestAID and u2LargestAID */
+			if ((u2AssocId < prP2pSpecificBssInfo->u2SmallestAID) ||
+			    (prP2pSpecificBssInfo->u2SmallestAID == 0)) {
+				prP2pSpecificBssInfo->u2SmallestAID = u2AssocId;
+			}
+
+			if ((u2AssocId > prP2pSpecificBssInfo->u2LargestAID) ||
+			    (prP2pSpecificBssInfo->u2LargestAID == 0)) {
+				prP2pSpecificBssInfo->u2LargestAID = u2AssocId;
+			}
+		}
+	}
+
+}				/* end of bssSetTIMBitmap() */
+#endif
+
+#endif /* CFG_SUPPORT_AAA */
+
+VOID bssCreateStaRecFromAuth(IN P_ADAPTER_T prAdapter)
+{
+
+}
+
+VOID bssUpdateStaRecFromAssocReq(IN P_ADAPTER_T prAdapter)
+{
+
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c
new file mode 100644
index 0000000000000..39af02df2af29
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c
@@ -0,0 +1,738 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm.c#2
+*/
+
+/*! \file   "cnm.c"
+    \brief  Module of Concurrent Network Management
+
+    Module of Concurrent Network Management
+*/
+
+/*
+** Log: cnm.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 11 15 2011 cm.chang
+ * NULL
+ * Fix possible wrong message when P2P is unregistered
+ *
+ * 11 14 2011 yuche.tsai
+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
+ * Fix large network type index assert in FW issue.
+ *
+ * 11 10 2011 cm.chang
+ * NULL
+ * Modify debug message for XLOG
+ *
+ * 11 08 2011 cm.chang
+ * NULL
+ * Add RLM and CNM debug message for XLOG
+ *
+ * 11 01 2011 cm.chang
+ * [WCXRP00001077] [All Wi-Fi][Driver] Fix wrong preferred channel for AP and BOW
+ * Only check AIS channel for P2P and BOW
+ *
+ * 10 25 2011 cm.chang
+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
+ * Extension channel of some 5G AP will not follow regulation requirement
+ *
+ * 09 30 2011 cm.chang
+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band
+ * .
+ *
+ * 09 01 2011 cm.chang
+ * [WCXRP00000937] [MT6620 Wi-Fi][Driver][FW] cnm.c line #848 assert when doing monkey test
+ * Print message only in Linux platform for monkey testing
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * change parameter name from PeerAddr to BSSID
+ *
+ * 06 20 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * 1. specify target's BSSID when requesting channel privilege.
+ * 2. pass BSSID information to firmware domain
+ *
+ * 06 01 2011 cm.chang
+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function
+ * Limit AIS to fixed channel same with BOW
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 03 10 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Check if P2P network index is Tethering AP
+ *
+ * 03 10 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel
+ *
+ * 02 17 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * When P2P registried, invoke BOW deactivate function
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Provide function to decide if BSS can be activated or not
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 11 08 2010 cm.chang
+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID
+ * Remove CNM channel reover message ID
+ *
+ * 10 13 2010 cm.chang
+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
+ * Add exception handle when cmd buffer is not available
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 07 19 2010 wh.su
+ *
+ * update for security supporting.
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Fix wrong message ID for channel grant to requester
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Modify CNM message handler for new flow
+ *
+ * 06 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Set 20/40M bandwidth of AP HT OP before association process
+ *
+ * 05 31 2010 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling
+ *
+ * 05 21 2010 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support TCP/UDP/IP Checksum offload feature
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 05 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add a new function to send abort message
+ *
+ * 04 27 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * BMC mac address shall be ignored in basic config command
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support change of MAC address by host command
+ *
+ * 04 16 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * adding the wpa-none for ibss beacon.
+ *
+ * 04 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Fix bug for OBSS scan
+ *
+ * 03 30 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support 2.4G OBSS scan
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ *  *  *  *  *  *  *  *  *  * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 25 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * use the Rx0 dor event indicate.
+ *
+ * 02 08 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support partial part about cmd basic configuration
+ *
+ * Dec 10 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Remove conditional compiling FPGA_V5
+ *
+ * Nov 18 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add function cnmFsmEventInit()
+ *
+ * Nov 2 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to initialize variables in CNM_INFO_T.
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmInit(P_ADAPTER_T prAdapter)
+{
+
+}				/* end of cnmInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to initialize variables in CNM_INFO_T.
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmUninit(P_ADAPTER_T prAdapter)
+{
+
+}				/* end of cnmUninit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Before handle the message from other module, it need to obtain
+*        the Channel privilege from Channel Manager
+*
+* @param[in] prMsgHdr   The message need to be handled.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_CH_REQ_T prMsgChReq;
+	P_CMD_CH_PRIVILEGE_T prCmdBody;
+	WLAN_STATUS rStatus;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prMsgChReq = (P_MSG_CH_REQ_T) prMsgHdr;
+
+	prCmdBody = (P_CMD_CH_PRIVILEGE_T)
+	    cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T));
+	ASSERT(prCmdBody);
+
+	/* To do: exception handle */
+	if (!prCmdBody) {
+		DBGLOG(CNM, ERROR, "ChReq: fail to get buf (net=%d, token=%d)\n",
+				    prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID);
+
+		cnmMemFree(prAdapter, prMsgHdr);
+		return;
+	}
+
+	DBGLOG(CNM, INFO, "ChReq net=%d token=%d b=%d c=%d s=%d\n",
+			   prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID,
+			   prMsgChReq->eRfBand, prMsgChReq->ucPrimaryChannel, prMsgChReq->eRfSco);
+
+	prCmdBody->ucNetTypeIndex = prMsgChReq->ucNetTypeIndex;
+	prCmdBody->ucTokenID = prMsgChReq->ucTokenID;
+	prCmdBody->ucAction = CMD_CH_ACTION_REQ;	/* Request */
+	prCmdBody->ucPrimaryChannel = prMsgChReq->ucPrimaryChannel;
+	prCmdBody->ucRfSco = (UINT_8) prMsgChReq->eRfSco;
+	prCmdBody->ucRfBand = (UINT_8) prMsgChReq->eRfBand;
+	prCmdBody->ucReqType = (UINT_8) prMsgChReq->eReqType;
+	prCmdBody->ucReserved = 0;
+	prCmdBody->u4MaxInterval = prMsgChReq->u4MaxInterval;
+	COPY_MAC_ADDR(prCmdBody->aucBSSID, prMsgChReq->aucBSSID);
+
+	ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	/* For monkey testing 20110901 */
+	if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM)
+		DBGLOG(CNM, ERROR, "CNM: ChReq with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex);
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_CH_PRIVILEGE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL,	/* pfCmdDoneHandler */
+				      NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(CMD_CH_PRIVILEGE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdBody,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+
+	cnmMemFree(prAdapter, prCmdBody);
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* end of cnmChMngrRequestPrivilege() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Before deliver the message to other module, it need to release
+*        the Channel privilege to Channel Manager.
+*
+* @param[in] prMsgHdr   The message need to be delivered
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_CH_ABORT_T prMsgChAbort;
+	P_CMD_CH_PRIVILEGE_T prCmdBody;
+	WLAN_STATUS rStatus;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prMsgChAbort = (P_MSG_CH_ABORT_T) prMsgHdr;
+
+	prCmdBody = (P_CMD_CH_PRIVILEGE_T)
+	    cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T));
+	ASSERT(prCmdBody);
+
+	/* To do: exception handle */
+	if (!prCmdBody) {
+		DBGLOG(CNM, ERROR, "ChAbort: fail to get buf (net=%d, token=%d)\n",
+				    prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID);
+
+		cnmMemFree(prAdapter, prMsgHdr);
+		return;
+	}
+
+	DBGLOG(CNM, INFO, "ChAbort net=%d token=%d\n", prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID);
+
+	prCmdBody->ucNetTypeIndex = prMsgChAbort->ucNetTypeIndex;
+	prCmdBody->ucTokenID = prMsgChAbort->ucTokenID;
+	prCmdBody->ucAction = CMD_CH_ACTION_ABORT;	/* Abort */
+
+	ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	/* For monkey testing 20110901 */
+	if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM)
+		DBGLOG(CNM, ERROR, "CNM: ChAbort with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex);
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_CH_PRIVILEGE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL,	/* pfCmdDoneHandler */
+				      NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(CMD_CH_PRIVILEGE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdBody,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+
+	cnmMemFree(prAdapter, prCmdBody);
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* end of cnmChMngrAbortPrivilege() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent)
+{
+	P_EVENT_CH_PRIVILEGE_T prEventBody;
+	P_MSG_CH_GRANT_T prChResp;
+
+	ASSERT(prAdapter);
+	ASSERT(prEvent);
+
+	prEventBody = (P_EVENT_CH_PRIVILEGE_T) (prEvent->aucBuffer);
+	prChResp = (P_MSG_CH_GRANT_T)
+	    cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_GRANT_T));
+	ASSERT(prChResp);
+
+	/* To do: exception handle */
+	if (!prChResp) {
+		DBGLOG(CNM, ERROR, "ChGrant: fail to get buf (net=%d, token=%d)\n",
+				    prEventBody->ucNetTypeIndex, prEventBody->ucTokenID);
+
+		return;
+	}
+
+	DBGLOG(CNM, INFO, "ChGrant net=%d token=%d ch=%d sco=%d\n",
+			   prEventBody->ucNetTypeIndex, prEventBody->ucTokenID,
+			   prEventBody->ucPrimaryChannel, prEventBody->ucRfSco);
+
+	ASSERT(prEventBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+	ASSERT(prEventBody->ucStatus == EVENT_CH_STATUS_GRANT);
+
+	/* Decide message ID based on network and response status */
+	if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX)
+		prChResp->rMsgHdr.eMsgId = MID_CNM_AIS_CH_GRANT;
+#if CFG_ENABLE_WIFI_DIRECT
+	else if ((prAdapter->fgIsP2PRegistered) && (prEventBody->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX))
+		prChResp->rMsgHdr.eMsgId = MID_CNM_P2P_CH_GRANT;
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+	else if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX)
+		prChResp->rMsgHdr.eMsgId = MID_CNM_BOW_CH_GRANT;
+#endif
+	else {
+		cnmMemFree(prAdapter, prChResp);
+		return;
+	}
+
+	prChResp->ucNetTypeIndex = prEventBody->ucNetTypeIndex;
+	prChResp->ucTokenID = prEventBody->ucTokenID;
+	prChResp->ucPrimaryChannel = prEventBody->ucPrimaryChannel;
+	prChResp->eRfSco = (ENUM_CHNL_EXT_T) prEventBody->ucRfSco;
+	prChResp->eRfBand = (ENUM_BAND_T) prEventBody->ucRfBand;
+	prChResp->eReqType = (ENUM_CH_REQ_TYPE_T) prEventBody->ucReqType;
+	prChResp->u4GrantInterval = prEventBody->u4GrantInterval;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prChResp, MSG_SEND_METHOD_BUF);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is invoked for P2P or BOW networks
+*
+* @param (none)
+*
+* @return TRUE: suggest to adopt the returned preferred channel
+*         FALSE: No suggestion. Caller should adopt its preference
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prBand);
+	ASSERT(pucPrimaryChannel);
+	ASSERT(prBssSCO);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+
+	if (RLM_NET_PARAM_VALID(prBssInfo)) {
+		*prBand = prBssInfo->eBand;
+		*pucPrimaryChannel = prBssInfo->ucPrimaryChannel;
+		*prBssSCO = prBssInfo->eBssSCO;
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param (none)
+*
+* @return TRUE: available channel is limited to return value
+*         FALSE: no limited
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel)
+{
+#if CFG_ENABLE_WIFI_DIRECT || (CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL)
+	P_BSS_INFO_T prBssInfo;
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+	if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) {
+
+		ASSERT(prAdapter->fgIsP2PRegistered);
+
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
+
+		*prBand = prBssInfo->eBand;
+		*pucPrimaryChannel = prBssInfo->ucPrimaryChannel;
+
+		return TRUE;
+	}
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL
+	if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) {
+
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX];
+
+		*prBand = prBssInfo->eBand;
+		*pucPrimaryChannel = prBssInfo->ucPrimaryChannel;
+
+		return TRUE;
+	}
+#endif
+
+	return FALSE;
+}
+
+#if CFG_P2P_LEGACY_COEX_REVISE
+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel)
+{
+	P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar;
+	P_BSS_INFO_T prP2PBssInfo = &prWifiVar->arBssInfo[NETWORK_TYPE_P2P_INDEX];
+#if CFG_ENABLE_WIFI_DIRECT
+	if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) &&
+	    (prP2PBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED ||
+	     (prP2PBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && prP2PBssInfo->eIntendOPMode == OP_MODE_NUM))) {
+		*prBand = prP2PBssInfo->eBand;
+		*pucPrimaryChannel = prP2PBssInfo->ucPrimaryChannel;
+#if CFG_SUPPORT_MCC
+		if (nicFreq2ChannelNum(prWifiVar->rConnSettings.u4FreqInKHz * 1000) != *pucPrimaryChannel) {
+			DBGLOG(CNM, INFO, "p2p is running on Channel %d, but supplicant try to run as MCC\n",
+					   *pucPrimaryChannel);
+			return FALSE;
+		}
+#endif
+		DBGLOG(CNM, INFO, "p2p is running on Channel %d, supplicant try to run as SCC\n",
+				   *pucPrimaryChannel);
+		return TRUE;
+	}
+#endif
+	return FALSE;
+}
+#endif
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter)
+{
+#if CFG_ENABLE_BT_OVER_WIFI
+	P_BSS_INFO_T prAisBssInfo, prBowBssInfo;
+
+	prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+	prBowBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX];
+
+	if (RLM_NET_PARAM_VALID(prAisBssInfo) && RLM_NET_PARAM_VALID(prBowBssInfo)) {
+		if (prAisBssInfo->eBand != prBowBssInfo->eBand ||
+		    prAisBssInfo->ucPrimaryChannel != prBowBssInfo->ucPrimaryChannel) {
+
+			/* Notify BOW to do deactivation */
+			bowNotifyAllLinkDisconnected(prAdapter);
+		}
+	}
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param (none)
+*
+* @return TRUE: permitted
+*         FALSE: Not permitted
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter)
+{
+#if CFG_ENABLE_WIFI_DIRECT
+	if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX))
+		return FALSE;
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX))
+		return FALSE;
+#endif
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param (none)
+*
+* @return TRUE: permitted
+*         FALSE: Not permitted
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+
+	if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS)
+		return FALSE;
+#if CFG_ENABLE_BT_OVER_WIFI
+	if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) {
+		/* Notify BOW to do deactivation */
+		bowNotifyAllLinkDisconnected(prAdapter);
+	}
+#endif
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param (none)
+*
+* @return TRUE: permitted
+*         FALSE: Not permitted
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+
+	if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS)
+		return FALSE;
+#if CFG_ENABLE_WIFI_DIRECT
+	if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX))
+		return FALSE;
+#endif
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param (none)
+*
+* @return TRUE: permitted
+*         FALSE: Not permitted
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx)
+{
+	P_BSS_INFO_T prBssInfo;
+	UINT_8 i;
+	P_BSS_DESC_T    prBssDesc = NULL;
+
+	/* Note: To support real-time decision instead of current activated-time,
+	 *       the STA roaming case shall be considered about synchronization
+	 *       problem. Another variable fgAssoc40mBwAllowed is added to
+	 *       represent HT capability when association
+	 */
+	for (i = 0; i < NETWORK_TYPE_INDEX_NUM; i++) {
+		if (i != (UINT_8) eNetTypeIdx) {
+			prBssInfo = &prAdapter->rWifiVar.arBssInfo[i];
+
+			if (IS_BSS_ACTIVE(prBssInfo) && (prBssInfo->fg40mBwAllowed || prBssInfo->fgAssoc40mBwAllowed))
+				return FALSE;
+		}
+	}
+
+	if (eNetTypeIdx == NETWORK_TYPE_AIS_INDEX)
+		prBssDesc = prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc;
+	else if ((eNetTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->rWifiVar.prP2pFsmInfo))
+		prBssDesc = prAdapter->rWifiVar.prP2pFsmInfo->prTargetBss;
+	if (prBssDesc) {
+#if (CFG_FORCE_USE_20BW == 1)
+		if (prBssDesc->eBand == BAND_2G4)
+			return FALSE;
+#endif
+		if (prBssDesc->eSco == CHNL_EXT_SCN)
+			return FALSE;
+	}
+
+	return TRUE;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c
new file mode 100644
index 0000000000000..05bd0ff35f7ac
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c
@@ -0,0 +1,1236 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#2
+*/
+
+/*! \file   "cnm_mem.c"
+    \brief  This file contain the management function of packet buffers and
+	    generic memory alloc/free functioin for mailbox message.
+
+	    A data packet has a fixed size of buffer, but a management
+	    packet can be equipped with a variable size of buffer.
+*/
+
+/*
+** Log: cnm_mem.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 03 14 2012 wh.su
+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
+ * Add code from 2.2
+ *
+ * 11 17 2011 tsaiyuan.hsu
+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
+ * initialize fgNeedResp.
+ *
+ * 11 17 2011 tsaiyuan.hsu
+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
+ * avoid deactivating staRec when changing state from 3 to 3.
+ *
+ * 02 01 2011 cm.chang
+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
+ * .
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * Allocate system RAM if fixed message or mgmt buffer is not available
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 12 13 2010 cp.wu
+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
+ * create branch for Wi-Fi driver v1.1
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 11 29 2010 cm.chang
+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC
+ * for initial TX rate selection of auto-rate algorithm
+ * Sync RCPI of STA_REC to FW as reference of initial TX rate
+ *
+ * 11 25 2010 yuche.tsai
+ * NULL
+ * Update SLT Function for QoS Support and not be affected by fixed rate function.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete
+ * and might leads to BSOD when entering RF test with AIS associated
+ * 1. remove redundant variables in STA_REC structure
+ * 2. add STA-REC uninitialization routine for clearing pending events
+ *
+ * 10 13 2010 cm.chang
+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
+ * Add exception handle when cmd buffer is not available
+ *
+ * 10 12 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * add HT (802.11n) fixed rate support.
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * adding fixed rate support for distance test. (from registry setting)
+ *
+ * 09 24 2010 wh.su
+ * NULL
+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD
+ * when entering RF test with AIS associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 16 2010 cm.chang
+ * NULL
+ * Change conditional compiling options for BOW
+ *
+ * 09 10 2010 cm.chang
+ * NULL
+ * Always update Beacon content if FW sync OBSS info
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 19 2010 wh.su
+ * NULL
+ * adding the tx pkt call back handle for countermeasure.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 07 07 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support state of STA record change from 1 to 1
+ *
+ * 07 05 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Fix correct structure size in cnmStaSendDeactivateCmd()
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) ignore RSN checking when RSN is not turned on.
+ * 2) set STA-REC deactivation callback as NULL
+ * 3) add variable initialization API based on PHY configuration
+ *
+ * 07 02 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * spin lock target revised
+ *
+ * 07 02 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change inner loop index from i to k.
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support sync command of STA_REC
+ *
+ * 06 23 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Merge g_arStaRec[] into adapter->arStaRec[]
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 05 31 2010 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling
+ *
+ * 05 28 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support checking  of duplicated buffer free
+ *
+ * 05 28 2010 wh.su
+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
+ * fixed the ad-hoc wpa-none send non-encrypted frame issue.
+ *
+ * 05 28 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 28 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Modified some MQM-related data structures (SN counter, TX/RX BA table)
+ *
+ * 04 27 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Added new TX/RX BA tables in STA_REC
+ *
+ * 04 27 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Notify MQM, TXM, and RXM upon disconnection .
+ *
+ * 04 26 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Call mqm, txm, rxm functions upon disconnection
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft code to support protection in AP mode
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support
+ *  *  *  *  *  *  *  *  *  *  and will send Null frame to diagnose connection
+ *
+ * 04 09 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * [BORA00000644] WiFi phase 4 integration
+ *  * Added per-TID SN cache in STA_REC
+ *
+ * 04 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Different invoking order for WTBL entry of associated AP
+ *
+ * 03 29 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * move the wlan table alloc / free to change state function.
+ *
+ * 03 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support power control
+ *
+ * 03 03 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Initialize StaRec->arStaWaitQueue
+ *
+ * 03 03 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add debug message when no available pkt buffer
+ *
+ * 03 01 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k]
+ *
+ * 02 26 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added fgIsWmmSupported in STA_RECORD_T.
+ *
+ * 02 26 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added fgIsUapsdSupported in STA_RECORD_T
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * add support of Driver STA_RECORD_T activation
+ *
+ * 02 13 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added arTspecTable in STA_REC for TSPEC management
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Enable mgmt buffer debug by default
+ *
+ * 02 12 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Added BUFFER_SOURCE_BCN
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 08 2010 cp.wu
+ * [BORA00000368]Integrate HIF part into BORA
+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h
+ *  *  *  *  *  *  *  *  * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem
+ *  *  *  *  *  *  *  *  * 3) use cnmMemAlloc() instead to allocate SRAM buffer
+ *
+ * 12 25 2009 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM)
+ *  *  *  *  *  *  * MQM: BA handling
+ *  *  *  *  *  *  * TXM: Macros updates
+ *  *  *  *  *  *  * RXM: Macros/Duplicate Removal updates
+ *
+ * 12 24 2009 yarco.yang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * 12 21 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support several data buffer banks.
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .For new FPGA memory size
+ *
+ * Dec 9 2009 MTK02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Removed DBGPRINT
+ *
+ * Dec 9 2009 mtk02752
+ * [BORA00000368] Integrate HIF part into BORA
+ * add cnmDataPktFree() for emulation loopback purpose
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix warning of null pointer
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T
+ *
+ * Nov 23 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Assign ucBufferSource in function cnmMgtPktAlloc()
+ *
+ * Nov 23 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Added packet redispatch function calls
+ *
+ * Nov 13 2009 mtk01084
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * enable packet re-usable in current emulation driver
+ *
+ * Nov 12 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * 1. Add new function cnmGetStaRecByIndex()
+ * 2. Rename STA_REC_T to STA_RECORD_T
+ *
+ * Nov 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Call cnmDataPktDispatch() in cnmPktFree()
+ *
+ * Nov 2 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Remove definition of pragma section code
+ *
+ * Oct 28 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+ * Oct 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix lint warning
+ *
+ * Oct 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix typo
+ *
+ * Oct 12 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+ * Oct 8 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf);
+
+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp);
+
+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+P_MSDU_INFO_T cnmMgtPktAlloc(P_ADAPTER_T prAdapter, UINT_32 u4Length)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	P_QUE_T prQueList;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
+
+	/* Get a free MSDU_INFO_T */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+	QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+
+	if (prMsduInfo) {
+		prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length);
+		prMsduInfo->eSrc = TX_PACKET_MGMT;
+
+		if (prMsduInfo->prPacket == NULL) {
+			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+			QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry);
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+			prMsduInfo = NULL;
+		}
+		if (prMsduInfo) {
+			prMsduInfo->eCmdType = COMMAND_TYPE_NUM;
+			prMsduInfo->ucCID = 0xff;
+			prMsduInfo->u4InqueTime = 0;
+			prMsduInfo->ucPacketType = TX_PACKET_NUM;
+		}
+	} else {
+		P_QUE_T prTxingQue;
+		P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+		P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL;
+		P_TX_TCQ_STATUS_T pTc = (P_TX_TCQ_STATUS_T) NULL;
+
+		prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue);
+		pTc = &(prAdapter->rTxCtrl.rTc);
+
+		DBGLOG(MEM, LOUD, "++dump TxPendingMsdu=%u, Tc0=%d Tc1=%d Tc2=%d Tc3=%d, Tc4=%d Tc5=%d\n",
+				   prTxingQue->u4NumElem, pTc->aucFreeBufferCount[TC0_INDEX],
+				   pTc->aucFreeBufferCount[TC1_INDEX], pTc->aucFreeBufferCount[TC2_INDEX],
+				   pTc->aucFreeBufferCount[TC3_INDEX], pTc->aucFreeBufferCount[TC4_INDEX],
+				   pTc->aucFreeBufferCount[TC5_INDEX]);
+
+		prQueueEntry = QUEUE_GET_HEAD(prTxingQue);
+
+		while (prQueueEntry) {
+			prMsduInfo = (P_MSDU_INFO_T) prQueueEntry;
+
+			DBGLOG(MEM, LOUD,
+			       "msdu type=%u, ucid=%u, type=%d, time=%u, seq=%u, sta=%u\n",
+				prMsduInfo->ucPacketType,
+				prMsduInfo->ucCID,
+				prMsduInfo->eCmdType,
+				prMsduInfo->u4InqueTime, prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex);
+			prQueueEntry = QUEUE_GET_NEXT_ENTRY(prQueueEntry);
+		}
+		DBGLOG(MEM, LOUD, "--end dump\n");
+	}
+
+#if DBG
+	if (prMsduInfo == NULL) {
+		DBGLOG(MEM, WARN, "MgtDesc#=%u\n", prQueList->u4NumElem);
+
+#if CFG_DBG_MGT_BUF
+		DBGLOG(MEM, WARN, "rMgtBufInfo: alloc#=%u, free#=%u, null#=%u\n",
+				   prAdapter->rMgtBufInfo.u4AllocCount,
+				   prAdapter->rMgtBufInfo.u4FreeCount, prAdapter->rMgtBufInfo.u4AllocNullCount);
+#endif
+
+		DBGLOG(MEM, WARN, "\n");
+	}
+#endif
+
+	return prMsduInfo;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmMgtPktFree(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_QUE_T prQueList;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
+
+	ASSERT(prMsduInfo->prPacket);
+	if (prMsduInfo->prPacket) {
+		cnmMemFree(prAdapter, prMsduInfo->prPacket);
+		prMsduInfo->prPacket = NULL;
+	}
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+	prMsduInfo->fgIsBasicRate = FALSE;
+	QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry)
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is used to initial the MGMT/MSG memory pool.
+*
+* \param (none)
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmMemInit(P_ADAPTER_T prAdapter)
+{
+	P_BUF_INFO_T prBufInfo;
+
+	/* Initialize Management buffer pool */
+	prBufInfo = &prAdapter->rMgtBufInfo;
+	kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo));
+	prBufInfo->pucBuf = prAdapter->pucMgtBufCached;
+
+	/* Setup available memory blocks. 1 indicates FREE */
+	prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
+
+	/* Initialize Message buffer pool */
+	prBufInfo = &prAdapter->rMsgBufInfo;
+	kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo));
+	prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0];
+
+	/* Setup available memory blocks. 1 indicates FREE */
+	prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
+
+	return;
+
+}				/* end of cnmMemInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Allocate MGMT/MSG memory pool.
+*
+* \param[in] eRamType       Target RAM type.
+*                           TCM blk_sz= 16bytes, BUF blk_sz= 256bytes
+* \param[in] u4Length       Length of the buffer to allocate.
+*
+* \retval !NULL    Pointer to the start address of allocated memory.
+* \retval NULL     Fail to allocat memory
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 u4MemAllocCnt = 0, u4MemFreeCnt = 0;
+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length)
+{
+	P_BUF_INFO_T prBufInfo;
+	BUF_BITMAP rRequiredBitmap;
+	UINT_32 u4BlockNum;
+	UINT_32 i, u4BlkSzInPower;
+	PVOID pvMemory;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(u4Length);
+
+	u4MemAllocCnt++;
+
+	if (eRamType == RAM_TYPE_MSG && u4Length <= 256) {
+		prBufInfo = &prAdapter->rMsgBufInfo;
+		u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
+
+		u4Length += (MSG_BUF_BLOCK_SIZE - 1);
+		u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
+
+		ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
+	} else {
+		eRamType = RAM_TYPE_BUF;
+
+		prBufInfo = &prAdapter->rMgtBufInfo;
+		u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
+
+		u4Length += (MGT_BUF_BLOCK_SIZE - 1);
+		u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
+
+		ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
+	}
+
+#if CFG_DBG_MGT_BUF
+	prBufInfo->u4AllocCount++;
+#endif
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
+
+	if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) {
+
+		/* Convert number of block into bit cluster */
+		rRequiredBitmap = BITS(0, u4BlockNum - 1);
+
+		for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) {
+
+			/* Have available memory blocks */
+			if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap)
+			    == rRequiredBitmap) {
+
+				/* Clear corresponding bits of allocated memory blocks */
+				prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap;
+
+				/* Store how many blocks be allocated */
+				prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum;
+
+				KAL_RELEASE_SPIN_LOCK(prAdapter,
+						      eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
+
+				/* Return the start address of allocated memory */
+				return (PVOID) (prBufInfo->pucBuf + (i << u4BlkSzInPower));
+
+			}
+
+			rRequiredBitmap <<= 1;
+		}
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
+
+	/* cannot move the allocation between spin_lock_irqsave and spin_unlock_irqrestore */
+#ifdef LINUX
+	pvMemory = (PVOID) kalMemAlloc(u4Length, VIR_MEM_TYPE);
+	if (pvMemory)
+		kalMemZero(pvMemory, u4Length);
+#else
+	pvMemory = (PVOID) NULL;
+#endif
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
+
+#if CFG_DBG_MGT_BUF
+	prBufInfo->u4AllocNullCount++;
+
+	if (pvMemory)
+		prAdapter->u4MemAllocDynamicCount++;
+#endif
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
+
+	return pvMemory;
+
+}				/* end of cnmMemAlloc() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Release memory to MGT/MSG memory pool.
+*
+* \param pucMemory  Start address of previous allocated memory
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory)
+{
+	P_BUF_INFO_T prBufInfo;
+	UINT_32 u4BlockIndex;
+	BUF_BITMAP rAllocatedBlocksBitmap;
+	ENUM_RAM_TYPE_T eRamType;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(pvMemory);
+	if (!pvMemory)
+		return;
+
+	u4MemFreeCnt++;
+
+	/* Judge it belongs to which RAM type */
+	if (((ULONG) pvMemory >= (ULONG)&prAdapter->aucMsgBuf[0]) &&
+	    ((ULONG) pvMemory <= (ULONG)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE - 1])) {
+
+		prBufInfo = &prAdapter->rMsgBufInfo;
+		u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf)
+		    >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
+		ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
+		eRamType = RAM_TYPE_MSG;
+	} else if (((ULONG) pvMemory >= (ULONG) prAdapter->pucMgtBufCached) &&
+		   ((ULONG) pvMemory <= ((ULONG) prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE - 1))) {
+		prBufInfo = &prAdapter->rMgtBufInfo;
+		u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf)
+		    >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
+		ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
+		eRamType = RAM_TYPE_BUF;
+	} else {
+#ifdef LINUX
+		/* For Linux, it is supported because size is not needed */
+		kalMemFree(pvMemory, VIR_MEM_TYPE, 0);
+#else
+		/* For Windows, it is not supported because of no size argument */
+		ASSERT(0);
+#endif
+
+#if CFG_DBG_MGT_BUF
+		prAdapter->u4MemFreeDynamicCount++;
+#endif
+		return;
+	}
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
+
+#if CFG_DBG_MGT_BUF
+	prBufInfo->u4FreeCount++;
+#endif
+
+	/* Convert number of block into bit cluster */
+	ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0);
+
+	rAllocatedBlocksBitmap = BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1);
+	rAllocatedBlocksBitmap <<= u4BlockIndex;
+
+	/* Clear saved block count for this memory segment */
+	prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0;
+
+	/* Set corresponding bit of released memory block */
+	prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap;
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
+
+	return;
+
+}				/* end of cnmMemFree() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmStaRecInit(P_ADAPTER_T prAdapter)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 i;
+
+	for (i = 0; i < CFG_STA_REC_NUM; i++) {
+		prStaRec = &prAdapter->arStaRec[i];
+
+		prStaRec->ucIndex = (UINT_8) i;
+		prStaRec->fgIsInUse = FALSE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 i;
+
+	for (i = 0; i < CFG_STA_REC_NUM; i++) {
+		prStaRec = &prAdapter->arStaRec[i];
+
+		if (prStaRec->fgIsInUse)
+			cnmStaRecFree(prAdapter, prStaRec, FALSE);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+P_STA_RECORD_T cnmStaRecAlloc(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 i, k;
+
+	ASSERT(prAdapter);
+
+	for (i = 0; i < CFG_STA_REC_NUM; i++) {
+		prStaRec = &prAdapter->arStaRec[i];
+
+		if (!prStaRec->fgIsInUse) {
+			/*---- Initialize STA_REC_T here ----*/
+			kalMemZero(prStaRec, sizeof(STA_RECORD_T));
+			prStaRec->ucIndex = (UINT_8) i;
+			prStaRec->ucNetTypeIndex = ucNetTypeIndex;
+			prStaRec->fgIsInUse = TRUE;
+
+			if (prStaRec->pucAssocReqIe) {
+				kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
+				prStaRec->pucAssocReqIe = NULL;
+				prStaRec->u2AssocReqIeLen = 0;
+			}
+
+			/* Initialize the SN caches for duplicate detection */
+			for (k = 0; k < TID_NUM + 1; k++)
+				prStaRec->au2CachedSeqCtrl[k] = 0xFFFF;
+
+			/* Initialize SW TX queues in STA_REC */
+			for (k = 0; k < STA_WAIT_QUEUE_NUM; k++)
+				LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]);
+
+			/* Default enable TX/RX AMPDU */
+			prStaRec->fgTxAmpduEn = TRUE;
+			prStaRec->fgRxAmpduEn = TRUE;
+
+#if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE
+			prStaRec->u4TotalTxPktsNumber = 0;
+			prStaRec->u4TotalTxPktsTime = 0;
+			prStaRec->u4MaxTxPktsTime = 0;
+#endif
+
+			for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++)
+				QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]);
+
+			break;
+		}
+	}
+
+	return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmStaRecFree(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgSyncToChip)
+{
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+
+	/* To do: free related resources, e.g. timers, buffers, etc */
+	cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+	prStaRec->fgTransmitKeyExist = FALSE;
+	prStaRec->fgSetPwrMgtBit = FALSE;
+
+	if (prStaRec->pucAssocReqIe) {
+		kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
+		prStaRec->pucAssocReqIe = NULL;
+		prStaRec->u2AssocReqIeLen = 0;
+	}
+
+	qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
+
+	if (fgSyncToChip)
+		cnmStaSendRemoveCmd(prAdapter, prStaRec);
+
+	prStaRec->fgIsInUse = FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 i;
+
+	for (i = 0; i < CFG_STA_REC_NUM; i++) {
+		prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
+
+		if (prStaRec->fgIsInUse && prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex)
+			cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip);
+	}	/* end of for loop */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+P_STA_RECORD_T cnmGetStaRecByIndex(P_ADAPTER_T prAdapter, UINT_8 ucIndex)
+{
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+
+	prStaRec = (ucIndex < CFG_STA_REC_NUM) ? &prAdapter->arStaRec[ucIndex] : NULL;
+
+	if (prStaRec && prStaRec->fgIsInUse == FALSE)
+		prStaRec = NULL;
+
+	return prStaRec;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Get STA_RECORD_T by Peer MAC Address(Usually TA).
+*
+* @param[in] pucPeerMacAddr      Given Peer MAC Address.
+*
+* @retval   Pointer to STA_RECORD_T, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_STA_RECORD_T cnmGetStaRecByAddress(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex, PUINT_8 pucPeerMacAddr)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 i;
+
+	ASSERT(prAdapter);
+	ASSERT(pucPeerMacAddr);
+
+	for (i = 0; i < CFG_STA_REC_NUM; i++) {
+		prStaRec = &prAdapter->arStaRec[i];
+
+		if (prStaRec->fgIsInUse &&
+		    prStaRec->ucNetTypeIndex == ucNetTypeIndex &&
+		    EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) {
+			break;
+		}
+	}
+
+	return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Reset the Status and Reason Code Field to 0 of all Station Records for
+*        the specified Network Type
+*
+* @param[in] eNetType       Specify Network Type
+*
+* @return   (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmStaRecResetStatus(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE);
+
+#if 0
+	P_STA_RECORD_T prStaRec;
+	UINT_16 i;
+
+	ASSERT(prAdapter);
+
+	for (i = 0; i < CFG_STA_REC_NUM; i++) {
+		prStaRec = &prAdapter->arStaRec[i];
+
+		if (prStaRec->fgIsInUse) {
+			if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) && IS_STA_IN_AIS(prStaRec->eStaType)) {
+
+				prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
+				prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
+				prStaRec->ucJoinFailureCount = 0;
+				prStaRec->fgTransmitKeyExist = FALSE;
+
+				prStaRec->fgSetPwrMgtBit = FALSE;
+			}
+
+			/* TODO(Kevin): For P2P and BOW */
+		}
+	}
+
+	return;
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will change the ucStaState of STA_RECORD_T and also do
+*        event indication to HOST to sync the STA_RECORD_T in driver.
+*
+* @param[in] prStaRec       Pointer to the STA_RECORD_T
+* @param[in] u4NewState     New STATE to change.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmStaRecChangeState(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, UINT_8 ucNewState)
+{
+	BOOLEAN fgNeedResp;
+
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+	ASSERT(prStaRec->fgIsInUse);
+
+	/* Do nothing when following state transitions happen,
+	 * other 6 conditions should be sync to FW, including 1-->1, 3-->3
+	 */
+	if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) ||
+	    (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) {
+		prStaRec->ucStaState = ucNewState;
+		return;
+	}
+
+	fgNeedResp = FALSE;
+	if (ucNewState == STA_STATE_3) {
+		secFsmEventStart(prAdapter, prStaRec);
+		if (ucNewState != prStaRec->ucStaState)
+			fgNeedResp = TRUE;
+	} else {
+		if (ucNewState != prStaRec->ucStaState && prStaRec->ucStaState == STA_STATE_3)
+			qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
+		fgNeedResp = FALSE;
+	}
+	prStaRec->ucStaState = ucNewState;
+
+	cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	/* To do: Confirm if it is invoked here or other location, but it should
+	 *        be invoked after state sync of STA_REC
+	 * Update system operation parameters for AP mode
+	 */
+	if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
+		P_BSS_INFO_T prBssInfo;
+
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
+
+		if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)
+			rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE);
+	}
+#endif
+}
+
+P_STA_RECORD_T
+cnmStaTheTypeGet(P_ADAPTER_T prAdapter,
+		 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx)
+{
+	P_STA_RECORD_T prStaRec = NULL;
+	UINT_16 i;
+
+	for (i = *pu4StartIdx; i < CFG_STA_REC_NUM; i++) {
+		prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
+
+		if (prStaRec->fgIsInUse &&
+		    prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex && prStaRec->eStaType == eStaType) {
+			i++;
+			break;
+		}
+
+		prStaRec = NULL;	/* reset */
+	}			/* end of for loop */
+
+	*pu4StartIdx = i;
+	return prStaRec;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf)
+{
+	P_EVENT_ACTIVATE_STA_REC_T prEventContent;
+	P_STA_RECORD_T prStaRec;
+
+	prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf;
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx);
+
+	if (prStaRec && prStaRec->ucStaState == STA_STATE_3 &&
+	    !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0], MAC_ADDR_LEN)) {
+
+		qmActivateStaRec(prAdapter, prStaRec);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp)
+{
+	P_CMD_UPDATE_STA_RECORD_T prCmdContent;
+	WLAN_STATUS rStatus;
+
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+	ASSERT(prStaRec->fgIsInUse);
+
+	/* To do: come out a mechanism to limit one STA_REC sync once for AP mode
+	 *        to avoid buffer empty case when many STAs are associated
+	 *        simultaneously.
+	 */
+
+	/* To do: how to avoid 2 times of allocated memory. Use Stack?
+	 *        One is here, the other is in wlanSendQueryCmd()
+	 */
+	prCmdContent = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T));
+	ASSERT(prCmdContent);
+
+	/* To do: exception handle */
+	if (!prCmdContent)
+		return;
+
+	prCmdContent->ucIndex = prStaRec->ucIndex;
+	prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType;
+	kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN);
+	prCmdContent->u2AssocId = prStaRec->u2AssocId;
+	prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval;
+	prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex;
+
+	prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
+	prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet;
+	prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
+	prCmdContent->ucMcsSet = prStaRec->ucMcsSet;
+	prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32;
+	prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo;
+	prCmdContent->ucNeedResp = (UINT_8) fgNeedResp;
+
+#if !CFG_SLT_SUPPORT
+	if (prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) {
+		/* override rate configuration */
+		nicUpdateRateParams(prAdapter,
+				    prAdapter->rWifiVar.eRateSetting,
+				    &(prCmdContent->ucDesiredPhyTypeSet),
+				    &(prCmdContent->u2DesiredNonHTRateSet),
+				    &(prCmdContent->u2BSSBasicRateSet),
+				    &(prCmdContent->ucMcsSet),
+				    &(prCmdContent->ucSupMcs32), &(prCmdContent->u2HtCapInfo));
+	}
+#endif
+
+	prCmdContent->ucIsQoS = prStaRec->fgIsQoS;
+	prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported;
+	prCmdContent->ucStaState = prStaRec->ucStaState;
+
+	prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam;
+	prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap;
+	prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap;
+	prCmdContent->ucAselCap = prStaRec->ucAselCap;
+	prCmdContent->ucRCPI = prStaRec->ucRCPI;
+
+	prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4);
+	prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp;
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_UPDATE_STA_RECORD,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      fgNeedResp,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      fgNeedResp ? cnmStaRecHandleEventPkt : NULL, NULL, /* pfCmdTimeoutHandler */
+				      sizeof(CMD_UPDATE_STA_RECORD_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+
+	cnmMemFree(prAdapter, prCmdContent);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec)
+{
+	CMD_REMOVE_STA_RECORD_T rCmdContent;
+	WLAN_STATUS rStatus;
+
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+
+	rCmdContent.ucIndex = prStaRec->ucIndex;
+	kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN);
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_REMOVE_STA_RECORD,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL,	/* pfCmdDoneHandler */
+				      NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(CMD_REMOVE_STA_RECORD_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) &rCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c
new file mode 100644
index 0000000000000..8cc9ef9078fe4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c
@@ -0,0 +1,482 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1
+*/
+
+/*! \file   "cnm_timer.c"
+    \brief
+
+*/
+
+/*
+** Log: cnm_timer.c
+ *
+ * 12 13 2011 cm.chang
+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer
+ * Add wake lock if timer timeout value is smaller than 5 seconds
+ *
+ * 02 24 2011 cp.wu
+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation
+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms
+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * cnm_timer has been migrated.
+ *
+ * 05 28 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support sleep notification to host
+ *
+ * 05 19 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add some checking assertions
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Return timer token back to COS when entering wait off state
+ *
+ * 01 11 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Remove compiling warning
+ *
+ * 01 08 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb
+ *
+ * 01 06 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Fix system time is 32KHz instead of 1ms
+ *
+ * 01 04 2010 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * For working out the first connection Chariot-verified version
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Place rRootTimer.rNextExpiredSysTime = rExpiredSysTime; before set timer
+ *
+ * Oct 30 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * In cnmTimerInitialize(), just stop timer if it was already created.
+ *
+ * Oct 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Move the external reference for Lint to precomp.h
+ *
+ * Oct 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix lint warning
+ *
+ * Oct 28 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the time to do the time out check.
+*
+* \param[in] rTimeout Time out interval from current time.
+*
+* \retval TRUE Success.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static BOOLEAN cnmTimerSetTimer(IN P_ADAPTER_T prAdapter, IN OS_SYSTIME rTimeout)
+{
+	P_ROOT_TIMER prRootTimer;
+	BOOLEAN fgNeedWakeLock;
+
+	ASSERT(prAdapter);
+
+	prRootTimer = &prAdapter->rRootTimer;
+
+	kalSetTimer(prAdapter->prGlueInfo, rTimeout);
+
+	if (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME)) {
+		fgNeedWakeLock = TRUE;
+
+		if (!prRootTimer->fgWakeLocked) {
+			KAL_WAKE_LOCK(prAdapter, &prRootTimer->rWakeLock);
+			prRootTimer->fgWakeLocked = TRUE;
+		}
+	} else {
+		fgNeedWakeLock = FALSE;
+	}
+
+	return fgNeedWakeLock;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routines is called to initialize a root timer.
+*
+* \param[in] prAdapter
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter)
+{
+	P_ROOT_TIMER prRootTimer;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	prRootTimer = &prAdapter->rRootTimer;
+
+	/* Note: glue layer have configured timer */
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+	LINK_INITIALIZE(&prRootTimer->rLinkHead);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+
+	KAL_WAKE_LOCK_INIT(prAdapter, &prRootTimer->rWakeLock, "WLAN Timer");
+	prRootTimer->fgWakeLocked = FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routines is called to destroy a root timer.
+*        When WIFI is off, the token shall be returned back to system.
+*
+* \param[in]
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter)
+{
+	P_ROOT_TIMER prRootTimer;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	prRootTimer = &prAdapter->rRootTimer;
+
+	if (prRootTimer->fgWakeLocked) {
+		KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock);
+		prRootTimer->fgWakeLocked = FALSE;
+	}
+	KAL_WAKE_LOCK_DESTROY(prAdapter, &prRootTimer->rWakeLock);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+	LINK_INITIALIZE(&prRootTimer->rLinkHead);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+
+	/* Note: glue layer will be responsible for timer destruction */
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routines is called to initialize a timer.
+*
+* \param[in] prTimer Pointer to a timer structure.
+* \param[in] pfnFunc Pointer to the call back function.
+* \param[in] u4Data Parameter for call back function.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData)
+{
+	ASSERT(prAdapter);
+
+	ASSERT(prTimer);
+
+#if DBG
+	/* Note: NULL function pointer is permitted for HEM POWER */
+	if (pfFunc == NULL)
+		DBGLOG(CNM, WARN, "Init timer with NULL callback function!\n");
+#endif
+
+#if DBG
+	ASSERT(prAdapter->rRootTimer.rLinkHead.prNext);
+	{
+		P_LINK_T prTimerList;
+		P_LINK_ENTRY_T prLinkEntry;
+		P_TIMER_T prPendingTimer;
+
+		prTimerList = &(prAdapter->rRootTimer.rLinkHead);
+
+		LINK_FOR_EACH(prLinkEntry, prTimerList) {
+			prPendingTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry);
+			ASSERT(prPendingTimer);
+			ASSERT(prPendingTimer != prTimer);
+		}
+	}
+#endif
+
+	LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry);
+
+	prTimer->pfMgmtTimeOutFunc = pfFunc;
+	prTimer->ulData = ulData;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routines is called to stop a timer.
+*
+* \param[in] prTimer Pointer to a timer structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID cnmTimerStopTimer_impl(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN BOOLEAN fgAcquireSpinlock)
+{
+	P_ROOT_TIMER prRootTimer;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(prTimer);
+
+	prRootTimer = &prAdapter->rRootTimer;
+
+	if (fgAcquireSpinlock)
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+
+	if (timerPendingTimer(prTimer)) {
+		LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead, &prTimer->rLinkEntry);
+
+		/* Reduce dummy timeout for power saving, especially HIF activity.
+		 * If two or more timers exist and being removed timer is smallest,
+		 * this dummy timeout will still happen, but it is OK.
+		 */
+		if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) {
+			kalCancelTimer(prAdapter->prGlueInfo);
+
+			if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) {
+				KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock);
+				prRootTimer->fgWakeLocked = FALSE;
+			}
+		}
+	}
+
+	if (fgAcquireSpinlock)
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routines is called to stop a timer.
+*
+* \param[in] prTimer Pointer to a timer structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer)
+{
+	ASSERT(prAdapter);
+	ASSERT(prTimer);
+
+	cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routines is called to start a timer with wake_lock.
+*
+* \param[in] prTimer Pointer to a timer structure.
+* \param[in] u4TimeoutMs Timeout to issue the timer and call back function
+*                        (unit: ms).
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs)
+{
+	P_ROOT_TIMER prRootTimer;
+	P_LINK_T prTimerList;
+	OS_SYSTIME rExpiredSysTime, rTimeoutSystime;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(prTimer);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+
+	prRootTimer = &prAdapter->rRootTimer;
+	prTimerList = &prRootTimer->rLinkHead;
+
+	/* If timeout interval is larger than 1 minute, the mod value is set
+	 * to the timeout value first, then per minutue.
+	 */
+	if (u4TimeoutMs > MSEC_PER_MIN) {
+		ASSERT(u4TimeoutMs <= ((UINT_32) 0xFFFF * MSEC_PER_MIN));
+
+		prTimer->u2Minutes = (UINT_16) (u4TimeoutMs / MSEC_PER_MIN);
+		u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN);
+		if (u4TimeoutMs == 0) {
+			u4TimeoutMs = MSEC_PER_MIN;
+			prTimer->u2Minutes--;
+		}
+	} else {
+		prTimer->u2Minutes = 0;
+	}
+
+	/* The assertion check if MSEC_TO_SYSTIME() may be overflow. */
+	ASSERT(u4TimeoutMs < (((UINT_32) 0x80000000 - MSEC_PER_SEC) / KAL_HZ));
+	rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs);
+	rExpiredSysTime = kalGetTimeTick() + rTimeoutSystime;
+
+	/* If no timer pending or the fast time interval is used. */
+	if (LINK_IS_EMPTY(prTimerList) || TIME_BEFORE(rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) {
+
+		prRootTimer->rNextExpiredSysTime = rExpiredSysTime;
+		cnmTimerSetTimer(prAdapter, rTimeoutSystime);
+	}
+
+	/* Add this timer to checking list */
+	prTimer->rExpiredSysTime = rExpiredSysTime;
+
+	if (!timerPendingTimer(prTimer))
+		LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry);
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routines is called to check the timer list.
+*
+* \param[in]
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter)
+{
+	P_ROOT_TIMER prRootTimer;
+	P_LINK_T prTimerList;
+	P_LINK_ENTRY_T prLinkEntry;
+	P_TIMER_T prTimer;
+	OS_SYSTIME rCurSysTime;
+	PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc;
+	ULONG ulTimeoutData;
+	BOOLEAN fgNeedWakeLock;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	/* acquire spin lock */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+
+	prRootTimer = &prAdapter->rRootTimer;
+	prTimerList = &prRootTimer->rLinkHead;
+
+	rCurSysTime = kalGetTimeTick();
+
+	/* Set the permitted max timeout value for new one */
+	prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL;
+
+	LINK_FOR_EACH(prLinkEntry, prTimerList) {
+		prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry);
+		ASSERT(prTimer);
+
+		/* Check if this entry is timeout. */
+		if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) {
+			cnmTimerStopTimer_impl(prAdapter, prTimer, FALSE);
+
+			pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc;
+			ulTimeoutData = prTimer->ulData;
+
+			if (prTimer->u2Minutes > 0) {
+				prTimer->u2Minutes--;
+				prTimer->rExpiredSysTime = rCurSysTime + MSEC_TO_SYSTIME(MSEC_PER_MIN);
+				LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry);
+			} else if (pfMgmtTimeOutFunc) {
+				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+				(pfMgmtTimeOutFunc) (prAdapter, ulTimeoutData);
+				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+			}
+
+			/* Search entire list again because of nest del and add timers
+			 * and current MGMT_TIMER could be volatile after stopped
+			 */
+			prLinkEntry = (P_LINK_ENTRY_T) prTimerList;
+
+			prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL;
+		} else if (TIME_BEFORE(prTimer->rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) {
+			prRootTimer->rNextExpiredSysTime = prTimer->rExpiredSysTime;
+		}
+	}			/* end of for loop */
+
+	/* Setup the prNext timeout event. It is possible the timer was already
+	 * set in the above timeout callback function.
+	 */
+	fgNeedWakeLock = FALSE;
+	if (!LINK_IS_EMPTY(prTimerList)) {
+		ASSERT(TIME_AFTER(prRootTimer->rNextExpiredSysTime, rCurSysTime));
+
+		fgNeedWakeLock = cnmTimerSetTimer(prAdapter, (OS_SYSTIME)
+						  ((INT_32) prRootTimer->rNextExpiredSysTime - (INT_32) rCurSysTime));
+	}
+
+	if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) {
+		KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock);
+		prRootTimer->fgWakeLocked = FALSE;
+	}
+
+	/* release spin lock */
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c
new file mode 100644
index 0000000000000..c7a23eb018b63
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c
@@ -0,0 +1,816 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/hem_mbox.c#3
+*/
+
+/*! \file   "hem_mbox.c"
+    \brief
+
+*/
+
+/*
+** Log: hem_mbox.c
+**
+** 08 31 2012 yuche.tsai
+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device
+** have connected to AP previously,one device reboots automatically with KE
+** Fix possible KE when concurrent & disconnect.
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 05 03 2012 cp.wu
+ * [WCXRP00001231] [MT6620 Wi-Fi][MT5931][Driver] Correct SCAN_V2 related debugging facilities within hem_mbox.c
+ * correct for debug message string table by adding missed scan_v2 related definitions.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 17 2012 yuche.tsai
+ * NULL
+ * Update mgmt frame filter setting.
+ * Please also update FW 2.1
+ *
+ * 01 13 2012 yuche.tsai
+ * NULL
+ * WiFi Hot Spot Tethering for ICS ALPHA testing version.
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 15 2011 cm.chang
+ * NULL
+ * Add exception handle for NULL function pointer of mailbox message
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 07 18 2011 cp.wu
+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search
+ * for more than one SSID in a single scanning request
+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support
+ * as well as uProbeDelay in NDIS 6.x driver model
+ *
+ * 06 07 2011 yuche.tsai
+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response.
+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue
+ * Add invitation support.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 03 29 2011 cm.chang
+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning
+ * As CR title
+ *
+ * 02 24 2011 cp.wu
+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation
+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms
+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions
+ *
+ * 02 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update bowString and channel grant.
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * Allocate system RAM if fixed message or mgmt buffer is not available
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Fix Compile Error when DBG is disabled.
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 12 08 2010 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support concurrent networks.
+ *
+ * 11 08 2010 cm.chang
+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID
+ * Remove CNM channel reover message ID
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 08 2010 wh.su
+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
+ * update the frog's new p2p state machine.
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 16 2010 cm.chang
+ * NULL
+ * Remove unused message ID
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * Add P2P Connection Abort Event Message handler.
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 24 2010 yarco.yang
+ * NULL
+ * Fixed Driver ASSERT at mboxInitMsgMap()
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy.
+ * Update saa_fsm for BOW.
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Add CFG_ENABLE_BT_OVER_WIFI.
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * add interface for RLM to trigger OBSS-SCAN.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Add debug message for newly add P2P message.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add some function entry for P2P FSM under provisioning phase..
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add some events to P2P Module.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Add message box event for P2P device switch on & device discovery.
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * remove unused mailbox message definitions.
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * message table should not be commented out by compilation option without modifying header file
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Add Ad-Hoc support to AIS-FSM
+ *
+ * 07 19 2010 yuche.tsai
+ *
+ * Add wifi direct scan done callback.
+ *
+ * 07 09 2010 cp.wu
+ *
+ * change handler of MID_MNY_CNM_CONNECTION_ABORT from NULL to mboxDummy.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * AIS-FSM integration with CNM channel request messages
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Modify CNM message handler for new flow
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * enable currently migrated message call-backs.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * restore utility function invoking via hem_mbox to direct calls
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add buildable & linkable ais_fsm.c
+ *
+ * related reference are still waiting to be resolved
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * hem_mbox is migrated.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Fix file merge error
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 29 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME
+ *
+ * 04 29 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Removed MID_RXM_MQM_BA_ACTION_FRAME
+ *
+ * 04 27 2010 tehuang.liu
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * MID_RXM_MQM_BA_ACTION_FRAME
+ *
+ * 03 30 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support 2.4G OBSS scan
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ *  *  *  *  *  *  *  *  *  *  *  *  *  * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 03 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Develop partial DPD code
+ *
+ * 02 11 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Updated arMsgMapTable for MID_RXM_MQM_QOS_ACTION_FRAME
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * Dec 9 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add hemRunEventScanDone() to arMsgMapTable[]
+ *
+ * Dec 4 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix mboxDummy() didn't free prMsgHdr
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add saaAisJoinComplete event handler
+ *
+ * Dec 2 2009 MTK02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Fixed the handler function name in arMsgMapTable for MID_RXM_MQM_BA_ACTION_FRAME
+ *
+ * Dec 2 2009 MTK02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Added MID_RXM_MQM_BA_ACTION_FRAME to MsgMapTable
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Revise MSG Handler (remove dummy and add for SAA)
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add aisFsmRunEventAbort() event handler
+ *
+ * Nov 11 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix typo
+ *
+ * Nov 10 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add more MSG_HNDL_ENTRY_T to avoid ASSERT() in mboxInitMsgMap()
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add SCN message and function entry to arMsgMapTable[]
+ *
+ * Nov 2 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix sorting algorithm in mboxInitMsgMap()
+ *
+ * Oct 28 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if DBG
+/*lint -save -e64 Type mismatch */
+static PUINT_8 apucDebugMsg[] = {
+	(PUINT_8) DISP_STRING("MID_MNY_CNM_CH_REQ"),
+	(PUINT_8) DISP_STRING("MID_MNY_CNM_CH_ABORT"),
+	(PUINT_8) DISP_STRING("MID_CNM_AIS_CH_GRANT"),
+	(PUINT_8) DISP_STRING("MID_CNM_P2P_CH_GRANT"),
+	(PUINT_8) DISP_STRING("MID_CNM_BOW_CH_GRANT"),
+
+	(PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ"),
+	(PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ_V2"),
+	(PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_CANCEL"),
+	(PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ"),
+	(PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ_V2"),
+	(PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_CANCEL"),
+	(PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ"),
+	(PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ_V2"),
+	(PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_CANCEL"),
+	(PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ"),
+	(PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ_V2"),
+	(PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_CANCEL"),
+	(PUINT_8) DISP_STRING("MID_SCN_AIS_SCAN_DONE"),
+	(PUINT_8) DISP_STRING("MID_SCN_P2P_SCAN_DONE"),
+	(PUINT_8) DISP_STRING("MID_SCN_BOW_SCAN_DONE"),
+	(PUINT_8) DISP_STRING("MID_SCN_RLM_SCAN_DONE"),
+
+	(PUINT_8) DISP_STRING("MID_OID_AIS_FSM_JOIN_REQ"),
+	(PUINT_8) DISP_STRING("MID_OID_AIS_FSM_ABORT"),
+	(PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_START"),
+	(PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_ABORT"),
+	(PUINT_8) DISP_STRING("MID_SAA_AIS_JOIN_COMPLETE"),
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	(PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_START"),
+	(PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_ABORT"),
+	(PUINT_8) DISP_STRING("MID_SAA_BOW_JOIN_COMPLETE"),
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+	(PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_START"),
+	(PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_ABORT"),
+	(PUINT_8) DISP_STRING("MID_SAA_P2P_JOIN_COMPLETE"),
+
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_FUN_SWITCH"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_DEVICE_DISCOVERY"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_REQ"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_ABORT"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_BEACON_UPDATE"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_STOP_AP"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_REQ"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_ABORT"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_TX"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_GROUP_DISSOLVE"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_REGISTER"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_NET_DEV_REGISTER"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_START_AP"),
+	(PUINT_8) DISP_STRING("MID_MNY_P2P_UPDATE_IE_BUF"),
+#endif
+
+#if CFG_SUPPORT_ADHOC
+	/* (PUINT_8)DISP_STRING("MID_AIS_CNM_CREATE_IBSS_REQ"), */
+	/* (PUINT_8)DISP_STRING("MID_CNM_AIS_CREATE_IBSS_GRANT"), */
+	/* (PUINT_8)DISP_STRING("MID_AIS_CNM_MERGE_IBSS_REQ"), */
+	/* (PUINT_8)DISP_STRING("MID_CNM_AIS_MERGE_IBSS_GRANT"), */
+	(PUINT_8) DISP_STRING("MID_SCN_AIS_FOUND_IBSS"),
+#endif /* CFG_SUPPORT_ADHOC */
+
+	(PUINT_8) DISP_STRING("MID_SAA_AIS_FSM_ABORT"),
+	(PUINT_8) DISP_STRING("MID_MNY_AIS_REMAIN_ON_CHANNEL"),
+	(PUINT_8) DISP_STRING("MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL"),
+	(PUINT_8) DISP_STRING("MID_MNY_AIS_MGMT_TX")
+};
+
+/*lint -restore */
+#endif /* DBG */
+
+/* This message entry will be re-ordered based on the message ID order
+ * by invoking mboxInitMsgMap()
+ */
+static MSG_HNDL_ENTRY_T arMsgMapTable[] = {
+	{MID_MNY_CNM_CH_REQ, cnmChMngrRequestPrivilege},
+	{MID_MNY_CNM_CH_ABORT, cnmChMngrAbortPrivilege},
+	{MID_CNM_AIS_CH_GRANT, aisFsmRunEventChGrant},
+#if CFG_ENABLE_WIFI_DIRECT
+	{MID_CNM_P2P_CH_GRANT, p2pFsmRunEventChGrant},	/*set in gl_p2p_init.c */
+#else
+	{MID_CNM_P2P_CH_GRANT, mboxDummy},
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	{MID_CNM_BOW_CH_GRANT, bowRunEventChGrant},
+#else
+	{MID_CNM_BOW_CH_GRANT, mboxDummy},
+#endif
+
+    /*--------------------------------------------------*/
+	/* SCN Module Mailbox Messages                      */
+    /*--------------------------------------------------*/
+	{MID_AIS_SCN_SCAN_REQ, scnFsmMsgStart},
+	{MID_AIS_SCN_SCAN_REQ_V2, scnFsmMsgStart},
+	{MID_AIS_SCN_SCAN_CANCEL, scnFsmMsgAbort},
+	{MID_P2P_SCN_SCAN_REQ, scnFsmMsgStart},
+	{MID_P2P_SCN_SCAN_REQ_V2, scnFsmMsgStart},
+	{MID_P2P_SCN_SCAN_CANCEL, scnFsmMsgAbort},
+	{MID_BOW_SCN_SCAN_REQ, scnFsmMsgStart},
+	{MID_BOW_SCN_SCAN_REQ_V2, scnFsmMsgStart},
+	{MID_BOW_SCN_SCAN_CANCEL, scnFsmMsgAbort},
+	{MID_RLM_SCN_SCAN_REQ, scnFsmMsgStart},
+	{MID_RLM_SCN_SCAN_REQ_V2, scnFsmMsgStart},
+	{MID_RLM_SCN_SCAN_CANCEL, scnFsmMsgAbort},
+	{MID_SCN_AIS_SCAN_DONE, aisFsmRunEventScanDone},
+#if CFG_ENABLE_WIFI_DIRECT
+	{MID_SCN_P2P_SCAN_DONE, p2pFsmRunEventScanDone},	/*set in gl_p2p_init.c */
+#else
+	{MID_SCN_P2P_SCAN_DONE, mboxDummy},
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	{MID_SCN_BOW_SCAN_DONE, bowResponderScanDone},
+#else
+	{MID_SCN_BOW_SCAN_DONE, mboxDummy},
+#endif
+	{MID_SCN_RLM_SCAN_DONE, rlmObssScanDone},
+
+    /*--------------------------------------------------*/
+	/* AIS Module Mailbox Messages                      */
+    /*--------------------------------------------------*/
+	{MID_OID_AIS_FSM_JOIN_REQ, aisFsmRunEventAbort},
+	{MID_OID_AIS_FSM_ABORT, aisFsmRunEventAbort},
+	{MID_AIS_SAA_FSM_START, saaFsmRunEventStart},
+	{MID_AIS_SAA_FSM_ABORT, saaFsmRunEventAbort},
+	{MID_SAA_AIS_JOIN_COMPLETE, aisFsmRunEventJoinComplete},
+
+#if CFG_ENABLE_BT_OVER_WIFI
+    /*--------------------------------------------------*/
+	/* BOW Module Mailbox Messages                      */
+    /*--------------------------------------------------*/
+	{MID_BOW_SAA_FSM_START, saaFsmRunEventStart},
+	{MID_BOW_SAA_FSM_ABORT, saaFsmRunEventAbort},
+	{MID_SAA_BOW_JOIN_COMPLETE, bowFsmRunEventJoinComplete},
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT	/*set in gl_p2p_init.c */
+	{MID_P2P_SAA_FSM_START, saaFsmRunEventStart},
+	{MID_P2P_SAA_FSM_ABORT, saaFsmRunEventAbort},
+	{MID_SAA_P2P_JOIN_COMPLETE, p2pFsmRunEventJoinComplete},	/* TODO: p2pFsmRunEventJoinComplete */
+
+	{MID_MNY_P2P_FUN_SWITCH, p2pFsmRunEventSwitchOPMode},
+	{MID_MNY_P2P_DEVICE_DISCOVERY, p2pFsmRunEventScanRequest},
+	{MID_MNY_P2P_CONNECTION_REQ, p2pFsmRunEventConnectionRequest},
+	{MID_MNY_P2P_CONNECTION_ABORT, p2pFsmRunEventConnectionAbort},
+	{MID_MNY_P2P_BEACON_UPDATE, p2pFsmRunEventBeaconUpdate},
+	{MID_MNY_P2P_STOP_AP, p2pFsmRunEventStopAP},
+	{MID_MNY_P2P_CHNL_REQ, p2pFsmRunEventChannelRequest},
+	{MID_MNY_P2P_CHNL_ABORT, p2pFsmRunEventChannelAbort},
+	{MID_MNY_P2P_MGMT_TX, p2pFsmRunEventMgmtFrameTx},
+	{MID_MNY_P2P_GROUP_DISSOLVE, p2pFsmRunEventDissolve},
+	{MID_MNY_P2P_MGMT_FRAME_REGISTER, p2pFsmRunEventMgmtFrameRegister},
+	{MID_MNY_P2P_NET_DEV_REGISTER, p2pFsmRunEventNetDeviceRegister},
+	{MID_MNY_P2P_START_AP, p2pFsmRunEventStartAP},
+	{MID_MNY_P2P_MGMT_FRAME_UPDATE, p2pFsmRunEventUpdateMgmtFrame},
+	{MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, p2pFsmRunEventExtendListen},
+#if CFG_SUPPORT_WFD
+	{MID_MNY_P2P_WFD_CFG_UPDATE, p2pFsmRunEventWfdSettingUpdate},
+#endif
+
+#endif
+
+#if CFG_SUPPORT_ADHOC
+	{MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer},
+#endif /* CFG_SUPPORT_ADHOC */
+
+	{MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort},
+	{MID_MNY_AIS_REMAIN_ON_CHANNEL, aisFsmRunEventRemainOnChannel},
+	{MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, aisFsmRunEventCancelRemainOnChannel},
+	{MID_MNY_AIS_MGMT_TX, aisFsmRunEventMgmtFrameTx}
+};
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+#if DBG
+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \
+	ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \
+	if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \
+		DBGLOG(CNM, LOUD, "DO MSG [%d: %s]\n", prMsg->eMsgId, apucDebugMsg[prMsg->eMsgId]); \
+		arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \
+	} \
+	else { \
+	    DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \
+	    cnmMemFree(prAdapter, prMsg); \
+	} \
+} while (0)
+#else
+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \
+	ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \
+	if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \
+		DBGLOG(CNM, LOUD, "DO MSG [%d]\n", prMsg->eMsgId); \
+		arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \
+	} \
+	else { \
+	    DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \
+	    cnmMemFree(prAdapter, prMsg); \
+	} \
+} while (0)
+#endif
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mboxInitMsgMap(VOID)
+{
+	UINT_32 i, idx;
+	MSG_HNDL_ENTRY_T rTempEntry;
+
+	ASSERT((sizeof(arMsgMapTable) / sizeof(MSG_HNDL_ENTRY_T)) == MID_TOTAL_NUM);
+
+	for (i = 0; i < MID_TOTAL_NUM; i++) {
+		if (arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i)
+			continue;
+		for (idx = i + 1; idx < MID_TOTAL_NUM; idx++) {
+			if (arMsgMapTable[idx].eMsgId == (ENUM_MSG_ID_T) i)
+				break;
+		}
+		ASSERT(idx < MID_TOTAL_NUM);
+		if (idx >= MID_TOTAL_NUM)
+			continue;
+
+		/* Swap target entry and current entry */
+		rTempEntry.eMsgId = arMsgMapTable[idx].eMsgId;
+		rTempEntry.pfMsgHndl = arMsgMapTable[idx].pfMsgHndl;
+
+		arMsgMapTable[idx].eMsgId = arMsgMapTable[i].eMsgId;
+		arMsgMapTable[idx].pfMsgHndl = arMsgMapTable[i].pfMsgHndl;
+
+		arMsgMapTable[i].eMsgId = rTempEntry.eMsgId;
+		arMsgMapTable[i].pfMsgHndl = rTempEntry.pfMsgHndl;
+	}
+
+	/* Verify the correctness of final message map */
+	for (i = 0; i < MID_TOTAL_NUM; i++) {
+		ASSERT(arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i);
+		while (arMsgMapTable[i].eMsgId != (ENUM_MSG_ID_T) i)
+			;
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId)
+{
+	P_MBOX_T prMbox;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(eMboxId < MBOX_ID_TOTAL_NUM);
+	ASSERT(prAdapter);
+
+	prMbox = &(prAdapter->arMbox[eMboxId]);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+	LINK_INITIALIZE(&prMbox->rLinkHead);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+mboxSendMsg(IN P_ADAPTER_T prAdapter,
+	    IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod)
+{
+	P_MBOX_T prMbox;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(eMboxId < MBOX_ID_TOTAL_NUM);
+	ASSERT(prMsg);
+	ASSERT(prAdapter);
+
+	prMbox = &(prAdapter->arMbox[eMboxId]);
+
+	switch (eMethod) {
+	case MSG_SEND_METHOD_BUF:
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+		LINK_INSERT_TAIL(&prMbox->rLinkHead, &prMsg->rLinkEntry);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+
+		/* to wake up main service thread */
+		GLUE_SET_EVENT(prAdapter->prGlueInfo);
+
+		break;
+
+	case MSG_SEND_METHOD_UNBUF:
+		MBOX_HNDL_MSG(prAdapter, prMsg);
+		break;
+
+	default:
+		ASSERT(0);
+		break;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, ENUM_MBOX_ID_T eMboxId)
+{
+	P_MBOX_T prMbox;
+	P_MSG_HDR_T prMsg;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(eMboxId < MBOX_ID_TOTAL_NUM);
+	ASSERT(prAdapter);
+
+	prMbox = &(prAdapter->arMbox[eMboxId]);
+
+	while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) {
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+		LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+
+		ASSERT(prMsg);
+		MBOX_HNDL_MSG(prAdapter, prMsg);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mboxInitialize(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	/* Initialize Mailbox */
+	mboxInitMsgMap();
+
+	/* Setup/initialize each mailbox */
+	for (i = 0; i < MBOX_ID_TOTAL_NUM; i++)
+		mboxSetup(prAdapter, i);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mboxDestroy(IN P_ADAPTER_T prAdapter)
+{
+	P_MBOX_T prMbox;
+	P_MSG_HDR_T prMsg;
+	UINT_8 i;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) {
+		prMbox = &(prAdapter->arMbox[i]);
+
+		while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) {
+			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+			LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T);
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX);
+
+			ASSERT(prMsg);
+			cnmMemFree(prAdapter, prMsg);
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This is dummy function to prevent empty arMsgMapTable[] for compiling.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mboxDummy(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	ASSERT(prAdapter);
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c
new file mode 100644
index 0000000000000..7fb71a199ccf4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c
@@ -0,0 +1,498 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2
+*/
+
+/*! \file   "hs20.c"
+    \brief  This file including the hotspot 2.0 related function.
+
+    This file provided the macros and functions library support for the
+    protocol layer hotspot 2.0 related function.
+
+*/
+
+/*
+** Log: hs20.c
+ *
+ */
+
+ /*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called to generate Interworking IE for Probe Rsp, Bcn, Assoc Req/Rsp.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[out] prMsduInfo  Pointer of the Msdu Info
+*
+* \return VOID
+*/
+/*----------------------------------------------------------------------------*/
+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo)
+{
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called to generate Roaming Consortium IE for Probe Rsp, Bcn, Assoc Req/Rsp.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[out] prMsduInfo  Pointer of the Msdu Info
+*
+* \return VOID
+*/
+/*----------------------------------------------------------------------------*/
+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo)
+{
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called to generate HS2.0 IE for Probe Rsp, Bcn, Assoc Req/Rsp.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[out] prMsduInfo  Pointer of the Msdu Info
+*
+* \return VOID
+*/
+/*----------------------------------------------------------------------------*/
+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo)
+{
+	PUINT_8 pucBuffer;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
+		return;
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+	/* ASSOC INFO IE ID: 221 :0xDD */
+	if (prAdapter->prGlueInfo->u2HS20AssocInfoIELen) {
+		kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucHS20AssocInfoIE,
+			   prAdapter->prGlueInfo->u2HS20AssocInfoIELen);
+		prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2HS20AssocInfoIELen;
+	}
+
+}
+
+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo)
+{
+	P_HS20_EXT_CAP_T prExtCap;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	/* Add Extended Capabilities IE */
+	prExtCap = (P_HS20_EXT_CAP_T)
+	    (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+
+	prExtCap->ucId = ELEM_ID_EXTENDED_CAP;
+	if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE)
+		prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP;
+	else
+		prExtCap->ucLength = 3 - ELEM_HDR_LEN;
+
+	kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength);
+
+	prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL;
+
+	if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+		prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP;
+
+	if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) {
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT);
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT);
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT);
+
+		/* For R2 WNM-Notification */
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT);
+	}
+	kalPrint("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP);
+	ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP));
+
+	prMsduInfo->u2FrameLength += IE_SIZE(prExtCap);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called to fill up the content of Ext Cap IE bit 31.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[out] pucIE  Pointer of the IE buffer
+*
+* \return VOID
+*/
+/*----------------------------------------------------------------------------*/
+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE)
+{
+	P_HS20_EXT_CAP_T prExtCap;
+
+	ASSERT(prAdapter);
+
+	/* Add Extended Capabilities IE */
+	prExtCap = (P_HS20_EXT_CAP_T) pucIE;
+
+	prExtCap->ucId = ELEM_ID_EXTENDED_CAP;
+	if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE)
+		prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP;
+	else
+		prExtCap->ucLength = 3 - ELEM_HDR_LEN;
+
+	kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength);
+
+	prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL;
+
+	if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) {
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT);
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT);
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT);
+
+		/* For R2 WNM-Notification */
+		SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called to fill up the content of HS2.0 IE.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[out] pucIE  Pointer of the IE buffer
+*
+* \return VOID
+*/
+/*----------------------------------------------------------------------------*/
+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE)
+{
+	P_IE_HS20_INDICATION_T prHS20IndicationIe;
+	/* P_HS20_INFO_T prHS20Info; */
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
+
+	/* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */
+
+	prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pucIE;
+
+	prHS20IndicationIe->ucId = ELEM_ID_VENDOR;
+	prHS20IndicationIe->ucLength = sizeof(IE_HS20_INDICATION_T) - ELEM_HDR_LEN;
+	prHS20IndicationIe->aucOui[0] = aucWfaOui[0];
+	prHS20IndicationIe->aucOui[1] = aucWfaOui[1];
+	prHS20IndicationIe->aucOui[2] = aucWfaOui[2];
+	prHS20IndicationIe->ucType = VENDOR_OUI_TYPE_HS20;
+	prHS20IndicationIe->ucHotspotConfig = 0x00;	/* prHS20Info->ucHotspotConfig; */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called while calculating length of hotspot 2.0 indication IE for Probe Request.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[in] pucTargetBSSID  Pointer of target HESSID
+*
+* \return the length of composed HS20 IE
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID)
+{
+	UINT_32 u4IeLength;
+
+	if (0)			/* Todo:: Not HS20 STA */
+		return 0;
+
+	u4IeLength =
+	    sizeof(IE_HS20_INDICATION_T) + /* sizeof(IE_INTERWORKING_T) */ + (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP);
+
+	if (!pucTargetBSSID) {
+		/* Do nothing */
+		/* u4IeLength -= MAC_ADDR_LEN; */
+	}
+
+	return u4IeLength;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called while composing hotspot 2.0 indication IE for Probe Request.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+* \param[in] pucTargetBSSID  Pointer of target HESSID
+* \param[out] prIE  Pointer of the IE buffer
+*
+* \return the wlan status
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE)
+{
+	if (0)			/* Todo:: Not HS20 STA */
+		return 0;
+#if 0
+	P_HS20_INFO_T prHS20Info;
+
+	prHS20Info = &(prAdapter->rWifiVar.rHS20Info);
+
+	/*
+	 * Generate 802.11u Interworking IE (107)
+	 */
+	hs20FillInterworkingIE(prAdapter,
+			       prHS20Info->ucAccessNetworkOptions,
+			       prHS20Info->ucVenueGroup, prHS20Info->ucVenueType, pucTargetBSSID, prIE);
+	prIE += IE_SIZE(prIE);
+#endif
+	/*
+	 * Generate Ext Cap IE (127)
+	 */
+	hs20FillProreqExtCapIE(prAdapter, prIE);
+	prIE += IE_SIZE(prIE);
+
+	/*
+	 * Generate HS2.0 Indication IE (221)
+	 */
+	hs20FillHS20IE(prAdapter, prIE);
+	prIE += IE_SIZE(prIE);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb)
+{
+	PUINT_8 pucSenderIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET;
+	PUINT_8 pucTargetIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET;
+	PUINT_8 pucSenderMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SNEDER_MAC_OFFSET);
+#if CFG_HS20_DEBUG && 0
+/* UINT_8  aucIpAllZero[4] = {0,0,0,0}; */
+/* UINT_8  aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */
+	PUINT_8 pucTargetMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET);
+#endif
+
+#if CFG_HS20_DEBUG && 0
+	PUINT_16 pu2ArpOper = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET);
+
+	kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper));
+	kalPrint("SENDER[ %pM ] [%pI4]\n", pucSenderMac, pucSenderIP);
+	kalPrint("TARGET[ %pM ] [%pI4]\n", pucTargetMac, pucTargetIP);
+#endif
+
+	/* IsGratuitousArp */
+	if (!kalMemCmp(pucSenderIP, pucTargetIP, 4)) {
+		kalPrint("Drop Gratuitous ARP from [ %pM ] [%pI4]\n", pucSenderMac, pucTargetIP);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb)
+{
+	PUINT_8 pucIpv6Protocol = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_PROTOCOL_OFFSET);
+
+	/* kalPrint("pucIpv6Protocol [%02X:%02X]\n", *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); */
+	if (*pucIpv6Protocol == IPV6_PROTOCOL_ICMPV6) {
+		PUINT_8 pucICMPv6Type =
+		    ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_TYPE_OFFSET);
+		/* kalPrint("pucICMPv6Type [%02X:%02X]\n", *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); */
+		if (*pucICMPv6Type == ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT) {
+			PUINT_8 pucICMPv6Flag =
+			    ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_FLAG_OFFSET);
+			PUINT_8 pucSrcMAC = ((PUINT_8) prCurrSwRfb->pvHeader + MAC_ADDR_LEN);
+
+#if CFG_HS20_DEBUG
+			kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n",
+				 *pucICMPv6Flag,
+				 (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_ROUTER_BIT) >> 7,
+				 (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT) >> 6,
+				 (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_OVERWRITE_BIT) >> 5);
+#endif
+			if (!(*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT)) {
+				kalPrint("Drop Unsolicited Neighbor Advertisement from [%pM]\n", pucSrcMAC);
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+#if CFG_ENABLE_GTK_FRAME_FILTER
+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb)
+{
+	/*
+	P_CONNECTION_SETTINGS_T prConnSettings = &prAdapter->rWifiVar.rConnSettings;
+	PUINT_8 pucEthDestAddr = prCurrSwRfb->pvHeader;
+	*/
+	/* 3 TODO: Need to verify this function before enable it */
+	return FALSE;
+	/*
+	if ((prConnSettings->eEncStatus != ENUM_ENCRYPTION_DISABLED) && IS_BMCAST_MAC_ADDR(pucEthDestAddr)) {
+		UINT_8 ucIdx = 0;
+		PUINT_32 prIpAddr, prPacketDA;
+		PUINT_16 pu2PktIpVer =
+		    (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN));
+
+		if (*pu2PktIpVer == htons(ETH_P_IPV4)) {
+			if (!prBssInfo->prIpV4NetAddrList)
+				return FALSE;
+			for (ucIdx = 0; ucIdx < prBssInfo->prIpV4NetAddrList->ucAddrCount; ucIdx++) {
+				prIpAddr = (PUINT_32) &prBssInfo->prIpV4NetAddrList->arNetAddr[ucIdx].aucIpAddr[0];
+				prPacketDA =
+				    (PUINT_32) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN +
+						IPV4_HDR_IP_DST_ADDR_OFFSET);
+
+				if (kalMemCmp(prIpAddr, prPacketDA, 4) == 0) {
+					kalPrint("Drop FORGED IPv4 packet\n");
+					return TRUE;
+				}
+			}
+		}
+#ifdef CONFIG_IPV6
+		else if (*pu2PktIpVer == htons(ETH_P_IPV6)) {
+			UINT_8 aucIPv6Mac[MAC_ADDR_LEN];
+			PUINT_8 pucIdx =
+			    prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET;
+
+			kalMemCopy(&aucIPv6Mac[0], pucIdx, 3);
+			pucIdx += 5;
+			kalMemCopy(&aucIPv6Mac[3], pucIdx, 3);
+			kalPrint("Get IPv6 frame Dst IP MAC part %pM\n", aucIPv6Mac);
+			if (EQUAL_MAC_ADDR(aucIPv6Mac, prBssInfo->aucOwnMacAddr)) {
+				kalPrint("Drop FORGED IPv6 packet\n");
+				return TRUE;
+			}
+		}
+#endif
+	}
+
+	return FALSE;
+	*/
+}
+#endif
+
+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb)
+{
+	PUINT_16 pu2PktIpVer = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN));
+
+	/* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */
+#if CFG_HS20_DEBUG & 0
+	UINT_8 i = 0;
+
+	kalPrint("===============================================");
+	for (i = 0; i < 96; i++) {
+		if (!(i % 16))
+			kalPrint("\n");
+		kalPrint("%02X ", *((PUINT_8) prCurrSwRfb->pvHeader + i));
+	}
+	kalPrint("\n");
+#endif
+
+#if CFG_ENABLE_GTK_FRAME_FILTER
+	if (hs20IsForgedGTKFrame(prAdapter, prBssInfo, prCurrSwRfb))
+		return TRUE;
+
+#endif
+	if (*pu2PktIpVer == htons(ETH_P_ARP))
+		return hs20IsGratuitousArp(prAdapter, prCurrSwRfb);
+	else if (*pu2PktIpVer == htons(ETH_P_IPV6))
+		return hs20IsUnsolicitedNeighborAdv(prAdapter, prCurrSwRfb);
+
+	return FALSE;
+}
+
+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
+{
+#if 1
+	if (prAdapter->prGlueInfo->fgConnectHS20AP)
+		return TRUE;
+#else
+	PARAM_SSID_T rParamSsid;
+	P_BSS_DESC_T prBssDesc;
+
+	rParamSsid.u4SsidLen = prBssInfo->ucSSIDLen;
+	COPY_SSID(rParamSsid.aucSsid, rParamSsid.u4SsidLen, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
+
+	prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, prBssInfo->aucBSSID, TRUE, &rParamSsid);
+	if (!prBssDesc)
+		return FALSE;
+
+	if (prBssDesc->fgIsSupportHS20) {
+		if (!(prBssDesc->ucHotspotConfig & ELEM_HS_CONFIG_DGAF_DISABLED_MASK))
+			return TRUE;
+
+		/* Disable frame filter only if DGAF == 1 */
+		return FALSE;
+
+	}
+#endif
+
+	/* For Now, always return true to run hs20 check even for legacy AP */
+	return TRUE;
+}
+
+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx)
+{
+	P_PARAM_HS20_SET_BSSID_POOL prParamBssidPool = (P_PARAM_HS20_SET_BSSID_POOL) pvBuffer;
+	P_HS20_INFO_T prHS20Info;
+	UINT_8 ucIdx;
+
+	prHS20Info = &(prAdapter->rWifiVar.rHS20Info);
+	kalPrint("[%s]Set Bssid Pool! enable[%d] num[%d]\n", __func__, prParamBssidPool->fgIsEnable,
+	       prParamBssidPool->ucNumBssidPool);
+	for (ucIdx = 0; ucIdx < prParamBssidPool->ucNumBssidPool; ucIdx++) {
+		COPY_MAC_ADDR(prHS20Info->arBssidPool[ucIdx].aucBSSID, &prParamBssidPool->arBSSID[ucIdx]);
+		kalPrint("[%s][%d][ %pM ]\n", __func__, ucIdx, (prHS20Info->arBssidPool[ucIdx].aucBSSID));
+	}
+	prHS20Info->fgIsHS2SigmaMode = prParamBssidPool->fgIsEnable;
+	prHS20Info->ucNumBssidPoolEntry = prParamBssidPool->ucNumBssidPool;
+
+#if 0
+	wlanClearScanningResult(prAdapter);
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c
new file mode 100644
index 0000000000000..469a48ebe9c10
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c
@@ -0,0 +1,111 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/mib.c#1
+*/
+
+/*! \file   "mib.c"
+    \brief  This file includes the mib default vale and functions.
+*/
+
+/*
+** Log: mib.c
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add mib.c.
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[] = {
+	{RATE_SET_HR_DSSS, TRUE, FALSE}
+	,			/* For PHY_TYPE_HR_DSSS_INDEX(0) */
+	{RATE_SET_ERP, TRUE, TRUE}
+	,			/* For PHY_TYPE_ERP_INDEX(1) */
+	{RATE_SET_ERP_P2P, TRUE, TRUE}
+	,			/* For PHY_TYPE_ERP_P2P_INDEX(2) */
+	{RATE_SET_OFDM, FALSE, FALSE}
+	,			/* For PHY_TYPE_OFDM_INDEX(3) */
+};
+
+NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[AD_HOC_MODE_NUM] = {
+	{PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS}
+	,			/* For AD_HOC_MODE_11B(0) */
+	{PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP}
+	,			/* For AD_HOC_MODE_MIXED_11BG(1) */
+	{PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP}
+	,			/* For AD_HOC_MODE_11G(2) */
+	{PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM}
+	,			/* For AD_HOC_MODE_11A(3) */
+};
+
+NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[AP_MODE_NUM] = {
+	{PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS}
+	,			/* For AP_MODE_11B(0) */
+	{PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP}
+	,			/* For AP_MODE_MIXED_11BG(1) */
+	{PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP}
+	,			/* For AP_MODE_11G(2) */
+	{PHY_TYPE_ERP_P2P_INDEX, BASIC_RATE_SET_ERP_P2P}
+	,			/* For AP_MODE_11G_P2P(3) */
+	{PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM}
+	,			/* For AP_MODE_11A(4) */
+};
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c
new file mode 100644
index 0000000000000..cb5fbebedd495
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c
@@ -0,0 +1,87 @@
+/*
+** Id: @(#) p2p_assoc.c@@
+*/
+
+/*! \file   "p2p_assoc.c"
+    \brief  This file includes the Wi-Fi Direct association-related functions.
+
+    This file includes the association-related functions.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to compose Common Information Elements for P2P Association
+*        Request Frame.
+*
+* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer)
+{
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+	/* Fill the SSID element. */
+	SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID;
+
+	/* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of
+	 * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame.
+	 */
+
+	COPY_SSID(SSID_IE(pucBuffer)->aucSSID,
+		  SSID_IE(pucBuffer)->ucLength, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen);
+
+	prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+	pucBuffer += IE_SIZE(pucBuffer);
+	return pucBuffer;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c
new file mode 100644
index 0000000000000..72a20a322cee6
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c
@@ -0,0 +1,58 @@
+/*
+** Id: @(#) p2p_bss.c@@
+*/
+
+/*! \file   "p2p_bss.c"
+    \brief  This file contains the functions for creating p2p BSS(AP).
+
+    This file contains the functions for BSS(AP). We may create a BSS
+    network, or merge with exist IBSS network and sending Beacon Frame or reply
+    the Probe Response Frame for received Probe Request Frame.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c
new file mode 100644
index 0000000000000..f8c09e2aa9ded
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c
@@ -0,0 +1,3139 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/mgmt/p2p_fsm.c#61
+*/
+
+/*! \file   "p2p_fsm.c"
+    \brief  This file defines the FSM for P2P Module.
+
+    This file defines the FSM for P2P Module.
+*/
+
+/*
+** Log: p2p_fsm.c
+**
+** 12 20 2012 yuche.tsai
+** [ALPS00410124] [Rose][Free Test][KE][rlmUpdateParamsForAP]The device reboot automatically
+** and then "Fatal/Kernel" pops up during use data service.(Once)
+** Fix possible NULL station record cause KE under AP mode.
+** May due to variable uninitial.
+** Review: http://mtksap20:8080/go?page=NewReview&reviewid=49970
+**
+** 09 12 2012 wcpadmin
+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
+** .
+**
+** 08 31 2012 yuche.tsai
+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected
+**to AP previously,one device reboots automatically with KE
+** Fix possible KE when concurrent & disconnect.
+**
+** 08 21 2012 yuche.tsai
+** NULL
+** fix disconnect indication.
+**
+** 08 16 2012 yuche.tsai
+** NULL
+** Fix compile warning.
+**
+** 08 14 2012 yuche.tsai
+** NULL
+** Fix p2p bug find on ALPS.JB trunk.
+**
+** 07 27 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update for driver unload KE issue.
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Fix the compile flag of enhancement.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000808] [Volunteer Patch][MT6620][Driver/FW] Device discoverability issue fix
+ * Change device discoverability methodology. From driver SCAN to FW lock channel.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Add wifi direct connection enhancement method I, II & VI.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000833] [Volunteer Patch][WiFi Direct][Driver] Service Discovery Frame RX Indicate Issue
+ * Fix Service Discovery Race Condition Issue.
+ *
+ * 06 23 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * change parameter name from PeerAddr to BSSID
+ *
+ * 06 21 2011 yuche.tsai
+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue.
+ * Fix an issue of accepting connection of GO.
+ *
+ * 06 21 2011 yuche.tsai
+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability
+ * Drop GAS frame when SD is not enabled.
+ *
+ * 06 20 2011 yuche.tsai
+ * NULL
+ * Fix compile error.
+ *
+ * 06 20 2011 yuche.tsai
+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue.
+ * Fix connection indication twice issue.
+ *
+ * 06 20 2011 cp.wu
+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module
+ * 1. specify target's BSSID when requesting channel privilege.
+ * 2. pass BSSID information to firmware domain
+ *
+ * 06 20 2011 yuche.tsai
+ * [WCXRP00000795] [Volunteer Patch][MT6620][Driver] GO can not connect second device issue
+ * Solve P2P GO can not formation with second device issue.
+ *
+ * 06 14 2011 yuche.tsai
+ * NULL
+ * Change disconnect feature.
+ *
+ * 06 10 2011 yuche.tsai
+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability[WCXRP00000776]
+ * [Need Patch][MT6620][Driver] MT6620 response probe request of P2P device with P2P IE under Hot Spot mode.
+ * 1. Dynamic enable SD capability after P2P supplicant ready.
+ * 2. Avoid response probe respone with p2p IE when under hot spot mode.
+ *
+ * 06 07 2011 yuche.tsai
+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue
+ * Fix RX SD request under AP mode issue.
+ *
+ * 06 02 2011 cp.wu
+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction
+ * eliminate unused parameters for SAA-FSM
+ *
+ * 05 26 2011 yuche.tsai
+ * [WCXRP00000745] Support accepting connection after one Group Connection Lost.
+
+After Group Formation & lost connection, if MT6620 behave as:
+
+1. GO: It would keep under GO state until been dissolved by supplicant.
+
+	  At this time, other P2P device can use join method to join this group.
+
+2. GC: It would keep on searching target GO or target device until been dissolved by supplicant.
+
+At this time, it would ignore other P2P device formation request.
+
+--
+
+Modification: Make driver to accept GO NEGO REQ at this time, to let user decide to accept new connection or not.
+
+ * [Volunteer Patch][MT6620][Driver]
+ * Driver would indicate connection request, if password ID is not ready but connection request is issued.
+ *
+ * 05 18 2011 yuche.tsai
+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue.
+ * A solution for both connection request & IO control.
+ *
+ * 05 16 2011 yuche.tsai
+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue.
+ * Fix SD request can not send out issue.
+ *
+ * 05 09 2011 terry.wu
+ * [WCXRP00000711] [MT6620 Wi-Fi][Driver] Set Initial value of StaType in StaRec for Hotspot Client
+ * Set initial value of StaType in StaRec for hotspot client.
+ *
+ * 05 04 2011 yuche.tsai
+ * [WCXRP00000697] [Volunteer Patch][MT6620][Driver]
+ * Bug fix for p2p descriptor is NULL if BSS descriptor is found first.
+ *
+ * 05 04 2011 yuche.tsai
+ * NULL
+ * Support partial persistent group function.
+ *
+ * 05 02 2011 yuche.tsai
+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout.
+ * Clear formation flag after formation timeout.
+ *
+ * 04 20 2011 yuche.tsai
+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition
+ * when add scan & query scan result at the same time.
+ * Fix side effect while starting ATGO.
+ *
+ * 04 20 2011 yuche.tsai
+ * NULL
+ * Fix ASSERT issue in FW, side effect of last change.
+ *
+ * 04 19 2011 yuche.tsai
+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition
+ * when add scan & query scan result at the same time.
+ * Workaround for multiple device connection, before invitation ready.
+ *
+ * 04 19 2011 yuche.tsai
+ * [WCXRP00000665] [Wifi Direct][MT6620 E4] When use Ralink's dongle to establish wifi direct connection with PBC.
+ * But 6573 always not pop accept option to establish connection.
+ * Support connection indication when GO NEGO REQ doesn't have configure method, instead it has PasswordID.
+ *
+ * 04 18 2011 yuche.tsai
+ * NULL
+ * Fix error.
+ *
+ * 04 14 2011 yuche.tsai
+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
+ * Fix a connection issue.
+ *
+ * 04 14 2011 yuche.tsai
+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
+ * Fix the channel issue of AP mode.
+ *
+ * 04 14 2011 yuche.tsai
+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
+ * Connection flow refine for Sigma test.
+ *
+ * 04 09 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Fix Device discoverability related issue.
+ *
+ * 04 09 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Fix bug for Device Discoverability.
+ *
+ * 04 08 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Fix compile error.
+ *
+ * 04 08 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Add device discoverability support.
+ *
+ * 03 28 2011 yuche.tsai
+ * NULL
+ * Fix a possible issue for retry join when media status connected.
+ *
+ * 03 25 2011 yuche.tsai
+ * NULL
+ * Improve some error handleing.
+ *
+ * 03 24 2011 yuche.tsai
+ * NULL
+ * Assign AID before change STA_REC state to state 3.
+ *
+ * 03 23 2011 yuche.tsai
+ * NULL
+ * Fix Response Rate Issue when TX Auth Rsp Frame under P2P Mode.
+ *
+ * 03 23 2011 yuche.tsai
+ * NULL
+ * Fix issue of connection to one GC.
+ *
+ * 03 23 2011 yuche.tsai
+ * NULL
+ * Fix ASSERT issue when starting Hot-spot.
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * When Target Information is not available, change to passive mode.
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * Fix one connection issue while using Keypad to connect a GO.
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * 1. Fix two issues that may cause kernel panic.
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * Fix GC connect to other device issue.
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * 1.Shorten the LISTEN interval.
+ * 2. Fix IF address issue when we are GO
+ * 3. Fix LISTEN channel issue.
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * Modify formation policy setting.
+ *
+ * 03 21 2011 yuche.tsai
+ * NULL
+ * Solve Listen State doesn't response probe response issue.
+ *
+ * 03 21 2011 yuche.tsai
+ * NULL
+ * Change P2P Connection Request Flow.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
+ * Add beacon timeout support.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue
+ * Indicate the correct Group SSID when join on Group.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue
+ * Support the third P2P device to join GO/GC group.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue
+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO.
+ *
+ * 03 18 2011 yuche.tsai
+ * [WCXRP00000578] [Volunteer Patch][MT6620][Driver] Separate Connection Request from general IOCTL
+ * Separate connection request from general IOCTL.
+ *
+ * 03 18 2011 yuche.tsai
+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow
+ * Modify connection flow after Group Formation Complete, or device connect to a GO.
+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN.
+ *
+ * 03 17 2011 yuche.tsai
+ * NULL
+ * When AIS is connect to an AP, Hot Spot would be enabled under fixed same channel.
+ *
+ * 03 17 2011 yuche.tsai
+ * NULL
+ * Solve the Group Info IE in Probe Response incorrect issue.
+ *
+ * 03 17 2011 yuche.tsai
+ * NULL
+ * Release Channel after Join Complete.
+ *
+ * 03 16 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * enable the protected while at P2P start GO, and skip some security check .
+ *
+ * 03 15 2011 yuche.tsai
+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue
+ * Fix local configure method issue.
+ *
+ * 03 15 2011 yuche.tsai
+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue
+ * Fix some configure method issue.
+ *
+ * 03 14 2011 yuche.tsai
+ * NULL
+ * .
+ *
+ * 03 14 2011 yuche.tsai
+ * NULL
+ * Fix password ID issue.
+ *
+ * 03 10 2011 yuche.tsai
+ * NULL
+ * Add P2P API.
+ *
+ * 03 08 2011 yuche.tsai
+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue[WCXRP00000509]
+ * [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module.
+ * .
+ *
+ * 03 07 2011 yuche.tsai
+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation.
+ * .
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 04 2011 wh.su
+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue
+ * fixed the p2p action frame type check for device request indication.
+ *
+ * 03 02 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Fix Service Discovery RX packet buffer pointer.
+ *
+ * 03 01 2011 yuche.tsai
+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation
+ * Update channel issue when doing GO formation..
+ *
+ * 03 01 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Update Service Discovery Related wlanoid function.
+ *
+ * 02 21 2011 yuche.tsai
+ * [WCXRP00000481] [Volunteer Patch][MT6620][FW] Scan hang under concurrent case.
+ * Fix all BE issue of WSC or P2P IE.
+ *
+ * 02 18 2011 wh.su
+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
+ * fixed the wsc config method mapping to driver used config method issue.
+ *
+ * 02 18 2011 yuche.tsai
+ * [WCXRP00000479] [Volunteer Patch][MT6620][Driver] Probe Response of P2P using 11b rate.
+ * Update basic rate to FW, after P2P is initialed.
+ *
+ * 02 18 2011 yuche.tsai
+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame during search
+ * phase do not contain P2P wildcard SSID.
+ * Use P2P Wildcard SSID when scan type of P2P_WILDCARD_SSID is set.
+ *
+ * 02 18 2011 yuche.tsai
+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
+ * Fix WSC IE BE format issue.
+ *
+ * 02 17 2011 wh.su
+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
+ * append the WSC IE config method attribute at provision discovery request.
+ *
+ * 02 16 2011 wh.su
+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
+ * fixed the probe request send out without WSC IE issue (at P2P).
+ *
+ * 02 16 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * If two station connected to the Hot-Spot and one disconnect, FW would get into an infinite loop
+ *
+ * 02 15 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Fix re-connection issue after RX deauthentication.
+ *
+ * 02 15 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Fix conneciton issue after disconnect with AP.
+ *
+ * 02 12 2011 yuche.tsai
+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled.
+ * P2P Create Station Type according to Target BSS capability.
+ *
+ * 02 10 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Support Disassoc & Deauthentication for Hot-Spot.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Add Service Discovery Indication Related code.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add Support for MLME deauthentication for Hot-Spot.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue
+ * Fix Client Limit Issue.
+ *
+ * 02 08 2011 yuche.tsai
+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect
+ * to target station for AAA module.
+ * Disconnect every station client when disolve on P2P group.
+ *
+ * 02 08 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * 1. Fix Service Disocvery Logical issue.
+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station.
+ *
+ * 02 08 2011 yuche.tsai
+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect
+ * to target station for AAA module.
+ * Workaround of disable P2P network.
+ *
+ * 02 08 2011 yuche.tsai
+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue
+ * 1. Fixed SSID wrong length issue.
+ * 2. Under Hot Spot configuration, there won't be any P2P IE.
+ * 3. Under Hot Spot configuration, P2P FSM won't get into LISTEN state first.
+ *
+ * 01 27 2011 yuche.tsai
+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
+ * Modify Start GO flow.
+ *
+ * 01 27 2011 yuche.tsai
+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
+ * Fix desire phy type set issue.
+ *
+ * 01 27 2011 yuche.tsai
+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
+ * Add desire phy type set phase I.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Fix P2P Disconnect Issue.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Add Service Discovery Function.
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Fix compile error when DBG is disabled.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type Definition.
+ *
+ * 01 19 2011 yuche.tsai
+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update
+ * when STA record is created under AP Mode.
+ * Add P2P QoS Support.
+ *
+ * 01 19 2011 george.huang
+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability
+ * Null NOA attribute setting when no related parameters.
+ *
+ * 01 14 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Modify AAA flow according to CM's comment.
+ *
+ * 01 13 2011 yuche.tsai
+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update
+ * when STA record is created under AP Mode.
+ * Resolve Channel ZERO issue. (Uninitialized default channel)
+ *
+ * 01 13 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Update P2P State Debug Message.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update
+ * when STA record is created under AP Mode.
+ * Fix bug when allocating message buffer.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update
+ * when STA record is created under AP Mode.
+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate,
+ * but if the P2P device is connected, 11b rate is not allowed.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s.
+ * 2. Call cnmP2pIsPermit() before active P2P network.
+ * 3. Add channel selection support for AP mode.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Fix Bug of reference to NULL pointer.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Modify some behavior of AP mode.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Fix bug of wrong pointer check.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Fix Compile Error.
+ *
+ * 01 11 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Add station record into client list before change it state from STATE_2 to STATE_3.
+ *
+ * 01 05 2011 yuche.tsai
+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request,
+ * but the SSID length is still invalid.
+ * Specify SSID Type when issue a scan request.
+ *
+ * 01 05 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations
+ * to ease physically continuous memory demands
+ * correct typo
+ *
+ * 01 05 2011 george.huang
+ * [WCXRP00000343] [MT6620 Wi-Fi] Add TSF reset path for concurrent operation
+ * modify NOA update path for preventing assertion false alarm.
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations
+ * to ease physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 01 03 2011 wh.su
+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!!
+ * let the p2p ap mode acept a legacy device join.
+ *
+ * 12 22 2010 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Fix Compile Error.
+ *
+ * 12 15 2010 yuche.tsai
+ * [WCXRP00000245] 1. Invitation Request/Response.
+2. Provision Discovery Request/Response
+
+ * Refine Connection Flow.
+ *
+ * 12 08 2010 yuche.tsai
+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in
+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add
+ *
+ * 12 08 2010 yuche.tsai
+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode.
+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client
+ * by checking the P2P IE in assoc req frame.
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * The order of invoking nicUpdateBss() and rlm functions
+ *
+ * 12 02 2010 yuche.tsai
+ * NULL
+ * Update P2P Connection Policy for Invitation.
+ *
+ * 12 02 2010 yuche.tsai
+ * NULL
+ * Update P2P Connection Policy for Invitation & Provision Discovery.
+ *
+ * 11 30 2010 yuche.tsai
+ * NULL
+ * Invitation & Provision Discovery Indication.
+ *
+ * 11 30 2010 yuche.tsai
+ * NULL
+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ
+ *
+ * 11 30 2010 yuche.tsai
+ * NULL
+ * Update RCIP value when RX assoc request frame.
+ *
+ * 11 29 2010 yuche.tsai
+ * NULL
+ * Update P2P related function for INVITATION & PROVISION DISCOVERY.
+ *
+ * 11 26 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * Update P2P PS for NOA function.
+ *
+ * 11 25 2010 yuche.tsai
+ * NULL
+ * Update Code for Invitation Related Function.
+ *
+ * 11 17 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW]
+ * Set the Tx lowest rate at wlan table for normal operation
+ * fixed some ASSERT check.
+ *
+ * 11 05 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * fixed the p2p role code error.
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * fixed the ASSERT check error
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Add the code to support disconnect p2p group
+ *
+ * 10 19 2010 wh.su
+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state
+ * machine[WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android
+ * fixed the compiling error.
+ *
+ * 10 14 2010 wh.su
+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android
+ * adding a code to support Direct GO with a compiling flag .
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert.
+ * correct erroneous logic: specifying eBand with incompatible eSco
+ *
+ * 10 08 2010 wh.su
+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
+ * fixed the compiling error.
+ *
+ * 10 08 2010 wh.su
+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
+ * update the frog's new p2p state machine.
+ *
+ * 09 10 2010 wh.su
+ * NULL
+ * fixed the compiling error at WinXP.
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * Reset Common IE Buffer of P2P INFO when scan request is issued.
+ * If an action frame other than public action frame is received, return direcly.
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 06 2010 wh.su
+ * NULL
+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * Add P2P Connection Abort Event Message handler.
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 23 2010 yuche.tsai
+ * NULL
+ * 1. Fix Interface Address from GO Nego Req/Rsp is not correct.
+ * 2. Fix GO mode does not change media state after station connected.
+ * 3. Fix STA don't response probe request when there is a connection request.
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 20 2010 kevin.huang
+ * NULL
+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete()
+ *
+ * 08 20 2010 yuche.tsai
+ * NULL
+ * Add Glue Layer indication.
+ *
+ * 08 17 2010 yuche.tsai
+ * NULL
+ * Fix compile warning under Linux.
+ *
+ * 08 17 2010 yuche.tsai
+ * NULL
+ * Fix some P2P FSM bug.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Add random Interface Address Generation support.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Fix some P2P FSM bug.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Update P2P FSM code for GO Nego.
+ *
+ * 08 16 2010 kevin.huang
+ * NULL
+ * Refine AAA functions
+ *
+ * 08 12 2010 kevin.huang
+ * NULL
+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse()
+ *
+ * 08 12 2010 yuche.tsai
+ * NULL
+ * Join complete indication.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add two boolean in connection request.
+ * Based on these two boolean value, P2P FSM should
+ * decide to do invitation or group formation or start a GO directly.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Update P2P FSM, currently P2P Device Discovery is verified.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Update P2P FSM for group formation.
+ *
+ * 08 03 2010 george.huang
+ * NULL
+ * handle event for updating NOA parameters indicated from FW
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * limit build always needs spin-lock declaration.
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Add P2P FSM code check in.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add P2P Scan & Scan Result Parsing & Saving.
+ *
+ * 07 19 2010 yuche.tsai
+ *
+ * Update P2P FSM.
+ *
+ * 07 09 2010 george.huang
+ *
+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Fix compile error while enable WIFI_DIRECT support.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Update P2P Function call.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * First draft for migration P2P FSM from FW to Driver.
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support and will send Null frame to diagnose connection
+ *
+ * 03 18 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Rename CFG flag for P2P
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add code to test P2P GO
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add Wi-Fi Direct SSID and P2P GO Test Mode
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Modify code due to BAND_24G define was changed
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_ENABLE_WIFI_DIRECT
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if DBG
+/*lint -save -e64 Type mismatch */
+static PUINT_8 apucDebugP2pState[P2P_STATE_NUM] = {
+	(PUINT_8) DISP_STRING("P2P_STATE_IDLE"),
+	(PUINT_8) DISP_STRING("P2P_STATE_SCAN"),
+	(PUINT_8) DISP_STRING("P2P_STATE_AP_CHANNEL_DETECT"),
+	(PUINT_8) DISP_STRING("P2P_STATE_REQING_CHANNEL"),
+	(PUINT_8) DISP_STRING("P2P_STATE_CHNL_ON_HAND"),
+	(PUINT_8) DISP_STRING("P2P_STATE_GC_JOIN")
+};
+
+/*lint -restore */
+#else
+static UINT_8 apucDebugP2pState[P2P_STATE_NUM] = {
+	P2P_STATE_IDLE,
+	P2P_STATE_SCAN,
+	P2P_STATE_AP_CHANNEL_DETECT,
+	P2P_STATE_REQING_CHANNEL,
+	P2P_STATE_CHNL_ON_HAND,
+	P2P_STATE_GC_JOIN
+};
+
+#endif /* DBG */
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*   p2pStateXXX : Processing P2P FSM related action.
+  *   p2pFSMXXX : Control P2P FSM flow.
+  *   p2pFuncXXX : Function for doing one thing.
+  */
+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter)
+{
+
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		ASSERT_BREAK(prP2pFsmInfo != NULL);
+
+		LINK_INITIALIZE(&(prP2pFsmInfo->rMsgEventQueue));
+		LINK_INITIALIZE(&(prP2pBssInfo->rStaRecOfClientList));
+
+		prP2pFsmInfo->eCurrentState = prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE;
+		prP2pFsmInfo->prTargetBss = NULL;
+		prP2pFsmInfo->fgIsWPSMode = 0;
+
+		cnmTimerInitTimer(prAdapter,
+				  &(prAdapter->rP2pFsmTimeoutTimer),
+				  (PFN_MGMT_TIMEOUT_FUNC) p2pFsmRunEventFsmTimeout, (ULONG) prP2pFsmInfo);
+
+		/* 4 <2> Initiate BSS_INFO_T - common part */
+		BSS_INFO_INIT(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		/* 4 <2.1> Initiate BSS_INFO_T - Setup HW ID */
+		prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P;
+		prP2pBssInfo->ucHwDefaultFixedRateCode = RATE_OFDM_6M;
+
+		prP2pBssInfo->ucNonHTBasicPhyType = (UINT_8)
+		    rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
+		prP2pBssInfo->u2BSSBasicRateSet =
+		    rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;
+
+		prP2pBssInfo->u2OperationalRateSet =
+		    rNonHTPhyAttributes[prP2pBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;
+
+		rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet,
+					    prP2pBssInfo->u2BSSBasicRateSet,
+					    prP2pBssInfo->aucAllSupportedRates, &prP2pBssInfo->ucAllSupportedRatesLen);
+
+		prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter,
+							OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH);
+
+		if (prP2pBssInfo->prBeacon) {
+			prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT;
+			prP2pBssInfo->prBeacon->ucStaRecIndex = 0xFF;	/* NULL STA_REC */
+			prP2pBssInfo->prBeacon->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
+		} else {
+			/* Out of memory. */
+			ASSERT(FALSE);
+		}
+
+		prP2pBssInfo->eCurrentOPMode = OP_MODE_NUM;
+
+		prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL;
+		prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL;
+		prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2;
+		prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL;
+		prP2pBssInfo->eBand = BAND_2G4;
+		prP2pBssInfo->eBssSCO = CHNL_EXT_SCN;
+
+		if (prAdapter->rWifiVar.fgSupportQoS)
+			prP2pBssInfo->fgIsQBSS = TRUE;
+		else
+			prP2pBssInfo->fgIsQBSS = FALSE;
+
+		SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+
+	} while (FALSE);
+
+}				/* p2pFsmInit */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief The function is used to uninitialize the value in P2P_FSM_INFO_T for
+*        P2P FSM operation
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		DEBUGFUNC("p2pFsmUninit()");
+		DBGLOG(P2P, INFO, "->p2pFsmUninit()\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, OP_MODE_P2P_DEVICE, TRUE);
+
+		p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo);
+
+		p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM);
+
+		UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		wlanAcquirePowerControl(prAdapter);
+
+		/* Release all pending CMD queue. */
+		DBGLOG(P2P, TRACE, "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n",
+				    (UINT_32) prAdapter->prGlueInfo->rCmdQueue.u4NumElem);
+		wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue);
+
+		wlanReleasePowerControl(prAdapter);
+
+		/* Release pending mgmt frame,
+		 * mgmt frame may be pending by CMD without resource.
+		 */
+		kalClearMgmtFramesByNetType(prAdapter->prGlueInfo, NETWORK_TYPE_P2P_INDEX);
+
+		/* Clear PendingCmdQue */
+		wlanReleasePendingCMDbyNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		if (prP2pBssInfo->prBeacon) {
+			cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon);
+			prP2pBssInfo->prBeacon = NULL;
+		}
+
+	} while (FALSE);
+
+	return;
+
+}				/* end of p2pFsmUninit() */
+
+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState)
+{
+	BOOLEAN fgIsTransOut = (BOOLEAN) FALSE;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+		if (!IS_BSS_ACTIVE(prP2pBssInfo)) {
+			if (!cnmP2PIsPermitted(prAdapter))
+				return;
+
+			SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+			nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
+		}
+
+		fgIsTransOut = fgIsTransOut ? FALSE : TRUE;
+
+		if (!fgIsTransOut) {
+#if DBG
+			DBGLOG(P2P, STATE, "TRANSITION: [%s] -> [%s]\n",
+					    apucDebugP2pState[prP2pFsmInfo->eCurrentState],
+					    apucDebugP2pState[eNextState]);
+#else
+			DBGLOG(P2P, STATE, "[%d] TRANSITION: [%d] -> [%d]\n",
+					    DBG_P2P_IDX, apucDebugP2pState[prP2pFsmInfo->eCurrentState],
+					    apucDebugP2pState[eNextState]);
+#endif
+
+			/* Transition into current state. */
+			prP2pFsmInfo->ePreviousState = prP2pFsmInfo->eCurrentState;
+			prP2pFsmInfo->eCurrentState = eNextState;
+		}
+
+		switch (prP2pFsmInfo->eCurrentState) {
+		case P2P_STATE_IDLE:
+			if (fgIsTransOut)
+				p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, eNextState);
+			else
+				fgIsTransOut = p2pStateInit_IDLE(prAdapter, prP2pFsmInfo, prP2pBssInfo, &eNextState);
+			break;
+		case P2P_STATE_SCAN:
+			if (fgIsTransOut) {
+				/* Scan done / scan canceled. */
+				p2pStateAbort_SCAN(prAdapter, prP2pFsmInfo, eNextState);
+			} else {
+				/* Initial scan request. */
+				p2pStateInit_SCAN(prAdapter, prP2pFsmInfo);
+			}
+
+			break;
+		case P2P_STATE_AP_CHANNEL_DETECT:
+			if (fgIsTransOut) {
+				/* Scan done */
+				/* Get sparse channel result. */
+				p2pStateAbort_AP_CHANNEL_DETECT(prAdapter,
+								prP2pFsmInfo, prP2pSpecificBssInfo, eNextState);
+			}
+
+			else {
+				/* Initial passive scan request. */
+				p2pStateInit_AP_CHANNEL_DETECT(prAdapter, prP2pFsmInfo);
+			}
+
+			break;
+		case P2P_STATE_REQING_CHANNEL:
+			if (fgIsTransOut) {
+				/* Channel on hand / Channel canceled. */
+				p2pStateAbort_REQING_CHANNEL(prAdapter, prP2pFsmInfo, eNextState);
+			} else {
+				/* Initial channel request. */
+				p2pFuncAcquireCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+			}
+
+			break;
+		case P2P_STATE_CHNL_ON_HAND:
+			if (fgIsTransOut) {
+				p2pStateAbort_CHNL_ON_HAND(prAdapter, prP2pFsmInfo, prP2pBssInfo, eNextState);
+			} else {
+				/* Initial channel ready. */
+				/* Send channel ready event. */
+				/* Start a FSM timer. */
+				p2pStateInit_CHNL_ON_HAND(prAdapter, prP2pBssInfo, prP2pFsmInfo);
+			}
+
+			break;
+		case P2P_STATE_GC_JOIN:
+			if (fgIsTransOut) {
+				/* Join complete / join canceled. */
+				p2pStateAbort_GC_JOIN(prAdapter, prP2pFsmInfo, &(prP2pFsmInfo->rJoinInfo), eNextState);
+			} else {
+				if (prP2pFsmInfo->prTargetBss == NULL) {
+					ASSERT(FALSE);
+				} else {
+					/* Send request to SAA module. */
+					p2pStateInit_GC_JOIN(prAdapter,
+						     prP2pFsmInfo,
+						     prP2pBssInfo,
+						     &(prP2pFsmInfo->rJoinInfo), prP2pFsmInfo->prTargetBss);
+				}
+			}
+
+			break;
+		default:
+			break;
+		}
+
+	} while (fgIsTransOut);
+
+}				/* p2pFsmStateTransition */
+
+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_MSG_P2P_SWITCH_OP_MODE_T prSwitchOpMode = (P_MSG_P2P_SWITCH_OP_MODE_T) prMsgHdr;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prSwitchOpMode != NULL));
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventSwitchOPMode\n");
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+		if (prSwitchOpMode->eOpMode >= OP_MODE_NUM) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		/* P2P Device / GC. */
+		p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, prSwitchOpMode->eOpMode, TRUE);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventSwitchOPMode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is used to handle scan done event during Device Discovery.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL;
+	P_MSG_SCN_SCAN_DONE prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) NULL;
+	ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		/* This scan done event is either for "SCAN" phase or "SEARCH" state or "LISTEN" state.
+		 * The scan done for SCAN phase & SEARCH state doesn't imply Device
+		 * Discovery over.
+		 */
+		DBGLOG(P2P, TRACE, "P2P Scan Done Event\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo);
+		prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr;
+
+		if (prScanDoneMsg->ucSeqNum != prScanReqInfo->ucSeqNumOfScnMsg) {
+			/* Scan Done message sequence number mismatch.
+			 * Ignore this event. (P2P FSM issue two scan events.)
+			 */
+			/* The scan request has been cancelled.
+			 * Ignore this message. It is possible.
+			 */
+			DBGLOG(P2P, TRACE, "P2P Scan Don SeqNum:%d <-> P2P Fsm SCAN Msg:%d\n",
+					    prScanDoneMsg->ucSeqNum, prScanReqInfo->ucSeqNumOfScnMsg);
+
+			break;
+		}
+
+		switch (prP2pFsmInfo->eCurrentState) {
+		case P2P_STATE_SCAN:
+			{
+				P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo);
+
+				prScanReqInfo->fgIsAbort = FALSE;
+
+				if (prConnReqInfo->fgIsConnRequest) {
+					prP2pFsmInfo->prTargetBss = p2pFuncKeepOnConnection(prAdapter,
+										&prP2pFsmInfo->rConnReqInfo,
+										&prP2pFsmInfo->rChnlReqInfo,
+										&prP2pFsmInfo->rScanReqInfo);
+					if (prP2pFsmInfo->prTargetBss == NULL)
+						eNextState = P2P_STATE_SCAN;
+					else
+						eNextState = P2P_STATE_REQING_CHANNEL;
+				} else {
+					eNextState = P2P_STATE_IDLE;
+				}
+
+			}
+			break;
+		case P2P_STATE_AP_CHANNEL_DETECT:
+			eNextState = P2P_STATE_REQING_CHANNEL;
+			break;
+		default:
+			/* Unexpected channel scan done event without being chanceled. */
+			ASSERT(FALSE);
+			break;
+		}
+
+		prScanReqInfo->fgIsScanRequest = FALSE;
+
+		p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventScanDone */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is call when channel is granted by CNM module from FW.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+	P_MSG_CH_GRANT_T prMsgChGrant = (P_MSG_CH_GRANT_T) NULL;
+	UINT_8 ucTokenID = 0;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		DBGLOG(P2P, TRACE, "P2P Run Event Channel Grant\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr;
+		ucTokenID = prMsgChGrant->ucTokenID;
+		prP2pFsmInfo->u4GrantInterval = prMsgChGrant->u4GrantInterval;
+
+		prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+		if (ucTokenID == prChnlReqInfo->ucSeqNumOfChReq) {
+			ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM;
+
+			switch (prP2pFsmInfo->eCurrentState) {
+			case P2P_STATE_REQING_CHANNEL:
+				switch (prChnlReqInfo->eChannelReqType) {
+				case CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL:
+					eNextState = P2P_STATE_CHNL_ON_HAND;
+					break;
+				case CHANNEL_REQ_TYPE_GC_JOIN_REQ:
+					eNextState = P2P_STATE_GC_JOIN;
+					break;
+				case CHANNEL_REQ_TYPE_GO_START_BSS:
+					eNextState = P2P_STATE_IDLE;
+					break;
+				default:
+					break;
+				}
+
+				p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState);
+				break;
+			default:
+				/* Channel is granted under unexpected state.
+				 * Driver should cancel channel privileagea before leaving the states.
+				 */
+				ASSERT(FALSE);
+				break;
+			}
+
+		} else {
+			/* Channel requsted, but released. */
+			/* ASSERT(!prChnlReqInfo->fgIsChannelRequested); */
+			DBGLOG(P2P, TRACE, "Channel requsted, but released\n");
+		}
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+	return;
+
+}				/* p2pFsmRunEventChGrant */
+
+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+	P_MSG_P2P_CHNL_REQUEST_T prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) NULL;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) prMsgHdr;
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelRequest\n");
+
+		/* Special case of time renewing for same frequency. */
+		if ((prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) &&
+		    (prChnlReqInfo->ucReqChnlNum == prP2pChnlReqMsg->rChannelInfo.ucChannelNum) &&
+		    (prChnlReqInfo->eBand == prP2pChnlReqMsg->rChannelInfo.eBand) &&
+		    (prChnlReqInfo->eChnlSco == prP2pChnlReqMsg->eChnlSco)) {
+
+			ASSERT(prChnlReqInfo->fgIsChannelRequested == TRUE);
+			ASSERT(prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL);
+
+			prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie;
+			prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration;
+
+			/* Re-enter the state. */
+			eNextState = P2P_STATE_CHNL_ON_HAND;
+		} else {
+
+			/* Make sure the state is in IDLE state. */
+			p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo);
+
+			/* Cookie can only be assign after abort.(for indication) */
+			prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie;
+			prChnlReqInfo->ucReqChnlNum = prP2pChnlReqMsg->rChannelInfo.ucChannelNum;
+			prChnlReqInfo->eBand = prP2pChnlReqMsg->rChannelInfo.eBand;
+			prChnlReqInfo->eChnlSco = prP2pChnlReqMsg->eChnlSco;
+			prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration;
+			prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL;
+
+			eNextState = P2P_STATE_REQING_CHANNEL;
+		}
+
+		p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventChannelRequest */
+
+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_MSG_P2P_CHNL_ABORT_T prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) NULL;
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) prMsgHdr;
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo;
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelAbort\n");
+
+		if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) && (prChnlReqInfo->fgIsChannelRequested)) {
+
+			ASSERT((prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL ||
+				(prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND)));
+
+			p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+		}
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventChannelAbort */
+
+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_MSG_P2P_SCAN_REQUEST_T prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) NULL;
+	P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL;
+	UINT_32 u4ChnlListSize = 0;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) prMsgHdr;
+		prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo);
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventScanRequest\n");
+
+		/* Make sure the state is in IDLE state. */
+		p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo);
+
+		ASSERT(prScanReqInfo->fgIsScanRequest == FALSE);
+
+		prScanReqInfo->fgIsAbort = TRUE;
+		prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN;
+		prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED;
+
+		/* Channel List */
+		prScanReqInfo->ucNumChannelList = prP2pScanReqMsg->u4NumChannel;
+		DBGLOG(P2P, TRACE, "Scan Request Channel List Number: %d\n", prScanReqInfo->ucNumChannelList);
+		if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) {
+			DBGLOG(P2P, TRACE, "Channel List Number Overloaded: %d, change to: %d\n",
+					    prScanReqInfo->ucNumChannelList, MAXIMUM_OPERATION_CHANNEL_LIST);
+			prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST;
+		}
+
+		u4ChnlListSize = sizeof(RF_CHANNEL_INFO_T) * prScanReqInfo->ucNumChannelList;
+		kalMemCopy(prScanReqInfo->arScanChannelList, prP2pScanReqMsg->arChannelListInfo, u4ChnlListSize);
+
+		/* TODO: I only take the first SSID. Multiple SSID may be needed in the future. */
+		/* SSID */
+		if (prP2pScanReqMsg->i4SsidNum >= 1)
+			kalMemCopy(&(prScanReqInfo->rSsidStruct), prP2pScanReqMsg->prSSID, sizeof(P2P_SSID_STRUCT_T));
+		else
+			prScanReqInfo->rSsidStruct.ucSsidLen = 0;
+
+		/* IE Buffer */
+		kalMemCopy(prScanReqInfo->aucIEBuf, prP2pScanReqMsg->pucIEBuf, prP2pScanReqMsg->u4IELen);
+
+		prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen;
+
+		p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventScanRequest */
+
+VOID p2pFsmRunEventScanAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventScanAbort\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) {
+			P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo);
+
+			prScanReqInfo->fgIsAbort = TRUE;
+
+			p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+		}
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventScanAbort */
+
+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventAbort\n");
+
+		if (prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) {
+
+			if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) {
+
+				P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo);
+
+				prScanReqInfo->fgIsAbort = TRUE;
+			} else if (prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL) {
+				/* 2012/08/06: frog
+				 * Prevent Start GO.
+				 */
+				prP2pBssInfo->eIntendOPMode = OP_MODE_NUM;
+			}
+			/* For other state, is there any special action that should be take before leaving? */
+
+			p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+		} else {
+			/* P2P State IDLE. */
+			P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+			if (prChnlReqInfo->fgIsChannelRequested)
+				p2pFuncReleaseCh(prAdapter, prChnlReqInfo);
+
+			cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer));
+		}
+
+	} while (FALSE);
+
+}				/* p2pFsmRunEventAbort */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is used to handle FSM Timeout.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) ulParam;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		DBGLOG(P2P, TRACE, "P2P FSM Timeout Event\n");
+
+		switch (prP2pFsmInfo->eCurrentState) {
+		case P2P_STATE_IDLE:
+			{
+				P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo;
+
+				if (prChnlReqInfo->fgIsChannelRequested) {
+					p2pFuncReleaseCh(prAdapter, prChnlReqInfo);
+				} else if (IS_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX)) {
+					UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+					nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
+				}
+
+			}
+			break;
+
+/* case P2P_STATE_SCAN: */
+/* break; */
+/* case P2P_STATE_AP_CHANNEL_DETECT: */
+/* break; */
+/* case P2P_STATE_REQING_CHANNEL: */
+/* break; */
+		case P2P_STATE_CHNL_ON_HAND:
+			switch (prP2pFsmInfo->eListenExted) {
+			case P2P_DEV_NOT_EXT_LISTEN:
+			case P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT:
+				DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n",
+					prP2pFsmInfo->eListenExted);
+				p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+				prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN;
+				break;
+			case P2P_DEV_EXT_LISTEN_ING:
+				DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n",
+					prP2pFsmInfo->eListenExted);
+				p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_CHNL_ON_HAND);
+				prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT;
+				break;
+			default:
+				ASSERT(FALSE);
+				DBGLOG(P2P, ERROR,
+					"Current P2P State %d is unexpected for FSM timeout event.\n",
+					prP2pFsmInfo->eCurrentState);
+			}
+			break;
+/* case P2P_STATE_GC_JOIN: */
+/* break; */
+		default:
+			break;
+		}
+
+	} while (FALSE);
+
+}				/* p2pFsmRunEventFsmTimeout */
+
+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_MSG_P2P_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventMgmtFrameTx\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) prMsgHdr;
+
+		p2pFuncTxMgmtFrame(prAdapter,
+				   &prP2pFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+	return;
+
+}				/* p2pFsmRunEventMgmtTx */
+
+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventStartAP\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) prMsgHdr;
+		prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+		if (prP2pStartAPMsg->u4BcnInterval) {
+			DBGLOG(P2P, TRACE, "Beacon interval updated to :%u\n", prP2pStartAPMsg->u4BcnInterval);
+			prP2pBssInfo->u2BeaconInterval = (UINT_16) prP2pStartAPMsg->u4BcnInterval;
+		} else if (prP2pBssInfo->u2BeaconInterval == 0) {
+			prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT;
+		}
+
+		if (prP2pStartAPMsg->u4DtimPeriod) {
+			DBGLOG(P2P, TRACE, "DTIM interval updated to :%u\n", prP2pStartAPMsg->u4DtimPeriod);
+			prP2pBssInfo->ucDTIMPeriod = (UINT_8) prP2pStartAPMsg->u4DtimPeriod;
+		} else if (prP2pBssInfo->ucDTIMPeriod == 0) {
+			prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT;
+		}
+
+		if (prP2pStartAPMsg->u2SsidLen != 0) {
+			kalMemCopy(prP2pBssInfo->aucSSID, prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen);
+			kalMemCopy(prP2pSpecificBssInfo->aucGroupSsid, prP2pStartAPMsg->aucSsid,
+				   prP2pStartAPMsg->u2SsidLen);
+			prP2pBssInfo->ucSSIDLen = prP2pSpecificBssInfo->u2GroupSsidLen = prP2pStartAPMsg->u2SsidLen;
+		}
+
+		prP2pBssInfo->eHiddenSsidType = prP2pStartAPMsg->ucHiddenSsidType;
+
+		/* TODO: JB */
+		/* Privacy & inactive timeout. */
+
+		if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ||
+		    (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) {
+			UINT_8 ucPreferedChnl = 0;
+			ENUM_BAND_T eBand = BAND_NULL;
+			ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN;
+			ENUM_P2P_STATE_T eNextState = P2P_STATE_SCAN;
+			P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+			if (prP2pFsmInfo->eCurrentState != P2P_STATE_SCAN &&
+			    prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) {
+				/* Make sure the state is in IDLE state. */
+				p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo);
+			}
+			prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0;
+			DBGLOG(P2P, INFO,
+			       "NFC:p2pFsmRunEventStartAP,fgIsGOInitialDone[%d]\n",
+				prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone);
+
+			/* 20120118: Moved to p2pFuncSwitchOPMode(). */
+			/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+
+			/* Leave IDLE state. */
+			SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+			/* sync with firmware */
+			/* DBGLOG(P2P, INFO, ("Activate P2P Network.\n")); */
+			/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+
+			/* Key to trigger P2P FSM to allocate channel for AP mode. */
+			prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT;
+
+			/* Sparse Channel to decide which channel to use. */
+			if ((cnmPreferredChannel(prAdapter,
+						 &eBand,
+						 &ucPreferedChnl,
+						 &eSco) == FALSE) && (prP2pConnSettings->ucOperatingChnl == 0)) {
+				/* Sparse Channel Detection using passive mode. */
+				eNextState = P2P_STATE_AP_CHANNEL_DETECT;
+			} else {
+				P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo =
+				    prAdapter->rWifiVar.prP2pSpecificBssInfo;
+				P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo;
+
+#if 1
+				/* 2012-01-27: frog - Channel set from upper layer is the first priority. */
+				/* Because the channel & beacon is decided by p2p_supplicant. */
+				if (prP2pConnSettings->ucOperatingChnl != 0) {
+					prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl;
+					prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand;
+				}
+
+				else {
+					ASSERT(ucPreferedChnl != 0);
+					prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl;
+					prP2pSpecificBssInfo->eRfBand = eBand;
+				}
+#else
+				if (ucPreferedChnl) {
+					prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl;
+					prP2pSpecificBssInfo->eRfBand = eBand;
+				} else {
+					ASSERT(prP2pConnSettings->ucOperatingChnl != 0);
+					prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl;
+					prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand;
+				}
+
+#endif
+				prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel;
+				prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand;
+				prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS;
+
+				DBGLOG(P2P, INFO, "p2pFsmRunEventStartAP GO Scan\n");
+			}
+
+			/* If channel is specified, use active scan to shorten the scan time. */
+			p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, eNextState);
+		}
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventStartAP */
+
+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_P2P_NETDEV_REGISTER_T prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) NULL;
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventNetDeviceRegister\n");
+
+		prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) prMsgHdr;
+
+		if (prNetDevRegisterMsg->fgIsEnable) {
+			p2pSetMode((prNetDevRegisterMsg->ucMode == 1) ? TRUE : FALSE);
+
+			if (p2pLaunch(prAdapter->prGlueInfo))
+				ASSERT(prAdapter->fgIsP2PRegistered);
+
+		} else {
+			if (prAdapter->fgIsP2PRegistered)
+				p2pRemove(prAdapter->prGlueInfo);
+
+		}
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventNetDeviceRegister */
+
+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_P2P_MGMT_FRAME_UPDATE_T prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) NULL;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventUpdateMgmtFrame\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) prMsgHdr;
+
+		switch (prP2pMgmtFrameUpdateMsg->eBufferType) {
+		case ENUM_FRAME_TYPE_EXTRA_IE_BEACON:
+			break;
+		case ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP:
+			break;
+		case ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP:
+			break;
+		case ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE:
+			break;
+		case ENUM_FRAME_TYPE_BEACON_TEMPLATE:
+			break;
+		default:
+			break;
+		}
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventUpdateMgmtFrame */
+
+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_MSG_P2P_BEACON_UPDATE_T prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconUpdate\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) prMsgHdr;
+
+		p2pFuncBeaconUpdate(prAdapter,
+				    prP2pBssInfo,
+				    &prP2pFsmInfo->rBcnContentInfo,
+				    prBcnUpdateMsg->pucBcnHdr,
+				    prBcnUpdateMsg->u4BcnHdrLen,
+				    prBcnUpdateMsg->pucBcnBody, prBcnUpdateMsg->u4BcnBodyLen);
+
+		if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) &&
+		    (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) {
+			/* AP is created, Beacon Update. */
+			/* nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+
+			bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+			/* nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+		}
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventBeaconUpdate */
+
+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventStopAP\n");
+
+		if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)
+		    && (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) {
+			/* AP is created, Beacon Update. */
+
+			p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS);
+
+			DBGLOG(P2P, TRACE, "Stop Beaconing\n");
+			nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+			/* Reset RLM related field of BSSINFO. */
+			rlmBssAborted(prAdapter, prP2pBssInfo);
+		}
+		/* 20120118: Moved to p2pFuncSwitchOPMode(). */
+		/* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+
+		/* Enter IDLE state. */
+		SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		DBGLOG(P2P, INFO, "Re activate P2P Network.\n");
+		nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+#if CFG_SUPPORT_WFD
+		p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL);
+#endif
+
+		/* p2pFsmRunEventAbort(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo); */
+		p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, P2P_STATE_IDLE);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventStopAP */
+
+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+	P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL;
+	P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) prMsgHdr;
+
+		prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo);
+		prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionRequest\n");
+
+		if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+			break;
+
+		SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		/* Make sure the state is in IDLE state. */
+		p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo);
+
+		/* Update connection request information. */
+		prConnReqInfo->fgIsConnRequest = TRUE;
+		COPY_MAC_ADDR(prConnReqInfo->aucBssid, prConnReqMsg->aucBssid);
+		kalMemCopy(&(prConnReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T));
+		kalMemCopy(prConnReqInfo->aucIEBuf, prConnReqMsg->aucIEBuf, prConnReqMsg->u4IELen);
+		prConnReqInfo->u4BufLength = prConnReqMsg->u4IELen;
+
+		/* Find BSS Descriptor first. */
+		prP2pFsmInfo->prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo);
+
+		if (prP2pFsmInfo->prTargetBss == NULL) {
+			/* Update scan parameter... to scan target device. */
+			P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo);
+
+			DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest,Trigger New Scan\n");
+
+			prScanReqInfo->ucNumChannelList = 1;
+			prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN;
+			prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED;
+			prScanReqInfo->arScanChannelList[0].ucChannelNum = prConnReqMsg->rChannelInfo.ucChannelNum;
+			kalMemCopy(&(prScanReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T));
+			prScanReqInfo->u4BufLength = 0;	/* Prevent other P2P ID in IE. */
+			prScanReqInfo->fgIsAbort = TRUE;
+
+			p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN);
+		} else {
+			prChnlReqInfo->u8Cookie = 0;
+			prChnlReqInfo->ucReqChnlNum = prConnReqMsg->rChannelInfo.ucChannelNum;
+			prChnlReqInfo->eBand = prConnReqMsg->rChannelInfo.eBand;
+			prChnlReqInfo->eChnlSco = prConnReqMsg->eChnlSco;
+			prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL;
+			prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ;
+			DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest, Report the Connecting BSS Again.\n");
+			p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_REQING_CHANNEL);
+		}
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+	return;
+
+}				/* p2pFsmRunEventConnectionRequest */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is used to handle Connection Request from Supplicant.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL;
+	/* P_STA_RECORD_T prTargetStaRec = (P_STA_RECORD_T)NULL; */
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionAbort: Connection Abort.\n");
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) prMsgHdr;
+
+		switch (prP2pBssInfo->eCurrentOPMode) {
+		case OP_MODE_INFRASTRUCTURE:
+			{
+				UINT_8 aucBCBSSID[] = BC_BSSID;
+
+				if (!prP2pBssInfo->prStaRecOfAP) {
+					DBGLOG(P2P, TRACE, "GO's StaRec is NULL\n");
+					break;
+				}
+				if (UNEQUAL_MAC_ADDR(prP2pBssInfo->prStaRecOfAP->aucMacAddr, prDisconnMsg->aucTargetID)
+				    && UNEQUAL_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCBSSID)) {
+					DBGLOG(P2P, TRACE,
+					       "Unequal MAC ADDR [ %pM : %pM ]\n",
+						prP2pBssInfo->prStaRecOfAP->aucMacAddr,
+						prDisconnMsg->aucTargetID);
+					break;
+				}
+
+				kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo,
+                                                                 NULL, NULL, 0, 0,
+                                                                 WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY);
+
+				/* Stop rejoin timer if it is started. */
+				/* TODO: If it has. */
+
+				p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, prDisconnMsg->fgSendDeauth,
+						  prDisconnMsg->u2ReasonCode);
+
+				/* prTargetStaRec = prP2pBssInfo->prStaRecOfAP; */
+
+				/* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). */
+				/* hit prStaRecOfAP == NULL. */
+				p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+
+				prP2pBssInfo->prStaRecOfAP = NULL;
+
+				SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+				p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+
+			}
+			break;
+		case OP_MODE_ACCESS_POINT:
+			{
+				P_LINK_T prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList;
+				/* Search specific client device, and disconnect. */
+				/* 1. Send deauthentication frame. */
+				/* 2. Indication: Device disconnect. */
+				P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+				P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL;
+
+				DBGLOG(P2P, TRACE,
+				       "Disconnecting with Target ID: %pM\n",
+					prDisconnMsg->aucTargetID);
+
+				LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
+					prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry);
+
+					ASSERT(prCurrStaRec);
+
+					if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prDisconnMsg->aucTargetID)) {
+
+						DBGLOG(P2P, TRACE,
+						       "Disconnecting: %pM\n",
+							prCurrStaRec->aucMacAddr);
+
+						/* Remove STA from client list. */
+						LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList,
+									&prCurrStaRec->rLinkEntry);
+
+						/* Glue layer indication. */
+						/* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */
+
+						/* Send deauth & do indication. */
+						p2pFuncDisconnect(prAdapter, prCurrStaRec, prDisconnMsg->fgSendDeauth,
+								  prDisconnMsg->u2ReasonCode);
+
+						/* prTargetStaRec = prCurrStaRec; */
+
+						break;
+					}
+				}
+
+			}
+			break;
+		case OP_MODE_P2P_DEVICE:
+		default:
+			ASSERT(FALSE);
+			break;
+		}
+
+	} while (FALSE);
+
+	/* 20120830 moved into p2pFuncDisconnect() */
+	/* if ((!prDisconnMsg->fgSendDeauth) && (prTargetStaRec)) { */
+	/* cnmStaRecFree(prAdapter, prTargetStaRec, TRUE); */
+	/* } */
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventConnectionAbort */
+
+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+
+	/* TODO: */
+
+	DBGLOG(P2P, TRACE, "p2pFsmRunEventDissolve\n");
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}
+
+WLAN_STATUS
+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter,
+			   IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus;
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		DBGLOG(P2P, INFO, "Deauth TX Done Status: %d, seqNo %d\n",
+			rTxDoneStatus, prMsduInfo->ucTxSeqNum);
+
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+		if (prStaRec == NULL) {
+			DBGLOG(P2P, TRACE, "Station Record NULL, Index:%d\n", prMsduInfo->ucStaRecIndex);
+			break;
+		}
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		eOriMediaStatus = prP2pBssInfo->eConnectionState;
+		/* Change station state. */
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+		/* Reset Station Record Status. */
+		p2pFuncResetStaRecStatus(prAdapter, prStaRec);
+
+		bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec);
+
+		 /**/ cnmStaRecFree(prAdapter, prStaRec, TRUE);
+
+		if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ||
+		    (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) {
+			DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n");
+			p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+		}
+
+		/* Because the eConnectionState is changed before Deauth TxDone. Dont Check eConnectionState */
+		/* if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { */
+		/* Update Disconnected state to FW. */
+		nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
+		/* } */
+
+	} while (FALSE);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* p2pFsmRunEventDeauthTxDone */
+
+WLAN_STATUS
+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter,
+			      IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_P2P_MGMT_TX_REQ_INFO_T) NULL;
+	BOOLEAN fgIsSuccess = FALSE;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+		prMgmtTxReqInfo = &(prP2pFsmInfo->rMgmtTxInfo);
+
+		if (rTxDoneStatus != TX_RESULT_SUCCESS) {
+			DBGLOG(P2P, INFO, "Mgmt Frame TX Fail, Status: %d, seq NO. %d, Cookie: 0x%llx\n",
+				rTxDoneStatus, prMsduInfo->ucTxSeqNum, prMgmtTxReqInfo->u8Cookie);
+		} else {
+			fgIsSuccess = TRUE;
+			DBGLOG(P2P, TRACE, "Mgmt Frame TX Done.\n");
+		}
+
+		if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) {
+			kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo,
+						   prMgmtTxReqInfo->u8Cookie,
+						   fgIsSuccess,
+						   prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength);
+
+			prMgmtTxReqInfo->prMgmtTxMsdu = NULL;
+		}
+
+	} while (FALSE);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* p2pFsmRunEventMgmtFrameTxDone */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called when JOIN complete message event is received from SAA.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL;
+	P_MSG_JOIN_COMP_T prJoinCompMsg = (P_MSG_JOIN_COMP_T) NULL;
+	P_SW_RFB_T prAssocRspSwRfb = (P_SW_RFB_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+	DBGLOG(P2P, TRACE, "P2P Join Complete\n");
+
+	prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+	if (prP2pFsmInfo == NULL) {
+		if (prMsgHdr)
+			cnmMemFree(prAdapter, prMsgHdr);
+		return;
+	}
+
+	prJoinInfo = &(prP2pFsmInfo->rJoinInfo);
+	if (prMsgHdr == NULL)
+		return;
+	prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr;
+	prAssocRspSwRfb = prJoinCompMsg->prSwRfb;
+	prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+	if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) {
+		P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+
+		prStaRec = prJoinCompMsg->prStaRec;
+
+		/* Check SEQ NUM */
+		if (prJoinCompMsg->ucSeqNum == prJoinInfo->ucSeqNumOfReqMsg) {
+			ASSERT(prStaRec == prJoinInfo->prTargetStaRec);
+			prJoinInfo->fgIsJoinComplete = TRUE;
+
+			if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) {
+
+				/* 4 <1.1> Change FW's Media State immediately. */
+				p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+
+				/* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */
+				if ((prP2pBssInfo->prStaRecOfAP) && (prP2pBssInfo->prStaRecOfAP != prStaRec)) {
+					cnmStaRecChangeState(prAdapter, prP2pBssInfo->prStaRecOfAP,
+							     STA_STATE_1);
+
+					cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE);
+
+					prP2pBssInfo->prStaRecOfAP = NULL;
+				}
+				/* 4 <1.3> Update BSS_INFO_T */
+				p2pFuncUpdateBssInfoForJOIN(prAdapter, prP2pFsmInfo->prTargetBss, prStaRec,
+							    prAssocRspSwRfb);
+
+				/* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+				DBGLOG(P2P, INFO, "P2P GC Join Success\n");
+
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+				/* <1.5> Update RSSI if necessary */
+				nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX,
+					      (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0);
+#endif
+
+				/* 4 <1.6> Indicate Connected Event to Host immediately. */
+				/* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */
+				/* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, */
+				/* prStaRec->aucMacAddr); */
+				if (prP2pFsmInfo->prTargetBss)
+					scanReportBss2Cfg80211(prAdapter, OP_MODE_P2P_DEVICE,
+							       prP2pFsmInfo->prTargetBss);
+				kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo,
+								 &prP2pFsmInfo->rConnReqInfo,
+								 prJoinInfo->aucIEBuf, prJoinInfo->u4BufLength,
+								 prStaRec->u2StatusCode,
+                                                                 WLAN_STATUS_MEDIA_CONNECT);
+
+			} else {
+				/* Join Fail */
+				/* 4 <2.1> Redo JOIN process with other Auth Type if possible */
+				if (p2pFuncRetryJOIN(prAdapter, prStaRec, prJoinInfo) == FALSE) {
+					P_BSS_DESC_T prBssDesc;
+
+					/* Increase Failure Count */
+					prStaRec->ucJoinFailureCount++;
+
+					prBssDesc = prP2pFsmInfo->prTargetBss;
+
+					ASSERT(prBssDesc);
+					ASSERT(prBssDesc->fgIsConnecting);
+
+					prBssDesc->fgIsConnecting = FALSE;
+
+					if (prStaRec->ucJoinFailureCount >= 3) {
+
+						kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo,
+										 &prP2pFsmInfo->rConnReqInfo,
+										 prJoinInfo->aucIEBuf,
+										 prJoinInfo->u4BufLength,
+										 prStaRec->u2StatusCode,
+                                                                                 WLAN_STATUS_MEDIA_CONNECT);
+					} else {
+						/* Sometime the GO is not ready to response auth. */
+						/* Connect it again */
+						prP2pFsmInfo->prTargetBss = NULL;
+					}
+					DBGLOG(P2P, INFO, "P2P GC Join Failed\n");
+
+				}
+
+			}
+		}
+	}
+
+	if (prAssocRspSwRfb)
+		nicRxReturnRFB(prAdapter, prAssocRspSwRfb);
+
+	if (prP2pFsmInfo->eCurrentState == P2P_STATE_GC_JOIN) {
+
+		if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState ==
+		    PARAM_MEDIA_STATE_CONNECTED) {
+			/* Return to IDLE state. */
+			p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+		} else {
+			/* p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); */
+			/* one more scan */
+			p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN);
+		}
+	}
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+}				/* p2pFsmRunEventJoinComplete */
+
+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) prMsgHdr;
+
+		p2pFuncMgmtFrameRegister(prAdapter,
+					 prMgmtFrameRegister->u2FrameType,
+					 prMgmtFrameRegister->fgIsRegister, &prP2pFsmInfo->u4P2pPacketFilter);
+
+	} while (FALSE);
+
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+
+	return;
+
+}				/* p2pFsmRunEventMgmtFrameRegister */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is call when RX deauthentication frame from the AIR.
+*             If we are under STA mode, we would go back to P2P Device.
+*             If we are under AP mode, we would stay in AP mode until disconnect event from HOST.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb)
+{
+
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	UINT_16 u2ReasonCode = 0;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
+
+		if (prStaRec == NULL)
+			prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		if (!prStaRec)
+			break;
+
+		prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
+
+		if (prStaRec->ucStaState == STA_STATE_1)
+			break;
+
+		DBGLOG(P2P, TRACE, "RX Deauth\n");
+
+		switch (prP2pBssInfo->eCurrentOPMode) {
+		case OP_MODE_INFRASTRUCTURE:
+			if (authProcessRxDeauthFrame(prSwRfb,
+						     prStaRec->aucMacAddr, &u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+				P_WLAN_DEAUTH_FRAME_T prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
+				UINT_16 u2IELength = 0;
+
+				if (prP2pBssInfo->prStaRecOfAP != prStaRec)
+					break;
+
+				prStaRec->u2ReasonCode = u2ReasonCode;
+				u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN);
+
+				ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec);
+
+				/* Indicate disconnect to Host. */
+				kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo,
+								 NULL,
+								 prDeauthFrame->aucInfoElem, u2IELength, u2ReasonCode,
+                                                                 WLAN_STATUS_MEDIA_DISCONNECT);
+
+				prP2pBssInfo->prStaRecOfAP = NULL;
+				DBGLOG(P2P, INFO, "GC RX Deauth Reason: %d\n", u2ReasonCode);
+
+				p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode);
+				p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+
+				SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+				p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+			}
+			break;
+		case OP_MODE_ACCESS_POINT:
+			/* Delete client from client list. */
+			if (authProcessRxDeauthFrame(prSwRfb,
+						     prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+				P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL;
+				P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+				P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL;
+
+				prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList;
+
+				LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
+					prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry);
+
+					ASSERT(prCurrStaRec);
+
+					if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) {
+
+						/* Remove STA from client list. */
+						LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList,
+									&prCurrStaRec->rLinkEntry);
+
+						/* Indicate to Host. */
+						/* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */
+
+						/* Indicate disconnect to Host. */
+						DBGLOG(P2P, INFO, "GO RX Deauth Reason: %d\n", u2ReasonCode);
+						p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode);
+
+						break;
+					}
+				}
+			}
+			break;
+		case OP_MODE_P2P_DEVICE:
+		default:
+			/* Findout why someone sent deauthentication frame to us. */
+			ASSERT(FALSE);
+			break;
+		}
+
+		DBGLOG(P2P, TRACE, "Deauth Reason:%d\n", u2ReasonCode);
+
+	} while (FALSE);
+}				/* p2pFsmRunEventRxDeauthentication */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is call when RX deauthentication frame from the AIR.
+*             If we are under STA mode, we would go back to P2P Device.
+*             If we are under AP mode, we would stay in AP mode until disconnect event from HOST.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	UINT_16 u2ReasonCode = 0;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo == NULL)
+			break;
+
+		if (prStaRec == NULL) {
+			prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+			if (prStaRec == NULL)
+				break;
+		}
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		if (prStaRec->ucStaState == STA_STATE_1)
+			break;
+
+		DBGLOG(P2P, TRACE, "RX Disassoc\n");
+
+		switch (prP2pBssInfo->eCurrentOPMode) {
+		case OP_MODE_INFRASTRUCTURE:
+			if (assocProcessRxDisassocFrame(prAdapter,
+							prSwRfb,
+							prStaRec->aucMacAddr,
+							&prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+				P_WLAN_DISASSOC_FRAME_T prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader;
+				UINT_16 u2IELength = 0;
+
+				ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec);
+
+				if (prP2pBssInfo->prStaRecOfAP != prStaRec)
+					break;
+
+				u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN);
+
+				/* Indicate disconnect to Host. */
+				kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo,
+								 NULL,
+								 prDisassocFrame->aucInfoElem,
+								 u2IELength, prStaRec->u2ReasonCode,
+                                                                 WLAN_STATUS_MEDIA_DISCONNECT);
+
+				prP2pBssInfo->prStaRecOfAP = NULL;
+
+				DBGLOG(P2P, INFO, "GC RX Disassoc Reason %d\n", prStaRec->u2ReasonCode);
+				p2pFuncDisconnect(prAdapter, prStaRec, FALSE, prStaRec->u2ReasonCode);
+				p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+				SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+				p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+
+			}
+			break;
+		case OP_MODE_ACCESS_POINT:
+			/* Delete client from client list. */
+			if (assocProcessRxDisassocFrame(prAdapter,
+							prSwRfb,
+							prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+				P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL;
+				P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+				P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL;
+
+				prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList;
+
+				LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
+					prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry);
+
+					ASSERT(prCurrStaRec);
+
+					if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) {
+
+						/* Remove STA from client list. */
+						LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList,
+									&prCurrStaRec->rLinkEntry);
+
+						/* Indicate to Host. */
+						/* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */
+
+						/* Indicate disconnect to Host. */
+						DBGLOG(P2P, INFO, "GO RX Disassoc Reason %d\n", u2ReasonCode);
+						p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode);
+
+						break;
+					}
+				}
+			}
+			break;
+		case OP_MODE_P2P_DEVICE:
+		default:
+			ASSERT(FALSE);
+			break;
+		}
+
+	} while (FALSE);
+}				/* p2pFsmRunEventRxDisassociation */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is called when a probe request frame is received.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return boolean value if probe response frame is accepted & need cancel scan request.
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	P_WLAN_MAC_MGMT_HEADER_T prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (prBssDesc != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+		prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+		prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
+
+		/* There is a connection request. */
+		prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader;
+
+	} while (FALSE);
+
+}				/* p2pFsmRunEventRxProbeResponseFrame */
+
+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconTimeout: Beacon Timeout\n");
+
+		/* Only client mode would have beacon lost event. */
+		ASSERT(prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE);
+
+		if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+			/* Indicate disconnect to Host. */
+			kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo,
+							 NULL, NULL, 0, REASON_CODE_DISASSOC_INACTIVITY,
+                                                         WLAN_STATUS_MEDIA_DISCONNECT);
+
+			if (prP2pBssInfo->prStaRecOfAP != NULL) {
+				P_STA_RECORD_T prStaRec = prP2pBssInfo->prStaRecOfAP;
+
+				prP2pBssInfo->prStaRecOfAP = NULL;
+
+				p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_DISASSOC_LEAVING_BSS);
+
+				/* 20120830 moved into p2pFuncDisconnect() */
+				/* cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); */
+				p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+				SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX);
+				p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+
+			}
+		}
+	} while (FALSE);
+
+}				/* p2pFsmRunEventBeaconTimeout */
+
+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = NULL;
+	struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prExtListenMsg = NULL;
+
+	ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL));
+
+	prExtListenMsg = (struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *) prMsgHdr;
+
+	prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+	ASSERT_BREAK(prP2pFsmInfo);
+
+	if (!prExtListenMsg->wait) {
+		DBGLOG(P2P, INFO, "reset listen interval\n");
+		prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN;
+		if (prMsgHdr)
+			cnmMemFree(prAdapter, prMsgHdr);
+		return;
+	}
+
+	if (prP2pFsmInfo && (prP2pFsmInfo->eListenExted == P2P_DEV_NOT_EXT_LISTEN)) {
+		DBGLOG(P2P, INFO, "try to ext listen, p2p state: %d\n", prP2pFsmInfo->eCurrentState);
+		if (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) {
+			DBGLOG(P2P, INFO, "here to ext listen interval\n");
+			prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_ING;
+		}
+	}
+	if (prMsgHdr)
+		cnmMemFree(prAdapter, prMsgHdr);
+}				/* p2pFsmRunEventUpdateMgmtFrame */
+
+#if CFG_SUPPORT_WFD
+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+	P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL;
+	WLAN_STATUS rStatus;
+
+	DBGLOG(P2P, INFO, "p2pFsmRunEventWfdSettingUpdate\n");
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL));
+
+		if (prMsgHdr != NULL) {
+			prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) prMsgHdr;
+			prWfdCfgSettings = prMsgWfdCfgSettings->prWfdCfgSettings;
+		} else {
+			prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
+		}
+
+		DBGLOG(P2P, INFO, "WFD Enalbe %x info %x state %x flag %x adv %x\n",
+				   prWfdCfgSettings->ucWfdEnable,
+				   prWfdCfgSettings->u2WfdDevInfo,
+				   (UINT_32) prWfdCfgSettings->u4WfdState,
+				   (UINT_32) prWfdCfgSettings->u4WfdFlag,
+				   (UINT_32) prWfdCfgSettings->u4WfdAdvancedFlag);
+
+		rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+					      CMD_ID_SET_WFD_CTRL,	/* ucCID */
+					      TRUE,	/* fgSetQuery */
+					      FALSE,	/* fgNeedResp */
+					      FALSE,	/* fgIsOid */
+					      NULL, NULL,	/* pfCmdTimeoutHandler */
+					      sizeof(WFD_CFG_SETTINGS_T),	/* u4SetQueryInfoLen */
+					      (PUINT_8) prWfdCfgSettings,	/* pucInfoBuffer */
+					      NULL,	/* pvSetQueryBuffer */
+					      0	/* u4SetQueryBufferLen */
+		    );
+
+	} while (FALSE);
+
+	return;
+
+}
+
+/* p2pFsmRunEventWfdSettingUpdate */
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to generate P2P IE for Beacon frame.
+*
+* @param[in] prMsduInfo             Pointer to the composed MSDU_INFO_T.
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+		if (prStaRec != NULL) {
+			if (IS_STA_P2P_TYPE(prStaRec)) {
+				/* Do nothing */
+				/* TODO: */
+			}
+		}
+
+	} while (FALSE);
+
+	return;
+
+}				/* end of p2pGenerateP2P_IEForAssocReq() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to generate P2P IE for Probe Request frame.
+*
+* @param[in] prMsduInfo             Pointer to the composed MSDU_INFO_T.
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	ASSERT(prAdapter);
+	ASSERT(pucBuf);
+
+	/* TODO: */
+
+	return;
+
+}				/* end of p2pGenerateP2P_IEForProbReq() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to calculate P2P IE length for Beacon frame.
+*
+* @param[in] eNetTypeIndex      Specify which network
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return The length of P2P IE added
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32
+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter,
+				 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+
+	if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX)
+		return 0;
+	/* TODO: */
+
+	return 0;
+
+}				/* end of p2pCalculateP2P_IELenForProbeReq() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate the Event of Tx Fail of AAA Module.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec);
+
+	p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_UNSPECIFIED);
+
+	/* 20120830 moved into p2puUncDisconnect. */
+	/* cnmStaRecFree(prAdapter, prStaRec, TRUE); */
+
+}				/* p2pRunEventAAATxFail */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate the Event of Successful Completion of AAA Module.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	ENUM_PARAM_MEDIA_STATE_T eOriMediaState;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		eOriMediaState = prP2pBssInfo->eConnectionState;
+
+		if (prStaRec != NULL)
+			bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec);
+		else
+			break;
+
+		if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT ||
+		    kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) {
+			rStatus = WLAN_STATUS_RESOURCES;
+			break;
+		}
+
+		bssAddStaRecToClientList(prAdapter, prP2pBssInfo, prStaRec);
+
+		prStaRec->u2AssocId = bssAssignAssocID(prStaRec);
+
+		if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT ||
+		    kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) {
+			rStatus = WLAN_STATUS_RESOURCES;
+			break;
+		}
+		DBGLOG(P2P, INFO, "P2P GO Join Complete\n");
+
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+
+		p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED);
+
+		/* Update Connected state to FW. */
+		if (eOriMediaState != prP2pBssInfo->eConnectionState)
+			nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+	} while (FALSE);
+
+	return rStatus;
+}				/* p2pRunEventAAAComplete */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will indicate the Event of Successful Completion of AAA Module.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL));
+
+		/* Glue layer indication. */
+		kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, TRUE);
+
+	} while (FALSE);
+
+	return rStatus;
+}				/* p2pRunEventAAASuccess */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_P2P_PUBLIC_ACTION_FRAME_T prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) NULL;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+
+	ASSERT(prSwRfb);
+	ASSERT(prAdapter);
+
+	prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) prSwRfb->pvHeader;
+	prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+	DBGLOG(P2P, TRACE, "RX Public Action Frame Token:%d.\n", prPublicActionFrame->ucDialogToken);
+
+	if (prPublicActionFrame->ucCategory != CATEGORY_PUBLIC_ACTION)
+		return rWlanStatus;
+
+	switch (prPublicActionFrame->ucAction) {
+	case ACTION_PUBLIC_WIFI_DIRECT:
+		break;
+	case ACTION_GAS_INITIAL_REQUEST:
+	case ACTION_GAS_INITIAL_RESPONSE:
+	case ACTION_GAS_COMEBACK_REQUEST:
+	case ACTION_GAS_COMEBACK_RESPONSE:
+		break;
+	default:
+		break;
+	}
+
+	return rWlanStatus;
+}				/* p2pRxPublicActionFrame */
+
+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_P2P_ACTION_FRAME_T prP2pActionFrame = (P_P2P_ACTION_FRAME_T) NULL;
+	UINT_8 aucOui[3] = VENDOR_OUI_WFA_SPECIFIC;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
+
+		prP2pActionFrame = (P_P2P_ACTION_FRAME_T) prSwRfb->pvHeader;
+
+		if (prP2pActionFrame->ucCategory != CATEGORY_VENDOR_SPECIFIC_ACTION) {
+			DBGLOG(P2P, TRACE, "RX Action Frame but not vendor specific.\n");
+			break;
+		}
+
+		if ((prP2pActionFrame->ucOuiType != VENDOR_OUI_TYPE_P2P) ||
+		    (prP2pActionFrame->aucOui[0] != aucOui[0]) ||
+		    (prP2pActionFrame->aucOui[1] != aucOui[1]) || (prP2pActionFrame->aucOui[2] != aucOui[2])) {
+			DBGLOG(P2P, TRACE, "RX Vendor Specific Action Frame but not P2P Type or not WFA OUI.\n");
+			break;
+		}
+
+	} while (FALSE);
+
+	return rWlanStatus;
+}				/* p2pRxActionFrame */
+
+VOID
+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter,
+			       UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam)
+{
+	P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;
+	UINT_32 i;
+	BOOLEAN fgNoaAttrExisted = FALSE;
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIndex]);
+	prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+	prP2pSpecificBssInfo->fgEnableOppPS = prEventUpdateNoaParam->fgEnableOppPS;
+	prP2pSpecificBssInfo->u2CTWindow = prEventUpdateNoaParam->u2CTWindow;
+	prP2pSpecificBssInfo->ucNoAIndex = prEventUpdateNoaParam->ucNoAIndex;
+	prP2pSpecificBssInfo->ucNoATimingCount = prEventUpdateNoaParam->ucNoATimingCount;
+
+	fgNoaAttrExisted |= prP2pSpecificBssInfo->fgEnableOppPS;
+
+	DBGLOG(P2P, INFO, "Update NoA Count=%d.\n", prEventUpdateNoaParam->ucNoATimingCount);
+
+	ASSERT(prP2pSpecificBssInfo->ucNoATimingCount <= P2P_MAXIMUM_NOA_COUNT);
+
+	for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) {
+		/* in used */
+		prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse = prEventUpdateNoaParam->arEventNoaTiming[i].fgIsInUse;
+		/* count */
+		prP2pSpecificBssInfo->arNoATiming[i].ucCount = prEventUpdateNoaParam->arEventNoaTiming[i].ucCount;
+		/* duration */
+		prP2pSpecificBssInfo->arNoATiming[i].u4Duration = prEventUpdateNoaParam->arEventNoaTiming[i].u4Duration;
+		/* interval */
+		prP2pSpecificBssInfo->arNoATiming[i].u4Interval = prEventUpdateNoaParam->arEventNoaTiming[i].u4Interval;
+		/* start time */
+		prP2pSpecificBssInfo->arNoATiming[i].u4StartTime =
+		    prEventUpdateNoaParam->arEventNoaTiming[i].u4StartTime;
+
+		fgNoaAttrExisted |= prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse;
+	}
+
+	prP2pSpecificBssInfo->fgIsNoaAttrExisted = fgNoaAttrExisted;
+
+	/* update beacon content by the change */
+	bssUpdateBeaconContent(prAdapter, ucNetTypeIndex);
+}
+
+#endif /* CFG_ENABLE_WIFI_DIRECT */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c
new file mode 100644
index 0000000000000..586a74721b3bf
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c
@@ -0,0 +1,3796 @@
+#include "precomp.h"
+#include <uapi/linux/sched/types.h>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wformat"
+#endif
+
+APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = {
+	{(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS), NULL, p2pFuncAppendAttriStatusForAssocRsp}	/* 0 */
+	, {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING), NULL, p2pFuncAppendAttriExtListenTiming}	/* 8 */
+};
+
+APPEND_VAR_IE_ENTRY_T txProbeRspIETable[] = {
+	{(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}	/* 50 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}	/* 42 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}	/* 45 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}	/* 61 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}	/* 48 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}	/* 74 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}	/* 127 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}	/* 221 */
+	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}	/* 221 */
+};
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Function for requesting scan. There is an option to do ACTIVE or PASSIVE scan.
+*
+* @param eScanType - Specify the scan type of the scan request. It can be an ACTIVE/PASSIVE
+*                                  Scan.
+*              eChannelSet - Specify the preferred channel set.
+*                                    A FULL scan would request a legacy full channel normal scan.(usually ACTIVE).
+*                                    A P2P_SOCIAL scan would scan 1+6+11 channels.(usually ACTIVE)
+*                                    A SPECIFIC scan would only 1/6/11 channels scan. (Passive Listen/Specific Search)
+*               ucChannelNum - A specific channel number. (Only when channel is specified)
+*               eBand - A specific band. (Only when channel is specified)
+*
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo)
+{
+
+	P_MSG_SCN_SCAN_REQ prScanReq = (P_MSG_SCN_SCAN_REQ) NULL;
+	/*NFC Beam + Indication */
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	BOOLEAN fgIsPureAP = FALSE;
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+
+	prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+	fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode;
+
+	DEBUGFUNC("p2pFuncRequestScan()");
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL));
+
+		if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) {
+			ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0);
+			DBGLOG(P2P, LOUD,
+			       "P2P Scan Request Channel:%d\n", prScanReqInfo->arScanChannelList[0].ucChannelNum);
+		}
+
+		prScanReq = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ));
+		if (!prScanReq) {
+			ASSERT(0);	/* Can't trigger SCAN FSM */
+			break;
+		}
+
+		prScanReq->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_REQ;
+		prScanReq->ucSeqNum = ++prScanReqInfo->ucSeqNumOfScnMsg;
+		prScanReq->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX;
+		prScanReq->eScanType = prScanReqInfo->eScanType;
+		prScanReq->eScanChannel = prScanReqInfo->eChannelSet;
+		prScanReq->u2IELen = 0;
+
+		/* Copy IE for Probe Request. */
+		if (prScanReqInfo->u4BufLength > MAX_IE_LENGTH)
+			prScanReqInfo->u4BufLength = MAX_IE_LENGTH;
+		kalMemCopy(prScanReq->aucIE, prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength);
+		prScanReq->u2IELen = (UINT_16) prScanReqInfo->u4BufLength;
+
+		prScanReq->u2ChannelDwellTime = prScanReqInfo->u2PassiveDewellTime;
+
+		switch (prScanReqInfo->eChannelSet) {
+		case SCAN_CHANNEL_SPECIFIED:
+			{
+				UINT_32 u4Idx = 0;
+				P_RF_CHANNEL_INFO_T prDomainInfo =
+						(P_RF_CHANNEL_INFO_T) prScanReqInfo->arScanChannelList;
+				UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID;
+
+
+				if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST)
+					prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST;
+
+				for (u4Idx = 0; u4Idx < prScanReqInfo->ucNumChannelList; u4Idx++) {
+					prScanReq->arChnlInfoList[u4Idx].ucChannelNum = prDomainInfo->ucChannelNum;
+					prScanReq->arChnlInfoList[u4Idx].eBand = prDomainInfo->eBand;
+					prDomainInfo++;
+				}
+
+				prScanReq->ucChannelListNum = prScanReqInfo->ucNumChannelList;
+
+				/*NFC Beam + Indication */
+				prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo;
+				if (prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_GO_START_BSS &&
+					prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT &&
+					!fgIsPureAP) {
+					prScanReq->ucChannelListNum = 1;
+					prScanReq->arChnlInfoList[0].ucChannelNum = prChnlReqInfo->ucReqChnlNum;
+					prScanReq->arChnlInfoList[0].eBand = prChnlReqInfo->eBand;
+
+					DBGLOG(P2P, INFO,
+				       "NFC:GO Skip Scan and Only Froce on %s[%d]\n",
+						prChnlReqInfo->eBand == 1 ? "2.4G" : "5G",
+						prChnlReqInfo->ucReqChnlNum);
+					}
+
+				COPY_SSID(prScanReq->aucSSID,
+					  prScanReq->ucSSIDLength,
+					  prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen);
+
+				/* For compatible. */
+				if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN,
+						prScanReq->aucSSID, prScanReq->ucSSIDLength)) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD;
+				} else if (prScanReq->ucSSIDLength != 0) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
+				}
+
+			}
+			break;
+
+		case SCAN_CHANNEL_FULL:
+			{
+				UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID;
+
+				COPY_SSID(prScanReq->aucSSID,
+					  prScanReq->ucSSIDLength,
+					  prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen);
+
+				/* For compatible. */
+				if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN,
+						prScanReq->aucSSID, prScanReq->ucSSIDLength)) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD;
+				} else if (prScanReq->ucSSIDLength != 0) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
+				}
+			}
+			break;
+
+		case SCAN_CHANNEL_2G4:
+			{
+				UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID;
+
+				COPY_SSID(prScanReq->aucSSID,
+					  prScanReq->ucSSIDLength,
+					  prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen);
+
+				/* For compatible. */
+				if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN,
+						prScanReq->aucSSID, prScanReq->ucSSIDLength)) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD;
+				} else if (prScanReq->ucSSIDLength != 0) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
+				}
+			}
+			break;
+
+		case SCAN_CHANNEL_P2P_SOCIAL:
+			{
+				UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID;
+
+				COPY_SSID(prScanReq->aucSSID,
+					  prScanReq->ucSSIDLength,
+					  prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen);
+
+				/* For compatible. */
+				if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN,
+						prScanReq->aucSSID, prScanReq->ucSSIDLength)) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD;
+				} else if (prScanReq->ucSSIDLength != 0) {
+						prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
+				}
+			}
+			break;
+		default:
+			/* Currently there is no other scan channel set. */
+			ASSERT(FALSE);
+			break;
+		}
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReq, MSG_SEND_METHOD_BUF);
+
+	} while (FALSE);
+
+}				/* p2pFuncRequestScan */
+
+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanInfo)
+{
+	P_MSG_SCN_SCAN_CANCEL prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prScanInfo != NULL));
+
+		if (!prScanInfo->fgIsScanRequest)
+			break;
+
+		if (prScanInfo->ucSeqNumOfScnMsg) {
+			/* There is a channel privilege on hand. */
+			DBGLOG(P2P, TRACE, "P2P Cancel Scan\n");
+
+			prScanCancelMsg =
+			    (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL));
+			if (!prScanCancelMsg) {
+				/* Buffer not enough, can not cancel scan request. */
+				DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n");
+				ASSERT(FALSE);
+				break;
+			}
+
+			prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL;
+			prScanCancelMsg->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+			prScanCancelMsg->ucSeqNum = prScanInfo->ucSeqNumOfScnMsg++;
+			prScanCancelMsg->fgIsChannelExt = FALSE;
+			prScanInfo->fgIsScanRequest = FALSE;
+
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF);
+
+		}
+
+	} while (FALSE);
+
+}				/* p2pFuncCancelScan */
+
+VOID
+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter,
+		    IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW)
+{
+	if (!prAdapter)
+		return;
+	if (!prAdapter->prGlueInfo)
+		return;
+	if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT)
+		return;
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (eOpMode < OP_MODE_NUM));
+
+		if (prP2pBssInfo->eCurrentOPMode != eOpMode) {
+			DBGLOG(P2P, TRACE,
+			       "p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", prP2pBssInfo->eCurrentOPMode,
+				eOpMode);
+
+			switch (prP2pBssInfo->eCurrentOPMode) {
+			case OP_MODE_ACCESS_POINT:
+				p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS);
+
+				p2pFsmRunEventStopAP(prAdapter, NULL);
+				break;
+			default:
+				break;
+			}
+
+			prP2pBssInfo->eIntendOPMode = eOpMode;
+			prP2pBssInfo->eCurrentOPMode = eOpMode;
+			switch (eOpMode) {
+			case OP_MODE_INFRASTRUCTURE:
+				DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to Client.\n");
+			case OP_MODE_ACCESS_POINT:
+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */
+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+/* } */
+
+				/* Change interface address. */
+				if (eOpMode == OP_MODE_ACCESS_POINT) {
+					DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to AP.\n");
+					prP2pBssInfo->ucSSIDLen = 0;
+				}
+
+				COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucInterfaceAddress);
+				COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucInterfaceAddress);
+
+				break;
+			case OP_MODE_P2P_DEVICE:
+				{
+					/* Change device address. */
+					DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch back to P2P Device.\n");
+
+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */
+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+/* } */
+
+					p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+
+					COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr,
+						      prAdapter->rWifiVar.aucDeviceAddress);
+					COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress);
+
+				}
+				break;
+			default:
+/* if (IS_BSS_ACTIVE(prP2pBssInfo)) { */
+/* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+
+/* nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+/* } */
+				ASSERT(FALSE);
+				break;
+			}
+
+			if (1) {
+				P2P_DISCONNECT_INFO rP2PDisInfo;
+
+				rP2PDisInfo.ucRole = 2;
+				wlanSendSetQueryCmd(prAdapter,
+						    CMD_ID_P2P_ABORT,
+						    TRUE,
+						    FALSE,
+						    FALSE,
+						    NULL,
+						    NULL,
+						    sizeof(P2P_DISCONNECT_INFO), (PUINT_8)&rP2PDisInfo, NULL, 0);
+			}
+
+			DBGLOG(P2P, TRACE,
+			       "The device address is changed to %pM\n",
+				prP2pBssInfo->aucOwnMacAddr);
+			DBGLOG(P2P, TRACE, "The BSSID is changed to %pM\n", prP2pBssInfo->aucBSSID);
+
+			/* Update BSS INFO to FW. */
+			if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT))
+				nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
+		}
+
+	} while (FALSE);
+
+}				/* p2pFuncSwitchOPMode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will start a P2P Group Owner and send Beacon Frames.
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+p2pFuncStartGO(IN P_ADAPTER_T prAdapter,
+	       IN P_BSS_INFO_T prBssInfo,
+	       IN PUINT_8 pucSsidBuf,
+	       IN UINT_8 ucSsidLen,
+	       IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP)
+{
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL));
+
+		ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT);
+
+		prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 1;
+		DBGLOG(P2P, INFO,
+		       "p2pFuncStartGO:NFC Done[%d]\n",
+			prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone);
+		/* AP mode started. */
+		p2pFuncSwitchOPMode(prAdapter, prBssInfo, prBssInfo->eIntendOPMode, FALSE);
+
+		prBssInfo->eIntendOPMode = OP_MODE_NUM;
+
+		/* 4 <1.1> Assign SSID */
+		COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, pucSsidBuf, ucSsidLen);
+
+		DBGLOG(P2P, TRACE, "GO SSID:%s\n", prBssInfo->aucSSID);
+
+		/* 4 <1.2> Clear current AP's STA_RECORD_T and current AID */
+		prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+		prBssInfo->u2AssocId = 0;
+
+		/* 4 <1.3> Setup Channel, Band and Phy Attributes */
+		prBssInfo->ucPrimaryChannel = ucChannelNum;
+		prBssInfo->eBand = eBand;
+		prBssInfo->eBssSCO = eSco;
+
+		DBGLOG(P2P, TRACE, "GO Channel:%d\n", ucChannelNum);
+
+		if (prBssInfo->eBand == BAND_5G) {
+			/* Depend on eBand */
+			prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN);
+			/* Depend on eCurrentOPMode and ucPhyTypeSet */
+			prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A;
+		} else if (fgIsPureAP) {
+			/* Depend on eBand */
+			prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN);
+			/* Depend on eCurrentOPMode and ucPhyTypeSet */
+			prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG;
+		} else {
+			/* Depend on eBand */
+			prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN);
+			/* Depend on eCurrentOPMode and ucPhyTypeSet */
+			prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P;
+		}
+
+		prBssInfo->ucNonHTBasicPhyType = (UINT_8)
+		    rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
+		prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;
+		prBssInfo->u2OperationalRateSet =
+		    rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;
+
+		if (prBssInfo->ucAllSupportedRatesLen == 0) {
+			rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet,
+						    prBssInfo->u2BSSBasicRateSet,
+						    prBssInfo->aucAllSupportedRates,
+						    &prBssInfo->ucAllSupportedRatesLen);
+		}
+		/* 4 <1.5> Setup MIB for current BSS */
+		prBssInfo->u2ATIMWindow = 0;
+		prBssInfo->ucBeaconTimeoutCount = 0;
+
+		/* 3 <2> Update BSS_INFO_T common part */
+#if CFG_SUPPORT_AAA
+		if (!fgIsPureAP) {
+			prBssInfo->fgIsProtection = TRUE;	/* Always enable protection at P2P GO */
+			kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP);
+		} else {
+			if (kalP2PGetCipher(prAdapter->prGlueInfo))
+				prBssInfo->fgIsProtection = TRUE;
+		}
+
+		/* 20120106 frog: I want separate OP_Mode & Beacon TX Function. */
+		/* p2pFuncSwitchOPMode(prAdapter, prBssInfo, OP_MODE_ACCESS_POINT, FALSE); */
+
+		bssInitForAP(prAdapter, prBssInfo, FALSE);
+
+		nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_P2P_INDEX);
+#endif /* CFG_SUPPORT_AAA */
+
+		/* 3 <3> Set MAC HW */
+		/* 4 <3.1> Setup channel and bandwidth */
+		rlmBssInitForAPandIbss(prAdapter, prBssInfo);
+
+		/* 4 <3.2> Reset HW TSF Update Mode and Beacon Mode */
+		nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+		/* 4 <3.3> Update Beacon again for network phy type confirmed. */
+		bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+#if 0				/* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */
+		{
+			CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg;
+
+			arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE;
+			arHotspotOptimizationCfg.u4Level = (0x3) << 8 | 0x5;
+			wlanoidSendSetQueryP2PCmd(prAdapter,
+						  CMD_ID_SET_HOTSPOT_OPTIMIZATION,
+						  TRUE,
+						  FALSE,
+						  TRUE,
+						  NULL,
+						  NULL,
+						  sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG),
+						  (PUINT_8)&arHotspotOptimizationCfg, NULL, 0);
+		}
+#endif
+
+		/* 4 <3.4> Setup BSSID */
+		nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+	} while (FALSE);
+
+}				/* p2pFuncStartGO() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    This function is to inform CNM that channel privilege
+*           has been released
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo)
+{
+	P_MSG_CH_ABORT_T prMsgChRelease = (P_MSG_CH_ABORT_T) NULL;
+
+	DEBUGFUNC("p2pFuncReleaseCh()");
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL));
+
+		if (!prChnlReqInfo->fgIsChannelRequested)
+			break;
+
+		DBGLOG(P2P, TRACE, "P2P Release Channel\n");
+		prChnlReqInfo->fgIsChannelRequested = FALSE;
+
+		/* 1. return channel privilege to CNM immediately */
+		prMsgChRelease = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T));
+		if (!prMsgChRelease) {
+			ASSERT(0);	/* Can't release Channel to CNM */
+			break;
+		}
+
+		prMsgChRelease->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT;
+		prMsgChRelease->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+		prMsgChRelease->ucTokenID = prChnlReqInfo->ucSeqNumOfChReq++;
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChRelease, MSG_SEND_METHOD_BUF);
+
+	} while (FALSE);
+
+}				/* p2pFuncReleaseCh */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State.
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo)
+{
+	P_MSG_CH_REQ_T prMsgChReq = (P_MSG_CH_REQ_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL));
+
+		p2pFuncReleaseCh(prAdapter, prChnlReqInfo);
+
+		/* send message to CNM for acquiring channel */
+		prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T));
+
+		if (!prMsgChReq) {
+			ASSERT(0);	/* Can't indicate CNM for channel acquiring */
+			break;
+		}
+
+		prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ;
+		prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+		prMsgChReq->ucTokenID = ++prChnlReqInfo->ucSeqNumOfChReq;
+		prMsgChReq->eReqType = CH_REQ_TYPE_JOIN;
+		if (prChnlReqInfo->u4MaxInterval < P2P_EXT_LISTEN_TIME_MS)
+			prMsgChReq->u4MaxInterval = P2P_EXT_LISTEN_TIME_MS;
+		else
+			prMsgChReq->u4MaxInterval = prChnlReqInfo->u4MaxInterval;
+
+		prMsgChReq->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum;
+		prMsgChReq->eRfSco = prChnlReqInfo->eChnlSco;
+		prMsgChReq->eRfBand = prChnlReqInfo->eBand;
+
+		kalMemZero(prMsgChReq->aucBSSID, MAC_ADDR_LEN);
+
+		/* Channel request join BSSID. */
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF);
+
+		prChnlReqInfo->fgIsChannelRequested = TRUE;
+
+	} while (FALSE);
+
+}				/* p2pFuncAcquireCh */
+
+#if 0
+WLAN_STATUS
+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter,
+		    IN PUINT_8 pucBcnHdr,
+		    IN UINT_32 u4HdrLen,
+		    IN PUINT_8 pucBcnBody, IN UINT_32 u4BodyLen, IN UINT_32 u4DtimPeriod, IN UINT_32 u4BcnInterval)
+{
+	WLAN_STATUS rResultStatus = WLAN_STATUS_INVALID_DATA;
+	P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL;
+	PUINT_8 pucTIMBody = (PUINT_8) NULL;
+	UINT_16 u2FrameLength = 0, UINT_16 u2OldBodyLen = 0;
+	UINT_8 aucIEBuf[MAX_IE_LENGTH];
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prBcnMsduInfo = prP2pBssInfo->prBeacon ASSERT_BREAK(prBcnMsduInfo != NULL);
+
+		/* TODO: Find TIM IE pointer. */
+		prBcnFrame = prBcnMsduInfo->prPacket;
+
+		ASSERT_BREAK(prBcnFrame != NULL);
+
+		do {
+			/* Ori header. */
+			UINT_16 u2IELength = 0, u2Offset = 0;
+			PUINT_8 pucIEBuf = prBcnFrame->aucInfoElem;
+
+			u2IELength = prBcnMsduInfo->u2FrameLength - prBcnMsduInfo->ucMacHeaderLength;
+
+			IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) {
+				if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) || ((IE_ID(pucIEBuf) > ELEM_ID_IBSS_PARAM_SET))) {
+					pucTIMBody = pucIEBuf;
+					break;
+				}
+				u2FrameLength += IE_SIZE(pucIEBuf);
+			}
+
+			if (pucTIMBody == NULL)
+				pucTIMBody = pucIEBuf;
+
+			/* Body not change. */
+			u2OldBodyLen = (UINT_16) ((UINT_32) pucTIMBody - (UINT_32) prBcnFrame->aucInfoElem);
+			/* Move body. */
+			kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen);
+		} while (FALSE);
+
+		if (pucBcnHdr) {
+			kalMemCopy(prBcnMsduInfo->prPacket, pucBcnHdr, u4HdrLen);
+			pucTIMBody = (PUINT_8) ((UINT_32) prBcnMsduInfo->prPacket + u4HdrLen);
+			prBcnMsduInfo->ucMacHeaderLength = (WLAN_MAC_MGMT_HEADER_LEN +
+				(TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN));
+			u2FrameLength = u4HdrLen;	/* Header + Partial Body. */
+		} else {
+			/* Header not change. */
+			u2FrameLength += prBcnMsduInfo->ucMacHeaderLength;
+		}
+
+		if (pucBcnBody) {
+			kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen);
+			u2FrameLength += (UINT_16) u4BodyLen;
+		} else {
+			kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen);
+			u2FrameLength += u2OldBodyLen;
+		}
+
+		/* Frame Length */
+		prBcnMsduInfo->u2FrameLength = u2FrameLength;
+		prBcnMsduInfo->fgIs802_11 = TRUE;
+		prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
+		prP2pBssInfo->u2BeaconInterval = (UINT_16) u4BcnInterval;
+		prP2pBssInfo->ucDTIMPeriod = (UINT_8) u4DtimPeriod;
+		prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo;
+		prBcnMsduInfo->ucPacketType = 3;
+		rResultStatus = nicUpdateBeaconIETemplate(prAdapter,
+						      IE_UPD_METHOD_UPDATE_ALL,
+						      NETWORK_TYPE_P2P_INDEX,
+						      prP2pBssInfo->u2CapInfo,
+						      (PUINT_8) prBcnFrame->aucInfoElem,
+						      prBcnMsduInfo->u2FrameLength -
+						      OFFSET_OF(WLAN_BEACON_FRAME_T,
+								aucInfoElem));
+		if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
+			/* AP is created, Beacon Update. */
+			nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX);
+			nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX);
+		}
+
+	} while (FALSE);
+	return rResultStatus;
+}	/* p2pFuncBeaconUpdate */
+
+#else
+WLAN_STATUS
+	p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter,
+		    IN P_BSS_INFO_T prP2pBssInfo,
+		    IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo,
+		    IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen)
+{
+WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL;
+P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL;
+PUINT_8 pucIEBuf = (PUINT_8) NULL;
+PUINT_8 paucIEBuf = (PUINT_8) NULL;/*[MAX_IE_LENGTH]; aucIEBuf*/
+
+do {
+	ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (prBcnUpdateInfo != NULL));
+
+	prBcnMsduInfo = prP2pBssInfo->prBeacon;
+
+#if DBG
+	if (prBcnUpdateInfo->pucBcnHdr != NULL) {
+		ASSERT((UINT_32) prBcnUpdateInfo->pucBcnHdr ==
+		       ((UINT_32) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD));
+	}
+
+	if (prBcnUpdateInfo->pucBcnBody != NULL) {
+		ASSERT((UINT_32) prBcnUpdateInfo->pucBcnBody ==
+		       ((UINT_32) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen));
+	}
+#endif
+	prBcnFrame = (P_WLAN_BEACON_FRAME_T) ((ULONG) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD);
+
+	if (!pucNewBcnBody) {
+		/* Old body. */
+		pucNewBcnBody = prBcnUpdateInfo->pucBcnBody;
+		ASSERT(u4NewBodyLen == 0);
+		u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen;
+	} else {
+		prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen;
+	}
+
+	paucIEBuf = kalMemAlloc(MAX_IE_LENGTH, VIR_MEM_TYPE);
+	if (paucIEBuf == NULL) {
+		DBGLOG(P2P, TRACE, "p2p alloc paucIEBuf fail\n");
+		return WLAN_STATUS_FAILURE;
+	}
+
+	/* Temp buffer body part. */
+	kalMemCopy(paucIEBuf, pucNewBcnBody, u4NewBodyLen);
+
+	if (pucNewBcnHdr) {
+		kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen);
+		prBcnUpdateInfo->pucBcnHdr = (PUINT_8) prBcnFrame;
+		prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen;
+	}
+
+	pucIEBuf = (PUINT_8) ((ULONG) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen);
+	kalMemCopy(pucIEBuf, paucIEBuf, u4NewBodyLen);
+	kalMemFree(paucIEBuf, VIR_MEM_TYPE, MAX_IE_LENGTH);
+	prBcnUpdateInfo->pucBcnBody = pucIEBuf;
+
+	/* Frame Length */
+	prBcnMsduInfo->u2FrameLength = (UINT_16) (prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen);
+
+	prBcnMsduInfo->ucPacketType = 3;
+	prBcnMsduInfo->fgIs802_11 = TRUE;
+	prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
+
+	/* Update BSS INFO related information. */
+	COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr);
+	COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID);
+	prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo;
+
+	p2pFuncParseBeaconContent(prAdapter,
+				  prP2pBssInfo,
+				  (PUINT_8) prBcnFrame->aucInfoElem,
+				  (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)));
+
+#if 1
+	/* bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+#else
+	nicUpdateBeaconIETemplate(prAdapter,
+				  IE_UPD_METHOD_UPDATE_ALL,
+				  NETWORK_TYPE_P2P_INDEX,
+				  prBcnFrame->u2CapInfo,
+				  (PUINT_8) prBcnFrame->aucInfoElem,
+				  (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)));
+#endif
+} while (FALSE);
+
+return rWlanStatus;
+}				/* p2pFuncBeaconUpdate */
+
+#endif
+
+/* TODO: We do not apply IE in deauth frame set from upper layer now. */
+WLAN_STATUS
+p2pFuncDeauth(IN P_ADAPTER_T prAdapter,
+	      IN PUINT_8 pucPeerMacAddr,
+	      IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDeauth)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE;
+	P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	BOOLEAN fgIsStaFound = FALSE;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr);
+
+		switch (prP2pBssInfo->eCurrentOPMode) {
+		case OP_MODE_ACCESS_POINT:
+			{
+				P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL;
+				P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+
+				prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList);
+
+				LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
+					if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) {
+						LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry);
+						fgIsStaFound = TRUE;
+						break;
+					}
+				}
+
+			}
+			break;
+		case OP_MODE_INFRASTRUCTURE:
+			ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP);
+			if (prCliStaRec != prP2pBssInfo->prStaRecOfAP)
+				break;
+			prP2pBssInfo->prStaRecOfAP = NULL;
+			fgIsStaFound = TRUE;
+			break;
+		default:
+			break;
+		}
+
+		if (fgIsStaFound)
+			p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDeauth, u2ReasonCode);
+
+		rWlanStatus = WLAN_STATUS_SUCCESS;
+	} while (FALSE);
+
+	return rWlanStatus;
+}				/* p2pFuncDeauth */
+
+/* TODO: We do not apply IE in disassoc frame set from upper layer now. */
+WLAN_STATUS
+p2pFuncDisassoc(IN P_ADAPTER_T prAdapter,
+		IN PUINT_8 pucPeerMacAddr,
+		IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDisassoc)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE;
+	P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	BOOLEAN fgIsStaFound = FALSE;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr);
+
+		switch (prP2pBssInfo->eCurrentOPMode) {
+		case OP_MODE_ACCESS_POINT:
+			{
+				P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL;
+				P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+
+				prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList);
+
+				LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
+					if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) {
+						LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry);
+						fgIsStaFound = TRUE;
+						/* p2pFuncDisconnect(prAdapter, prCliStaRec,
+						 * fgSendDisassoc, u2ReasonCode); */
+						break;
+					}
+				}
+
+			}
+			break;
+		case OP_MODE_INFRASTRUCTURE:
+			ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP);
+			if (prCliStaRec != prP2pBssInfo->prStaRecOfAP)
+				break;
+			/* p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); */
+			prP2pBssInfo->prStaRecOfAP = NULL;
+			fgIsStaFound = TRUE;
+			break;
+		default:
+			break;
+		}
+
+		if (fgIsStaFound) {
+
+			p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode);
+			/* 20120830 moved into p2pFuncDisconnect(). */
+			/* cnmStaRecFree(prAdapter, prCliStaRec, TRUE); */
+
+		}
+
+		rWlanStatus = WLAN_STATUS_SUCCESS;
+	} while (FALSE);
+
+	return rWlanStatus;
+}				/* p2pFuncDisassoc */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.)
+*              1. GC: Disconnect from AP. (Send Deauth)
+*              2. GO: Disconnect all STA
+*
+* @param[in] prAdapter   Pointer to the adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+p2pFuncDissolve(IN P_ADAPTER_T prAdapter,
+		IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode)
+{
+	DEBUGFUNC("p2pFuncDissolve()");
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL));
+
+		switch (prP2pBssInfo->eCurrentOPMode) {
+		case OP_MODE_INFRASTRUCTURE:
+			/* Reset station record status. */
+			if (prP2pBssInfo->prStaRecOfAP) {
+				kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo,
+								 NULL, NULL, 0, REASON_CODE_DEAUTH_LEAVING_BSS,
+                                                                 WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY);
+
+				/* 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL. */
+				p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, fgSendDeauth, u2ReasonCode);
+			}
+
+			/* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected().
+			 * hit prStaRecOfAP == NULL. */
+			p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+
+			prP2pBssInfo->prStaRecOfAP = NULL;
+
+			break;
+		case OP_MODE_ACCESS_POINT:
+			/* Under AP mode, we would net send deauthentication frame to each STA.
+			 * We only stop the Beacon & let all stations timeout.
+			 */
+			{
+				P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL;
+
+				/* Send deauth. */
+				authSendDeauthFrame(prAdapter,
+						    NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL);
+
+				prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList;
+
+				while (!LINK_IS_EMPTY(prStaRecOfClientList)) {
+					P_STA_RECORD_T prCurrStaRec;
+
+					LINK_REMOVE_HEAD(prStaRecOfClientList, prCurrStaRec, P_STA_RECORD_T);
+
+					/* Indicate to Host. */
+					/* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */
+
+					p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode);
+
+				}
+				prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0;
+			}
+
+			break;
+		default:
+			return;	/* 20110420 -- alreay in Device Mode. */
+		}
+
+		/* Make the deauth frame send to FW ASAP. */
+		wlanAcquirePowerControl(prAdapter);
+		wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue);
+		wlanReleasePowerControl(prAdapter);
+
+		kalMdelay(100);
+
+		/* Change Connection Status. */
+		p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+
+	} while (FALSE);
+
+}				/* p2pFuncDissolve */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.)
+*              1. GC: Disconnect from AP. (Send Deauth)
+*              2. GO: Disconnect all STA
+*
+* @param[in] prAdapter   Pointer to the adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter,
+		  IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		eOriMediaStatus = prP2pBssInfo->eConnectionState;
+
+		/* Indicate disconnect. */
+		/* TODO: */
+		/* kalP2PGOStationUpdate */
+		/* kalP2PGCIndicateConnectionStatus */
+		/* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, prStaRec->aucMacAddr); */
+		DBGLOG(P2P, INFO, "p2pFuncDisconnect, eCurrentOPMode: %d, sendDeauth: %s\n",
+			prP2pBssInfo->eCurrentOPMode, fgSendDeauth ? "True" : "False");
+		if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)
+			kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE);
+
+		if (fgSendDeauth) {
+			/* Send deauth. */
+			authSendDeauthFrame(prAdapter,
+					    prStaRec,
+					    (P_SW_RFB_T) NULL,
+					    u2ReasonCode, (PFN_TX_DONE_HANDLER) p2pFsmRunEventDeauthTxDone);
+		} else {
+			/* Change station state. */
+			cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+			/* Reset Station Record Status. */
+			p2pFuncResetStaRecStatus(prAdapter, prStaRec);
+
+			cnmStaRecFree(prAdapter, prStaRec, TRUE);
+
+			if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ||
+			    (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) {
+				DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n");
+				p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
+			}
+
+			if (eOriMediaStatus != prP2pBssInfo->eConnectionState) {
+				/* Update Disconnected state to FW. */
+				nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
+			}
+
+		}
+
+		if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) {
+			/* GO: It would stop Beacon TX. GC: Stop all BSS related PS function. */
+			nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+			/* Reset RLM related field of BSSINFO. */
+			rlmBssAborted(prAdapter, prP2pBssInfo);
+		}
+
+	} while (FALSE);
+
+	return;
+
+}				/* p2pFuncDisconnect */
+
+/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */
+#define WLAN_ACTION_SPECTRUM_MGMT 0
+#define WLAN_ACTION_QOS 1
+#define WLAN_ACTION_DLS 2
+#define WLAN_ACTION_BLOCK_ACK 3
+#define WLAN_ACTION_PUBLIC 4
+#define WLAN_ACTION_RADIO_MEASUREMENT 5
+#define WLAN_ACTION_FT 6
+#define WLAN_ACTION_HT 7
+#define WLAN_ACTION_SA_QUERY 8
+#define WLAN_ACTION_PROTECTED_DUAL 9
+#define WLAN_ACTION_WNM 10
+#define WLAN_ACTION_UNPROTECTED_WNM 11
+#define WLAN_ACTION_TDLS 12
+#define WLAN_ACTION_SELF_PROTECTED 15
+#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */
+#define WLAN_ACTION_VENDOR_SPECIFIC 127
+
+/* Public action codes */
+#define WLAN_PA_20_40_BSS_COEX 0
+#define WLAN_PA_VENDOR_SPECIFIC 9
+#define WLAN_PA_GAS_INITIAL_REQ 10
+#define WLAN_PA_GAS_INITIAL_RESP 11
+#define WLAN_PA_GAS_COMEBACK_REQ 12
+#define WLAN_PA_GAS_COMEBACK_RESP 13
+#define WLAN_TDLS_DISCOVERY_RESPONSE 14
+
+/* P2P public action frames */
+enum p2p_action_frame_type {
+	P2P_GO_NEG_REQ = 0,
+	P2P_GO_NEG_RESP = 1,
+	P2P_GO_NEG_CONF = 2,
+	P2P_INVITATION_REQ = 3,
+	P2P_INVITATION_RESP = 4,
+	P2P_DEV_DISC_REQ = 5,
+	P2P_DEV_DISC_RESP = 6,
+	P2P_PROV_DISC_REQ = 7,
+	P2P_PROV_DISC_RESP = 8
+};
+
+const char *p2p_to_string(enum p2p_action_frame_type p2p_action)
+{
+	switch (p2p_action) {
+	case P2P_GO_NEG_REQ:
+		return "GO_NEG_REQ";
+	case P2P_GO_NEG_RESP:
+		return "GO_NEG_RESP";
+	case P2P_GO_NEG_CONF:
+		return "GO_NEG_CONF";
+	case P2P_INVITATION_REQ:
+		return "INVITATION_REQ";
+	case P2P_INVITATION_RESP:
+		return "INVITATION_RESP";
+	case P2P_DEV_DISC_REQ:
+		return "DEV_DISC_REQ";
+	case P2P_DEV_DISC_RESP:
+		return "DEV_DISC_RESP";
+	case P2P_PROV_DISC_REQ:
+		return "PROV_DISC_REQ";
+	case P2P_PROV_DISC_RESP:
+		return "PROV_DISC_RESP";
+	}
+
+	return "UNKNOWN P2P Public Action";
+}
+const char *pa_to_string(int pa_action)
+{
+	switch (pa_action) {
+	case WLAN_PA_20_40_BSS_COEX:
+		return "PA_20_40_BSS_COEX";
+	case WLAN_PA_VENDOR_SPECIFIC:
+		return "PA_VENDOR_SPECIFIC";
+	case WLAN_PA_GAS_INITIAL_REQ:
+		return "PA_GAS_INITIAL_REQ";
+	case WLAN_PA_GAS_INITIAL_RESP:
+		return "PA_GAS_INITIAL_RESP";
+	case WLAN_PA_GAS_COMEBACK_REQ:
+		return "PA_GAS_COMEBACK_REQ";
+	case WLAN_PA_GAS_COMEBACK_RESP:
+		return "PA_GAS_COMEBACK_RESP";
+	case WLAN_TDLS_DISCOVERY_RESPONSE:
+		return "TDLS_DISCOVERY_RESPONSE";
+	}
+
+	return "UNKNOWN Public Action";
+}
+
+const char *action_to_string(int wlan_action)
+{
+	switch (wlan_action) {
+	case WLAN_ACTION_SPECTRUM_MGMT:
+		return "SPECTRUM_MGMT";
+	case WLAN_ACTION_QOS:
+		return "QOS";
+	case WLAN_ACTION_DLS:
+		return "DLS";
+	case WLAN_ACTION_BLOCK_ACK:
+		return "BLOCK_ACK";
+	case WLAN_ACTION_PUBLIC:
+		return "PUBLIC";
+	case WLAN_ACTION_RADIO_MEASUREMENT:
+		return "RADIO_MEASUREMENT";
+	case WLAN_ACTION_FT:
+		return "FT";
+	case WLAN_ACTION_HT:
+		return "HT";
+	case WLAN_ACTION_SA_QUERY:
+		return "SA_QUERY";
+	case WLAN_ACTION_PROTECTED_DUAL:
+		return "PROTECTED_DUAL";
+	case WLAN_ACTION_WNM:
+		return "WNM";
+	case WLAN_ACTION_UNPROTECTED_WNM:
+		return "UNPROTECTED_WNM";
+	case WLAN_ACTION_TDLS:
+		return "TDLS";
+	case WLAN_ACTION_SELF_PROTECTED:
+		return "SELF_PROTECTED";
+	case WLAN_ACTION_WMM:
+		return "WMM";
+	case WLAN_ACTION_VENDOR_SPECIFIC:
+		return "VENDOR_SPECIFIC";
+	}
+
+	return "UNKNOWN Action Frame";
+}
+
+VOID p2pFuncTagActionActionP2PFrame(IN P_MSDU_INFO_T prMgmtTxMsdu,
+			IN P_WLAN_ACTION_FRAME prActFrame,
+			IN UINT_8 ucP2pAction, IN UINT_64 u8Cookie)
+{
+	DBGLOG(P2P, INFO, "Found P2P_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNO: %d\n",
+		p2p_to_string(ucP2pAction),
+		prActFrame->aucSrcAddr,
+		prActFrame->aucDestAddr,
+		u8Cookie,
+		prMgmtTxMsdu->ucTxSeqNum);
+}
+
+VOID p2pFuncTagActionActionFrame(IN P_MSDU_INFO_T prMgmtTxMsdu,
+			IN P_WLAN_ACTION_FRAME prActFrame,
+			IN UINT_8 ucAction, IN UINT_64 u8Cookie)
+{
+	PUINT_8 pucVendor = NULL;
+
+	DBGLOG(P2P, INFO, "Found WLAN_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNo: %d\n",
+		pa_to_string(ucAction),
+		prActFrame->aucSrcAddr,
+		prActFrame->aucDestAddr,
+		u8Cookie,
+		prMgmtTxMsdu->ucTxSeqNum);
+
+	if (ucAction == WLAN_PA_VENDOR_SPECIFIC) {
+		pucVendor = (PUINT_8)prActFrame + 26;
+		if (*(pucVendor + 0) == 0x50 &&
+		    *(pucVendor + 1) == 0x6f &&
+		    *(pucVendor + 2) == 0x9a) {
+			if (*(pucVendor + 3) == 0x09)
+				/* found p2p IE */
+				p2pFuncTagActionActionP2PFrame(prMgmtTxMsdu,
+					prActFrame, *(pucVendor + 4), u8Cookie);
+			else if (*(pucVendor + 3) == 0x0a)
+				/* found WFD IE */
+				DBGLOG(P2P, INFO, "Found WFD IE, SA: %pM - DA: %pM\n",
+					prActFrame->aucSrcAddr,
+					prActFrame->aucDestAddr);
+			else
+				DBGLOG(P2P, INFO, "Found Other vendor 0x%x, SA: %pM - DA: %pM\n",
+					*(pucVendor + 3),
+					prActFrame->aucSrcAddr,
+					prActFrame->aucDestAddr);
+		}
+	}
+}
+
+VOID p2pFuncTagActionCategoryFrame(IN P_MSDU_INFO_T prMgmtTxMsdu,
+			P_WLAN_ACTION_FRAME prActFrame,
+			IN UINT_8 ucCategory,
+			IN UINT_64 u8Cookie)
+{
+
+	UINT_8 ucAction = 0;
+
+	DBGLOG(P2P, INFO, "Found WLAN_ACTION_%s, SA: %pM - DA: %pM, u8Cookie: 0x%llx, SeqNO: %d\n",
+		action_to_string(ucCategory),
+		prActFrame->aucSrcAddr,
+		prActFrame->aucDestAddr,
+		u8Cookie,
+		prMgmtTxMsdu->ucTxSeqNum);
+
+	if (ucCategory == WLAN_ACTION_PUBLIC) {
+		ucAction = prActFrame->ucAction;
+		p2pFuncTagActionActionFrame(prMgmtTxMsdu, prActFrame, ucAction, u8Cookie);
+
+	}
+}
+
+/*
+ * used to debug p2p mgmt frame:
+ * GO Nego Req
+ * GO Nego Res
+ * GO Nego Confirm
+ * GO Invite Req
+ * GO Invite Res
+ * Device Discoverability Req
+ * Device Discoverability Res
+ * Provision Discovery Req
+ * Provision Discovery Res
+ */
+
+VOID
+p2pFuncTagMgmtFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie)
+{
+	/* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */
+	P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;
+	P_WLAN_PROBE_RSP_FRAME_T prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T)NULL;
+	UINT_16 u2TxFrameCtrl;
+	P_WLAN_ACTION_FRAME prActFrame;
+	UINT_8 ucCategory;
+
+	prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD);
+	/*
+	 * mgmt frame MASK_FC_TYPE = 0
+	 * use MASK_FRAME_TYPE is oK for frame type/subtype judge
+	 */
+	u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE;
+
+	switch (u2TxFrameCtrl) {
+	case MAC_FRAME_PROBE_RSP:
+
+		prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T) prWlanHdr;
+		DBGLOG(P2P, INFO, "TX Probe Response Frame, SA: %pM - DA: %pM, cookie: 0x%llx, seqNo: %d\n",
+			prProbRspHdr->aucSrcAddr, prProbRspHdr->aucDestAddr,
+			u8Cookie,
+			prMgmtTxMsdu->ucTxSeqNum);
+
+		break;
+
+	case MAC_FRAME_ACTION:
+
+		prActFrame = (P_WLAN_ACTION_FRAME)prWlanHdr;
+		ucCategory = prActFrame->ucCategory;
+		p2pFuncTagActionCategoryFrame(prMgmtTxMsdu, prActFrame,
+			ucCategory, u8Cookie);
+
+		break;
+	default:
+		DBGLOG(P2P, INFO, "MGMT:, un-tagged frame type: 0x%x, A1: %pM, A2: %pM, A3: %pM seqNo: %d\n",
+			u2TxFrameCtrl,
+			prWlanHdr->aucAddr1,
+			prWlanHdr->aucAddr2,
+			prWlanHdr->aucAddr3,
+			prMgmtTxMsdu->ucTxSeqNum);
+		break;
+	}
+}
+
+WLAN_STATUS
+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter,
+		   IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL;
+	P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	BOOLEAN fgIsProbrsp = FALSE;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL));
+
+		if (prMgmtTxReqInfo->fgIsMgmtTxRequested) {
+
+			/* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */
+			/* Packet on driver, not done yet, drop it. */
+			prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu;
+			if (prTxMsduInfo != NULL) {
+
+				kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo,
+							   prMgmtTxReqInfo->u8Cookie,
+							   FALSE,
+							   prTxMsduInfo->prPacket,
+							   (UINT_32) prTxMsduInfo->u2FrameLength);
+
+				/* Leave it to TX Done handler. */
+				/* cnmMgtPktFree(prAdapter, prTxMsduInfo); */
+				prMgmtTxReqInfo->prMgmtTxMsdu = NULL;
+				DBGLOG(P2P, INFO, "p2pFuncTxMgmtFrame: Drop MGMT cookie: 0x%llx\n",
+					prMgmtTxReqInfo->u8Cookie);
+			}
+			/* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */
+			/* Packet transmitted, wait tx done. (cookie issue) */
+			/* 20120105 frog - use another u8cookie to store this value. */
+		}
+
+		ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL);
+
+		prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD);
+		prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, prWlanHdr->aucAddr1);
+		prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_P2P_INDEX;
+
+		switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) {
+		case MAC_FRAME_PROBE_RSP:
+			DBGLOG(P2P, TRACE, "p2pFuncTxMgmtFrame:  TX MAC_FRAME_PROBE_RSP\n");
+			fgIsProbrsp = TRUE;
+			prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, prMgmtTxMsdu);
+			break;
+		default:
+			break;
+		}
+
+		prMgmtTxReqInfo->u8Cookie = u8Cookie;
+		prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu;
+		prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE;
+
+		prMgmtTxMsdu->eSrc = TX_PACKET_MGMT;
+		prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+		prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF);
+		if (prStaRec != NULL)
+			DBGLOG(P2P, TRACE, "Mgmt with station record: %pM.\n", prStaRec->aucMacAddr);
+
+		prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;	/* TODO: undcertain. */
+		prMgmtTxMsdu->fgIs802_1x = FALSE;
+		prMgmtTxMsdu->fgIs802_11 = TRUE;
+		prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+		prMgmtTxMsdu->pfTxDoneHandler = p2pFsmRunEventMgmtFrameTxDone;
+		prMgmtTxMsdu->fgIsBasicRate = TRUE;
+
+		p2pFuncTagMgmtFrame(prMgmtTxMsdu, u8Cookie);
+
+		nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu);
+
+	} while (FALSE);
+
+	return rWlanStatus;
+}				/* p2pFuncTxMgmtFrame */
+
+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo)
+{
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL));
+
+		prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+		prP2pConnSettings->ucOperatingChnl = prRfChannelInfo->ucChannelNum;
+		prP2pConnSettings->eBand = prRfChannelInfo->eBand;
+
+	} while (FALSE);
+
+}
+
+/* p2pFuncSetChannel */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH
+*
+* @param[in] prStaRec       Pointer to the STA_RECORD_T
+*
+* @retval TRUE      We will retry JOIN
+* @retval FALSE     We will not retry JOIN
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo)
+{
+	P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL;
+	BOOLEAN fgRetValue = FALSE;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL) && (prJoinInfo != NULL));
+
+		/* Retry other AuthType if possible */
+		if (!prJoinInfo->ucAvailableAuthTypes)
+			break;
+
+		if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) {
+
+			DBGLOG(P2P, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n");
+
+			prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY;
+
+			prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY;
+		} else {
+			DBGLOG(P2P, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n");
+			ASSERT(0);
+			break;
+		}
+
+		prJoinInfo->ucAvailableAuthTypes = 0;	/* No more available Auth Types */
+
+		/* Trigger SAA to start JOIN process. */
+		prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T));
+		if (!prJoinReqMsg) {
+			ASSERT(0);	/* Can't trigger SAA FSM */
+			break;
+		}
+
+		prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START;
+		prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg;
+		prJoinReqMsg->prStaRec = prStaRec;
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF);
+
+		fgRetValue = TRUE;
+	} while (FALSE);
+
+	return fgRetValue;
+
+}				/* end of p2pFuncRetryJOIN() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will update the contain of BSS_INFO_T for AIS network once
+*        the association was completed.
+*
+* @param[in] prStaRec               Pointer to the STA_RECORD_T
+* @param[in] prAssocRspSwRfb        Pointer to SW RFB of ASSOC RESP FRAME.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter,
+			    IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL;
+	UINT_16 u2IELength;
+	PUINT_8 pucIE;
+
+	DEBUGFUNC("p2pUpdateBssInfoForJOIN()");
+
+	ASSERT(prAdapter);
+	ASSERT(prStaRec);
+	ASSERT(prAssocRspSwRfb);
+
+	prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+	prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+	prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader;
+
+	DBGLOG(P2P, INFO, "Update P2P_BSS_INFO_T and apply settings to MAC\n");
+
+	/* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */
+	/* 4 <1.1> Setup Operation Mode */
+	prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE;
+
+	/* 4 <1.2> Setup SSID */
+	COPY_SSID(prP2pBssInfo->aucSSID,
+		  prP2pBssInfo->ucSSIDLen, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen);
+
+	if (prBssDesc == NULL) {
+		/* Target BSS NULL. */
+		DBGLOG(P2P, TRACE, "Target BSS NULL\n");
+		return;
+	}
+
+	if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAssocRspFrame->aucBSSID))
+		ASSERT(FALSE);
+	/* 4 <1.3> Setup Channel, Band */
+	prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum;
+	prP2pBssInfo->eBand = prBssDesc->eBand;
+
+	/* 3 <2> Update BSS_INFO_T from STA_RECORD_T */
+	/* 4 <2.1> Save current AP's STA_RECORD_T and current AID */
+	prP2pBssInfo->prStaRecOfAP = prStaRec;
+	prP2pBssInfo->u2AssocId = prStaRec->u2AssocId;
+
+	/* 4 <2.2> Setup Capability */
+	prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo;	/* Use AP's Cap Info as BSS Cap Info */
+
+	if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)
+		prP2pBssInfo->fgIsShortPreambleAllowed = TRUE;
+	else
+		prP2pBssInfo->fgIsShortPreambleAllowed = FALSE;
+
+	/* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */
+	prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
+
+	prP2pBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType;
+
+	prP2pBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet;
+	prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
+
+	/* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */
+	/* 4 <3.1> Setup BSSID */
+	COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAssocRspFrame->aucBSSID);
+
+	u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) -
+				(OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN));
+	pucIE = prAssocRspFrame->aucInfoElem;
+
+	/* 4 <3.2> Parse WMM and setup QBSS flag */
+	/* Parse WMM related IEs and configure HW CRs accordingly */
+	mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
+
+	prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS;
+
+	/* 3 <4> Update BSS_INFO_T from BSS_DESC_T */
+	ASSERT(prBssDesc);
+
+	prBssDesc->fgIsConnecting = FALSE;
+	prBssDesc->fgIsConnected = TRUE;
+
+	/* 4 <4.1> Setup MIB for current BSS */
+	prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
+	/* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */
+	prP2pBssInfo->ucDTIMPeriod = 0;
+	prP2pBssInfo->u2ATIMWindow = 0;
+
+	prP2pBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA;
+
+	/* 4 <4.2> Update HT information and set channel */
+	/* Record HT related parameters in rStaRec and rBssInfo
+	 * Note: it shall be called before nicUpdateBss()
+	 */
+	rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
+
+	/* 4 <4.3> Sync with firmware for BSS-INFO */
+	nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+	/* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */
+	/* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */
+
+}				/* end of p2pUpdateBssInfoForJOIN() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Auth Frame and then return
+*        the status code to AAA to indicate if need to perform following actions
+*        when the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[in] pprStaRec          Pointer to pointer of STA_RECORD_T structure.
+* @param[out] pu2StatusCode     The Status Code of Validation Result
+*
+* @retval TRUE      Reply the Auth
+* @retval FALSE     Don't reply the Auth
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter,
+		    IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode)
+{
+	BOOLEAN fgReplyAuth = TRUE;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL;
+
+	DBGLOG(P2P, INFO, "p2pValidate Authentication Frame\n");
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) &&
+			     (prSwRfb != NULL) && (pprStaRec != NULL) && (pu2StatusCode != NULL));
+
+		/* P2P 3.2.8 */
+		*pu2StatusCode = STATUS_CODE_REQ_DECLINED;
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
+
+		if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT)
+		    || (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) {
+			/* We are not under AP Mode yet. */
+			fgReplyAuth = FALSE;
+			DBGLOG(P2P, WARN,
+			       "Current OP mode is not under AP mode. (%d)\n", prP2pBssInfo->eCurrentOPMode);
+			break;
+		}
+
+		prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX, prAuthFrame->aucSrcAddr);
+
+		if (!prStaRec) {
+			prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX);
+
+			/* TODO(Kevin): Error handling of allocation of STA_RECORD_T for
+			 * exhausted case and do removal of unused STA_RECORD_T.
+			 */
+			/* Sent a message event to clean un-used STA_RECORD_T. */
+			ASSERT(prStaRec);
+			if (!prStaRec) {
+				DBGLOG(AAA, INFO, "Station Limit Full. Decline a new Authentication.\n");
+				break;
+			}
+
+			COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr);
+
+			prSwRfb->ucStaRecIdx = prStaRec->ucIndex;
+
+			prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet;
+
+			prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P;
+
+			prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P;
+			prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN;
+			prStaRec->eStaType = STA_TYPE_P2P_GC;
+
+			/* NOTE(Kevin): Better to change state here, not at TX Done */
+			cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+		} else {
+			prSwRfb->ucStaRecIdx = prStaRec->ucIndex;
+
+			if ((prStaRec->ucStaState > STA_STATE_1) && (IS_STA_IN_P2P(prStaRec))) {
+
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+				p2pFuncResetStaRecStatus(prAdapter, prStaRec);
+
+				bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec);
+			}
+
+		}
+
+		if (prP2pBssInfo->rStaRecOfClientList.u4NumElem >= P2P_MAXIMUM_CLIENT_COUNT ||
+		    kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) {
+			/* GROUP limit full. */
+			/* P2P 3.2.8 */
+			DBGLOG(P2P, WARN,
+			       "Group Limit Full. (%d)\n", (INT_16) prP2pBssInfo->rStaRecOfClientList.u4NumElem);
+
+			bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec);
+
+			cnmStaRecFree(prAdapter, prStaRec, FALSE);
+			fgReplyAuth = TRUE;
+			*pu2StatusCode = STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD;
+			break;
+		}
+		/* Hotspot Blacklist */
+		if (prAuthFrame->aucSrcAddr) {
+			if (kalP2PCmpBlackList(prAdapter->prGlueInfo, prAuthFrame->aucSrcAddr)) {
+				fgReplyAuth = TRUE;
+				*pu2StatusCode = STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD;
+				return fgReplyAuth;
+			}
+		}
+
+		/* prStaRec->eStaType = STA_TYPE_INFRA_CLIENT; */
+		prStaRec->eStaType = STA_TYPE_P2P_GC;
+
+		prStaRec->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
+
+		/* Update Station Record - Status/Reason Code */
+		prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
+
+		prStaRec->ucJoinFailureCount = 0;
+
+		*pprStaRec = prStaRec;
+
+		*pu2StatusCode = STATUS_CODE_SUCCESSFUL;
+
+	} while (FALSE);
+
+	return fgReplyAuth;
+
+}				/* p2pFuncValidateAuth */
+
+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	do {
+		if ((prAdapter == NULL) || (prStaRec == NULL)) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
+		prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
+		prStaRec->ucJoinFailureCount = 0;
+		prStaRec->fgTransmitKeyExist = FALSE;
+
+		prStaRec->fgSetPwrMgtBit = FALSE;
+
+	} while (FALSE);
+
+}				/* p2pFuncResetStaRecStatus */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief The function is used to initialize the value of the connection settings for
+*        P2P network
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings)
+{
+	P_DEVICE_TYPE_T prDevType;
+	UINT_8 aucDefaultDevName[] = P2P_DEFAULT_DEV_NAME;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+#if CFG_SUPPORT_CFG_FILE
+	P_WIFI_VAR_T prWifiVar = NULL;
+#endif
+
+	ASSERT(prP2PConnSettings);
+#if CFG_SUPPORT_CFG_FILE
+	prWifiVar = &(prAdapter->rWifiVar);
+	ASSERT(prWifiVar);
+#endif
+
+	/* Setup Default Device Name */
+	prP2PConnSettings->ucDevNameLen = P2P_DEFAULT_DEV_NAME_LEN;
+	kalMemCopy(prP2PConnSettings->aucDevName, aucDefaultDevName, sizeof(aucDefaultDevName));
+
+	/* Setup Primary Device Type (Big-Endian) */
+	prDevType = &prP2PConnSettings->rPrimaryDevTypeBE;
+
+	prDevType->u2CategoryId = HTONS(P2P_DEFAULT_PRIMARY_CATEGORY_ID);
+	prDevType->u2SubCategoryId = HTONS(P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID);
+
+	prDevType->aucOui[0] = aucWfaOui[0];
+	prDevType->aucOui[1] = aucWfaOui[1];
+	prDevType->aucOui[2] = aucWfaOui[2];
+	prDevType->aucOui[3] = VENDOR_OUI_TYPE_WPS;
+
+	/* Setup Secondary Device Type */
+	prP2PConnSettings->ucSecondaryDevTypeCount = 0;
+
+	/* Setup Default Config Method */
+	prP2PConnSettings->eConfigMethodSelType = ENUM_CONFIG_METHOD_SEL_AUTO;
+	prP2PConnSettings->u2ConfigMethodsSupport = P2P_DEFAULT_CONFIG_METHOD;
+	prP2PConnSettings->u2TargetConfigMethod = 0;
+	prP2PConnSettings->u2LocalConfigMethod = 0;
+	prP2PConnSettings->fgIsPasswordIDRdy = FALSE;
+
+	/* For Device Capability */
+	prP2PConnSettings->fgSupportServiceDiscovery = FALSE;
+	prP2PConnSettings->fgSupportClientDiscoverability = TRUE;
+	prP2PConnSettings->fgSupportConcurrentOperation = TRUE;
+	prP2PConnSettings->fgSupportInfraManaged = FALSE;
+	prP2PConnSettings->fgSupportInvitationProcedure = FALSE;
+
+	/* For Group Capability */
+#if CFG_SUPPORT_PERSISTENT_GROUP
+	prP2PConnSettings->fgSupportPersistentP2PGroup = TRUE;
+#else
+	prP2PConnSettings->fgSupportPersistentP2PGroup = FALSE;
+#endif
+	prP2PConnSettings->fgSupportIntraBSSDistribution = TRUE;
+	prP2PConnSettings->fgSupportCrossConnection = TRUE;
+	prP2PConnSettings->fgSupportPersistentReconnect = FALSE;
+
+	prP2PConnSettings->fgSupportOppPS = FALSE;
+	prP2PConnSettings->u2CTWindow = P2P_CTWINDOW_DEFAULT;
+
+	/* For Connection Settings. */
+	prP2PConnSettings->eAuthMode = AUTH_MODE_OPEN;
+
+	prP2PConnSettings->prTargetP2pDesc = NULL;
+	prP2PConnSettings->ucSSIDLen = 0;
+
+	/* Misc */
+	prP2PConnSettings->fgIsScanReqIssued = FALSE;
+	prP2PConnSettings->fgIsServiceDiscoverIssued = FALSE;
+	prP2PConnSettings->fgP2pGroupLimit = FALSE;
+	prP2PConnSettings->ucOperatingChnl = 0;
+	prP2PConnSettings->ucListenChnl = 0;
+	prP2PConnSettings->ucTieBreaker = (UINT_8) (kalRandomNumber() & 0x1);
+
+	prP2PConnSettings->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO;
+#if CFG_SUPPORT_CFG_FILE
+	/* prP2PConnSettings->fgIsWPSMode =  prWifiVar->ucApWpsMode; */
+	prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = prWifiVar->ucApWpsMode;
+#endif
+}				/* p2pFuncInitConnectionSettings */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Assoc Req Frame and then return
+*        the status code to AAA to indicate if need to perform following actions
+*        when the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu2StatusCode     The Status Code of Validation Result
+*
+* @retval TRUE      Reply the Assoc Resp
+* @retval FALSE     Don't reply the Assoc Resp
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode)
+{
+	BOOLEAN fgReplyAssocResp = TRUE;
+	P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+#if CFG_SUPPORT_WFD
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+	P_WFD_ATTRIBUTE_T prWfdAttribute = (P_WFD_ATTRIBUTE_T) NULL;
+	BOOLEAN fgNeedFree = FALSE;
+#endif
+	/* UINT_16 u2AttriListLen = 0; */
+	UINT_16 u2WfdDevInfo = 0;
+	P_WFD_DEVICE_INFORMATION_IE_T prAttriWfdDevInfo;
+
+	/* TODO(Kevin): Call P2P functions to check ..
+	   2. Check we can accept connection from thsi peer
+	   a. If we are in PROVISION state, only accept the peer we do the GO formation previously.
+	   b. If we are in OPERATION state, only accept the other peer when P2P_GROUP_LIMIT is 0.
+	   3. Check Black List here.
+	 */
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (pu2StatusCode != NULL));
+
+		*pu2StatusCode = STATUS_CODE_REQ_DECLINED;
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
+
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+		if (prStaRec == NULL) {
+			/* Station record should be ready while RX AUTH frame. */
+			fgReplyAssocResp = FALSE;
+			ASSERT(FALSE);
+			break;
+		}
+		prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
+
+		prStaRec->u2DesiredNonHTRateSet &= prP2pBssInfo->u2OperationalRateSet;
+		prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet;
+
+		if (prStaRec->ucDesiredPhyTypeSet == 0) {
+			/* The station only support 11B rate. */
+			*pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED;
+			break;
+		}
+#if CFG_SUPPORT_WFD && 1
+		/* LOG_FUNC("Skip check WFD IE because some API is not ready\n"); */
+		if (!prAdapter->rWifiVar.prP2pFsmInfo) {
+			fgReplyAssocResp = FALSE;
+			ASSERT(FALSE);
+			break;
+		}
+
+		prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
+		DBGLOG(P2P, INFO, "AssocReq, wfd_en %u wfd_info 0x%x wfd_policy 0x%x wfd_flag 0x%x\n",
+				prWfdCfgSettings->ucWfdEnable, prWfdCfgSettings->u2WfdDevInfo,
+				prWfdCfgSettings->u4WfdPolicy, prWfdCfgSettings->u4WfdFlag);	/* Eddie */
+		if (prWfdCfgSettings->ucWfdEnable) {
+			if (prWfdCfgSettings->u4WfdPolicy & BIT(6)) {
+				/* Rejected all. */
+				break;
+			}
+
+			/* fgNeedFree = p2pFuncGetAttriList(prAdapter, */
+			/* VENDOR_OUI_TYPE_WFD, */
+			/* (PUINT_8)prAssocReqFrame->aucInfoElem, */
+			/* (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), */
+			/* (PPUINT_8)&prWfdAttribute, */
+			/* &u2AttriListLen); */
+
+			prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T)
+			    p2pFuncGetSpecAttri(prAdapter,
+						VENDOR_OUI_TYPE_WFD,
+						(PUINT_8) prAssocReqFrame->aucInfoElem,
+						(prSwRfb->u2PacketLen -
+						 OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)),
+						WFD_ATTRI_ID_DEV_INFO);
+
+			if ((prWfdCfgSettings->u4WfdPolicy & BIT(5)) && (prAttriWfdDevInfo != NULL)) {
+				/* Rejected with WFD IE. */
+				break;
+			}
+
+			if ((prWfdCfgSettings->u4WfdPolicy & BIT(0)) && (prAttriWfdDevInfo == NULL)) {
+				/* Rejected without WFD IE. */
+				break;
+			}
+
+			if (prAttriWfdDevInfo == NULL) {
+				/*
+				 * Without WFD IE.
+				 * Do nothing. Accept the connection request.
+				 */
+				*pu2StatusCode = STATUS_CODE_SUCCESSFUL;
+				break;
+			}
+
+			/* prAttriWfdDevInfo = */
+			/* (P_WFD_DEVICE_INFORMATION_IE_T)p2pFuncGetSpecAttri(prAdapter, */
+			/* VENDOR_OUI_TYPE_WFD, */
+			/* (PUINT_8)prWfdAttribute, */
+			/* u2AttriListLen, */
+			/* WFD_ATTRI_ID_DEV_INFO); */
+			/* if (prAttriWfdDevInfo == NULL) { */
+			/* No such attribute. */
+			/* break; */
+			/* } */
+
+			WLAN_GET_FIELD_BE16(&prAttriWfdDevInfo->u2WfdDevInfo, &u2WfdDevInfo);
+			DBGLOG(P2P, INFO, "RX Assoc Req WFD Info:0x%x.\n", u2WfdDevInfo);
+
+			if ((prWfdCfgSettings->u4WfdPolicy & BIT(1)) && ((u2WfdDevInfo & 0x3) == 0x0)) {
+				/* Rejected because of SOURCE. */
+				break;
+			}
+
+			if ((prWfdCfgSettings->u4WfdPolicy & BIT(2)) && ((u2WfdDevInfo & 0x3) == 0x1)) {
+				/* Rejected because of Primary Sink. */
+				break;
+			}
+
+			if ((prWfdCfgSettings->u4WfdPolicy & BIT(3)) && ((u2WfdDevInfo & 0x3) == 0x2)) {
+				/* Rejected because of Secondary Sink. */
+				break;
+			}
+
+			if ((prWfdCfgSettings->u4WfdPolicy & BIT(4)) && ((u2WfdDevInfo & 0x3) == 0x3)) {
+				/* Rejected because of Source & Primary Sink. */
+				break;
+			}
+
+			/* Check role */
+
+			if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) &&
+				((prWfdCfgSettings->u2WfdDevInfo & BITS(0, 1)) == 0x3)) {
+				/* P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate =
+				 * (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T)NULL; */
+				UINT_16 u2DevInfo = prWfdCfgSettings->u2WfdDevInfo;
+
+				/* We may change role here if we are dual role */
+
+				if ((u2WfdDevInfo & BITS(0, 1)) == 0x00 /* Peer is Source */) {
+					DBGLOG(P2P, INFO, "WFD: Switch role to primary sink\n");
+
+					prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1);
+					prWfdCfgSettings->u2WfdDevInfo |= 0x1;
+
+					/* event to annonce the role is chanaged to P-Sink */
+
+				} else if ((u2WfdDevInfo & BITS(0, 1)) == 0x01 /* Peer is P-Sink */) {
+					DBGLOG(P2P, INFO, "WFD: Switch role to source\n");
+
+					prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1);
+					/* event to annonce the role is chanaged to Source */
+				} else {
+					DBGLOG(P2P, INFO, "WFD: Peer role is wrong type(dev 0x%x)\n",
+						(u2DevInfo));
+					DBGLOG(P2P, INFO, "WFD: Switch role to source\n");
+
+					prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1);
+					/* event to annonce the role is chanaged to Source */
+				}
+
+				p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL);
+
+			} /* Dual role p2p->wfd_params->WfdDevInfo */
+
+			/* WFD_FLAG_DEV_INFO_VALID */
+		}
+		/* ucWfdEnable */
+#endif
+		*pu2StatusCode = STATUS_CODE_SUCCESSFUL;
+	} while (FALSE);
+
+#if CFG_SUPPORT_WFD
+	if ((prWfdAttribute) && (fgNeedFree))
+		kalMemFree(prWfdAttribute, VIR_MEM_TYPE, WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE);
+#endif
+
+	return fgReplyAssocResp;
+
+}				/* p2pFuncValidateAssocReq */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to check the P2P IE
+*
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType)
+{
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
+	P_IE_WFA_T prWfaIE = (P_IE_WFA_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pucOuiType != NULL));
+
+		prWfaIE = (P_IE_WFA_T) pucBuf;
+
+		if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) {
+			break;
+		} else if (prWfaIE->aucOui[0] != aucWfaOui[0] ||
+			   prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) {
+			break;
+		}
+
+		*pucOuiType = prWfaIE->ucOuiType;
+
+		return TRUE;
+	} while (FALSE);
+
+	return FALSE;
+}				/* p2pFuncParseCheckForP2PInfoElem */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Probe Request Frame and then return
+*        result to BSS to indicate if need to send the corresponding Probe Response
+*        Frame if the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu4ControlFlags   Control flags for replying the Probe Response
+*
+* @retval TRUE      Reply the Probe Response
+* @retval FALSE     Don't reply the Probe Response
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags)
+{
+	BOOLEAN fgIsReplyProbeRsp = FALSE;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+
+	DEBUGFUNC("p2pFuncValidateProbeReq");
+	DBGLOG(P2P, TRACE, "p2pFuncValidateProbeReq\n");
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) {
+
+			DBGLOG(P2P, TRACE, "report probe req to OS\n");
+			/* Leave the probe response to p2p_supplicant. */
+			kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb);
+		}
+
+	} while (FALSE);
+
+	return fgIsReplyProbeRsp;
+
+}				/* end of p2pFuncValidateProbeReq() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will validate the Rx Probe Request Frame and then return
+*        result to BSS to indicate if need to send the corresponding Probe Response
+*        Frame if the specified conditions were matched.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] prSwRfb            Pointer to SW RFB data structure.
+* @param[out] pu4ControlFlags   Control flags for replying the Probe Response
+*
+* @retval TRUE      Reply the Probe Response
+* @retval FALSE     Don't reply the Probe Response
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+
+	DEBUGFUNC("p2pFuncValidateProbeReq");
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME) {
+			/* Leave the probe response to p2p_supplicant. */
+			kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb);
+		}
+
+	} while (FALSE);
+
+	return;
+
+}				/* p2pFuncValidateRxMgmtFrame */
+
+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo)
+{
+	if (prP2pFsmInfo) {
+		if (prP2pFsmInfo->fgIsWPSMode == 1)
+			return FALSE;
+		return prP2pFsmInfo->fgIsApMode;
+	} else {
+		return FALSE;
+	}
+}
+
+/* p2pFuncIsAPMode */
+
+VOID
+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter,
+			  IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen)
+{
+	PUINT_8 pucIE = (PUINT_8) NULL;
+	UINT_16 u2Offset = 0;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	BOOLEAN ucNewSecMode = FALSE;
+	BOOLEAN ucOldSecMode = FALSE;
+	UINT_8 ucOuiType;
+	UINT_16 u2SubTypeVersion;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL));
+
+		if (u4IELen == 0)
+			break;
+
+		prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+		prP2pSpecificBssInfo->u2AttributeLen = 0;
+
+		ASSERT_BREAK(pucIEInfo != NULL);
+
+		pucIE = pucIEInfo;
+
+		ucOldSecMode = kalP2PGetCipher(prAdapter->prGlueInfo);
+
+		IE_FOR_EACH(pucIE, u4IELen, u2Offset) {
+			switch (IE_ID(pucIE)) {
+			case ELEM_ID_SSID:
+				{
+					/* 0 */ /* V */ /* Done */
+					/* DBGLOG(P2P, TRACE, ("SSID update\n")); */
+					/* SSID is saved when start AP/GO */
+					/* SSID IE set in beacon from supplicant will not always be */
+					/* the true since hidden SSID case */
+					/*
+					   COPY_SSID(prP2pBssInfo->aucSSID,
+					   prP2pBssInfo->ucSSIDLen,
+					   SSID_IE(pucIE)->aucSSID,
+					   SSID_IE(pucIE)->ucLength);
+
+					   COPY_SSID(prP2pSpecificBssInfo->aucGroupSsid,
+					   prP2pSpecificBssInfo->u2GroupSsidLen,
+					   SSID_IE(pucIE)->aucSSID,
+					   SSID_IE(pucIE)->ucLength);
+					 */
+				}
+				break;
+			case ELEM_ID_SUP_RATES:
+				{
+					/* 1 */ /* V */ /* Done */
+					DBGLOG(P2P, TRACE, "Support Rate IE\n");
+					kalMemCopy(prP2pBssInfo->aucAllSupportedRates,
+						   SUP_RATES_IE(pucIE)->aucSupportedRates,
+						   SUP_RATES_IE(pucIE)->ucLength);
+
+					prP2pBssInfo->ucAllSupportedRatesLen = SUP_RATES_IE(pucIE)->ucLength;
+
+					DBGLOG_MEM8(P2P, TRACE, SUP_RATES_IE(pucIE)->aucSupportedRates,
+						    SUP_RATES_IE(pucIE)->ucLength);
+				}
+				break;
+			case ELEM_ID_DS_PARAM_SET:
+				{
+					/* 3 */ /* V */ /* Done */
+					P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings =
+					    prAdapter->rWifiVar.prP2PConnSettings;
+
+					DBGLOG(P2P, TRACE, "DS PARAM IE\n");
+
+					ASSERT(prP2pConnSettings->ucOperatingChnl == DS_PARAM_IE(pucIE)->ucCurrChnl);
+
+					if (prP2pConnSettings->eBand != BAND_2G4) {
+						ASSERT(FALSE);
+						break;
+					}
+					/* prP2pBssInfo->ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; */
+
+					/* prP2pBssInfo->eBand = BAND_2G4; */
+				}
+				break;
+			case ELEM_ID_TIM:	/* 5 */ /* V */
+				DBGLOG(P2P, TRACE, "TIM IE\n");
+				TIM_IE(pucIE)->ucDTIMPeriod = prP2pBssInfo->ucDTIMPeriod;
+				break;
+			case ELEM_ID_ERP_INFO:	/* 42 */ /* V */
+				{
+#if 1
+					/* This IE would dynamic change due to FW detection change is required. */
+					DBGLOG(P2P, TRACE, "ERP IE will be over write by driver\n");
+					DBGLOG(P2P, TRACE, "    ucERP: %x.\n", ERP_INFO_IE(pucIE)->ucERP);
+
+#else
+					/* This IE would dynamic change due to FW detection change is required. */
+					DBGLOG(P2P, TRACE, "ERP IE.\n");
+
+					prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11GN;
+
+					ASSERT(prP2pBssInfo->eBand == BAND_2G4);
+
+					prP2pBssInfo->fgObssErpProtectMode =
+					    ((ERP_INFO_IE(pucIE)->ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE);
+
+					prP2pBssInfo->fgErpProtectMode =
+					    ((ERP_INFO_IE(pucIE)->ucERP &
+					      (ERP_INFO_USE_PROTECTION | ERP_INFO_NON_ERP_PRESENT)) ? TRUE : FALSE);
+#endif
+
+				}
+				break;
+			case ELEM_ID_HT_CAP:	/* 45 */ /* V */
+				{
+#if 1
+					DBGLOG(P2P, TRACE, "HT CAP IE would be overwritten by driver\n");
+
+					DBGLOG(P2P, TRACE,
+					       "HT Cap Info:%x, AMPDU Param:%x\n", HT_CAP_IE(pucIE)->u2HtCapInfo,
+						HT_CAP_IE(pucIE)->ucAmpduParam);
+
+					DBGLOG(P2P, TRACE,
+					"HT Extended Cap Info%x,TX Beamforming Cap Info%x,Ant Selection Cap Info%x\n",
+						HT_CAP_IE(pucIE)->u2HtExtendedCap, HT_CAP_IE(pucIE)->u4TxBeamformingCap,
+						HT_CAP_IE(pucIE)->ucAselCap);
+#else
+					prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N;
+
+					/* u2HtCapInfo */
+					if ((HT_CAP_IE(pucIE)->u2HtCapInfo &
+					     (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M |
+					      HT_CAP_INFO_DSSS_CCK_IN_40M)) == 0) {
+						prP2pBssInfo->fgAssoc40mBwAllowed = FALSE;
+					} else {
+						prP2pBssInfo->fgAssoc40mBwAllowed = TRUE;
+					}
+
+					if ((HT_CAP_IE(pucIE)->u2HtCapInfo &
+					     (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M)) == 0) {
+						prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE;
+					} else {
+						prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = FALSE;
+					}
+
+					/* ucAmpduParam */
+					DBGLOG(P2P, TRACE,
+					       "AMPDU setting from supplicant:0x%x, & default value:0x%x\n",
+						(UINT_8) HT_CAP_IE(pucIE)->ucAmpduParam,
+						(UINT_8) AMPDU_PARAM_DEFAULT_VAL);
+
+					/* rSupMcsSet */
+					/* Can do nothing. the field is default value from other configuration. */
+					/* HT_CAP_IE(pucIE)->rSupMcsSet; */
+
+					/* u2HtExtendedCap */
+					ASSERT(HT_CAP_IE(pucIE)->u2HtExtendedCap ==
+					       (HT_EXT_CAP_DEFAULT_VAL &
+						~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE)));
+
+					/* u4TxBeamformingCap */
+					ASSERT(HT_CAP_IE(pucIE)->u4TxBeamformingCap == TX_BEAMFORMING_CAP_DEFAULT_VAL);
+
+					/* ucAselCap */
+					ASSERT(HT_CAP_IE(pucIE)->ucAselCap == ASEL_CAP_DEFAULT_VAL);
+#endif
+				}
+				break;
+			case ELEM_ID_RSN:	/* 48 */ /* V */
+				{
+					RSN_INFO_T rRsnIe;
+
+					DBGLOG(P2P, TRACE, "RSN IE\n");
+					kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP);
+					ucNewSecMode = TRUE;
+
+					if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) {
+						prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
+						prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP;
+						prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP;
+						prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK;
+						prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap;
+					}
+				}
+				break;
+			case ELEM_ID_EXTENDED_SUP_RATES:	/* 50 */ /* V */
+				/* Be attention,
+				 * ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */
+				DBGLOG(P2P, TRACE, "Ex Support Rate IE\n");
+				kalMemCopy(&(prP2pBssInfo->aucAllSupportedRates[prP2pBssInfo->ucAllSupportedRatesLen]),
+					   EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates,
+					   EXT_SUP_RATES_IE(pucIE)->ucLength);
+
+				DBGLOG_MEM8(P2P, TRACE, EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates,
+					    EXT_SUP_RATES_IE(pucIE)->ucLength);
+
+				prP2pBssInfo->ucAllSupportedRatesLen += EXT_SUP_RATES_IE(pucIE)->ucLength;
+				break;
+			case ELEM_ID_HT_OP:
+				{
+					/* 61 */ /* V */ /* TODO: */
+#if 1
+					DBGLOG(P2P, TRACE, "HT OP IE would be overwritten by driver\n");
+
+					DBGLOG(P2P, TRACE,
+					       "    Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n",
+						HT_OP_IE(pucIE)->ucPrimaryChannel, HT_OP_IE(pucIE)->ucInfo1,
+						HT_OP_IE(pucIE)->u2Info2, HT_OP_IE(pucIE)->u2Info3);
+#else
+					UINT_16 u2Info2 = 0;
+
+					prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N;
+
+					DBGLOG(P2P, TRACE, "HT OP IE\n");
+
+					/* ucPrimaryChannel. */
+					ASSERT(HT_OP_IE(pucIE)->ucPrimaryChannel == prP2pBssInfo->ucPrimaryChannel);
+
+					/* ucInfo1 */
+					prP2pBssInfo->ucHtOpInfo1 = HT_OP_IE(pucIE)->ucInfo1;
+
+					/* u2Info2 */
+					u2Info2 = HT_OP_IE(pucIE)->u2Info2;
+
+					if (u2Info2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) {
+						ASSERT(prP2pBssInfo->eGfOperationMode != GF_MODE_NORMAL);
+						u2Info2 &= ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT;
+					}
+
+					if (u2Info2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) {
+						prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER;
+						u2Info2 &= ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT;
+					}
+
+					switch (u2Info2 & HT_OP_INFO2_HT_PROTECTION) {
+					case HT_PROTECT_MODE_NON_HT:
+						prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NON_HT;
+						break;
+					case HT_PROTECT_MODE_NON_MEMBER:
+						prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE;
+						prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER;
+						break;
+					default:
+						prP2pBssInfo->eHtProtectMode = HT_OP_IE(pucIE)->u2Info2;
+						break;
+					}
+
+					/* u2Info3 */
+					prP2pBssInfo->u2HtOpInfo3 = HT_OP_IE(pucIE)->u2Info3;
+
+					/* aucBasicMcsSet */
+					DBGLOG_MEM8(P2P, TRACE, HT_OP_IE(pucIE)->aucBasicMcsSet, 16);
+#endif
+				}
+				break;
+			case ELEM_ID_OBSS_SCAN_PARAMS:	/* 74 */ /* V */
+				{
+					DBGLOG(P2P, TRACE,
+					       "ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n");
+				}
+				break;
+			case ELEM_ID_EXTENDED_CAP:	/* 127 */ /* V */
+				{
+					DBGLOG(P2P, TRACE, "ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n");
+				}
+				break;
+			case ELEM_ID_VENDOR:	/* 221 */ /* V */
+				DBGLOG(P2P, TRACE, "Vender Specific IE\n");
+				if (rsnParseCheckForWFAInfoElem
+				    (prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
+					if ((ucOuiType == VENDOR_OUI_TYPE_WPA)
+					    && (u2SubTypeVersion == VERSION_WPA)) {
+						kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP);
+						ucNewSecMode = TRUE;
+						kalMemCopy(prP2pSpecificBssInfo->aucWpaIeBuffer, pucIE,
+							   IE_SIZE(pucIE));
+						prP2pSpecificBssInfo->u2WpaIeLen = IE_SIZE(pucIE);
+					} else if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
+						kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 0, pucIE,
+								   IE_SIZE(pucIE));
+					}
+					/* WMM here. */
+				} else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
+					/* TODO Store the whole P2P IE & generate later. */
+					/* Be aware that there may be one or more P2P IE. */
+					if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
+						kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache
+							   [prP2pSpecificBssInfo->u2AttributeLen], pucIE,
+							   IE_SIZE(pucIE));
+
+						prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE);
+					} else if (ucOuiType == VENDOR_OUI_TYPE_WFD) {
+
+						kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache
+							   [prP2pSpecificBssInfo->u2AttributeLen], pucIE,
+							   IE_SIZE(pucIE));
+
+						prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE);
+					}
+				} else {
+
+					kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache
+						   [prP2pSpecificBssInfo->u2AttributeLen], pucIE,
+						   IE_SIZE(pucIE));
+
+					prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE);
+					DBGLOG(P2P, TRACE, "Driver unprocessed Vender Specific IE\n");
+					ASSERT(FALSE);
+				}
+
+				/* TODO: Store other Vender IE except for WMM Param. */
+				break;
+			default:
+				DBGLOG(P2P, TRACE, "Unprocessed element ID:%d\n", IE_ID(pucIE));
+				break;
+			}
+		}
+
+		if (!ucNewSecMode && ucOldSecMode)
+			kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_NONE);
+
+	} while (FALSE);
+
+}				/* p2pFuncParseBeaconContent */
+
+P_BSS_DESC_T
+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter,
+			IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo,
+			IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo)
+{
+	P_BSS_DESC_T prTargetBss = (P_BSS_DESC_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) &&
+			     (prConnReqInfo != NULL) && (prChnlReqInfo != NULL) && (prScanReqInfo != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+			break;
+		/* Update connection request information. */
+		ASSERT(prConnReqInfo->fgIsConnRequest == TRUE);
+
+		/* Find BSS Descriptor first. */
+		prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo);
+
+		if (prTargetBss == NULL) {
+			/* Update scan parameter... to scan target device. */
+			prScanReqInfo->ucNumChannelList = 1;
+			prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN;
+			prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL;
+			prScanReqInfo->u4BufLength = 0;	/* Prevent other P2P ID in IE. */
+			prScanReqInfo->fgIsAbort = TRUE;
+		} else {
+			prChnlReqInfo->u8Cookie = 0;
+			prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum;
+			prChnlReqInfo->eBand = prTargetBss->eBand;
+			prChnlReqInfo->eChnlSco = prTargetBss->eSco;
+			prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL;
+			prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ;
+		}
+
+	} while (FALSE);
+
+	return prTargetBss;
+}				/* p2pFuncKeepOnConnection */
+
+/* Currently Only for ASSOC Response Frame. */
+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL;
+	P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL;
+	INT_16 i2IELen = 0;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
+
+		prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader;
+
+		if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP)
+			break;
+
+		i2IELen = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN +
+						  CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN);
+
+		if (i2IELen <= 0)
+			break;
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+		prJoinInfo = &(prP2pFsmInfo->rJoinInfo);
+		prJoinInfo->u4BufLength = (UINT_32) i2IELen;
+
+		kalMemCopy(prJoinInfo->aucIEBuf, prAssocRspFrame->aucInfoElem, prJoinInfo->u4BufLength);
+
+	} while (FALSE);
+
+}				/* p2pFuncStoreAssocRspIEBuffer */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set Packet Filter.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+* \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_NOT_SUPPORTED
+* \retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter,
+			 IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter)
+{
+	UINT_32 u4NewPacketFilter = 0;
+
+	DEBUGFUNC("p2pFuncMgmtFrameRegister");
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		if (pu4P2pPacketFilter)
+			u4NewPacketFilter = *pu4P2pPacketFilter;
+
+		switch (u2FrameType) {
+		case MAC_FRAME_PROBE_REQ:
+			if (fgIsRegistered) {
+				u4NewPacketFilter |= PARAM_PACKET_FILTER_PROBE_REQ;
+				DBGLOG(P2P, TRACE, "Open packet filer probe request\n");
+			} else {
+				u4NewPacketFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ;
+				DBGLOG(P2P, TRACE, "Close packet filer probe request\n");
+			}
+			break;
+		case MAC_FRAME_ACTION:
+			if (fgIsRegistered) {
+				u4NewPacketFilter |= PARAM_PACKET_FILTER_ACTION_FRAME;
+				DBGLOG(P2P, TRACE, "Open packet filer action frame.\n");
+			} else {
+				u4NewPacketFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME;
+				DBGLOG(P2P, TRACE, "Close packet filer action frame.\n");
+			}
+			break;
+		default:
+			DBGLOG(P2P, TRACE, "Ask frog to add code for mgmt:%x\n", u2FrameType);
+			break;
+		}
+
+		if (pu4P2pPacketFilter)
+			*pu4P2pPacketFilter = u4NewPacketFilter;
+
+		/* u4NewPacketFilter |= prAdapter->u4OsPacketFilter; */
+
+		prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK;
+		prAdapter->u4OsPacketFilter |= u4NewPacketFilter;
+
+		DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter);
+
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_RX_FILTER,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    nicCmdEventSetCommon,
+				    nicOidCmdTimeoutCommon,
+				    sizeof(UINT_32),
+				    (PUINT_8) &prAdapter->u4OsPacketFilter,
+				    &u4NewPacketFilter, sizeof(u4NewPacketFilter)
+		    );
+
+	} while (FALSE);
+
+}				/* p2pFuncMgmtFrameRegister */
+
+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter)
+{
+
+	do {
+
+		prAdapter->rWifiVar.prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter;
+
+		if ((prAdapter->u4OsPacketFilter & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) {
+
+			prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK;
+
+			prAdapter->u4OsPacketFilter |= (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK);
+
+			wlanSendSetQueryCmd(prAdapter,
+					    CMD_ID_SET_RX_FILTER,
+					    TRUE,
+					    FALSE,
+					    FALSE,
+					    nicCmdEventSetCommon,
+					    nicOidCmdTimeoutCommon,
+					    sizeof(UINT_32),
+					    (PUINT_8) &prAdapter->u4OsPacketFilter, &u4OsFilter, sizeof(u4OsFilter)
+			    );
+			DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter);
+		}
+
+	} while (FALSE);
+
+}				/* p2pFuncUpdateMgmtFrameRegister */
+
+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo)
+{
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucMacAddr != NULL) && (prStaInfo != NULL));
+
+		prStaInfo->u4InactiveTime = 0;
+		prStaInfo->u4RxBytes = 0;
+		prStaInfo->u4TxBytes = 0;
+		prStaInfo->u4RxPackets = 0;
+		prStaInfo->u4TxPackets = 0;
+		/* TODO: */
+
+	} while (FALSE);
+
+}				/* p2pFuncGetStationInfo */
+
+BOOLEAN
+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter,
+		    IN UINT_8 ucOuiType,
+		    IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen)
+{
+	BOOLEAN fgIsAllocMem = FALSE;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
+	UINT_16 u2Offset = 0;
+	P_IE_P2P_T prIe = (P_IE_P2P_T) NULL;
+	PUINT_8 pucAttriListStart = (PUINT_8) NULL;
+	UINT_16 u2AttriListLen = 0, u2BufferSize = 0;
+	BOOLEAN fgBackupAttributes = FALSE;
+	UINT_16 u2CopyLen;
+
+	ASSERT(prAdapter);
+	ASSERT(pucIE);
+	ASSERT(ppucAttriList);
+	ASSERT(pu2AttriListLen);
+
+	if (ppucAttriList)
+		*ppucAttriList = NULL;
+	if (pu2AttriListLen)
+		*pu2AttriListLen = 0;
+
+	if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
+		aucWfaOui[0] = 0x00;
+		aucWfaOui[1] = 0x50;
+		aucWfaOui[2] = 0xF2;
+	} else if ((ucOuiType != VENDOR_OUI_TYPE_P2P)
+#if CFG_SUPPORT_WFD
+		   && (ucOuiType != VENDOR_OUI_TYPE_WFD)
+#endif
+	    ) {
+		DBGLOG(P2P, INFO, "Not supported OUI Type to parsing 0x%x\n", ucOuiType);
+		return fgIsAllocMem;
+	}
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		if (ELEM_ID_VENDOR != IE_ID(pucIE))
+			continue;
+
+		prIe = (P_IE_P2P_T) pucIE;
+
+		if (prIe->ucLength <= P2P_OUI_TYPE_LEN)
+			continue;
+
+		if ((prIe->aucOui[0] == aucWfaOui[0]) &&
+		    (prIe->aucOui[1] == aucWfaOui[1]) &&
+		    (prIe->aucOui[2] == aucWfaOui[2]) && (ucOuiType == prIe->ucOuiType)) {
+
+			if (!pucAttriListStart) {
+				pucAttriListStart = &prIe->aucP2PAttributes[0];
+				if (prIe->ucLength > P2P_OUI_TYPE_LEN)
+					u2AttriListLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN);
+				else
+					ASSERT(FALSE);
+				continue;
+			}
+/* More than 2 attributes. */
+
+			if (FALSE == fgBackupAttributes) {
+				P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo =
+				    prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+				fgBackupAttributes = TRUE;
+				if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
+					kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[0],
+						   pucAttriListStart, u2AttriListLen);
+
+					pucAttriListStart =
+					    &prP2pSpecificBssInfo->aucAttributesCache[0];
+
+					u2BufferSize = P2P_MAXIMUM_ATTRIBUTE_LEN;
+				} else if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
+					kalMemCopy(&prP2pSpecificBssInfo->aucWscAttributesCache
+						   [0], pucAttriListStart, u2AttriListLen);
+					pucAttriListStart =
+					    &prP2pSpecificBssInfo->aucWscAttributesCache[0];
+
+					u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE;
+				}
+#if CFG_SUPPORT_WFD
+				else if (ucOuiType == VENDOR_OUI_TYPE_WFD) {
+					PUINT_8 pucTmpBuf = (PUINT_8) NULL;
+
+					pucTmpBuf = (PUINT_8)
+					    kalMemAlloc(WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE,
+							VIR_MEM_TYPE);
+
+					if (pucTmpBuf != NULL) {
+						fgIsAllocMem = TRUE;
+					} else {
+						/* Can't alloca memory for WFD IE relocate. */
+						ASSERT(FALSE);
+						break;
+					}
+
+					kalMemCopy(pucTmpBuf,
+						   pucAttriListStart, u2AttriListLen);
+
+					pucAttriListStart = pucTmpBuf;
+
+					u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE;
+				}
+#endif
+				else
+					fgBackupAttributes = FALSE;
+			}
+
+			u2CopyLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN);
+
+			if ((u2AttriListLen + u2CopyLen) > u2BufferSize) {
+				u2CopyLen = u2BufferSize - u2AttriListLen;
+				DBGLOG(P2P, WARN,
+				"Length of received P2P attributes > maximum cache size.\n");
+			}
+
+			if (u2CopyLen) {
+				kalMemCopy((PUINT_8)
+					   ((ULONG) pucAttriListStart +
+					    (UINT_32) u2AttriListLen),
+					   &prIe->aucP2PAttributes[0], u2CopyLen);
+
+				u2AttriListLen += u2CopyLen;
+			}
+		}	/* prIe->aucOui */
+	}		/* IE_FOR_EACH */
+
+	if (pucAttriListStart) {
+		PUINT_8 pucAttribute = pucAttriListStart;
+
+		DBGLOG(P2P, LOUD, "Checking Attribute Length.\n");
+		if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
+			P2P_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset);
+		} else if (ucOuiType == VENDOR_OUI_TYPE_WFD) {
+			/* Do nothing */
+		} else if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
+			/* Big Endian: WSC, WFD. */
+			WSC_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset) {
+				DBGLOG(P2P, LOUD, "Attribute ID:%d, Length:%d.\n",
+						   WSC_ATTRI_ID(pucAttribute), WSC_ATTRI_LEN(pucAttribute));
+			}
+		} else {
+		}
+
+		ASSERT(u2Offset == u2AttriListLen);
+
+		if (ppucAttriList)
+			*ppucAttriList = pucAttriListStart;
+		if (pu2AttriListLen)
+			*pu2AttriListLen = u2AttriListLen;
+
+	} else {
+		if (ppucAttriList)
+			*ppucAttriList = (PUINT_8) NULL;
+		if (pu2AttriListLen)
+			*pu2AttriListLen = 0;
+	}
+
+	return fgIsAllocMem;
+}	/* p2pFuncGetAttriList */
+
+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu)
+{
+	P_MSDU_INFO_T prRetMsduInfo = prMgmtTxMsdu;
+	P_WLAN_PROBE_RSP_FRAME_T prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) NULL;
+	PUINT_8 pucIEBuf = (PUINT_8) NULL;
+	UINT_16 u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0;
+	BOOLEAN fgIsP2PIE = FALSE, fgIsWSCIE = FALSE;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	UINT_16 u2EstimateSize = 0, u2EstimatedExtraIELen = 0;
+	UINT_32 u4IeArraySize = 0, u4Idx = 0;
+	UINT_8 ucOuiType = 0;
+	UINT_16 u2SubTypeVersion = 0;
+
+	BOOLEAN fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+		/* 3 Make sure this is probe response frame. */
+		prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD);
+		ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP);
+
+		if (prP2pBssInfo->u2BeaconInterval)
+			prProbeRspFrame->u2BeaconInterval = prP2pBssInfo->u2BeaconInterval;
+
+		/* 3 Get the importent P2P IE. */
+		u2ProbeRspHdrLen =
+		    (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN);
+		pucIEBuf = prProbeRspFrame->aucInfoElem;
+		u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen;
+
+#if CFG_SUPPORT_WFD
+		prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen = 0;
+#endif
+
+		IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) {
+			switch (IE_ID(pucIEBuf)) {
+			case ELEM_ID_SSID:
+				{
+
+					COPY_SSID(prP2pBssInfo->aucSSID,
+						  prP2pBssInfo->ucSSIDLen,
+						  SSID_IE(pucIEBuf)->aucSSID, SSID_IE(pucIEBuf)->ucLength);
+				}
+				break;
+			case ELEM_ID_VENDOR:
+#if !CFG_SUPPORT_WFD
+				if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) {
+					if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
+						kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 2, pucIEBuf,
+							IE_SIZE(pucIEBuf));
+						fgIsWSCIE = TRUE;
+					}
+
+				} else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIEBuf, &ucOuiType)) {
+					if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
+						/* 2 Note(frog): I use WSC IE buffer for Probe Request to
+						 * store the P2P IE for Probe Response. */
+						kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 1, pucIEBuf,
+							IE_SIZE(pucIEBuf));
+						fgIsP2PIE = TRUE;
+					}
+
+				} else {
+					if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen +
+						IE_SIZE(pucIEBuf)) < 512) {
+						kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE,
+							pucIEBuf, IE_SIZE(pucIEBuf));
+						prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen +=
+						    IE_SIZE(pucIEBuf);
+					}
+				}
+#else
+				/* Eddie May be WFD */
+				if (rsnParseCheckForWFAInfoElem
+				    (prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) {
+					if (ucOuiType == VENDOR_OUI_TYPE_WMM)
+						break;
+
+				}
+				if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + IE_SIZE(pucIEBuf)) <
+				    1024) {
+					kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE +
+						   prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen, pucIEBuf,
+						   IE_SIZE(pucIEBuf));
+					prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf);
+				}
+#endif
+				break;
+			default:
+				break;
+			}
+
+		}
+
+		/* 3 Check the total size & current frame. */
+		u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN +
+		    TIMESTAMP_FIELD_LEN +
+		    BEACON_INTERVAL_FIELD_LEN +
+		    CAP_INFO_FIELD_LEN +
+		    (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) +
+		    (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET);
+
+		u2EstimatedExtraIELen = 0;
+
+		u4IeArraySize = sizeof(txProbeRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T);
+		for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) {
+			if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) {
+				u2EstimatedExtraIELen += txProbeRspIETable[u4Idx].u2EstimatedFixedIELen;
+			}
+
+			else {
+				ASSERT(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen);
+
+				u2EstimatedExtraIELen +=
+				    (UINT_16) (txProbeRspIETable[u4Idx].pfnCalculateVariableIELen
+					       (prAdapter, NETWORK_TYPE_P2P_INDEX, NULL));
+			}
+
+		}
+
+		if (fgIsWSCIE)
+			u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2);
+
+		if (fgIsP2PIE) {
+			u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1);
+			u2EstimatedExtraIELen += p2pFuncCalculateP2P_IE_NoA(prAdapter, 0, NULL);
+		}
+#if CFG_SUPPORT_WFD
+		u2EstimatedExtraIELen += prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen;
+#endif
+
+		u2EstimateSize += u2EstimatedExtraIELen;
+		if (u2EstimateSize > (prRetMsduInfo->u2FrameLength)) {
+			prRetMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimateSize);
+
+			if (prRetMsduInfo == NULL) {
+				DBGLOG(P2P, WARN, "No packet for sending new probe response, use original one\n");
+				prRetMsduInfo = prMgmtTxMsdu;
+				break;
+			}
+
+			prRetMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
+		}
+		/* 3 Compose / Re-compose probe response frame. */
+		bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8)
+							  ((ULONG) (prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+							  prProbeRspFrame->aucDestAddr, prProbeRspFrame->aucSrcAddr,
+							  prProbeRspFrame->aucBSSID, prProbeRspFrame->u2BeaconInterval,
+							  fgIsPureAP ? prP2pBssInfo->
+							  u2CapInfo : prProbeRspFrame->u2CapInfo);
+
+		prRetMsduInfo->u2FrameLength =
+		    (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN);
+
+		bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo, prP2pBssInfo, prProbeRspFrame->aucDestAddr);
+
+		for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) {
+			if (txProbeRspIETable[u4Idx].pfnAppendIE)
+				txProbeRspIETable[u4Idx].pfnAppendIE(prAdapter, prRetMsduInfo);
+
+		}
+
+		if (fgIsWSCIE) {
+			kalP2PGenWSC_IE(prAdapter->prGlueInfo,
+					2,
+					(PUINT_8) ((ULONG) prRetMsduInfo->prPacket +
+						   (UINT_32) prRetMsduInfo->u2FrameLength));
+
+			prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2);
+		}
+
+		if (fgIsP2PIE) {
+			kalP2PGenWSC_IE(prAdapter->prGlueInfo,
+					1,
+					(PUINT_8) ((ULONG) prRetMsduInfo->prPacket +
+						   (UINT_32) prRetMsduInfo->u2FrameLength));
+
+			prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1);
+			p2pFuncGenerateP2P_IE_NoA(prAdapter, prRetMsduInfo);
+		}
+#if CFG_SUPPORT_WFD
+		if (prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen > 0) {
+			kalMemCopy((PUINT_8) ((ULONG) prRetMsduInfo->prPacket + (UINT_32) prRetMsduInfo->u2FrameLength),
+				   prAdapter->prGlueInfo->prP2PInfo->aucVenderIE,
+				   prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen);
+			prRetMsduInfo->u2FrameLength += (UINT_16) prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen;
+		}
+#endif
+
+	} while (FALSE);
+
+	if (prRetMsduInfo != prMgmtTxMsdu)
+		cnmMgtPktFree(prAdapter, prMgmtTxMsdu);
+
+	return prRetMsduInfo;
+}				/* p2pFuncProcessP2pProbeRsp */
+
+#if 0				/* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */
+UINT_32
+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter,
+				     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	UINT_32 u4IELen = 0;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX));
+
+		if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo))
+			break;
+
+		prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+		u4IELen = prP2pSpeBssInfo->u2IELenForBCN;
+
+	} while (FALSE);
+
+	return u4IELen;
+}				/* p2pFuncCalculateP2p_IELenForBeacon */
+
+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	PUINT_8 pucIEBuf = (PUINT_8) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+		if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo))
+			break;
+
+		pucIEBuf = (PUINT_8) ((UINT_32) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+		kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucBeaconIECache, prP2pSpeBssInfo->u2IELenForBCN);
+
+		prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN;
+
+	} while (FALSE);
+
+}				/* p2pFuncGenerateExtra_IEForBeacon */
+
+#else
+UINT_32
+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter,
+				   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	UINT_32 u4IELen = 0;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX));
+
+		if (!prAdapter->fgIsP2PRegistered)
+			break;
+
+		if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo))
+			break;
+
+		prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+		u4IELen = prP2pSpeBssInfo->u2AttributeLen;
+
+	} while (FALSE);
+
+	return u4IELen;
+}				/* p2pFuncCalculateP2p_IELenForBeacon */
+
+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	PUINT_8 pucIEBuf = (PUINT_8) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		if (!prAdapter->fgIsP2PRegistered)
+			break;
+
+		prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+		if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo))
+			break;
+
+		pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+		kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen);
+
+		prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen;
+
+	} while (FALSE);
+
+}				/* p2pFuncGenerateP2p_IEForBeacon */
+
+UINT_32
+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter,
+				   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+	if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX)
+		return 0;
+
+	return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0);
+}				/* p2pFuncCalculateP2p_IELenForBeacon */
+
+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	PUINT_8 pucBuffer;
+	UINT_16 u2IELen = 0;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX)
+		return;
+
+	u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0);
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+	ASSERT(pucBuffer);
+
+	/* TODO: Check P2P FSM State. */
+	kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer);
+
+	prMsduInfo->u2FrameLength += u2IELen;
+
+}				/* p2pFuncGenerateP2p_IEForBeacon */
+
+#endif
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to calculate P2P IE length for Beacon frame.
+*
+* @param[in] eNetTypeIndex      Specify which network
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return The length of P2P IE added
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32
+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter,
+				     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+
+	if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX)
+		return 0;
+
+	return p2pFuncCalculateP2P_IELen(prAdapter,
+					 eNetTypeIndex,
+					 prStaRec,
+					 txAssocRspAttributesTable,
+					 sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T));
+
+}				/* p2pFuncCalculateP2p_IELenForAssocRsp */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to generate P2P IE for Beacon frame.
+*
+* @param[in] prMsduInfo             Pointer to the composed MSDU_INFO_T.
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+		if (!prStaRec)
+			break;
+
+		if (IS_STA_P2P_TYPE(prStaRec)) {
+			DBGLOG(P2P, TRACE, "Generate NULL P2P IE for Assoc Rsp.\n");
+
+			p2pFuncGenerateP2P_IE(prAdapter,
+					      TRUE,
+					      &prMsduInfo->u2FrameLength,
+					      prMsduInfo->prPacket,
+					      1500,
+					      txAssocRspAttributesTable,
+					      sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T));
+		} else {
+
+			DBGLOG(P2P, TRACE, "Legacy device, no P2P IE.\n");
+		}
+
+	} while (FALSE);
+
+	return;
+
+}				/* p2pFuncGenerateP2p_IEForAssocRsp */
+
+UINT_32
+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter,
+				     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+	DBGLOG(P2P, TRACE, "p2pFuncCalculateWSC_IELenForAssocRsp\n");
+	if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX)
+		return 0;
+
+	return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0);
+}				/* p2pFuncCalculateP2p_IELenForAssocRsp */
+
+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	PUINT_8 pucBuffer;
+	UINT_16 u2IELen = 0;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX)
+		return;
+	DBGLOG(P2P, TRACE, "p2pFuncGenerateWSC_IEForAssocRsp\n");
+
+	u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0);
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+	ASSERT(pucBuffer);
+
+	/* TODO: Check P2P FSM State. */
+	kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer);
+
+	prMsduInfo->u2FrameLength += u2IELen;
+
+}
+
+/* p2pFuncGenerateP2p_IEForAssocRsp */
+
+UINT_32
+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter,
+			  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+			  IN P_STA_RECORD_T prStaRec,
+			  IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize)
+{
+
+	UINT_32 u4OverallAttriLen, u4Dummy;
+	UINT_16 u2EstimatedFixedAttriLen;
+	UINT_32 i;
+
+	/* Overall length of all Attributes */
+	u4OverallAttriLen = 0;
+
+	for (i = 0; i < u4AttriTableSize; i++) {
+		u2EstimatedFixedAttriLen = arAppendAttriTable[i].u2EstimatedFixedAttriLen;
+
+		if (u2EstimatedFixedAttriLen) {
+			u4OverallAttriLen += u2EstimatedFixedAttriLen;
+		} else {
+			ASSERT(arAppendAttriTable[i].pfnCalculateVariableAttriLen);
+
+			u4OverallAttriLen += arAppendAttriTable[i].pfnCalculateVariableAttriLen(prAdapter, prStaRec);
+		}
+	}
+
+	u4Dummy = u4OverallAttriLen;
+	u4OverallAttriLen += P2P_IE_OUI_HDR;
+
+	for (; (u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) {
+		u4OverallAttriLen += P2P_IE_OUI_HDR;
+		u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN;
+	}
+
+	return u4OverallAttriLen;
+}				/* p2pFuncCalculateP2P_IELen */
+
+VOID
+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter,
+		      IN BOOLEAN fgIsAssocFrame,
+		      IN PUINT_16 pu2Offset,
+		      IN PUINT_8 pucBuf,
+		      IN UINT_16 u2BufSize,
+		      IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize)
+{
+	PUINT_8 pucBuffer = (PUINT_8) NULL;
+	P_IE_P2P_T prIeP2P = (P_IE_P2P_T) NULL;
+	UINT_32 u4OverallAttriLen;
+	UINT_32 u4AttriLen;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
+	UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN];
+	UINT_32 i;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL));
+
+		pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset));
+
+		ASSERT_BREAK(pucBuffer != NULL);
+
+		/* Check buffer length is still enough. */
+		ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR);
+
+		prIeP2P = (P_IE_P2P_T) pucBuffer;
+
+		prIeP2P->ucId = ELEM_ID_P2P;
+
+		prIeP2P->aucOui[0] = aucWfaOui[0];
+		prIeP2P->aucOui[1] = aucWfaOui[1];
+		prIeP2P->aucOui[2] = aucWfaOui[2];
+		prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P;
+
+		(*pu2Offset) += P2P_IE_OUI_HDR;
+
+		/* Overall length of all Attributes */
+		u4OverallAttriLen = 0;
+
+		for (i = 0; i < u4AttriTableSize; i++) {
+
+			if (arAppendAttriTable[i].pfnAppendAttri) {
+				u4AttriLen =
+				    arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf,
+									 u2BufSize);
+
+				u4OverallAttriLen += u4AttriLen;
+
+				if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) {
+					u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN;
+
+					prIeP2P->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN);
+
+					pucBuffer =
+					    (PUINT_8) ((ULONG) prIeP2P +
+						       (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN));
+
+					prIeP2P = (P_IE_P2P_T) ((ULONG) prIeP2P +
+								(ELEM_HDR_LEN +
+								 (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)));
+
+					kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen);
+
+					prIeP2P->ucId = ELEM_ID_P2P;
+
+					prIeP2P->aucOui[0] = aucWfaOui[0];
+					prIeP2P->aucOui[1] = aucWfaOui[1];
+					prIeP2P->aucOui[2] = aucWfaOui[2];
+					prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P;
+
+					kalMemCopy(prIeP2P->aucP2PAttributes, aucTempBuffer, u4OverallAttriLen);
+					(*pu2Offset) += P2P_IE_OUI_HDR;
+				}
+
+			}
+
+		}
+
+		prIeP2P->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen);
+
+	} while (FALSE);
+
+}				/* p2pFuncGenerateP2P_IE */
+
+UINT_32
+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter,
+				    IN BOOLEAN fgIsAssocFrame,
+				    IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	PUINT_8 pucBuffer;
+	P_P2P_ATTRI_STATUS_T prAttriStatus;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	UINT_32 u4AttriLen = 0;
+
+	ASSERT(prAdapter);
+	ASSERT(pucBuf);
+
+	prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+	if (fgIsAssocFrame)
+		return u4AttriLen;
+	/* TODO: For assoc request P2P IE check in driver & return status in P2P IE. */
+
+	pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset));
+
+	ASSERT(pucBuffer);
+	prAttriStatus = (P_P2P_ATTRI_STATUS_T) pucBuffer;
+
+	ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen));
+
+	prAttriStatus->ucId = P2P_ATTRI_ID_STATUS;
+	WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS);
+
+	prAttriStatus->ucStatusCode = P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR;
+
+	u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS);
+
+	(*pu2Offset) += (UINT_16) u4AttriLen;
+
+	return u4AttriLen;
+}				/* p2pFuncAppendAttriStatusForAssocRsp */
+
+UINT_32
+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter,
+				  IN BOOLEAN fgIsAssocFrame,
+				  IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	UINT_32 u4AttriLen = 0;
+	P_P2P_ATTRI_EXT_LISTEN_TIMING_T prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	PUINT_8 pucBuffer = NULL;
+
+	ASSERT(prAdapter);
+	ASSERT(pucBuf);
+
+	if (fgIsAssocFrame)
+		return u4AttriLen;
+	/* TODO: For extend listen timing. */
+
+	prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+	u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING);
+
+	ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen));
+
+	pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset));
+
+	ASSERT(pucBuffer);
+
+	prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) pucBuffer;
+
+	prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING;
+	WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING);
+	WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, prP2pSpecificBssInfo->u2AvailabilityInterval);
+	WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, prP2pSpecificBssInfo->u2AvailabilityPeriod);
+
+	(*pu2Offset) += (UINT_16) u4AttriLen;
+
+	return u4AttriLen;
+}				/* p2pFuncAppendAttriExtListenTiming */
+
+P_IE_HDR_T
+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter,
+		 IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore)
+{
+	P_IE_HDR_T prTargetIE = (P_IE_HDR_T) NULL;
+	PUINT_8 pucIE = (PUINT_8) NULL;
+	UINT_16 u2Offset = 0;
+
+	if (pfgIsMore)
+		*pfgIsMore = FALSE;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL)
+			     && (pucIEBuf != NULL));
+
+		pucIE = pucIEBuf;
+
+		IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) {
+			if (IE_ID(pucIE) == ucElemID) {
+				if ((prTargetIE) && (pfgIsMore)) {
+
+					*pfgIsMore = TRUE;
+					break;
+				}
+				prTargetIE = (P_IE_HDR_T) pucIE;
+
+				if (pfgIsMore == NULL)
+					break;
+
+			}
+		}
+
+	} while (FALSE);
+
+	return prTargetIE;
+}				/* p2pFuncGetSpecIE */
+
+P_ATTRIBUTE_HDR_T
+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter,
+		    IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID)
+{
+	P_IE_P2P_T prP2pIE = (P_IE_P2P_T) NULL;
+	P_ATTRIBUTE_HDR_T prTargetAttri = (P_ATTRIBUTE_HDR_T) NULL;
+	BOOLEAN fgIsMore = FALSE;
+	PUINT_8 pucIE = (PUINT_8) NULL, pucAttri = (PUINT_8) NULL;
+	UINT_16 u2OffsetAttri = 0;
+	UINT_16 u2BufferLenLeft = 0;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
+
+	DBGLOG(P2P, INFO, "Check AssocReq Oui type %u attri %u for len %u\n", ucOuiType, u2AttriID, u2BufferLen);
+
+	ASSERT(prAdapter);
+	ASSERT(pucIEBuf);
+
+	u2BufferLenLeft = u2BufferLen;
+	pucIE = pucIEBuf;
+	do {
+		fgIsMore = FALSE;
+		prP2pIE = (P_IE_P2P_T) p2pFuncGetSpecIE(prAdapter,
+						pucIE, u2BufferLenLeft, ELEM_ID_VENDOR, &fgIsMore);
+		if (prP2pIE == NULL)
+			continue;
+
+		ASSERT((ULONG) prP2pIE >= (ULONG) pucIE);
+
+		u2BufferLenLeft = u2BufferLen - (UINT_16) (((ULONG) prP2pIE) - ((ULONG) pucIEBuf));
+
+		DBGLOG(P2P, INFO, "Find vendor id %u len %u oui %u more %u LeftLen %u\n",
+				   IE_ID(prP2pIE), IE_LEN(prP2pIE), prP2pIE->ucOuiType, fgIsMore,
+				   u2BufferLenLeft);
+
+		if ((IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) && (prP2pIE->ucOuiType == ucOuiType)) {
+			switch (ucOuiType) {
+			case VENDOR_OUI_TYPE_WPS:
+				aucWfaOui[0] = 0x00;
+				aucWfaOui[1] = 0x50;
+				aucWfaOui[2] = 0xF2;
+				break;
+			case VENDOR_OUI_TYPE_P2P:
+				break;
+			case VENDOR_OUI_TYPE_WPA:
+			case VENDOR_OUI_TYPE_WMM:
+			case VENDOR_OUI_TYPE_WFD:
+			default:
+				break;
+			}
+
+			if ((prP2pIE->aucOui[0] != aucWfaOui[0])
+				|| (prP2pIE->aucOui[1] != aucWfaOui[1])
+				|| (prP2pIE->aucOui[2] != aucWfaOui[2]))
+				continue;
+
+			u2OffsetAttri = 0;
+			pucAttri = prP2pIE->aucP2PAttributes;
+
+			if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
+				WSC_ATTRI_FOR_EACH(pucAttri,
+					(IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) {
+					/* LOG_FUNC("WSC: attri id=%u len=%u\n",
+					 * WSC_ATTRI_ID(pucAttri),
+					 * WSC_ATTRI_LEN(pucAttri)); */
+					if (WSC_ATTRI_ID(pucAttri) == u2AttriID) {
+						prTargetAttri =
+						    (P_ATTRIBUTE_HDR_T) pucAttri;
+						break;
+					}
+				}
+
+			} else if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
+				P2P_ATTRI_FOR_EACH(pucAttri,
+					(IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) {
+					/* LOG_FUNC("P2P: attri id=%u len=%u\n",
+					 * ATTRI_ID(pucAttri), ATTRI_LEN(pucAttri)); */
+					if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) {
+						prTargetAttri = (P_ATTRIBUTE_HDR_T) pucAttri;
+						break;
+					}
+				}
+			}
+#if CFG_SUPPORT_WFD
+			else if (ucOuiType == VENDOR_OUI_TYPE_WFD) {
+				WFD_ATTRI_FOR_EACH(pucAttri,
+					(IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) {
+					/* DBGLOG(P2P, INFO, ("WFD: attri id=%u
+					 * len=%u\n",WFD_ATTRI_ID(pucAttri),
+					 * WFD_ATTRI_LEN(pucAttri))); */
+					if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) {
+						prTargetAttri =
+						    (P_ATTRIBUTE_HDR_T) pucAttri;
+						break;
+					}
+				}
+			}
+#endif
+			/* Do nothing */
+			/* Possible or else. */
+		}	/* ucOuiType */
+		/* P2P_OUI_TYPE_LEN */
+		pucIE = (PUINT_8) (((ULONG) prP2pIE) + IE_SIZE(prP2pIE));
+		/* prP2pIE */
+	} while (prP2pIE && fgIsMore && u2BufferLenLeft);
+
+	return prTargetAttri;
+}
+
+/* p2pFuncGetSpecAttri */
+
+WLAN_STATUS
+p2pFuncGenerateBeaconProbeRsp(IN P_ADAPTER_T prAdapter,
+			      IN P_BSS_INFO_T prBssInfo, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgIsProbeRsp)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL;
+/* P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = (P_APPEND_VAR_IE_ENTRY_T)NULL; */
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL) && (prMsduInfo != NULL));
+
+/* txBcnIETable */
+
+/* txProbeRspIETable */
+
+		prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket;
+
+		return nicUpdateBeaconIETemplate(prAdapter,
+						 IE_UPD_METHOD_UPDATE_ALL,
+						 NETWORK_TYPE_P2P_INDEX,
+						 prBssInfo->u2CapInfo,
+						 (PUINT_8) prBcnFrame->aucInfoElem,
+						 prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T,
+										       aucInfoElem));
+
+	} while (FALSE);
+
+	return rWlanStatus;
+}				/* p2pFuncGenerateBeaconProbeRsp */
+
+WLAN_STATUS
+p2pFuncComposeBeaconProbeRspTemplate(IN P_ADAPTER_T prAdapter,
+				     IN PUINT_8 pucBcnBuffer,
+				     IN UINT_32 u4BcnBufLen,
+				     IN BOOLEAN fgIsProbeRsp,
+				     IN P_P2P_PROBE_RSP_UPDATE_INFO_T prP2pProbeRspInfo, IN BOOLEAN fgSynToFW)
+{
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL;
+	P_WLAN_MAC_HEADER_T prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	PUINT_8 pucBuffer = (PUINT_8) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBcnBuffer != NULL));
+
+		prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) pucBcnBuffer;
+
+		if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) && (!fgIsProbeRsp)) {
+			rWlanStatus = WLAN_STATUS_INVALID_DATA;
+			break;
+		}
+
+		else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) {
+			rWlanStatus = WLAN_STATUS_INVALID_DATA;
+			break;
+		}
+
+		if (fgIsProbeRsp) {
+			ASSERT_BREAK(prP2pProbeRspInfo != NULL);
+
+			if (prP2pProbeRspInfo->prProbeRspMsduTemplate)
+				cnmMgtPktFree(prAdapter, prP2pProbeRspInfo->prProbeRspMsduTemplate);
+
+			prP2pProbeRspInfo->prProbeRspMsduTemplate = cnmMgtPktAlloc(prAdapter, u4BcnBufLen);
+
+			prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate;
+
+			prMsduInfo->eSrc = TX_PACKET_MGMT;
+			prMsduInfo->ucStaRecIndex = 0xFF;
+			prMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
+
+		} else {
+			prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+			prMsduInfo = prP2pBssInfo->prBeacon;
+
+			if (prMsduInfo == NULL) {
+				rWlanStatus = WLAN_STATUS_FAILURE;
+				break;
+			}
+
+			if (u4BcnBufLen > (OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH)) {
+				/* Unexpected error, buffer overflow. */
+				ASSERT(FALSE);
+				break;
+			}
+
+		}
+
+		pucBuffer = (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+		kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen);
+
+		prMsduInfo->fgIs802_11 = TRUE;
+		prMsduInfo->u2FrameLength = (UINT_16) u4BcnBufLen;
+
+		if (fgSynToFW && prP2pBssInfo)
+			rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, prP2pBssInfo, prMsduInfo, fgIsProbeRsp);
+
+	} while (FALSE);
+
+	return rWlanStatus;
+
+}				/* p2pFuncComposeBeaconTemplate */
+
+#if CFG_SUPPORT_WFD
+WLAN_STATUS wfdAdjustResource(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable)
+{
+#if 1
+	/* The API shall be called in tx_thread */
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable);
+	if (fgEnable) {
+		prQM->au4MinReservedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE;
+		if (QM_GUARANTEED_TC0_RESOURCE > 2) {
+			prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE - 2;
+			prQM->au4GuaranteedTcResource[TC2_INDEX] += 2;
+		}
+		if (QM_GUARANTEED_TC1_RESOURCE > 2) {
+			prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE - 2;
+			prQM->au4GuaranteedTcResource[TC2_INDEX] += 2;
+		}
+	} else {
+		prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE;
+		prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE;
+		prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE;
+		prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE;
+	}
+#endif
+	return WLAN_STATUS_SUCCESS;
+}
+
+WLAN_STATUS wfdAdjustThread(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable)
+{
+#define WFD_TX_THREAD_PRIORITY 70
+	DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable);
+	if (prAdapter->prGlueInfo->main_thread != NULL) {
+		if (fgEnable) {
+#ifdef LINUX
+			/* TODO the change schedule API shall be provided by OS glue layer */
+			/* Or the API shall be put in os glue layer */
+			struct sched_param param = {.sched_priority = WFD_TX_THREAD_PRIORITY };
+
+			sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_RR, &param);
+#endif
+		} else {
+#ifdef LINUX
+			/* TODO the change schedule API shall be provided by OS glue layer */
+			struct sched_param param = {.sched_priority = 0 };
+
+			sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_NORMAL, &param);
+#endif
+		}
+	} else {
+
+		DBGLOG(P2P, WARN, "main_thread is null, please check if the wlanRemove is called in advance\n");
+	}
+	return WLAN_STATUS_SUCCESS;
+}
+
+#endif /* CFG_SUPPORT_WFD  */
+
+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter,
+				IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ENUM_PARAM_MEDIA_STATE_T eConnectionState)
+{
+#if CFG_SUPPORT_WFD
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	if (prAdapter->fgIsP2PRegistered == FALSE)
+		return WLAN_STATUS_SUCCESS;
+	prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
+
+	if ((prWfdCfgSettings->ucWfdEnable) && ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) {
+
+		if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState ==
+		    PARAM_MEDIA_STATE_CONNECTED) {
+			wfdAdjustResource(prAdapter, TRUE);
+			wfdAdjustThread(prAdapter, TRUE);
+		} else {
+			wfdAdjustResource(prAdapter, FALSE);
+			wfdAdjustThread(prAdapter, FALSE);
+		}
+
+	}
+#endif
+	return WLAN_STATUS_SUCCESS;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c
new file mode 100644
index 0000000000000..991861f736082
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c
@@ -0,0 +1,612 @@
+#include "p2p_precomp.h"
+
+#if CFG_SUPPORT_WFD
+#if CFG_SUPPORT_WFD_COMPOSE_IE
+#if 0
+APPEND_VAR_ATTRI_ENTRY_T txProbeRspWFDAttributesTable[] = {
+	{(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo}	/* 0 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid}	/* 1 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo}	/* 6 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_EXT_CAPABILITY), NULL, wfdFuncAppendAttriExtCapability}	/* 7 */
+	, {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo}	/* 9 */
+};
+
+APPEND_VAR_ATTRI_ENTRY_T txBeaconWFDAttributesTable[] = {
+	{(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo}	/* 0 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid}	/* 1 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo}	/* 6 */
+};
+
+APPEND_VAR_ATTRI_ENTRY_T txAssocReqWFDAttributesTable[] = {
+	{(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo}	/* 0 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid}	/* 1 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo}	/* 6 */
+};
+#endif
+
+APPEND_VAR_ATTRI_ENTRY_T txAssocRspWFDAttributesTable[] = {
+	{(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo}	/* 0 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid}	/* 1 */
+	, {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo}	/* 6 */
+	, {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo}	/* 9 */
+
+};
+
+#endif
+
+UINT_32
+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter,
+			   IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL;
+	UINT_32 u4RetValue = 0;
+
+	do {
+		ASSERT_BREAK((eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) && (prAdapter != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo);
+
+		u4RetValue = prConnReqInfo->u4BufLength;
+
+		/* ADD HT Capability */
+		u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP);
+
+		/* ADD WMM Information Element */
+		u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO);
+
+	} while (FALSE);
+
+	return u4RetValue;
+}				/* p2pCalculate_IEForAssocReq */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to generate P2P IE for Beacon frame.
+*
+* @param[in] prMsduInfo             Pointer to the composed MSDU_INFO_T.
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL;
+	PUINT_8 pucIEBuf = (PUINT_8) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
+
+		prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
+
+		prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo);
+
+		pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+		kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, prConnReqInfo->u4BufLength);
+
+		prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength;
+
+		rlmReqGenerateHtCapIE(prAdapter, prMsduInfo);
+		mqmGenerateWmmInfoIE(prAdapter, prMsduInfo);
+
+	} while (FALSE);
+
+	return;
+
+}				/* p2pGenerate_IEForAssocReq */
+
+UINT_32
+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter,
+			  IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	UINT_32 u4AttriLen = 0;
+	PUINT_8 pucBuffer = NULL;
+	P_WFD_DEVICE_INFORMATION_IE_T prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) NULL;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL));
+
+		prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+		ASSERT_BREAK((prWfdCfgSettings != NULL));
+
+		if ((prWfdCfgSettings->ucWfdEnable == 0) ||
+		    ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0)) {
+			break;
+		}
+
+		pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset));
+
+		ASSERT_BREAK(pucBuffer != NULL);
+
+		prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) pucBuffer;
+
+		prWfdDevInfo->ucElemID = WFD_ATTRI_ID_DEV_INFO;
+
+		WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevInfo, prWfdCfgSettings->u2WfdDevInfo);
+
+		WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2SessionMgmtCtrlPort, prWfdCfgSettings->u2WfdControlPort);
+
+		WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevMaxSpeed, prWfdCfgSettings->u2WfdMaximumTp);
+
+		WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2Length, WFD_ATTRI_MAX_LEN_DEV_INFO);
+
+		u4AttriLen = WFD_ATTRI_MAX_LEN_DEV_INFO + WFD_ATTRI_HDR_LEN;
+
+	} while (FALSE);
+
+	(*pu2Offset) += (UINT_16) u4AttriLen;
+
+	return u4AttriLen;
+}
+
+/* wfdFuncAppendAttriDevInfo */
+
+UINT_32
+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter,
+			     IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	UINT_32 u4AttriLen = 0;
+	PUINT_8 pucBuffer = NULL;
+	P_WFD_ASSOCIATED_BSSID_IE_T prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) NULL;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+	P_BSS_INFO_T prAisBssInfo = (P_BSS_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL));
+
+		prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+		ASSERT_BREAK((prWfdCfgSettings != NULL));
+
+		if (prWfdCfgSettings->ucWfdEnable == 0)
+			break;
+
+		/* AIS network. */
+		prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+		if ((!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) ||
+		    (prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED)) {
+			break;
+		}
+
+		pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset));
+
+		ASSERT_BREAK(pucBuffer != NULL);
+
+		prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) pucBuffer;
+
+		prWfdAssocBssid->ucElemID = WFD_ATTRI_ID_ASSOC_BSSID;
+
+		WLAN_SET_FIELD_BE16(&prWfdAssocBssid->u2Length, WFD_ATTRI_MAX_LEN_ASSOC_BSSID);
+
+		COPY_MAC_ADDR(prWfdAssocBssid->aucAssocBssid, prAisBssInfo->aucBSSID);
+
+		u4AttriLen = WFD_ATTRI_MAX_LEN_ASSOC_BSSID + WFD_ATTRI_HDR_LEN;
+
+	} while (FALSE);
+
+	(*pu2Offset) += (UINT_16) u4AttriLen;
+
+	return u4AttriLen;
+}
+
+/* wfdFuncAppendAttriAssocBssid */
+
+UINT_32
+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter,
+				  IN BOOLEAN fgIsAssocFrame,
+				  IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	UINT_32 u4AttriLen = 0;
+	PUINT_8 pucBuffer = NULL;
+	P_WFD_COUPLE_SINK_INFORMATION_IE_T prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) NULL;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL));
+
+		prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+		ASSERT_BREAK((prWfdCfgSettings != NULL));
+
+		if ((prWfdCfgSettings->ucWfdEnable == 0) ||
+		    ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_SINK_INFO_VALID) == 0)) {
+			break;
+		}
+
+		pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset));
+
+		ASSERT_BREAK(pucBuffer != NULL);
+
+		prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) pucBuffer;
+
+		prWfdCoupleSinkInfo->ucElemID = WFD_ATTRI_ID_COUPLED_SINK_INFO;
+
+		WLAN_SET_FIELD_BE16(&prWfdCoupleSinkInfo->u2Length, WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO);
+
+		COPY_MAC_ADDR(prWfdCoupleSinkInfo->aucCoupleSinkMac, prWfdCfgSettings->aucWfdCoupleSinkAddress);
+
+		prWfdCoupleSinkInfo->ucCoupleSinkStatusBp = prWfdCfgSettings->ucWfdCoupleSinkStatus;
+
+		u4AttriLen = WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO + WFD_ATTRI_HDR_LEN;
+
+	} while (FALSE);
+
+	(*pu2Offset) += (UINT_16) u4AttriLen;
+
+	return u4AttriLen;
+}
+
+/* wfdFuncAppendAttriCoupledSinkInfo */
+
+UINT_32
+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter,
+				IN BOOLEAN fgIsAssocFrame,
+				IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	UINT_32 u4AttriLen = 0;
+	PUINT_8 pucBuffer = NULL;
+	P_WFD_EXTENDED_CAPABILITY_IE_T prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) NULL;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL));
+
+		prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+		ASSERT_BREAK((prWfdCfgSettings != NULL));
+
+		if ((prWfdCfgSettings->ucWfdEnable == 0) ||
+		    ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_EXT_CAPABILITY_VALID) == 0)) {
+			break;
+		}
+
+		pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset));
+
+		ASSERT_BREAK(pucBuffer != NULL);
+
+		prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) pucBuffer;
+
+		prWfdExtCapability->ucElemID = WFD_ATTRI_ID_EXT_CAPABILITY;
+
+		WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2Length, WFD_ATTRI_MAX_LEN_EXT_CAPABILITY);
+
+		WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2WfdExtCapabilityBp, prWfdCfgSettings->u2WfdExtendCap);
+
+		u4AttriLen = WFD_ATTRI_MAX_LEN_EXT_CAPABILITY + WFD_ATTRI_HDR_LEN;
+
+	} while (FALSE);
+
+	(*pu2Offset) += (UINT_16) u4AttriLen;
+
+	return u4AttriLen;
+}
+
+/* wfdFuncAppendAttriExtCapability */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to calculate length of Channel List Attribute
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return The length of Attribute added
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	UINT_16 u2AttriLen = 0;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL));
+
+		prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+		if (prWfdCfgSettings->ucWfdEnable == 0)
+			break;
+
+		u2AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN;
+
+	} while (FALSE);
+
+	return (UINT_32) u2AttriLen;
+
+}				/* wfdFuncCalculateAttriLenSessionInfo */
+
+UINT_32
+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter,
+			      IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize)
+{
+	UINT_32 u4AttriLen = 0;
+	PUINT_8 pucBuffer = NULL;
+	P_WFD_SESSION_INFORMATION_IE_T prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) NULL;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL));
+
+		prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+		ASSERT_BREAK((prWfdCfgSettings != NULL));
+
+		if ((prWfdCfgSettings->ucWfdEnable == 0) || (prWfdCfgSettings->u2WfdSessionInformationIELen == 0))
+			break;
+
+		pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset));
+
+		ASSERT_BREAK(pucBuffer != NULL);
+
+		prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) pucBuffer;
+
+		prWfdSessionInfo->ucElemID = WFD_ATTRI_ID_SESSION_INFO;
+
+		/* TODO: Check endian issue? */
+		kalMemCopy(prWfdSessionInfo->pucWfdDevInfoDesc, prWfdCfgSettings->aucWfdSessionInformationIE,
+			   prWfdCfgSettings->u2WfdSessionInformationIELen);
+
+		WLAN_SET_FIELD_16(&prWfdSessionInfo->u2Length, prWfdCfgSettings->u2WfdSessionInformationIELen);
+
+		u4AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN;
+
+	} while (FALSE);
+
+	(*pu2Offset) += (UINT_16) u4AttriLen;
+
+	return u4AttriLen;
+}
+
+/* wfdFuncAppendAttriSessionInfo */
+
+#if CFG_SUPPORT_WFD_COMPOSE_IE
+VOID
+wfdFuncGenerateWfd_IE(IN P_ADAPTER_T prAdapter,
+		      IN BOOLEAN fgIsAssocFrame,
+		      IN PUINT_16 pu2Offset,
+		      IN PUINT_8 pucBuf,
+		      IN UINT_16 u2BufSize,
+		      IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize)
+{
+
+	PUINT_8 pucBuffer = (PUINT_8) NULL;
+	P_IE_WFD_T prIeWFD = (P_IE_WFD_T) NULL;
+	UINT_32 u4OverallAttriLen;
+	UINT_32 u4AttriLen;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
+	UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN];
+	UINT_32 i;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL));
+
+		pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset));
+
+		ASSERT_BREAK(pucBuffer != NULL);
+
+		/* Check buffer length is still enough. */
+		ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= WFD_IE_OUI_HDR);
+
+		prIeWFD = (P_IE_WFD_T) pucBuffer;
+
+		prIeWFD->ucId = ELEM_ID_WFD;
+
+		prIeWFD->aucOui[0] = aucWfaOui[0];
+		prIeWFD->aucOui[1] = aucWfaOui[1];
+		prIeWFD->aucOui[2] = aucWfaOui[2];
+		prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD;
+
+		(*pu2Offset) += WFD_IE_OUI_HDR;
+
+		/* Overall length of all Attributes */
+		u4OverallAttriLen = 0;
+
+		for (i = 0; i < u4AttriTableSize; i++) {
+
+			if (arAppendAttriTable[i].pfnAppendAttri) {
+				u4AttriLen =
+				    arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf,
+									 u2BufSize);
+
+				u4OverallAttriLen += u4AttriLen;
+
+				if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) {
+					u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN;
+
+					prIeWFD->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN);
+
+					pucBuffer =
+					    (PUINT_8) ((ULONG) prIeWFD + (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN));
+
+					prIeWFD =
+					    (P_IE_WFD_T) ((ULONG) prIeWFD +
+							  (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN));
+
+					kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen);
+
+					prIeWFD->ucId = ELEM_ID_WFD;
+
+					prIeWFD->aucOui[0] = aucWfaOui[0];
+					prIeWFD->aucOui[1] = aucWfaOui[1];
+					prIeWFD->aucOui[2] = aucWfaOui[2];
+					prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD;
+
+					kalMemCopy(prIeWFD->aucWFDAttributes, aucTempBuffer, u4OverallAttriLen);
+					(*pu2Offset) += WFD_IE_OUI_HDR;
+				}
+
+			}
+
+		}
+
+		prIeWFD->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen);
+
+	} while (FALSE);
+
+}				/* wfdFuncGenerateWfd_IE */
+
+#endif /* CFG_SUPPORT_WFD_COMPOSE_IE */
+
+UINT_32
+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter,
+				    IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec)
+{
+
+#if CFG_SUPPORT_WFD_COMPOSE_IE
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+	if (!IS_STA_P2P_TYPE(prStaRec) || (prWfdCfgSettings->ucWfdEnable == 0))
+		return 0;
+
+	return p2pFuncCalculateP2P_IELen(prAdapter,
+					 eNetTypeIndex,
+					 prStaRec,
+					 txAssocRspWFDAttributesTable,
+					 sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T));
+
+#else
+	return 0;
+#endif
+}				/* wfdFuncCalculateWfdIELenForAssocRsp */
+
+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+
+#if CFG_SUPPORT_WFD_COMPOSE_IE
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+	P_STA_RECORD_T prStaRec;
+
+	do {
+		ASSERT_BREAK((prMsduInfo != NULL) && (prAdapter != NULL));
+
+		prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+		if (!prStaRec) {
+			ASSERT(FALSE);
+		} else if (IS_STA_P2P_TYPE(prStaRec)) {
+
+			if (prWfdCfgSettings->ucWfdEnable == 0)
+				break;
+			if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0)
+				break;
+
+			wfdFuncGenerateWfd_IE(prAdapter,
+					      FALSE,
+					      &prMsduInfo->u2FrameLength,
+					      prMsduInfo->prPacket,
+					      1500,
+					      txAssocRspWFDAttributesTable,
+					      sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T));
+		}
+	} while (FALSE);
+
+	return;
+#else
+
+	return;
+#endif
+}				/* wfdFuncGenerateWfdIEForAssocRsp */
+
+VOID p2pFuncComposeNoaAttribute(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+
+	P_IE_P2P_T prIeP2P;
+	P_P2P_ATTRI_NOA_T prNoaAttr = NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL;
+	P_NOA_DESCRIPTOR_T prNoaDesc = NULL;
+
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
+	UINT_32 u4AttributeLen;
+	UINT_32 u4NumOfNoaDesc = 0;
+	UINT_32 i = 0;
+	/*P2P IE format */
+	prIeP2P = (P_IE_P2P_T) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+	prIeP2P->ucId = ELEM_ID_P2P;
+	prIeP2P->aucOui[0] = aucWfaOui[0];
+	prIeP2P->aucOui[1] = aucWfaOui[1];
+	prIeP2P->aucOui[2] = aucWfaOui[2];
+	prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P;
+
+	prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+	/*P2P Attribute--NoA */
+	prNoaAttr = (P_P2P_ATTRI_NOA_T) prIeP2P->aucP2PAttributes;
+
+	prNoaAttr->ucId = P2P_ATTRI_ID_NOTICE_OF_ABSENCE;
+	prNoaAttr->ucIndex = prP2pSpecificBssInfo->ucNoAIndex;
+	 /*OPP*/ if (prP2pSpecificBssInfo->fgEnableOppPS) {
+		prNoaAttr->ucCTWOppPSParam = P2P_CTW_OPPPS_PARAM_OPPPS_FIELD |
+		    (prP2pSpecificBssInfo->u2CTWindow & P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK);
+	} else {
+		prNoaAttr->ucCTWOppPSParam = 0;
+	}
+	/*NoA Description */
+	DBGLOG(P2P, INFO, "Compose NoA count=%d.\n", prP2pSpecificBssInfo->ucNoATimingCount);
+	for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) {
+		if (prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse) {
+
+			prNoaDesc = (P_NOA_DESCRIPTOR_T) &prNoaAttr->aucNoADesc[u4NumOfNoaDesc];
+
+			prNoaDesc->ucCountType = prP2pSpecificBssInfo->arNoATiming[i].ucCount;
+			prNoaDesc->u4Duration = prP2pSpecificBssInfo->arNoATiming[i].u4Duration;
+			prNoaDesc->u4Interval = prP2pSpecificBssInfo->arNoATiming[i].u4Interval;
+			prNoaDesc->u4StartTime = prP2pSpecificBssInfo->arNoATiming[i].u4StartTime;
+
+			u4NumOfNoaDesc++;
+		}
+	}
+
+	/* include "index" + "OppPs Params" + "NOA descriptors" */
+	prNoaAttr->u2Length = 2 + u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T);
+	u4NumOfNoaDesc++;
+
+	/* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */
+	u4AttributeLen = P2P_ATTRI_HDR_LEN + prNoaAttr->u2Length;
+
+	prIeP2P->ucLength = VENDOR_OUI_TYPE_LEN + u4AttributeLen;
+	prMsduInfo->u2FrameLength += (ELEM_HDR_LEN + prIeP2P->ucLength);
+
+}
+
+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec)
+{
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL;
+	UINT_8 ucIdx;
+	UINT_32 u4NumOfNoaDesc = 0;
+
+	if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo))
+		return 0;
+
+	prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+	for (ucIdx = 0; ucIdx < prP2pSpecificBssInfo->ucNoATimingCount; ucIdx++) {
+		if (prP2pSpecificBssInfo->arNoATiming[ucIdx].fgIsInUse)
+			u4NumOfNoaDesc++;
+	}
+
+	/* include "index" + "OppPs Params" + "NOA descriptors" */
+	/* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */
+
+	return P2P_ATTRI_LEN_NOTICE_OF_ABSENCE + (u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T));
+}
+
+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) {	/* Hotspot */
+		return;
+	}
+
+	/* Compose NoA attribute */
+	p2pFuncComposeNoaAttribute(prAdapter,
+				   prMsduInfo /*prMsduInfo->ucBssIndex, prIeP2P->aucP2PAttributes, &u4AttributeLen */);
+
+}
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c
new file mode 100644
index 0000000000000..f25df82d9ca76
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c
@@ -0,0 +1,905 @@
+/*
+** Id: @(#) p2p_rlm.c@@
+*/
+
+/*! \file   "p2p_rlm.c"
+    \brief
+
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief  Init AP Bss
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	ENUM_BAND_T eBand;
+	UINT_8 ucChannel;
+	ENUM_CHNL_EXT_T eSCO;
+
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+
+	if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT)
+		return;
+
+	/* Operation band, channel shall be ready before invoking this function.
+	 * Bandwidth may be ready if other network is connected
+	 */
+	prBssInfo->fg40mBwAllowed = FALSE;
+	prBssInfo->fgAssoc40mBwAllowed = FALSE;
+	prBssInfo->eBssSCO = CHNL_EXT_SCN;
+
+	if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) {
+		/* In this case, the first BSS's SCO is 40MHz and known, so AP can
+		 * apply 40MHz bandwidth, but the first BSS's SCO may be changed
+		 * later if its Beacon lost timeout occurs
+		 */
+		if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) &&
+		    eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) {
+			prBssInfo->eBssSCO = eSCO;
+		} else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) {
+			prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo);
+		}
+
+		if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
+			prBssInfo->fg40mBwAllowed = TRUE;
+			prBssInfo->fgAssoc40mBwAllowed = TRUE;
+
+			prBssInfo->ucHtOpInfo1 = (UINT_8)
+			    (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
+
+			rlmUpdateBwByChListForAP(prAdapter, prBssInfo);
+		}
+	}
+
+	DBGLOG(RLM, INFO, "WLAN AP SCO=%d\n", prBssInfo->eBssSCO);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief For probe response (GO, IBSS) and association response
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_IE_OBSS_SCAN_PARAM_T prObssScanIe;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+	ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
+	ASSERT(prBssInfo);
+
+	if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) &&
+	    prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT &&
+	    (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) &&
+	    prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) {
+
+		prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T)
+		    (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+
+		/* Add 20/40 BSS coexistence IE */
+		prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS;
+		prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN;
+
+		prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell;
+		prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell;
+		prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval;
+		prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel;
+		prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel;
+		prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor;
+		prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold;
+
+		ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN));
+
+		prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P GO.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	UINT_8 ucLevel;
+	BOOLEAN fgBwChange;
+
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+
+	fgBwChange = FALSE;
+
+	if (prBssInfo->eBssSCO == CHNL_EXT_SCN)
+		return fgBwChange;
+
+	ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO);
+
+	if (ucLevel == CHNL_LEVEL0) {
+		/* Forced to 20MHz, so extended channel is SCN and STA width is zero */
+		prBssInfo->fgObssActionForcedTo20M = TRUE;
+
+		if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) {
+			prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
+			fgBwChange = TRUE;
+		}
+
+		cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC);
+	}
+
+	/* Clear up all channel lists */
+	prBssInfo->auc2G_20mReqChnlList[0] = 0;
+	prBssInfo->auc2G_NonHtChnlList[0] = 0;
+	prBssInfo->auc2G_PriChnlList[0] = 0;
+	prBssInfo->auc2G_SecChnlList[0] = 0;
+	prBssInfo->auc5G_20mReqChnlList[0] = 0;
+	prBssInfo->auc5G_NonHtChnlList[0] = 0;
+	prBssInfo->auc5G_PriChnlList[0] = 0;
+	prBssInfo->auc5G_SecChnlList[0] = 0;
+
+	return fgBwChange;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
+{
+	P_ACTION_20_40_COEXIST_FRAME prRxFrame;
+	P_IE_20_40_COEXIST_T prCoexist;
+	P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport;
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+	PUINT_8 pucIE;
+	UINT_16 u2IELength, u2Offset;
+	UINT_8 i, j;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader;
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+	if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST ||
+	    !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
+	    prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) ||
+	    HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != NETWORK_TYPE_P2P_INDEX) {
+		return;
+	}
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
+	ASSERT(prBssInfo);
+
+	if (!IS_BSS_ACTIVE(prBssInfo) ||
+	    prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) {
+		return;
+	}
+
+	prCoexist = &prRxFrame->rBssCoexist;
+	if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) {
+		ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
+		for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+			if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel)
+				break;
+		}
+		if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
+			prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel;
+			prBssInfo->auc2G_20mReqChnlList[0]++;
+		}
+	}
+
+	/* Process intolerant channel report IE */
+	pucIE = (PUINT_8) &prRxFrame->rChnlReport;
+	u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5);
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT:
+			prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE;
+
+			if (prChnlReport->ucLength <= 1)
+				break;
+
+			/* To do: process regulatory class. Now we assume 2.4G band */
+
+			for (j = 0; j < prChnlReport->ucLength - 1; j++) {
+				/* Update non-HT channel list */
+				ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
+				for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+					if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j])
+						break;
+				}
+				if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
+					prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j];
+					prBssInfo->auc2G_NonHtChnlList[0]++;
+				}
+			}
+			break;
+
+		default:
+			break;
+		}
+	}			/* end of IE_FOR_EACH */
+
+	if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) {
+		bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
+		rlmSyncOperationParams(prAdapter, prBssInfo);
+	}
+
+	/* Check if OBSS scan exemption response should be sent */
+	if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ)
+		rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
+{
+	P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader;
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+	if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH ||
+	    !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
+	    prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) {
+		return;
+	}
+
+	/* To do: depending regulation class 13 and 14 based on spec
+	 * Note: (ucChannelWidth==1) shall restored back to original capability,
+	 *       not current setting to 40MHz BW here
+	 */
+	if (prRxFrame->ucChannelWidth == 0)
+		prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
+	else if (prRxFrame->ucChannelWidth == 1)
+		prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+	cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prObssStatus);
+	ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex];
+	ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT);
+
+	prBssInfo->fgObssErpProtectMode = (BOOLEAN) prObssStatus->ucObssErpProtectMode;
+	prBssInfo->eObssHtProtectMode = (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode;
+	prBssInfo->eObssGfOperationMode = (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode;
+	prBssInfo->fgObssRifsOperationMode = (BOOLEAN) prObssStatus->ucObssRifsOperationMode;
+	prBssInfo->fgObssBeaconForcedTo20M = (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M;
+
+	/* Check if Beacon content need to be updated */
+	rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon)
+{
+	P_LINK_T prStaList;
+	P_STA_RECORD_T prStaRec;
+	BOOLEAN fgErpProtectMode, fgSta40mIntolerant;
+	BOOLEAN fgUseShortPreamble, fgUseShortSlotTime;
+	ENUM_HT_PROTECT_MODE_T eHtProtectMode;
+	ENUM_GF_MODE_T eGfOperationMode;
+	UINT_8 ucHtOpInfo1;
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+	P_GLUE_INFO_T prGlueInfo;
+#endif
+
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+
+	if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT)
+		return;
+
+	fgErpProtectMode = FALSE;
+	eHtProtectMode = HT_PROTECT_MODE_NONE;
+	eGfOperationMode = GF_MODE_NORMAL;
+	fgSta40mIntolerant = FALSE;
+	fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
+	fgUseShortSlotTime = TRUE;
+	ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
+
+	prStaList = &prBssInfo->rStaRecOfClientList;
+
+	LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) {
+		/* ASSERT(prStaRec); */
+		if (!prStaRec) {
+			DBGLOG(P2P, TRACE, "prStaRec is NULL in rlmUpdateParamsForAP()\n");
+			break;
+		}
+		if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 &&
+		    prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) {
+			if (!(prStaRec->ucPhyTypeSet & (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) {
+				/* B-only mode, so mode 1 (ERP protection) */
+				fgErpProtectMode = TRUE;
+			}
+
+			if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
+				/* BG-only or A-only */
+				eHtProtectMode = HT_PROTECT_MODE_NON_HT;
+			} else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) {
+				/* 20MHz-only */
+				/*
+				   The HT Protection field may be set to 20 MHz protection
+				   mode only if the following are true:
+				   \A1X All STAs detected (by any means) in the primary channel
+				   and all STAs detected (by any means) in      the secondary
+				   channel are HT STAs and all STAs that are members of
+				   this BSS are HT STAs, and
+				   \A1X This BSS is a 20/40 MHz BSS, and
+				   \A1X There is at least one 20 MHz HT STA associated with this BSS.
+				 */
+				if (eHtProtectMode == HT_PROTECT_MODE_NONE && prBssInfo->fgAssoc40mBwAllowed)
+					eHtProtectMode = HT_PROTECT_MODE_20M;
+			}
+
+			if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF))
+				eGfOperationMode = GF_MODE_PROTECT;
+
+			if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE))
+				fgUseShortPreamble = FALSE;
+
+			if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))
+				fgUseShortSlotTime = FALSE;
+
+			if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT)
+				fgSta40mIntolerant = TRUE;
+		}
+	}			/* end of LINK_FOR_EACH_ENTRY */
+
+	/* Check if HT operation IE about 20/40M bandwidth shall be updated */
+	if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
+		if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant &&
+		    !prBssInfo->fgObssActionForcedTo20M && !prBssInfo->fgObssBeaconForcedTo20M) {
+
+			ucHtOpInfo1 = (UINT_8)
+			    (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
+		}
+	}
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+	prGlueInfo = prAdapter->prGlueInfo;
+	if (prGlueInfo->prP2PInfo->u4PsLevel & BITS(8, 15))
+		fgErpProtectMode = TRUE;
+#endif
+
+	/* Check if any new parameter may be updated */
+	if (prBssInfo->fgErpProtectMode != fgErpProtectMode ||
+	    prBssInfo->eHtProtectMode != eHtProtectMode ||
+	    prBssInfo->eGfOperationMode != eGfOperationMode ||
+	    prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 ||
+	    prBssInfo->fgUseShortPreamble != fgUseShortPreamble ||
+	    prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) {
+
+		prBssInfo->fgErpProtectMode = fgErpProtectMode;
+		prBssInfo->eHtProtectMode = eHtProtectMode;
+		prBssInfo->eGfOperationMode = eGfOperationMode;
+		prBssInfo->ucHtOpInfo1 = ucHtOpInfo1;
+		prBssInfo->fgUseShortPreamble = fgUseShortPreamble;
+		prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime;
+
+		if (fgUseShortSlotTime)
+			prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
+		else
+			prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME;
+
+		rlmSyncOperationParams(prAdapter, prBssInfo);
+		fgUpdateBeacon = TRUE;
+	}
+
+	/* Update Beacon content if related IE content is changed */
+	if (fgUpdateBeacon)
+		bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    Initial the channel list from the domain information.
+*                 This function is called after P2P initial and Domain information changed.
+*                 Make sure the device is disconnected while changing domain information.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return boolean value if probe response frame is
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter)
+{
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY) NULL;
+	P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO) NULL;
+	P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL;
+	UINT_32 u4Idx = 0, u4IdxII = 0;
+	UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE;
+#if 0
+	UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0;
+#endif
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
+#if 0
+		ucAutoChnl = prP2pConnSetting->ucOperatingChnl;
+#endif
+
+		prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter);
+
+		ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL));
+
+		prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
+
+		for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) {
+			prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx];
+
+			if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) ||
+			    (prDomainSubBand->ucBand == BAND_NULL)) {
+				continue;
+			}
+
+			if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) {
+				/* Buffer is not enough to include all supported channels. */
+				break;	/* for */
+			}
+
+			prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass;
+			prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels;
+
+			for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) {
+				prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum +
+				    (u4IdxII * prDomainSubBand->ucChannelSpan);
+
+#if 0
+				switch (prChannelEntryField->aucChannelList[u4IdxII]) {
+				case 1:
+					ucSocialChnlSupport = 1;
+					break;
+				case 6:
+					ucSocialChnlSupport = 6;
+					break;
+				case 11:
+					ucSocialChnlSupport = 11;
+					break;
+				default:
+					break;
+				}
+
+#endif
+			}
+
+			if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels))
+				ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
+			else
+				break;
+
+			prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField +
+									 P2P_ATTRI_LEN_CHANNEL_ENTRY +
+									 (ULONG)
+									 prChannelEntryField->ucNumberOfChannels);
+
+		}
+
+#if 0
+		if (prP2pConnSetting->ucListenChnl == 0) {
+			prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL;
+
+			if (ucSocialChnlSupport != 0) {
+				/* 1. User Not Set LISTEN channel.
+				 * 2. Social channel is not empty.
+				 */
+				prP2pConnSetting->ucListenChnl = ucSocialChnlSupport;
+			}
+		}
+#endif
+
+		/* TODO: 20110921 frog - */
+		/* If LISTEN channel is not set,
+		 * a random supported channel would be set.
+		 * If no social channel is supported, DEFAULT channel would be set.
+		 */
+
+		prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize;
+
+#if 0
+		if (prP2pConnSetting->ucOperatingChnl == 0) {	/* User not set OPERATE channel. */
+
+			if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl))
+				break;	/* while */
+
+			ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
+
+			prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
+
+			while (ucBufferSize != 0) {
+				if (prChannelEntryField->ucNumberOfChannels != 0) {
+					ucAutoChnl = prChannelEntryField->aucChannelList[0];
+					break;	/* while */
+				}
+
+				else {
+					prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((UINT_32) prChannelEntryField +
+								P2P_ATTRI_LEN_CHANNEL_ENTRY +
+								(UINT_32)prChannelEntryField->ucNumberOfChannels);
+
+					ucBufferSize -=
+					    (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
+				}
+
+			}
+
+		}
+#endif
+		/* We assume user would not set a channel not in the channel list.
+		 * If so, the operating channel still depends on target device supporting capability.
+		 */
+
+		/* TODO: 20110921 frog - */
+		/* If the Operating channel is not set, a channel from supported channel list is set automatically.
+		 * If there is no supported channel in channel list, a DEFAULT channel is set.
+		 */
+
+	} while (FALSE);
+
+#if 0
+	prP2pConnSetting->ucOperatingChnl = ucAutoChnl;
+#endif
+
+}				/* rlmFuncInitialChannelList */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    Find a common channel list from the local channel list info & target channel list info.
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return boolean value if probe response frame is
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter,
+			 IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize)
+{
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) NULL, prChannelEntryIII =
+	    (P_CHANNEL_ENTRY_FIELD_T) NULL;
+	UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE] = {0};
+	UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0;
+
+	do {
+
+		ASSERT_BREAK(prAdapter != NULL);
+
+		prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
+
+		prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) aucCommonChannelList;
+
+		while (ucChannelListSize > 0) {
+
+			prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
+			ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize;
+
+			while (ucOriChnlSize > 0) {
+				if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) {
+					prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass;
+					/* TODO: Currently we assume that the regulatory class the same,
+					 * the channels are the same. */
+					kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList,
+						   prChannelEntryII->ucNumberOfChannels);
+					prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels;
+
+					ucNewChnlSize +=
+					    P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels;
+
+					prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryIII +
+								P2P_ATTRI_LEN_CHANNEL_ENTRY +
+								(ULONG)prChannelEntryIII->ucNumberOfChannels);
+				}
+
+				ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels);
+
+				prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryI +
+									     P2P_ATTRI_LEN_CHANNEL_ENTRY +
+									     (ULONG)
+									     prChannelEntryI->ucNumberOfChannels);
+
+			}
+
+			ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels);
+
+			prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryII +
+								      P2P_ATTRI_LEN_CHANNEL_ENTRY +
+								      (ULONG) prChannelEntryII->ucNumberOfChannels);
+
+		}
+
+		kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize);
+		prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize;
+
+	} while (FALSE);
+
+}				/* rlmFuncCommonChannelList */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum)
+{
+	UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL;
+	UINT_32 u4Idx = 0;
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
+		ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
+		prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
+
+		while (ucBufferSize != 0) {
+
+			for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) {
+				if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) {
+					ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass;
+					break;
+				}
+
+			}
+
+			if (ucRegulatoryClass != 0)
+				break;	/* while */
+
+			prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField +
+						P2P_ATTRI_LEN_CHANNEL_ENTRY +
+						(ULONG)prChannelEntryField->ucNumberOfChannels);
+
+			ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
+
+		}
+
+	} while (FALSE);
+
+	return ucRegulatoryClass;
+}				/* rlmFuncFindOperatingClass */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter,
+			    IN UINT_8 ucCheckChnl,
+			    IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel)
+{
+	BOOLEAN fgIsResultAvailable = FALSE;
+	P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0;
+
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		if (fgIsDefaultChannel)
+			ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL;
+
+		prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
+		ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
+		prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
+
+		while ((ucBufferSize != 0) && (!fgIsResultAvailable)) {
+
+			for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) {
+				if ((!fgIsSocialChannel) ||
+				    (prChannelEntry->aucChannelList[ucIdx] == 1) ||
+				    (prChannelEntry->aucChannelList[ucIdx] == 6) ||
+				    (prChannelEntry->aucChannelList[ucIdx] == 11)) {
+
+					if (prChannelEntry->aucChannelList[ucIdx] <= 11) {
+						/* 2.4G. */
+						ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
+					} else if ((prChannelEntry->aucChannelList[ucIdx] < 52) &&
+						   (prChannelEntry->aucChannelList[ucIdx] > 14)) {
+						/* 2.4G + 5G. */
+						ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
+					}
+
+					if (ucChannelSelected == ucCheckChnl) {
+						fgIsResultAvailable = TRUE;
+						break;
+					}
+				}
+
+			}
+
+			ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels);
+
+			prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntry +
+								    P2P_ATTRI_LEN_CHANNEL_ENTRY +
+								    (ULONG) prChannelEntry->ucNumberOfChannels);
+
+		}
+
+		if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) {
+			DBGLOG(P2P, TRACE,
+			       "The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl,
+				ucChannelSelected);
+			/* Given a suggested channel. */
+			*pucSuggestChannel = ucChannelSelected;
+		}
+
+	} while (FALSE);
+
+	return fgIsResultAvailable;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	P_DOMAIN_SUBBAND_INFO prSubband;
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+	UINT_8 ucSecondChannel, i, j;
+	ENUM_CHNL_EXT_T eSCO;
+
+	eSCO = CHNL_EXT_SCN;
+
+	if (prBssInfo->eBand == BAND_2G4) {
+		if (prBssInfo->ucPrimaryChannel != 14)
+			eSCO = (prBssInfo->ucPrimaryChannel > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA;
+	} else {
+		prDomainInfo = rlmDomainGetDomainInfo(prAdapter);
+		ASSERT(prDomainInfo);
+
+		for (i = 0; i < MAX_SUBBAND_NUM; i++) {
+			prSubband = &prDomainInfo->rSubBand[i];
+			if (prSubband->ucBand == prBssInfo->eBand) {
+				for (j = 0; j < prSubband->ucNumChannels; j++) {
+					if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan)
+					    == prBssInfo->ucPrimaryChannel) {
+						eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA;
+						break;
+					}
+				}
+
+				if (j < prSubband->ucNumChannels)
+					break;	/* Found */
+			}
+		}
+	}
+
+	/* Check if it is boundary channel and 40MHz BW is permitted */
+	if (eSCO != CHNL_EXT_SCN) {
+		ucSecondChannel = (eSCO == CHNL_EXT_SCA) ?
+		    (prBssInfo->ucPrimaryChannel + 4) : (prBssInfo->ucPrimaryChannel - 4);
+
+		if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel))
+			eSCO = CHNL_EXT_SCN;
+	}
+
+	return eSCO;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c
new file mode 100644
index 0000000000000..154f1e5db0f73
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c
@@ -0,0 +1,313 @@
+/*
+** Id: @(#) gl_p2p_cfg80211.c@@
+*/
+
+/*! \file   gl_p2p_cfg80211.c
+    \brief  Main routines of Linux driver interface for Wi-Fi Direct
+	    using cfg80211 interface
+
+    This file contains the main routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend);
+
+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend);
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Different concurrent network has itself channel lists, and
+*        concurrent networks should have been recorded in channel lists.
+*        If role of active P2P is GO, assume associated AP of AIS will
+*        record our Beacon for P2P GO because of same channel.
+*
+*        Note: If we have scenario of different channel in the future,
+*              the internal FW communication channel shall be established.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend)
+{
+	UINT_8 ucChannelLevel;
+
+	ASSERT(prBssInfo);
+
+	if (eBand == BAND_2G4) {
+		ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend);
+
+		/* (TBD) If concurrent networks permit different channel, extra
+		 *       channel judgement should be added. Please refer to
+		 *       previous version of this file.
+		 */
+	} else if (eBand == BAND_5G) {
+		ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend);
+
+		/* (TBD) If concurrent networks permit different channel, extra
+		 *       channel judgement should be added. Please refer to
+		 *       previous version of this file.
+		 */
+	} else {
+		ucChannelLevel = CHNL_LEVEL0;
+	}
+
+	return ucChannelLevel;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend)
+{
+	UINT_8 i, ucChannelLevel;
+	UINT_8 ucSecChannel, ucCenterChannel;
+	UINT_8 ucAffectedChnl_L, ucAffectedChnl_H;
+
+	ASSERT(prBssInfo);
+
+	ucChannelLevel = CHNL_LEVEL2;
+
+	/* Calculate center channel for 2.4G band */
+	if (eExtend == CHNL_EXT_SCA) {
+		ucCenterChannel = ucPriChannel + 2;
+		ucSecChannel = ucPriChannel + 4;
+	} else if (eExtend == CHNL_EXT_SCB) {
+		ucCenterChannel = ucPriChannel - 2;
+		ucSecChannel = ucPriChannel - 4;
+	} else {
+		return CHNL_LEVEL0;
+	}
+	ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14);
+
+	/* Calculated low/upper channels in affected freq range */
+	ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ? 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET);
+
+	ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ?
+	    14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET);
+
+	/* Check intolerant (Non-HT) channel list */
+	ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
+	for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+		if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L &&
+		     prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) &&
+		    prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) {
+
+			ucChannelLevel = CHNL_LEVEL0;
+			goto L_2G4_level_end;
+		}
+	}
+
+	/* Check 20M BW request channel list */
+	ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
+	for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+		if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L &&
+		     prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) {
+
+			ucChannelLevel = CHNL_LEVEL0;
+			goto L_2G4_level_end;
+		}
+	}
+
+	/* Check 2.4G primary channel list */
+	ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G);
+	for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+		if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L &&
+		     prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) &&
+		    prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) {
+
+			ucChannelLevel = CHNL_LEVEL0;
+			goto L_2G4_level_end;
+		}
+	}
+
+	/* Check 2.4G secondary channel list */
+	ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G);
+	for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+		if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L &&
+		     prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) &&
+		    prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) {
+
+			ucChannelLevel = CHNL_LEVEL0;
+			goto L_2G4_level_end;
+		}
+	}
+
+L_2G4_level_end:
+
+	return ucChannelLevel;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend)
+{
+	UINT_8 i, ucChannelLevel;
+	UINT_8 ucSecChannel;
+
+	ASSERT(prBssInfo);
+
+	ucChannelLevel = CHNL_LEVEL2;
+
+	/* Calculate center channel for 2.4G band */
+	if (eExtend == CHNL_EXT_SCA)
+		ucSecChannel = ucPriChannel + 4;
+	else if (eExtend == CHNL_EXT_SCB)
+		ucSecChannel = ucPriChannel - 4;
+	else
+		return CHNL_LEVEL0;
+	ASSERT(ucSecChannel >= 36);
+
+	/* Check 5G primary channel list */
+	ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G);
+	for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) {
+		if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) {
+
+			ucChannelLevel = CHNL_LEVEL0;
+			goto L_5G_level_end;
+		} else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) {
+			ucChannelLevel = CHNL_LEVEL1;
+		}
+	}
+
+	/* Check non-HT channel list */
+	ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G);
+	for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) {
+		if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) {
+
+			ucChannelLevel = CHNL_LEVEL0;
+			goto L_5G_level_end;
+		} else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) {
+			ucChannelLevel = CHNL_LEVEL1;
+		}
+	}
+
+	/* Check secondary channel list */
+	ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G);
+	for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) {
+		if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) {
+
+			ucChannelLevel = CHNL_LEVEL0;
+			goto L_5G_level_end;
+		}
+	}
+
+L_5G_level_end:
+
+	return ucChannelLevel;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	P_ACTION_20_40_COEXIST_FRAME prTxFrame;
+
+	/* To do: need an algorithm to do judgement. Now always reject request */
+
+	prMsduInfo = (P_MSDU_INFO_T)cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
+	if (prMsduInfo == NULL)
+		return;
+
+	DBGLOG(RLM, INFO, "Send 20/40 coexistence rsp frame!\n");
+
+	prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket;
+
+	prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
+	COPY_MAC_ADDR(prTxFrame->aucDestAddr, ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr);
+	COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
+	COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
+
+	prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
+	prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;
+
+	/* To do: find correct algorithm */
+	prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
+	prTxFrame->rBssCoexist.ucLength = 1;
+	prTxFrame->rBssCoexist.ucData = 0;
+
+	ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN);
+
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+	prMsduInfo->ucStaRecIndex = prSwRfb->ucStaRecIdx;
+	prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = NULL;
+	prMsduInfo->fgIsBasicRate = FALSE;
+
+	/* Send them to HW queue */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c
new file mode 100644
index 0000000000000..b5bd23965fe35
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c
@@ -0,0 +1,756 @@
+/*
+** Id: @(#) p2p_scan.c@@
+*/
+
+/*! \file   "p2p_scan.c"
+    \brief  This file defines the p2p scan profile and the processing function of
+	    scan result for SCAN Module.
+
+    The SCAN Profile selection is part of SCAN MODULE and responsible for defining
+    SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels.
+    In this file we also define the process of SCAN Result including adding, searching
+    and removing SCAN record from the list.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+P_P2P_DEVICE_DESC_T
+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc)
+{
+
+	P_P2P_DEVICE_DESC_T prTargetP2pDesc = (P_P2P_DEVICE_DESC_T) NULL;
+	P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL;
+	P_LINK_T prBSSDescList;
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+
+	ASSERT(prAdapter);
+	ASSERT(aucDeviceID);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	/* 4 <1> The outer loop to search for a candidate. */
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+		/* Loop for each prBssDesc */
+		prTargetP2pDesc = scanFindP2pDeviceDesc(prAdapter, prBssDesc, aucDeviceID, TRUE, FALSE);
+
+		if (prTargetP2pDesc != NULL)
+			break;
+	}
+
+	if ((pprBssDesc) && (prTargetP2pDesc != NULL)) {
+		/* Only valid if prTargetP2pDesc is not NULL. */
+		*pprBssDesc = prBssDesc;
+	}
+
+	return prTargetP2pDesc;
+}				/* scanSearchTargetP2pDesc */
+
+VOID scanInvalidAllP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+	P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+	P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL;
+
+	LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) {
+		prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
+
+		if (prTargetDesc->fgDevInfoValid)
+			prTargetDesc->fgDevInfoValid = FALSE;
+	}
+
+}				/* scanRenewP2pClientDevice */
+
+VOID scanRemoveInvalidP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+	P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL, prNexEntry = (P_LINK_ENTRY_T) NULL;
+	P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+	LINK_FOR_EACH_SAFE(prLinkEntry, prNexEntry, &prBssDesc->rP2pDeviceList) {
+		prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
+
+		if (!prTargetDesc->fgDevInfoValid) {
+			LINK_REMOVE_KNOWN_ENTRY(&prBssDesc->rP2pDeviceList, prLinkEntry);
+			if ((prP2pConnSettings) && (prP2pConnSettings->prTargetP2pDesc == prTargetDesc))
+				prP2pConnSettings->prTargetP2pDesc = NULL;
+			kalMemFree(prTargetDesc, VIR_MEM_TYPE, sizeof(P2P_DEVICE_DESC_T));
+		}
+	}
+
+}				/* scanRenewP2pClientDevice */
+
+P_P2P_DEVICE_DESC_T
+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter,
+		      IN P_BSS_DESC_T prBssDesc,
+		      IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound)
+{
+
+	P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL;
+	P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prBssDesc != NULL) && (aucMacAddr != NULL));
+
+		LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) {
+			prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
+
+			if (fgIsDeviceAddr) {
+				if (EQUAL_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr))
+					break;
+			} else {
+				if (EQUAL_MAC_ADDR(prTargetDesc->aucInterfaceAddr, aucMacAddr))
+					break;
+			}
+
+			prTargetDesc = NULL;
+		}
+
+		if ((fgAddIfNoFound) && (prTargetDesc == NULL)) {
+			/* Target Not Found. */
+			/* TODO: Use memory pool in the future. */
+			prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE);
+
+			if (prTargetDesc) {
+				kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T));
+				LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry));
+				COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr);
+				LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry);
+				prTargetDesc->fgDevInfoValid = TRUE;
+			} else {
+				ASSERT(FALSE);
+			}
+		}
+
+	} while (FALSE);
+
+	return prTargetDesc;
+}				/* scanFindP2pDeviceDesc */
+
+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+
+	P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL;
+
+	ASSERT(prAdapter);
+	ASSERT(prBssDesc);
+
+	if (prBssDesc->prP2pDesc == NULL) {
+
+		prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE);
+
+		if (prTargetDesc) {
+			kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T));
+			LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry));
+			LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry);
+			prTargetDesc->fgDevInfoValid = TRUE;
+			prBssDesc->prP2pDesc = prTargetDesc;
+			/* We are not sure the SrcAddr is Device Address or Interface Address. */
+			COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, prBssDesc->aucSrcAddr);
+			COPY_MAC_ADDR(prTargetDesc->aucInterfaceAddr, prBssDesc->aucSrcAddr);
+		} else {
+
+			ASSERT(FALSE);
+		}
+	} else {
+		prTargetDesc = prBssDesc->prP2pDesc;
+	}
+
+	return prTargetDesc;
+
+}				/* scanFindP2pDeviceDesc */
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet
+*
+* @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS   It is a valid Scan Result and been sent to the host.
+* @retval WLAN_STATUS_FAILURE   It is not a valid Scan Result.
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+	P_P2P_DEVICE_DESC_T prP2pDesc = (P_P2P_DEVICE_DESC_T) NULL;
+	P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL;
+	UINT_16 u2AttributeLen = 0;
+	UINT_32 u4Idx = 0;
+	BOOLEAN fgUpdateDevInfo = FALSE;
+
+	P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL;
+	P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL;
+
+	ASSERT(prAdapter);
+
+	prP2pDesc = scanGetP2pDeviceDesc(prAdapter, prBssDesc);
+
+	if (!prP2pDesc) {
+		ASSERT(FALSE);
+		return fgUpdateDevInfo;
+	}
+
+	p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute,
+			   &u2AttributeLen);
+
+	while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) {
+		switch (prP2pAttribute->ucId) {
+		case P2P_ATTRI_ID_P2P_CAPABILITY:	/* Beacon, Probe Response */
+			{
+				P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL;
+
+				prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute;
+				ASSERT(prP2pAttriCapability->u2Length == 2);
+
+				prP2pDesc->ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap;
+				prP2pDesc->ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap;
+			}
+			break;
+		case P2P_ATTRI_ID_P2P_DEV_ID:	/* Beacon */
+			{
+				P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL;
+
+				prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute;
+				ASSERT(prP2pAttriDevID->u2Length == P2P_ATTRI_MAX_LEN_P2P_DEV_ID);
+
+				kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN);
+			}
+			break;
+		case P2P_ATTRI_ID_P2P_DEV_INFO:	/* Probe Response */
+			{
+				P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL;
+				P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL;
+				UINT_16 u2NameLen = 0, u2Id = 0;
+
+				fgUpdateDevInfo = TRUE;
+
+				prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute;
+
+				kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN);
+
+				WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod);
+
+				prP2pDevType = &prP2pDesc->rPriDevType;
+				WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId,
+						    &prP2pDevType->u2CategoryID);
+				WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId,
+						    &prP2pDevType->u2SubCategoryID);
+
+				ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <=
+					P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT);
+				/* TODO: Fixme if secondary device type is more than 2. */
+				prP2pDesc->ucSecDevTypeNum = 0;
+				for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) {
+					if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) {
+						prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]);
+						WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->
+								    arSecondaryDevTypeListBE[u4Idx].u2CategoryId,
+								    &prP2pDevType->u2CategoryID);
+						WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->
+								    arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId,
+								    &prP2pDevType->u2SubCategoryID);
+						prP2pDesc->ucSecDevTypeNum++;
+					}
+
+				}
+				prP2pDevName =
+				    (P_DEVICE_NAME_TLV_T) ((PUINT_8) prP2pAttriDevInfo->arSecondaryDevTypeListBE +
+							   (u4Idx * sizeof(DEVICE_TYPE_T)));
+				WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &u2NameLen);
+				WLAN_GET_FIELD_BE16(&prP2pDevName->u2Id, &u2Id);
+				ASSERT(u2Id == WPS_ATTRI_ID_DEVICE_NAME);
+				if (u2NameLen > WPS_ATTRI_MAX_LEN_DEVICE_NAME)
+					u2NameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME;
+				prP2pDesc->u2NameLength = u2NameLen;
+				kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength);
+			}
+			break;
+		case P2P_ATTRI_ID_P2P_GROUP_INFO:	/* Probe Response */
+			prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute;
+			break;
+		case P2P_ATTRI_ID_NOTICE_OF_ABSENCE:
+			break;
+		case P2P_ATTRI_ID_EXT_LISTEN_TIMING:
+			/* TODO: Not implement yet. */
+			/* ASSERT(FALSE); */
+			break;
+		default:
+			break;
+		}
+
+		u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN);
+
+		prP2pAttribute =
+		    (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN));
+
+	}
+
+	if (prP2pAttriGroupInfo != NULL) {
+		P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL;
+		P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL;
+
+		scanInvalidAllP2pClientDevice(prAdapter, prBssDesc);
+
+		/* GO/Device itself. */
+		prP2pDesc->fgDevInfoValid = TRUE;
+
+		prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) prP2pAttriGroupInfo->arClientDesc;
+		u2AttributeLen = prP2pAttriGroupInfo->u2Length;
+
+		while (u2AttributeLen > 0) {
+			prP2pDesc =
+			    scanFindP2pDeviceDesc(prAdapter, prBssDesc, prClientInfoDesc->aucDevAddr, TRUE, TRUE);
+
+			if (!prP2pDesc) {
+				ASSERT(FALSE);
+				break;	/* while */
+			}
+
+			prP2pDesc->fgDevInfoValid = TRUE;
+
+			/* Basic size for P2P client info descriptor. */
+			ASSERT(u2AttributeLen >= 25);
+			if (u2AttributeLen < 25) {
+				DBGLOG(P2P, WARN, "Length incorrect warning.\n");
+				break;
+			}
+			COPY_MAC_ADDR(prP2pDesc->aucInterfaceAddr, prClientInfoDesc->aucIfAddr);
+
+			prP2pDesc->ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap;
+
+			WLAN_GET_FIELD_BE16(&prClientInfoDesc->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod);
+
+			prP2pDevType = &(prP2pDesc->rPriDevType);
+			WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId,
+					    &prP2pDevType->u2CategoryID);
+			WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId,
+					    &prP2pDevType->u2SubCategoryID);
+
+			ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT);
+			prP2pDesc->ucSecDevTypeNum = 0;
+			for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) {
+				if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) {
+					prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]);
+					WLAN_GET_FIELD_BE16(&prClientInfoDesc->
+							    arSecondaryDevTypeListBE[u4Idx].u2CategoryId,
+							    &prP2pDevType->u2CategoryID);
+					WLAN_GET_FIELD_BE16(&prClientInfoDesc->
+							    arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId,
+							    &prP2pDevType->u2SubCategoryID);
+					prP2pDesc->ucSecDevTypeNum++;
+				}
+
+			}
+			prP2pDevName =
+			    (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE +
+						   (u4Idx * sizeof(DEVICE_TYPE_T)));
+			WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &prP2pDesc->u2NameLength);
+			if (prP2pDesc->u2NameLength > WPS_ATTRI_MAX_LEN_DEVICE_NAME)
+				prP2pDesc->u2NameLength = WPS_ATTRI_MAX_LEN_DEVICE_NAME;
+
+			kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength);
+
+			u2AttributeLen -= (prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN);
+			prClientInfoDesc =
+			    (P_P2P_CLIENT_INFO_DESC_T) ((UINT_32) prClientInfoDesc +
+							(UINT_32) prClientInfoDesc->ucLength +
+							P2P_CLIENT_INFO_DESC_HDR_LEN);
+		}
+
+		scanRemoveInvalidP2pClientDevice(prAdapter, prBssDesc);
+	}
+
+	return fgUpdateDevInfo;
+}				/* end of scanAddP2pDeviceInfo() */
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet
+*
+* @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS   It is a valid Scan Result and been sent to the host.
+* @retval WLAN_STATUS_FAILURE   It is not a valid Scan Result.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb)
+{
+	EVENT_P2P_DEV_DISCOVER_RESULT_T rEventDevInfo;
+#if 1
+	P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL;
+	P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL;
+
+	LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) {
+		prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
+
+		COPY_MAC_ADDR(rEventDevInfo.aucDeviceAddr, prTargetDesc->aucDeviceAddr);
+		COPY_MAC_ADDR(rEventDevInfo.aucInterfaceAddr, prTargetDesc->aucInterfaceAddr);
+
+		rEventDevInfo.ucDeviceCapabilityBitmap = prTargetDesc->ucDeviceCapabilityBitmap;
+		rEventDevInfo.ucGroupCapabilityBitmap = prTargetDesc->ucGroupCapabilityBitmap;
+		rEventDevInfo.u2ConfigMethod = prTargetDesc->u2ConfigMethod;
+
+		kalMemCopy(&rEventDevInfo.rPriDevType, &prTargetDesc->rPriDevType, sizeof(P2P_DEVICE_TYPE_T));
+
+		kalMemCopy(rEventDevInfo.arSecDevType,
+			   prTargetDesc->arSecDevType, (prTargetDesc->ucSecDevTypeNum * sizeof(P2P_DEVICE_TYPE_T)));
+
+		rEventDevInfo.ucSecDevTypeNum = prTargetDesc->ucSecDevTypeNum;
+
+		rEventDevInfo.u2NameLength = prTargetDesc->u2NameLength;
+		kalMemCopy(rEventDevInfo.aucName, prTargetDesc->aucName, prTargetDesc->u2NameLength);
+
+		COPY_MAC_ADDR(rEventDevInfo.aucBSSID, prBssDesc->aucBSSID);
+
+		if (prTargetDesc == prBssDesc->prP2pDesc)
+			nicRxAddP2pDevice(prAdapter, &rEventDevInfo, prBssDesc->aucIEBuf, prBssDesc->u2IELength);
+		else
+			nicRxAddP2pDevice(prAdapter, &rEventDevInfo, NULL, 0);
+	}
+
+	kalP2PIndicateFound(prAdapter->prGlueInfo);
+
+#else
+
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL;
+	UINT_16 u2AttributeLen = 0;
+	UINT_32 u4Idx = 0;
+	P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL;
+	P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL;
+
+	ASSERT(prAdapter);
+
+	prP2pSpecificBssInfo = &prAdapter->rWifiVar.rP2pSpecificBssInfo;
+
+#if 1
+	p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute,
+			   &u2AttributeLen);
+#else
+	prP2pAttribute = (P_P2P_ATTRIBUTE_T) &prP2pSpecificBssInfo->aucAttributesCache[0];
+	u2AttributeLen = prP2pSpecificBssInfo->u2AttributeLen;
+#endif
+	rEventDevInfo.fgDevInfoValid = FALSE;
+
+	while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) {
+		switch (prP2pAttribute->ucId) {
+		case P2P_ATTRI_ID_P2P_CAPABILITY:
+			{
+				P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL;
+
+				prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute;
+				ASSERT(prP2pAttriCapability->u2Length == 2);
+				rEventDevInfo.ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap;
+				rEventDevInfo.ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap;
+			}
+			break;
+		case P2P_ATTRI_ID_P2P_DEV_ID:
+			{
+				P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL;
+
+				prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute;
+				ASSERT(prP2pAttriDevID->u2Length == 6);
+				kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN);
+			}
+			break;
+		case P2P_ATTRI_ID_P2P_DEV_INFO:
+			{
+				P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL;
+				P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL;
+
+				prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute;
+				rEventDevInfo.fgDevInfoValid = TRUE;
+				kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevInfo->aucDevAddr,
+					   MAC_ADDR_LEN);
+				rEventDevInfo.u2ConfigMethod = prP2pAttriDevInfo->u2ConfigMethodsBE;
+
+				prP2pDevType = &rEventDevInfo.rPriDevType;
+				prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId;
+				prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId;
+
+				ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= 2);
+				/* TODO: Fixme if secondary device type is more than 2. */
+				for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) {
+					/* TODO: Current sub device type can only support 2. */
+					prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx];
+					prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId;
+					prP2pDevType->u2SubCategoryID =
+					    prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId;
+				}
+
+				prP2pDevName =
+				    (P_DEVICE_NAME_TLV_T) (prP2pAttriDevInfo->arSecondaryDevTypeListBE +
+							   (u4Idx * sizeof(DEVICE_TYPE_T)));
+				ASSERT(prP2pDevName->u2Id == 0x1011);
+				ASSERT(prP2pDevName->u2Length <= 32);
+				/* TODO: Fixme if device name length is longer than 32 bytes. */
+				kalMemCopy(rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length);
+			}
+			break;
+		case P2P_ATTRI_ID_P2P_GROUP_INFO:
+			prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute;
+			break;
+		}
+
+		u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN);
+
+		prP2pAttribute =
+		    (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN));
+
+	}
+
+	nicRxAddP2pDevice(prAdapter, &rEventDevInfo);
+
+	if (prP2pAttriGroupInfo != NULL) {
+		P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL;
+		P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL;
+
+		prClientInfoDesc = prP2pAttriGroupInfo->arClientDesc;
+		u2AttributeLen = prP2pAttriGroupInfo->u2Length;
+
+		while (u2AttributeLen > 0) {
+			/* Basic size for P2P client info descriptor. */
+			ASSERT(u2AttributeLen >= 25);
+			rEventDevInfo.fgDevInfoValid = TRUE;
+			kalMemCopy(rEventDevInfo.aucCommunicateAddr, prClientInfoDesc->aucIfAddr, MAC_ADDR_LEN);
+			rEventDevInfo.ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap;
+			rEventDevInfo.u2ConfigMethod = prClientInfoDesc->u2ConfigMethodsBE;
+
+			prP2pDevType = &rEventDevInfo.rPriDevType;
+			prP2pDevType->u2CategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId;
+			prP2pDevType->u2SubCategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId;
+
+			ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= 2);
+			/* TODO: Fixme if secondary device type is more than 2. */
+			for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) {
+				/* TODO: Current sub device type can only support 2. */
+				prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx];
+				prP2pDevType->u2CategoryID =
+				    prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId;
+				prP2pDevType->u2SubCategoryID =
+				    prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId;
+			}
+
+			prP2pDevName =
+			    (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE +
+						   (u4Idx * sizeof(DEVICE_TYPE_T)));
+			ASSERT(prP2pDevName->u2Id == 0x1011);
+			ASSERT(prP2pDevName->u2Length <= 32);
+			/* TODO: Fixme if device name length is longer than 32 bytes. */
+			kalMemCopy(&rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length);
+
+			nicRxAddP2pDevice(prAdapter, &rEventDevInfo);
+
+			u2AttributeLen -= prP2pAttriGroupInfo->u2Length;
+			prP2pAttriGroupInfo = prP2pAttriGroupInfo + prP2pAttriGroupInfo->u2Length + 1;
+		}
+
+	}
+#endif
+	return WLAN_STATUS_SUCCESS;
+}				/* scanSendDeviceDiscoverEvent */
+
+VOID
+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter,
+				 IN P_SW_RFB_T prSwRfb,
+				 IN P_WLAN_STATUS prStatus,
+				 IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame)
+{
+	BOOLEAN fgIsSkipThisBeacon;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+	prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+	fgIsSkipThisBeacon = FALSE;
+	if (prBssDesc->fgIsP2PPresent) {
+		if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&	/* P2P GC */
+		    (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) &&	/* Connected */
+		    ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) {	/* TX Beacon */
+
+			fgIsSkipThisBeacon = TRUE;
+		}
+
+		if ((!prP2pBssInfo->ucDTIMPeriod) &&	/* First time. */
+		    fgIsSkipThisBeacon && (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
+		    prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen))) {	/* SSID Match */
+			prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
+			nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX);
+		}
+
+		do {
+			RF_CHANNEL_INFO_T rChannelInfo;
+
+			ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL));
+
+			if (((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_PROBE_RSP)) {
+				/* Only report Probe Response frame to supplicant. */
+				/* Probe response collect much more information. */
+
+				if (fgIsSkipThisBeacon || prBssDesc->eBand == BAND_2G4)
+					break;
+			}
+
+			rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum;
+			rChannelInfo.eBand = prBssDesc->eBand;
+			prBssDesc->fgIsP2PReport = TRUE;
+
+			DBGLOG(P2P, INFO, "indicate %s [%d]\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum);
+
+			kalP2PIndicateBssInfo(prAdapter->prGlueInfo,
+					      (PUINT_8) prSwRfb->pvHeader,
+					      (UINT_32) prSwRfb->u2PacketLen,
+					      &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI));
+
+		} while (FALSE);
+	}
+}
+
+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum)
+{
+
+	CMD_SCAN_CANCEL rCmdScanCancel;
+
+	/* send cancel message to firmware domain */
+	rCmdScanCancel.ucSeqNum = ucScnSeqNum;
+	rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE;
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SCAN_CANCEL,
+			    TRUE,
+			    FALSE, FALSE, NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8)&rCmdScanCancel, NULL, 0);
+
+}				/* scnEventReturnChannel */
+
+VOID scanRemoveAllP2pBssDesc(IN P_ADAPTER_T prAdapter)
+{
+	P_LINK_T prBSSDescList;
+	P_BSS_DESC_T prBssDesc;
+	P_BSS_DESC_T prBSSDescNext;
+
+	ASSERT(prAdapter);
+
+	prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList);
+
+	/* Search BSS Desc from current SCAN result list. */
+	LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+		scanRemoveP2pBssDesc(prAdapter, prBssDesc);
+	}
+}				/* scanRemoveAllP2pBssDesc */
+
+VOID scanRemoveP2pBssDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+
+
+}				/* scanRemoveP2pBssDesc */
+
+P_BSS_DESC_T
+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo)
+{
+	P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL, prBssDesc = (P_BSS_DESC_T) NULL;
+	P_LINK_T prBssDescList = (P_LINK_T) NULL;
+
+	do {
+		if ((prAdapter == NULL) || (prP2pBssInfo == NULL) || (prConnReqInfo == NULL))
+			break;
+
+		prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList);
+
+		DBGLOG(P2P, LOUD, "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid);
+		DBGLOG(P2P, LOUD, "Connecting to SSID:%s, length:%d\n",
+				   prConnReqInfo->rSsidStruct.aucSsid, prConnReqInfo->rSsidStruct.ucSsidLen);
+
+		LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, rLinkEntry, BSS_DESC_T) {
+			DBGLOG(P2P, LOUD, "Checking BSS: %pM\n", prBssDesc->aucBSSID);
+
+			if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) {
+				DBGLOG(P2P, LOUD, "Ignore mismatch BSS type.\n");
+				continue;
+			}
+
+			if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnReqInfo->aucBssid)) {
+				DBGLOG(P2P, LOUD, "Ignore mismatch BSSID.\n");
+				continue;
+			}
+
+			/* SSID should be the same? SSID is vary for each connection. so... */
+			if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid,
+					 prConnReqInfo->rSsidStruct.ucSsidLen,
+					 prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) {
+
+				DBGLOG(P2P, TRACE,
+				       "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid);
+				DBGLOG(P2P, TRACE,
+				       "Connecting to SSID:%s, length:%d\n", prConnReqInfo->rSsidStruct.aucSsid,
+					prConnReqInfo->rSsidStruct.ucSsidLen);
+				DBGLOG(P2P, TRACE,
+				       "Checking SSID:%s, length:%d\n", prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+				DBGLOG(P2P, TRACE, "Ignore mismatch SSID, (But BSSID match).\n");
+				ASSERT(FALSE);
+				continue;
+			}
+
+			if (!prBssDesc->fgIsP2PPresent) {
+				DBGLOG(P2P, ERROR, "SSID, BSSID, BSSTYPE match, but no P2P IE present.\n");
+				continue;
+			}
+
+			/* Final decision. */
+			prCandidateBssDesc = prBssDesc;
+			break;
+		}
+
+	} while (FALSE);
+
+	return prCandidateBssDesc;
+}				/* scanP2pSearchDesc */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c
new file mode 100644
index 0000000000000..befb9978f4735
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c
@@ -0,0 +1,466 @@
+#include "p2p_precomp.h"
+
+BOOLEAN
+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter,
+		  IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState)
+{
+	BOOLEAN fgIsTransOut = FALSE;
+/* P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL; */
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) &&
+			     (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (peNextState != NULL));
+
+		if ((prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT)
+		    && IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) {
+			P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+			fgIsTransOut = TRUE;
+			prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS;
+
+			DBGLOG(P2P, INFO, "p2pStateInit_IDLE GO Scan\n");
+			*peNextState = P2P_STATE_REQING_CHANNEL;
+
+		} else {
+#if 0
+			else
+		if (IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) {
+
+			ASSERT((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ||
+			       (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE));
+
+			prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo;
+
+			if (prChnlReqInfo->fgIsChannelRequested) {
+				/* Start a timer for return channel. */
+				DBGLOG(P2P, TRACE, "start a GO channel timer.\n");
+			}
+
+		}
+#endif
+			cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), 5000);
+		}
+
+	} while (FALSE);
+
+	return fgIsTransOut;
+}				/* p2pStateInit_IDLE */
+
+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState)
+{
+
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo;
+
+		if (prChnlReqInfo->fgIsChannelRequested) {
+			/* Release channel before timeout. */
+			p2pFuncReleaseCh(prAdapter, prChnlReqInfo);
+		}
+
+		/* Stop timer for leaving this state. */
+		cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer));
+
+	} while (FALSE);
+
+}				/* p2pStateAbort_IDLE */
+
+VOID p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo)
+{
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+		/* Store the original channel info. */
+		prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel;
+		prChnlReqInfo->eOriBand = prP2pBssInfo->eBand;
+		prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO;
+
+		/* RX Probe Request would check primary channel. */
+		prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum;
+		prP2pBssInfo->eBand = prChnlReqInfo->eBand;
+		prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco;
+
+		DBGLOG(P2P, TRACE, "start a channel on hand timer.\n");
+		if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING) {
+			cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer),
+				prChnlReqInfo->u4MaxInterval);
+
+			kalP2PIndicateChannelReady(prAdapter->prGlueInfo,
+				   prChnlReqInfo->u8Cookie,
+				   prChnlReqInfo->ucReqChnlNum,
+				   prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval);
+		} else
+			cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer),
+				(P2P_EXT_LISTEN_TIME_MS - prChnlReqInfo->u4MaxInterval));
+	} while (FALSE);
+
+}				/* p2pStateInit_CHNL_ON_HAND */
+
+VOID
+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter,
+			   IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+			   IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState)
+{
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+		cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer));
+
+		/* Restore the original channel info. */
+		prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum;
+		prP2pBssInfo->eBand = prChnlReqInfo->eOriBand;
+		prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco;
+
+		DBGLOG(P2P, INFO, "p2p state trans abort chann on hand, eListenExted: %d, eNextState: %d\n",
+			prP2pFsmInfo->eListenExted, eNextState);
+		if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING ||
+			eNextState != P2P_STATE_CHNL_ON_HAND) {
+			/* Here maybe have a bug, when it's extlistening, a new remain_on_channel
+			was sent to driver? need to verify */
+			prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN;
+			/* Indicate channel return. */
+			kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo);
+
+			/* Return Channel. */
+			p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+		}
+
+	} while (FALSE);
+}				/* p2pStateAbort_CHNL_ON_HAND */
+
+VOID
+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState)
+{
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (eNextState < P2P_STATE_NUM));
+
+		prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+		prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+		if (eNextState == P2P_STATE_IDLE) {
+			if (prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) {
+				/* Intend to be AP. */
+				/* Setup for AP mode. */
+				p2pFuncStartGO(prAdapter,
+					       prP2pBssInfo,
+					       prP2pSpecificBssInfo->aucGroupSsid,
+					       prP2pSpecificBssInfo->u2GroupSsidLen,
+					       prP2pSpecificBssInfo->ucPreferredChannel,
+					       prP2pSpecificBssInfo->eRfBand,
+					       prP2pSpecificBssInfo->eRfSco, prP2pFsmInfo->fgIsApMode);
+
+			} else {
+				/* Return Channel. */
+				p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+			}
+
+		}
+
+	} while (FALSE);
+
+}				/* p2pStateInit_AP_CHANNEL_DETECT */
+
+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo)
+{
+	P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo);
+
+		prScanReqInfo->eScanType = SCAN_TYPE_PASSIVE_SCAN;
+		prScanReqInfo->eChannelSet = SCAN_CHANNEL_2G4;
+		prScanReqInfo->u2PassiveDewellTime = 50;	/* 50ms for passive channel load detection */
+		prScanReqInfo->fgIsAbort = TRUE;
+		prScanReqInfo->fgIsScanRequest = TRUE;
+		prScanReqInfo->ucNumChannelList = 0;
+		prScanReqInfo->u4BufLength = 0;
+		prScanReqInfo->rSsidStruct.ucSsidLen = 0;
+
+		p2pFuncRequestScan(prAdapter, prScanReqInfo);
+
+	} while (FALSE);
+
+}				/* p2pStateInit_AP_CHANNEL_DETECT */
+
+VOID
+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter,
+				IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+				IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState)
+{
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	do {
+
+		if (eNextState == P2P_STATE_REQING_CHANNEL) {
+			UINT_8 ucPreferedChnl = 0;
+			ENUM_BAND_T eBand = BAND_NULL;
+			ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN;
+
+			prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
+
+			/* Determine the channel for AP. */
+			if (cnmPreferredChannel(prAdapter, &eBand, &ucPreferedChnl, &eSco) == FALSE) {
+
+				prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+				ucPreferedChnl = prP2pConnSettings->ucOperatingChnl;
+				if (ucPreferedChnl == 0) {
+
+					if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) {
+
+						/* What to do? */
+						ASSERT(FALSE);
+						/* TODO: Pick up a valid channel from channel list. */
+						ucPreferedChnl = 1;
+						eBand = BAND_2G4;
+					}
+				}
+			}
+
+			prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS;
+
+			DBGLOG(P2P, INFO, "p2pStateAbort_AP_CHANNEL_DETECT GO Scan\n");
+			prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl;
+			prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand;
+			prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco;
+		} else {
+			p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo));
+		}
+
+	} while (FALSE);
+
+}				/* p2pStateAbort_AP_CHANNEL_DETECT */
+
+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo)
+{
+	P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL;
+
+	do {
+
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
+
+		prScanReqInfo = &prP2pFsmInfo->rScanReqInfo;
+
+		prScanReqInfo->fgIsScanRequest = TRUE;
+
+		p2pFuncRequestScan(prAdapter, prScanReqInfo);
+
+	} while (FALSE);
+
+}				/* p2pStateInit_SCAN */
+
+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState)
+{
+	do {
+		ASSERT_BREAK(prAdapter != NULL);
+
+		/* 1. Scan cancel. (Make sure the scan request is invalid. */
+		p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo));
+
+		/* Scan done indication. */
+		kalP2PIndicateScanDone(prAdapter->prGlueInfo, prP2pFsmInfo->rScanReqInfo.fgIsAbort);
+	} while (FALSE);
+
+}				/* p2pStateAbort_SCAN */
+
+VOID
+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter,
+		     IN P_P2P_FSM_INFO_T prP2pFsmInfo,
+		     IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc)
+{
+	P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) &&
+			     (prP2pFsmInfo != NULL) &&
+			     (prP2pBssInfo != NULL) && (prJoinInfo != NULL) && (prBssDesc != NULL));
+
+		prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+		if (prBssDesc->ucSSIDLen) {
+			COPY_SSID(prP2pConnSettings->aucSSID,
+				  prP2pConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+		}
+		/* Setup a join timer. */
+		DBGLOG(P2P, TRACE, "Start a join init timer\n");
+		cnmTimerStartTimer(prAdapter,
+				   &(prAdapter->rP2pFsmTimeoutTimer),
+				   (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD));
+
+		/* 2 <1> We are goin to connect to this BSS */
+		prBssDesc->fgIsConnecting = TRUE;
+
+		/* 2 <2> Setup corresponding STA_RECORD_T */
+		prStaRec = bssCreateStaRecFromBssDesc(prAdapter,
+						      (prBssDesc->fgIsP2PPresent ? (STA_TYPE_P2P_GO)
+						       : (STA_TYPE_LEGACY_AP)), NETWORK_TYPE_P2P_INDEX, prBssDesc);
+
+		if (prStaRec == NULL) {
+			DBGLOG(P2P, TRACE, "Create station record fail\n");
+			break;
+		}
+
+		prJoinInfo->prTargetStaRec = prStaRec;
+		prJoinInfo->fgIsJoinComplete = FALSE;
+		prJoinInfo->u4BufLength = 0;
+
+		/* 2 <2.1> Sync. to FW domain */
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+		if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
+			P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+			prStaRec->fgIsReAssoc = FALSE;
+
+			prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+			switch (prP2pConnSettings->eAuthMode) {
+			case AUTH_MODE_OPEN:	/* Note: Omit break here. */
+			case AUTH_MODE_WPA:
+			case AUTH_MODE_WPA_PSK:
+			case AUTH_MODE_WPA2:
+			case AUTH_MODE_WPA2_PSK:
+				prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM;
+				break;
+			case AUTH_MODE_SHARED:
+				prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY;
+				break;
+			case AUTH_MODE_AUTO_SWITCH:
+				DBGLOG(P2P, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n");
+				prJoinInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM |
+									     AUTH_TYPE_SHARED_KEY);
+				break;
+			default:
+				ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE));
+				DBGLOG(P2P, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n",
+						    prP2pConnSettings->eAuthMode);
+				/* TODO(Kevin): error handling ? */
+				return;
+			}
+			prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT;
+		} else {
+			ASSERT(FALSE);
+			/* TODO: Shall we considering ROAMIN case for P2P Device?. */
+		}
+
+		/* 2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes. */
+		if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) {
+
+			DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n");
+
+			prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM;
+
+			prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM;
+		} else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) {
+
+			DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n");
+
+			prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY;
+
+			prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY;
+		} else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) {
+
+			DBGLOG(P2P, TRACE,
+			       "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n");
+
+			prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION;
+
+			prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION;
+		} else {
+			ASSERT(0);
+		}
+
+		/* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */
+		if (prBssDesc->ucSSIDLen) {
+			COPY_SSID(prJoinInfo->rSsidStruct.aucSsid,
+				  prJoinInfo->rSsidStruct.ucSsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+		}
+		/* 2 <5> Backup desired channel. */
+
+		/* 2 <6> Send a Msg to trigger SAA to start JOIN process. */
+		prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T));
+
+		if (!prJoinReqMsg) {
+			DBGLOG(P2P, TRACE, "Allocation Join Message Fail\n");
+			ASSERT(FALSE);
+			return;
+		}
+
+		prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START;
+		prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg;
+		prJoinReqMsg->prStaRec = prStaRec;
+
+		/* TODO: Consider fragmentation info in station record. */
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF);
+
+	} while (FALSE);
+
+}				/* p2pStateInit_GC_JOIN */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process of JOIN Abort. Leave JOIN State & Abort JOIN.
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter,
+		      IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState)
+{
+	P_MSG_JOIN_ABORT_T prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) NULL;
+
+	do {
+		ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prJoinInfo != NULL));
+
+		if (prJoinInfo->fgIsJoinComplete == FALSE) {
+
+			prJoinAbortMsg =
+			    (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T));
+			if (!prJoinAbortMsg) {
+				DBGLOG(P2P, TRACE, "Fail to allocate join abort message buffer\n");
+				ASSERT(FALSE);
+				return;
+			}
+
+			prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT;
+			prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg;
+			prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec;
+
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF);
+
+		}
+
+		/* Stop Join Timer. */
+		cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer));
+
+		/* Release channel requested. */
+		p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+
+	} while (FALSE);
+
+	return;
+
+}				/* p2pStateAbort_GC_JOIN */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c
new file mode 100644
index 0000000000000..72fa52e761da5
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c
@@ -0,0 +1,915 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/privacy.c#1
+*/
+
+/*! \file   "privacy.c"
+    \brief  This file including the protocol layer privacy function.
+
+    This file provided the macros and functions library support for the
+    protocol layer security setting from rsn.c and nic_privacy.c
+
+*/
+
+/*
+** Log: privacy.c
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the debug module level.
+ *
+ * 10 20 2011 terry.wu
+ * NULL
+ * Fix Hotspot deauth send failed.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 06 28 2011 tsaiyuan.hsu
+ * [WCXRP00000819] [MT6620 Wi-Fi][Driver] check if staRec is NULL or not in secCheckClassError
+ * check if staRec is NULL or not in secCheckClassError.
+ *
+ * 06 09 2011 tsaiyuan.hsu
+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size
+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T
+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 20 2010 wh.su
+ *
+ * adding the wapi code.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * modify some code for concurrent network.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * enable RX management frame handling.
+ *
+ * 06 19 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * adding the compiling flag for migration.
+ *
+ * 06 19 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * consdier the concurrent network setting.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration the security related function from firmware.
+ *
+ * 05 28 2010 wh.su
+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
+ * fixed the ad-hoc wpa-none send non-encrypted frame issue.
+ *
+ * 05 24 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval.
+ *
+ * 04 29 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * adjsut the pre-authentication code.
+ *
+ * 04 22 2010 wh.su
+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
+ * fixed the wpi same key id rx issue and fixed the remove wep key issue.
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Send Deauth for Class 3 Error and Leave Network Support
+ *
+ * 04 15 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * remove the assert code for allow ad-hoc pkt.
+ *
+ * 04 13 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * fixed the Klocwork error and refine the class error message.
+ *
+ * 03 04 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Code refine, and remove non-used code.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * move the AIS specific variable for security to AIS specific structure.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * Fixed the pre-authentication timer not correctly init issue,
+ * and modify the security related callback function prototype.
+ *
+ * 03 01 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Refine the variable and parameter for security.
+ *
+ * 02 26 2010 wh.su
+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
+ * change the waning message shown level, and clear the global transmit flag for CMD INFRASTRUCTURE.
+ *
+ * 02 25 2010 wh.su
+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
+ * For support the WHQL test, do the remove key code refine.
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 12 25 2009 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM)
+ *  *  *  *  *  *  *  *  * MQM: BA handling
+ *  *  *  *  *  *  *  *  * TXM: Macros updates
+ *  *  *  *  *  *  *  *  * RXM: Macros/Duplicate Removal updates
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 11 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * modify the cmd with result return
+ *
+ * Dec 11 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * fixed the value not initialize issue
+ *
+ * Dec 10 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * change the cmd return type
+ *
+ * Dec 8 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the function to update the auth mode and encryption status for cmd build connection
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding some code for wapi mode
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the call to check the 4th and eapol error report frame
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * rename the function name
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the code for parsing the EAPoL frame, and do some code refine
+ *
+ * Dec 3 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the class error check
+ *
+ * Dec 3 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the cmd_802_11_pmkid code
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * doing some function rename, and adding the code for cmd CMD_ADD_REMOVE_KEY
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the clear pmkid function
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix eStaType check for AIS
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the ap selection related code
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_PRIVACY_MIGRATION
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to initialize the privacy-related
+*        parameters.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] ucNetTypeIdx  Pointer to netowrk type index
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx)
+{
+	UINT_8 i;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_INFO_T prBssInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+	DEBUGFUNC("secInit");
+
+	ASSERT(prAdapter);
+
+	prConnSettings = &prAdapter->rWifiVar.rConnSettings;
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	prBssInfo->u4RsnSelectedGroupCipher = 0;
+	prBssInfo->u4RsnSelectedPairwiseCipher = 0;
+	prBssInfo->u4RsnSelectedAKMSuite = 0;
+
+#if CFG_ENABLE_WIFI_DIRECT
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
+
+	prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP;
+	prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP;
+	prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK;
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX];
+
+	prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP;
+	prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP;
+	prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK;
+#endif
+
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[0].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP40;
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[1].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_TKIP;
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[2].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_CCMP;
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[3].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP104;
+
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[4].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP40;
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[5].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_TKIP;
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[6].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_CCMP;
+	prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[7].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP104;
+
+	for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++)
+		prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE;
+
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[0].dot11RSNAConfigAuthenticationSuite =
+	    WPA_AKM_SUITE_NONE;
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[1].dot11RSNAConfigAuthenticationSuite =
+	    WPA_AKM_SUITE_802_1X;
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[2].dot11RSNAConfigAuthenticationSuite =
+	    WPA_AKM_SUITE_PSK;
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[3].dot11RSNAConfigAuthenticationSuite =
+	    RSN_AKM_SUITE_NONE;
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[4].dot11RSNAConfigAuthenticationSuite =
+	    RSN_AKM_SUITE_802_1X;
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[5].dot11RSNAConfigAuthenticationSuite =
+	    RSN_AKM_SUITE_PSK;
+
+#if CFG_SUPPORT_802_11W
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[6].dot11RSNAConfigAuthenticationSuite =
+	    RSN_AKM_SUITE_802_1X_SHA256;
+	prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[7].dot11RSNAConfigAuthenticationSuite =
+	    RSN_AKM_SUITE_PSK_SHA256;
+#endif
+
+	for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
+		prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i].dot11RSNAConfigAuthenticationSuiteEnabled =
+		    FALSE;
+	}
+
+	secClearPmkid(prAdapter);
+
+	cnmTimerInitTimer(prAdapter,
+			  &prAisSpecBssInfo->rPreauthenticationTimer,
+			  (PFN_MGMT_TIMEOUT_FUNC) rsnIndicatePmkidCand, (ULONG) NULL);
+
+#if CFG_SUPPORT_802_11W
+	cnmTimerInitTimer(prAdapter,
+			  &prAisSpecBssInfo->rSaQueryTimer, (PFN_MGMT_TIMEOUT_FUNC) rsnStartSaQueryTimer, (ULONG) NULL);
+#endif
+
+	prAisSpecBssInfo->fgCounterMeasure = FALSE;
+	prAisSpecBssInfo->ucWEPDefaultKeyID = 0;
+
+#if 0
+	for (i = 0; i < WTBL_SIZE; i++) {
+		g_prWifiVar->arWtbl[i].fgUsed = FALSE;
+		g_prWifiVar->arWtbl[i].prSta = NULL;
+		g_prWifiVar->arWtbl[i].ucNetTypeIdx = NETWORK_TYPE_INDEX_NUM;
+
+	}
+	nicPrivacyInitialize((UINT_8) NETWORK_TYPE_INDEX_NUM);
+#endif
+}				/* secInit */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will indicate an Event of "Rx Class Error" to SEC_FSM for
+*        JOIN Module.
+*
+* \param[in] prAdapter     Pointer to the Adapter structure
+* \param[in] prSwRfb       Pointer to the SW RFB.
+*
+* \return FALSE                Class Error
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec)
+{
+	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	if (!prStaRec)
+		return FALSE;
+
+	eNetTypeIndex = prStaRec->ucNetTypeIndex;
+	if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex))
+		return FALSE;
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetTypeIndex];
+	if ((STA_STATE_3 != prStaRec->ucStaState) && prBssInfo->fgIsNetAbsent == FALSE) {
+		/*(IS_AP_STA(prStaRec) || IS_CLIENT_STA(prStaRec))) { */
+
+#if 0	/* by scott's suggestions, do not put work-around in JB2,we need to find the root cause */
+		/* work-around for CR ALPS00816361 */
+		if (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
+			DBGLOG(RSN, INFO,
+			       "p2p> skip to send Deauth to MAC:[%pM] for Rx Class 3.\n",
+				prStaRec->aucMacAddr);
+			return TRUE;
+		}
+#endif
+
+		if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter,
+							       prStaRec,
+							       NULL,
+							       REASON_CODE_CLASS_3_ERR,
+							       (PFN_TX_DONE_HANDLER) NULL))
+
+			DBGLOG(RSN, INFO, "Send Deauth to [ %pM ] for Rx Class 3 Error.\n",
+					   prStaRec->aucMacAddr);
+		else
+			DBGLOG(RSN, INFO, "Host sends Deauth to [ %pM ] for Rx Class 3 fail.\n",
+					   prStaRec->aucMacAddr);
+		return FALSE;
+	}
+
+	return secRxPortControlCheck(prAdapter, prSwRfb);
+}				/* end of secCheckClassError() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to setting the sta port status.
+*
+* \param[in]  prAdapter Pointer to the Adapter structure
+* \param[in]  prSta Pointer to the sta
+* \param[in]  fgPortBlock The port status
+*
+* \retval none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPortBlock)
+{
+	if (prSta == NULL)
+		return;
+
+	prSta->fgPortBlock = fgPortBlock;
+
+	DBGLOG(RSN, TRACE,
+	       "The STA %pM port %s\n", prSta->aucMacAddr, fgPortBlock == TRUE ? "BLOCK" : " OPEN");
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to report the sta port status.
+*
+* \param[in]  prAdapter Pointer to the Adapter structure
+* \param[in]  prSta Pointer to the sta
+* \param[out]  fgPortBlock The port status
+*
+* \return TRUE sta exist, FALSE sta not exist
+*
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secGetPortStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, OUT PBOOLEAN pfgPortStatus)
+{
+	if (prSta == NULL)
+		return FALSE;
+
+	*pfgPortStatus = prSta->fgPortBlock;
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to handle Peer device Tx Security process MSDU.
+*
+* \param[in] prMsduInfo pointer to the packet info pointer
+*
+* \retval TRUE Accept the packet
+* \retval FALSE Refuse the MSDU packet due port blocked
+*
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN				/* ENUM_PORT_CONTROL_RESULT */
+secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec)
+{
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+	ASSERT(prStaRec);
+
+	if (prStaRec) {
+
+		/* Todo:: */
+		if (prMsduInfo->fgIs802_1x)
+			return TRUE;
+
+		if (prStaRec->fgPortBlock == TRUE) {
+			DBGLOG(SEC, TRACE, "Drop Tx packet due Port Control!\n");
+			return FALSE;
+		}
+#if CFG_SUPPORT_WAPI
+		if (prAdapter->rWifiVar.rConnSettings.fgWapiMode)
+			return TRUE;
+#endif
+		if (IS_STA_IN_AIS(prStaRec)) {
+			if (!prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist &&
+			    (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED)) {
+				DBGLOG(SEC, TRACE, "Drop Tx packet due the key is removed!!!\n");
+				return FALSE;
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to handle The Rx Security process MSDU.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] prSWRfb SW rfb pinter
+*
+* \retval TRUE Accept the packet
+* \retval FALSE Refuse the MSDU packet due port control
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb)
+{
+	ASSERT(prSWRfb);
+
+#if 0
+	/* whsu:Todo: Process MGMT and DATA */
+	if (prSWRfb->prStaRec) {
+		if (prSWRfb->prStaRec->fgPortBlock == TRUE) {
+			if (1 /* prSWRfb->fgIsDataFrame and not 1x */  &&
+			    (g_prWifiVar->rConnSettings.eAuthMode >= AUTH_MODE_WPA)) {
+				/* DBGLOG(SEC, WARN, ("Drop Rx data due port control !\r\n")); */
+				return TRUE;	/* Todo: whsu FALSE; */
+			}
+			/* if (!RX_STATUS_IS_PROTECT(prSWRfb->prRxStatus)) { */
+			/* DBGLOG(RSN, WARN, ("Drop rcv non-encrypted data frame!\n")); */
+			/* return FALSE; */
+			/* } */
+		}
+	} else {
+	}
+#endif
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine will enable/disable the cipher suite
+*
+* \param[in] prAdapter Pointer to the adapter object data area.
+* \param[in] u4CipherSuitesFlags flag for cipher suite
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags)
+{
+	UINT_32 i;
+	P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry;
+	P_IEEE_802_11_MIB_T prMib;
+
+	ASSERT(prAdapter);
+
+	prMib = &prAdapter->rMib;
+
+	ASSERT(prMib);
+
+	if (u4CipherSuitesFlags == CIPHER_FLAG_NONE) {
+		/* Disable all the pairwise cipher suites. */
+		for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++)
+			prMib->dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE;
+
+		/* Update the group cipher suite. */
+		prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE;
+
+		return;
+	}
+
+	for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) {
+		prEntry = &prMib->dot11RSNAConfigPairwiseCiphersTable[i];
+
+		switch (prEntry->dot11RSNAConfigPairwiseCipher) {
+		case WPA_CIPHER_SUITE_WEP40:
+		case RSN_CIPHER_SUITE_WEP40:
+			if (u4CipherSuitesFlags & CIPHER_FLAG_WEP40)
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE;
+			else
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE;
+			break;
+
+		case WPA_CIPHER_SUITE_TKIP:
+		case RSN_CIPHER_SUITE_TKIP:
+			if (u4CipherSuitesFlags & CIPHER_FLAG_TKIP)
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE;
+			else
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE;
+			break;
+
+		case WPA_CIPHER_SUITE_CCMP:
+		case RSN_CIPHER_SUITE_CCMP:
+			if (u4CipherSuitesFlags & CIPHER_FLAG_CCMP)
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE;
+			else
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE;
+			break;
+
+		case WPA_CIPHER_SUITE_WEP104:
+		case RSN_CIPHER_SUITE_WEP104:
+			if (u4CipherSuitesFlags & CIPHER_FLAG_WEP104)
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE;
+			else
+				prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Update the group cipher suite. */
+	if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i))
+		prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_CCMP;
+	else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i))
+		prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_TKIP;
+	else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i))
+		prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP104;
+	else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i))
+		prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP40;
+	else
+		prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE;
+
+}				/* secSetCipherSuite */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to handle The 2nd Tx EAPoL Frame.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] prMsduInfo pointer to the packet info pointer
+* \param[in] pucPayload pointer to the 1x hdr
+* \param[in] u2PayloadLen the 1x payload length
+*
+* \retval TRUE Accept the packet
+* \retval FALSE Refuse the MSDU packet due port control
+*
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+secProcessEAPOL(IN P_ADAPTER_T prAdapter,
+		IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen)
+{
+	P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL;
+	P_IEEE_802_1X_HDR pr1xHdr;
+	UINT_16 u2KeyInfo;
+
+	ASSERT(prMsduInfo);
+	ASSERT(prStaRec);
+
+	/* prStaRec = &(g_arStaRec[prMsduInfo->ucStaRecIndex]); */
+	ASSERT(prStaRec);
+
+	if (prStaRec && IS_AP_STA(prStaRec)) {
+		pr1xHdr = (P_IEEE_802_1X_HDR) pucPayload;
+		if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) {
+			prEapol = (P_EAPOL_KEY) ((PUINT_32) (pucPayload + 4));
+			WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo);
+			if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) {
+				if (u2KeyInfo & WPA_KEY_INFO_SECURE) {
+					/* 4th EAPoL check at secHandleTxDoneCallback() */
+					/* DBGLOG(RSN, TRACE, ("Tx 4th EAPoL frame\r\n")); */
+				} else if (u2PayloadLen == 123 /* Not include LLC */) {
+					DBGLOG(RSN, INFO, "Tx 2nd EAPoL frame\r\n");
+					secFsmEvent2ndEapolTx(prAdapter, prStaRec);
+				}
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will handle the 4th EAPoL Tx done and mic Error Report frame.
+*
+* \param[in] prAdapter            Pointer to the Adapter structure
+* \param[in] pMsduInfo            Pointer to the Msdu Info
+* \param[in] rStatus                The Tx done status
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter,
+			IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus)
+{
+	PUINT_8 pucPayload;
+	P_IEEE_802_1X_HDR pr1xHdr = (P_IEEE_802_1X_HDR) NULL;
+	P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL;
+	UINT_16 u2KeyInfo;
+	UINT_16 u2PayloadLen;
+
+	DEBUGFUNC("secHandleTxDoneCallback");
+
+	ASSERT(prMsduInfo);
+	/* Todo:: Notice if using the TX free immediate after send to firmware, the payload may not correcttly!!!! */
+
+	ASSERT(prStaRec);
+
+	/* Todo:: This call back may not need because the order of set key and send 4th 1x can be make sure */
+	/* Todo:: Notice the LLC offset */
+#if 1
+	pucPayload = (PUINT_8) prMsduInfo->prPacket;
+	ASSERT(pucPayload);
+
+	u2PayloadLen = prMsduInfo->u2FrameLength;
+
+	if (0 /* prMsduInfo->fgIs1xFrame */) {
+
+		if (prStaRec && IS_AP_STA(prStaRec)) {
+			pr1xHdr = (P_IEEE_802_1X_HDR) (PUINT_32) (pucPayload + 8);
+			if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) {
+				prEapol = (P_EAPOL_KEY) (PUINT_32) (pucPayload + 12);
+				WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo);
+				if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) {
+					if (prStaRec->rSecInfo.fg2nd1xSend == TRUE
+					    && u2PayloadLen ==
+					    107 /* include LLC *//* u2KeyInfo & WPA_KEY_INFO_SECURE */) {
+						DBGLOG(RSN, INFO, "Tx 4th EAPoL frame\r\n");
+						secFsmEvent4ndEapolTxDone(prAdapter, prStaRec);
+					} else if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone) {
+						DBGLOG(RSN, INFO, "Tx EAPoL Error report frame\r\n");
+						/* secFsmEventEapolTxDone(prAdapter, (UINT_32)prMsduInfo->prStaRec); */
+					}
+				}
+			}
+		}
+
+	}
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to initialize the pmkid parameters.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+VOID secClearPmkid(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+	DEBUGFUNC("secClearPmkid");
+
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+	DBGLOG(RSN, TRACE, "secClearPmkid\n");
+	prAisSpecBssInfo->u4PmkidCandicateCount = 0;
+	prAisSpecBssInfo->u4PmkidCacheCount = 0;
+	kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCandicate, sizeof(PMKID_CANDICATE_T) * CFG_MAX_PMKID_CACHE);
+	kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Whether WPA, or WPA2 but not WPA-None is enabled.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+*
+* \retval BOOLEAN
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	ASSERT(prAdapter);
+
+	prConnSettings = &prAdapter->rWifiVar.rConnSettings;
+
+	ASSERT(prConnSettings);
+
+	ASSERT(prConnSettings->eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT);
+
+	if (prConnSettings->eEncStatus == ENUM_ENCRYPTION_DISABLED)
+		return FALSE;
+
+	ASSERT(prConnSettings->eAuthMode < AUTH_MODE_NUM);
+	if ((prConnSettings->eAuthMode >= AUTH_MODE_WPA) && (prConnSettings->eAuthMode != AUTH_MODE_WPA_NONE))
+		return TRUE;
+
+	return FALSE;
+}				/* secRsnKeyHandshakeEnabled */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Return whether the transmit key alread installed.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] prSta Pointer the sta record
+*
+* \retval TRUE Default key or Transmit key installed
+*         FALSE Default key or Transmit key not installed
+*
+* \note:
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	ASSERT(prSta);
+
+	if (prSta->fgTransmitKeyExist)
+		return TRUE;
+	else
+		return FALSE;
+}				/* secTransmitKeyExist */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Whether 802.11 privacy is enabled.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+*
+* \retval BOOLEAN
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter)
+{
+	DEBUGFUNC("secEnabled");
+
+	ASSERT(prAdapter->rWifiVar.rConnSettings.eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT);
+
+	switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) {
+	case ENUM_ENCRYPTION_DISABLED:
+		return FALSE;
+	case ENUM_ENCRYPTION1_ENABLED:
+	case ENUM_ENCRYPTION2_ENABLED:
+	case ENUM_ENCRYPTION3_ENABLED:
+		return TRUE;
+	default:
+		DBGLOG(RSN, TRACE, "Unknown encryption setting %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus);
+		break;
+	}
+	return FALSE;
+}				/* secEnabled */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the privacy bit at mac header for TxM
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+* \param[in] prMsdu the msdu for known the sta record
+*
+* \return TRUE the privacy need to set
+*            FALSE the privacy no need to set
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec)
+{
+	ASSERT(prAdapter);
+
+	ASSERT(prMsdu);
+
+	ASSERT(prStaRec);
+	/* prStaRec = &(g_arStaRec[prMsdu->ucStaRecIndex]); */
+
+	if (prStaRec == NULL) {
+		if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist)
+			return TRUE;
+		return FALSE;	/* No privacy bit */
+	}
+
+	/* Todo:: */
+	if (0 /* prMsdu->fgIs1xFrame */) {
+		if (IS_STA_IN_AIS(prStaRec) && prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) {
+			DBGLOG(RSN, LOUD, "For AIS Legacy 1x, always not encryped\n");
+			return FALSE;
+		} else if (!prStaRec->fgTransmitKeyExist) {
+			DBGLOG(RSN, LOUD, "1x Not Protected.\n");
+			return FALSE;
+		} else if (prStaRec->rSecInfo.fgKeyStored) {
+			DBGLOG(RSN, LOUD, "1x not Protected due key stored!\n");
+			return FALSE;
+		}
+		DBGLOG(RSN, LOUD, "1x Protected.\n");
+		return TRUE;
+	}
+	if (!prStaRec->fgTransmitKeyExist) {
+		/* whsu , check for AIS only */
+		if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA &&
+		    prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) {
+			DBGLOG(RSN, LOUD, "Protected\n");
+			return TRUE;
+		}
+	} else {
+			DBGLOG(RSN, LOUD, "Protected.\n");
+		return TRUE;
+	}
+
+	/* No sec or key is removed!!! */
+	return FALSE;
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c
new file mode 100644
index 0000000000000..fd0a8772a6665
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c
@@ -0,0 +1,497 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1
+*/
+
+/*! \file   "rate.c"
+    \brief  This file contains the transmission rate handling routines.
+
+    This file contains the transmission rate handling routines for setting up
+    ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do
+    conversion between Rate Set and Data Rates.
+*/
+
+/*
+** Log: rate.c
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add rate.c.
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Update comments
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix DBGLOG
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+**  \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461
+**  Fix the problem that do not ASSERT the length of Supported Rate IE == 8
+**  \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088
+**  fixed the lint "possible using null pointer" warning
+**  \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461
+**  Update for Driver Review
+**  \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461
+**  Revise GEN Link Speed OID
+**  \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461
+**  Add rateGetRateSetFromDataRates() for set desired rate OID
+**  \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461
+**  Add adopt operational rate as ACK rate if BasicRateSet was not found
+**  Add comments
+**  \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461
+**  Add initial rate according rx signal quality support
+**  \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461
+**  Fix typo of rate adaptation of CtrlResp Frame
+**  \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461
+**  Add VOIP SCAN Support  & Refine Roaming
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* The list of valid data rates. */
+const UINT_8 aucDataRate[] = {
+	RATE_1M,		/* RATE_1M_INDEX = 0 */
+	RATE_2M,		/* RATE_2M_INDEX */
+	RATE_5_5M,		/* RATE_5_5M_INDEX */
+	RATE_11M,		/* RATE_11M_INDEX */
+	RATE_22M,		/* RATE_22M_INDEX */
+	RATE_33M,		/* RATE_33M_INDEX */
+	RATE_6M,		/* RATE_6M_INDEX */
+	RATE_9M,		/* RATE_9M_INDEX */
+	RATE_12M,		/* RATE_12M_INDEX */
+	RATE_18M,		/* RATE_18M_INDEX */
+	RATE_24M,		/* RATE_24M_INDEX */
+	RATE_36M,		/* RATE_36M_INDEX */
+	RATE_48M,		/* RATE_48M_INDEX */
+	RATE_54M,		/* RATE_54M_INDEX */
+	RATE_HT_PHY		/* RATE_HT_PHY_INDEX */
+};
+
+static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = {
+	RATE_1M_INDEX,		/* RATE_1M_INDEX = 0 */
+	RATE_2M_INDEX,		/* RATE_2M_INDEX */
+	RATE_5_5M_INDEX,	/* RATE_5_5M_INDEX */
+	RATE_11M_INDEX,		/* RATE_11M_INDEX */
+	RATE_1M_INDEX,		/* RATE_22M_INDEX - Not supported */
+	RATE_1M_INDEX,		/* RATE_33M_INDEX - Not supported */
+	RATE_6M_INDEX,		/* RATE_6M_INDEX */
+	RATE_6M_INDEX,		/* RATE_9M_INDEX */
+	RATE_12M_INDEX,		/* RATE_12M_INDEX */
+	RATE_12M_INDEX,		/* RATE_18M_INDEX */
+	RATE_24M_INDEX,		/* RATE_24M_INDEX */
+	RATE_24M_INDEX,		/* RATE_36M_INDEX */
+	RATE_24M_INDEX,		/* RATE_48M_INDEX */
+	RATE_24M_INDEX		/* RATE_54M_INDEX */
+};
+
+const BOOLEAN afgIsOFDMRate[RATE_NUM] = {
+	FALSE,			/* RATE_1M_INDEX = 0 */
+	FALSE,			/* RATE_2M_INDEX */
+	FALSE,			/* RATE_5_5M_INDEX */
+	FALSE,			/* RATE_11M_INDEX */
+	FALSE,			/* RATE_22M_INDEX - Not supported */
+	FALSE,			/* RATE_33M_INDEX - Not supported */
+	TRUE,			/* RATE_6M_INDEX */
+	TRUE,			/* RATE_9M_INDEX */
+	TRUE,			/* RATE_12M_INDEX */
+	TRUE,			/* RATE_18M_INDEX */
+	TRUE,			/* RATE_24M_INDEX */
+	TRUE,			/* RATE_36M_INDEX */
+	TRUE,			/* RATE_48M_INDEX */
+	TRUE			/* RATE_54M_INDEX */
+};
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Convert the given Supported Rate & Extended Supported Rate IE to the
+*        Operational Rate Set and Basic Rate Set, and also check if any Basic
+*        Rate Code is unknown by driver.
+*
+* @param[in] prIeSupportedRate          Pointer to the Supported Rate IE
+* @param[in] prIeExtSupportedRate       Pointer to the Ext Supported Rate IE
+* @param[out] pu2OperationalRateSet     Pointer to the Operational Rate Set
+* @param[out] pu2BSSBasicRateSet        Pointer to the Basic Rate Set
+* @param[out] pfgIsUnknownBSSBasicRate  Pointer to a Flag to indicate that Basic
+*                                       Rate Set has unknown Rate Code
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate,
+		      IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate,
+		      OUT PUINT_16 pu2OperationalRateSet,
+		      OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate)
+{
+	UINT_16 u2OperationalRateSet = 0;
+	UINT_16 u2BSSBasicRateSet = 0;
+	BOOLEAN fgIsUnknownBSSBasicRate = FALSE;
+	UINT_8 ucRate;
+	UINT_32 i, j;
+
+	ASSERT(pu2OperationalRateSet);
+	ASSERT(pu2BSSBasicRateSet);
+	ASSERT(pfgIsUnknownBSSBasicRate);
+
+	if (prIeSupportedRate) {
+		/* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
+		 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
+		 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
+		 */
+		/* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */
+		ASSERT(prIeSupportedRate->ucLength <= RATE_NUM);
+
+		for (i = 0; i < prIeSupportedRate->ucLength; i++) {
+			ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK;
+
+			/* Search all valid data rates */
+			for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) {
+				if (ucRate == aucDataRate[j]) {
+					u2OperationalRateSet |= BIT(j);
+
+					if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)
+						u2BSSBasicRateSet |= BIT(j);
+
+					break;
+				}
+			}
+
+			if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) &&
+			    (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) {
+				fgIsUnknownBSSBasicRate = TRUE;	/* A data rate not list in the aucDataRate[] */
+			}
+		}
+	}
+
+	if (prIeExtSupportedRate) {
+		/* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */
+
+		for (i = 0; i < prIeExtSupportedRate->ucLength; i++) {
+			ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK;
+
+			/* Search all valid data rates */
+			for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) {
+				if (ucRate == aucDataRate[j]) {
+					u2OperationalRateSet |= BIT(j);
+
+					if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)
+						u2BSSBasicRateSet |= BIT(j);
+
+					break;
+				}
+			}
+
+			if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) &&
+			    (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) {
+				fgIsUnknownBSSBasicRate = TRUE;	/* A data rate not list in the aucDataRate[] */
+			}
+		}
+	}
+
+	*pu2OperationalRateSet = u2OperationalRateSet;
+	*pu2BSSBasicRateSet = u2BSSBasicRateSet;
+	*pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate;
+
+	return;
+
+}				/* end of rateGetRateSetFromIEs() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code
+*        Format for used in (Ext)Supportec Rate IE.
+*
+* @param[in] u2OperationalRateSet   Operational Rate Set
+* @param[in] u2BSSBasicRateSet      Basic Rate Set
+* @param[out] pucDataRates          Pointer to the Data Rate Buffer
+* @param[out] pucDataRatesLen       Pointer to the Data Rate Buffer Length
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet,
+			    IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen)
+{
+	UINT_32 i, j;
+
+	ASSERT(pucDataRates);
+	ASSERT(pucDataRatesLen);
+
+	ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
+
+	for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) {
+		if (u2OperationalRateSet & BIT(i)) {
+
+			*(pucDataRates + j) = aucDataRate[i];
+
+			if (u2BSSBasicRateSet & BIT(i))
+				*(pucDataRates + j) |= RATE_BASIC_BIT;
+
+			j++;
+		}
+	}
+
+	*pucDataRatesLen = (UINT_8) j;
+
+	return;
+
+}				/* end of rateGetDataRatesFromRateSet() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Get the highest rate from given Rate Set.
+*
+* \param[in] u2RateSet              Rate Set
+* \param[out] pucHighestRateIndex   Pointer to buffer of the Highest Rate Index
+*
+* \retval TRUE  Highest Rate Index was found
+* \retval FALSE Highest Rate Index was not found
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex)
+{
+	INT_32 i;
+
+	ASSERT(pucHighestRateIndex);
+
+	for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
+		if (u2RateSet & BIT(i)) {
+			*pucHighestRateIndex = (UINT_8) i;
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+
+}				/* end of rateGetHighestRateIndexFromRateSet() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Get the lowest rate from given Rate Set.
+*
+* \param[in] u2RateSet              Rate Set
+* \param[out] pucLowestRateIndex    Pointer to buffer of the Lowest Rate Index
+*
+* \retval TRUE  Lowest Rate Index was found
+* \retval FALSE Lowest Rate Index was not found
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex)
+{
+	UINT_32 i;
+
+	ASSERT(pucLowestRateIndex);
+
+	for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) {
+		if (u2RateSet & BIT(i)) {
+			*pucLowestRateIndex = (UINT_8) i;
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+
+}				/* end of rateGetLowestRateIndexFromRateSet() */
+
+#if 0				/* NOTE(Kevin): For reference */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Convert the given Data Rates to the Rate Set.
+*
+* \param[in] pucDataRates       Pointer to the Data Rates
+* \param[in] ucDataRatesLen     Length of given Data Rates
+* \param[out] pu2RateSet        Pointer to the Rate Set
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates, IN UINT_8 ucDataRatesLen, OUT PUINT_16 pu2RateSet)
+{
+	UINT_16 u2RateSet = 0;
+	UINT_8 ucRate;
+	UINT_32 i, j;
+
+	ASSERT(pucDataRates);
+	ASSERT(pu2RateSet);
+
+	if (pucDataRates) {
+		for (i = 0; i < ucDataRatesLen; i++) {
+			ucRate = pucDataRates[i] & RATE_MASK;
+
+			/* Search all valid data rates */
+			for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) {
+				if (ucRate == aucDataRate[j]) {
+					u2RateSet |= BIT(j);
+					break;
+				}
+			}
+		}
+	}
+
+	*pu2RateSet = u2RateSet;
+
+	return;
+
+}				/* end of rateGetRateSetFromDataRates() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding
+*        ACK/CTS(Respnose) TX Rates.
+*
+* \param[in] u2OperationalRateSet   Operational Rate Set
+* \param[in] u2BSSBasicRateSet      Basic Rate Set
+* \param[out] aucAckCtsRateIndex    Pointer to the Ack/Cts Data Rate Buffer
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet,
+				  IN UINT_16 u2BSSBasicRateSet, IN OUT UINT_8 aucAckCtsRateIndex[])
+{
+	INT_32 i, j;
+
+	ASSERT(aucAckCtsRateIndex);
+	ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
+
+	/* Setup default ACK/CTS response rate */
+	kalMemCopy(aucAckCtsRateIndex, (PVOID) aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex));
+
+	for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
+		if (u2OperationalRateSet & BIT(i)) {
+			for (j = i; j >= RATE_1M_INDEX; j--) {
+				if (u2BSSBasicRateSet & BIT(j)) {
+					/* Reply ACK Frame at the same Modulation Scheme. */
+					if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) ||
+					    (!afgIsOFDMRate[i] && !afgIsOFDMRate[j]))
+						aucAckCtsRateIndex[i] = (UINT_8) j;
+					break;
+				}
+			}
+
+			/* NOTE(Kevin 2008/03/25): Following code is used for those AP which has
+			 * NULL BasicRateSet.
+			 * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL.
+			 * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"].
+			 * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M],
+			 * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still
+			 * use highest mandatory rate as default.
+			 */
+			if (j < RATE_1M_INDEX) {	/* The ACK/CTS rate was not found in BasicRateSet */
+				if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet))
+					aucAckCtsRateIndex[i] = (UINT_8) i;
+			}
+		}
+	}
+
+	return;
+
+}				/* end of rateSetAckCtsDataRatesFromRateSet() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Get the proper initial rate from Rate Set according to given RCPI value
+*
+* \param[in] u2RateSet              Rate Set
+* \param[in] rRcpi                  RCPI value from AP or Peer STA
+* \param[out] pucInitialRateIndex   Pointer to buffer of the initial Rate Index
+*
+* \retval TRUE  Initial Rate Index was found
+* \retval FALSE Initial Rate Index was not found
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rateGetBestInitialRateIndex(IN UINT_16 u2RateSet, IN RCPI rRcpi, OUT PUINT_8 pucInitialRateIndex)
+{
+	UINT_16 u2InitRateSet;
+	INT_32 i;
+
+	ASSERT(pucInitialRateIndex);
+
+	DBGLOG(MGT, TRACE, "rRcpi = %d\n", rRcpi);
+
+	if (rRcpi >= RCPI_100) {	/* Best Signal */
+		u2InitRateSet = INITIAL_RATE_SET(RCPI_100);
+	} else if (rRcpi >= RCPI_80) {	/* Better Signal */
+		u2InitRateSet = INITIAL_RATE_SET(RCPI_80);
+	} else if (rRcpi >= RCPI_60) {	/* Good Signal */
+		u2InitRateSet = INITIAL_RATE_SET(RCPI_60);
+	} else {		/* Worse Signal */
+		/* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index
+		 * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in
+		 * function - bssUpdateTxRateForControlFrame().
+		 */
+		return FALSE;
+	}
+
+	u2RateSet &= u2InitRateSet;
+
+	for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
+		if (u2RateSet & BIT(i)) {
+			*pucInitialRateIndex = (UINT_8) i;
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+
+}				/* end of rateGetBestInitialRateIndex() */
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c
new file mode 100644
index 0000000000000..244346983f405
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c
@@ -0,0 +1,1858 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#2
+*/
+
+/*! \file   "rlm.c"
+    \brief
+
+*/
+
+/*
+** Log: rlm.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 11 15 2011 cm.chang
+ * NULL
+ * Check length HT cap IE about RX associate request frame
+ *
+ * 11 10 2011 cm.chang
+ * NULL
+ * Modify debug message for XLOG
+ *
+ * 11 08 2011 cm.chang
+ * NULL
+ * Add RLM and CNM debug message for XLOG
+ *
+ * 11 03 2011 cm.chang
+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
+ * Fix preamble type of STA mode
+ *
+ * 10 25 2011 cm.chang
+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
+ * Not send ERP IE if peer STA is 802.11b-only
+ *
+ * 10 11 2011 cm.chang
+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter
+ * Ignore HT OP IE if its length field is not valid
+ *
+ * 09 28 2011 cm.chang
+ * NULL
+ * Add length check to reduce possibility to adopt wrong IE
+ *
+ * 09 20 2011 cm.chang
+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
+ * Handle client mode about preamble type and slot time
+ *
+ * 09 01 2011 cm.chang
+ * [WCXRP00000971] [MT6620 Wi-Fi][Driver][FW] Not set Beacon timeout interval when CPTT
+ * Final channel number only adopts the field from assoc response
+ *
+ * 06 10 2011 cm.chang
+ * [WCXRP00000773] [MT6620 Wi-Fi][Driver] Workaround some AP fill primary channel field with its secondary channel
+ * If DS IE exists, ignore the primary channel field in HT OP IE
+ *
+ * 05 03 2011 cm.chang
+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
+ * Fix compiling error
+ *
+ * 05 02 2011 cm.chang
+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
+ * Refine range of valid channel number
+ *
+ * 05 02 2011 cm.chang
+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
+ * Check if channel is valided before record ing BSS channel
+ *
+ * 04 14 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 03 29 2011 cm.chang
+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning
+ * As CR title
+ *
+ * 01 24 2011 cm.chang
+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode
+ * and stop ampdu timer when sta_rec is freed
+ * Process received 20/40 coexistence action frame for AP mode
+ *
+ * 12 13 2010 cp.wu
+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
+ * create branch for Wi-Fi driver v1.1
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 10 15 2010 cm.chang
+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
+ * Add exception handle when no mgmt buffer in free build
+ *
+ * 10 08 2010 cm.chang
+ * NULL
+ * When 20M only setting, ignore OBSS IE
+ *
+ * 09 16 2010 cm.chang
+ * NULL
+ * Change conditional compiling options for BOW
+ *
+ * 09 10 2010 cm.chang
+ * NULL
+ * Always update Beacon content if FW sync OBSS info
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 23 2010 cp.wu
+ * NULL
+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Temporary add rlmUpdateParamByStaForBow() and rlmBssInitForBow().
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Add CFG_ENABLE_BT_OVER_WIFI.
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * P2P Group Negotiation Code Check in.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Fix compile error while enabling WiFi Direct function.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add P2P Scan & Scan Result Parsing & Saving.
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * take use of RLM module for parsing/generating HT IEs for 11n capability
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 06 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Fix channel ID definition in RFB status to primary channel instead of center channel
+ *
+ * 06 02 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add TX short GI compiling option
+ *
+ * 06 02 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Roll back to remove CFG_SUPPORT_BCM_TEST.
+ *
+ * 06 01 2010 chinghwa.yu
+ * [BORA00000563]Add WiFi CoEx BCM module
+ * Update BCM Test and RW configuration.
+ *
+ * 05 31 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add some compiling options to control 11n functions
+ *
+ * 05 28 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Set RTS threshold of 2K bytes initially
+ *
+ * 05 18 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs
+ *
+ * 05 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Process 20/40 coexistence public action frame in AP mode
+ *
+ * 05 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft support for 20/40M bandwidth for AP mode
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft code to support protection in AP mode
+ *
+ * 04 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Utilize status of swRfb to know channel number and band
+ *
+ * 04 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Different invoking order for WTBL entry of associated AP
+ *
+ * 04 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add virtual test for OBSS scan
+ *
+ * 04 02 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Process Beacon only ready for infra STA now
+ *
+ * 03 30 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support 2.4G OBSS scan
+ *
+ * 03 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Not carry  HT cap when being associated with b/g only AP
+ *
+ * 03 24 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * fixed some WHQL testing error.
+ *
+ * 03 15 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Provide draft measurement and quiet functions
+ *
+ * 03 09 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * If bss is not 11n network, zero WTBL HT parameters
+ *
+ * 03 03 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * To support CFG_SUPPORT_BCM_STP
+ *
+ * 03 02 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Generate HT IE only depending on own phyTypeSet
+ *
+ * 03 02 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Not fill HT related IE if BssInfo does not include 11n phySet
+ *
+ * 03 01 2010 tehuang.liu
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * To store field AMPDU Parameters in STA_REC
+ *
+ * 02 26 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Enable RDG RX, but disable RDG TX for IOT and LongNAV
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Use bss info array for concurrent handle
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+ *
+ * 01 07 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Modify the parameter of rlmRecAssocRspHtInfo function
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 12 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix prBssInfo->ucPrimaryChannel handle for assoc resp
+ *
+ * Dec 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add some function to process HT operation
+ *
+ * Nov 28 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Call rlmStatisticsInit() to handle MIB counters
+ *
+ * Nov 18 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo);
+
+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo);
+
+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo);
+
+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength);
+
+static BOOLEAN
+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter,
+			       P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength);
+
+static BOOLEAN
+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter,
+		       P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength);
+
+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	/* Note: assume TIMER_T structures are reset to zero or stopped
+	 * before invoking this function.
+	 */
+
+	/* Initialize OBSS FSM */
+	rlmObssInit(prAdapter);
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+	rlmDomainCheckCountryPowerLimitTable(prAdapter);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter)
+{
+	P_BSS_INFO_T prBssInfo;
+	UINT_8 ucNetIdx;
+
+	ASSERT(prAdapter);
+
+	RLM_NET_FOR_EACH(ucNetIdx) {
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
+		ASSERT(prBssInfo);
+
+		/* Note: all RLM timers will also be stopped.
+		 *       Now only one OBSS scan timer.
+		 */
+		rlmBssReset(prAdapter, prBssInfo);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief For probe request, association request
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
+	ASSERT(prBssInfo);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) &&
+	    (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)))
+		rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief For probe request, association request
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
+	ASSERT(prBssInfo);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) &&
+	    (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)))
+		rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo);
+#if CFG_SUPPORT_HOTSPOT_2_0
+	else if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE)
+		hs20FillExtCapIE(prAdapter, prBssInfo, prMsduInfo);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief For probe response (GO, IBSS) and association response
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+	ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
+	ASSERT(prBssInfo);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)))
+		rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief For probe response (GO, IBSS) and association response
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+	ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
+	ASSERT(prBssInfo);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)))
+		rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief For probe response (GO, IBSS) and association response
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+	ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
+	ASSERT(prBssInfo);
+
+	if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)))
+		rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief For probe response (GO, IBSS) and association response
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+	P_IE_ERP_T prErpIe;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+	ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
+	ASSERT(prBssInfo);
+
+	if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 &&
+	    (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) {
+		prErpIe = (P_IE_ERP_T)
+		    (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+
+		/* Add ERP IE */
+		prErpIe->ucId = ELEM_ID_ERP_INFO;
+		prErpIe->ucLength = 1;
+
+		prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ? ERP_INFO_USE_PROTECTION : 0;
+
+		if (prBssInfo->fgErpProtectMode)
+			prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION);
+
+		/* Handle barker preamble */
+		if (!prBssInfo->fgUseShortPreamble)
+			prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE;
+
+		ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP));
+
+		prMsduInfo->u2FrameLength += IE_SIZE(prErpIe);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+UINT32
+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed,
+		       BOOLEAN fgShortGIDisabled,
+		       UINT_8 u8SupportRxSgi20,
+		       UINT_8 u8SupportRxSgi40,
+		       UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf)
+{
+	P_IE_HT_CAP_T prHtCap;
+	P_SUP_MCS_SET_FIELD prSupMcsSet;
+
+	ASSERT(pOutBuf);
+
+	prHtCap = (P_IE_HT_CAP_T) pOutBuf;
+
+	/* Add HT capabilities IE */
+	prHtCap->ucId = ELEM_ID_HT_CAP;
+	prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN;
+
+	prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL;
+	if (!fg40mAllowed) {
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH |
+					  HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M);
+	}
+	if (fgShortGIDisabled)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M);
+
+	if (u8SupportRxSgi20 == 2)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M);
+	if (u8SupportRxSgi40 == 2)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M);
+	if (u8SupportRxGf == 2)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF);
+	if (u8SupportRxSTBC == 2)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_RX_STBC_1_SS);
+	prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL;
+
+	prSupMcsSet = &prHtCap->rSupMcsSet;
+	kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM);
+
+	prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7);
+
+	if (fg40mAllowed)
+		prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0);	/* MCS32 */
+	prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE;
+	prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL;
+
+	prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL;
+	if (!fg40mAllowed || eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+		prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE);
+
+	prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL;
+
+	prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL;
+
+	ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP));
+
+	return IE_SIZE(prHtCap);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo)
+{
+	P_IE_HT_CAP_T prHtCap;
+/* P_SUP_MCS_SET_FIELD     prSupMcsSet; */
+	BOOLEAN fg40mAllowed;
+
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+	ASSERT(prMsduInfo);
+
+	fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
+
+	prHtCap = (P_IE_HT_CAP_T)
+	    (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+
+#if 0
+	/* Add HT capabilities IE */
+	prHtCap->ucId = ELEM_ID_HT_CAP;
+	prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN;
+
+	prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL;
+	if (!fg40mAllowed)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH |
+					  HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M);
+	if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M);
+
+	if (prAdapter->rWifiVar.u8SupportRxSgi20 == 2)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M);
+	if (prAdapter->rWifiVar.u8SupportRxSgi40 == 2)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M);
+	if (prAdapter->rWifiVar.u8SupportRxGf == 2)
+		prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF);
+
+	prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL;
+
+	prSupMcsSet = &prHtCap->rSupMcsSet;
+	kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM);
+
+	prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7);
+
+	if (fg40mAllowed)
+		prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0);	/* MCS32 */
+	prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE;
+	prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL;
+
+	prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL;
+	if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+		prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE);
+
+	prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL;
+
+	prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL;
+
+	ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP));
+
+	prMsduInfo->u2FrameLength += IE_SIZE(prHtCap);
+#else
+
+	prMsduInfo->u2FrameLength += rlmFillHtCapIEByParams(fg40mAllowed,
+							    prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled,
+							    prAdapter->rWifiVar.u8SupportRxSgi20,
+							    prAdapter->rWifiVar.u8SupportRxSgi40,
+							    prAdapter->rWifiVar.u8SupportRxGf,
+							    prAdapter->rWifiVar.u8SupportRxSTBC,
+							    prBssInfo->eCurrentOPMode, (UINT_8 *) prHtCap);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo)
+{
+#if CFG_SUPPORT_HOTSPOT_2_0
+	P_HS20_EXT_CAP_T prHsExtCap;
+#else
+	P_EXT_CAP_T prExtCap;
+#endif
+	BOOLEAN fg40mAllowed;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+	prHsExtCap = (P_HS20_EXT_CAP_T)
+	    (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+	prHsExtCap->ucId = ELEM_ID_EXTENDED_CAP;
+
+	if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE)
+		prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP;
+	else
+		prHsExtCap->ucLength = 3 - ELEM_HDR_LEN;
+
+	kalMemZero(prHsExtCap->aucCapabilities, sizeof(prHsExtCap->aucCapabilities));
+
+	prHsExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL;
+
+	if (!fg40mAllowed)
+		prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT;
+
+	if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+		prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP;
+
+	if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) {
+		SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT);
+
+		/* For R2 WNM-Notification */
+		SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT);
+	}
+
+	ASSERT(IE_SIZE(prHsExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP));
+
+	prMsduInfo->u2FrameLength += IE_SIZE(prHsExtCap);
+
+#else
+	/* Add Extended Capabilities IE */
+	prExtCap = (P_EXT_CAP_T)
+	    (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+
+	prExtCap->ucId = ELEM_ID_EXTENDED_CAP;
+
+	prExtCap->ucLength = 3 - ELEM_HDR_LEN;
+	kalMemZero(prExtCap->aucCapabilities, sizeof(prExtCap->aucCapabilities));
+
+	prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL;
+
+	if (!fg40mAllowed)
+		prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT;
+
+	if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+		prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP;
+
+	ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP));
+
+	prMsduInfo->u2FrameLength += IE_SIZE(prExtCap);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme)
+{
+	P_IE_HT_OP_T prHtOp;
+	UINT_16 i;
+
+	prHtOp = (P_IE_HT_OP_T) pFme;
+
+	/* Add HT operation IE */
+	prHtOp->ucId = ELEM_ID_HT_OP;
+	prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN;
+
+	/* RIFS and 20/40 bandwidth operations are included */
+	prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
+	prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1;
+
+	/* Decide HT protection mode field */
+	if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT)
+		prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT;
+	else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER)
+		prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER;
+	else {
+		/* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */
+		prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode;
+	}
+
+	if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) {
+		/* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED
+		 * Note: it will also be set in ad-hoc network
+		 */
+		prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT;
+	}
+
+	if (0 /* Regulatory class 16 */  &&
+	    prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
+		/* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection
+		 * although it is possible to have no protection by spec.
+		 */
+		prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT;
+	}
+
+	prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3;	/* To do: handle L-SIG TXOP */
+
+	/* No basic MCSx are needed temporarily */
+	for (i = 0; i < 16; i++)
+		prHtOp->aucBasicMcsSet[i] = 0;
+
+	return sizeof(IE_HT_OP_T);
+}
+
+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo)
+{
+/* P_IE_HT_OP_T        prHtOp; */
+/* UINT_16             i; */
+
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+	ASSERT(prMsduInfo);
+
+	prMsduInfo->u2FrameLength += rlmFillHtOpIeBody(prBssInfo,
+						       (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength));
+#if 0
+	prHtOp = (P_IE_HT_OP_T)
+	    (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+
+	/* Add HT operation IE */
+	prHtOp->ucId = ELEM_ID_HT_OP;
+	prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN;
+
+	/* RIFS and 20/40 bandwidth operations are included */
+	prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
+	prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1;
+
+	/* Decide HT protection mode field */
+	if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT)
+		prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT;
+	else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER)
+		prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER;
+	else {
+		/* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */
+		prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode;
+	}
+
+	if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) {
+		/* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED
+		 * Note: it will also be set in ad-hoc network
+		 */
+		prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT;
+	}
+
+	if (0 /* Regulatory class 16 */  &&
+	    prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
+		/* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection
+		 * although it is possible to have no protection by spec.
+		 */
+		prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT;
+	}
+
+	prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3;	/* To do: handle L-SIG TXOP */
+
+	/* No basic MCSx are needed temporarily */
+	for (i = 0; i < 16; i++)
+		prHtOp->aucBasicMcsSet[i] = 0;
+
+	ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP));
+
+	prMsduInfo->u2FrameLength += IE_SIZE(prHtOp);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function should be invoked to update parameters of associated AP.
+*        (Association response and Beacon)
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength)
+{
+	UINT_16 u2Offset;
+	P_STA_RECORD_T prStaRec;
+	P_IE_HT_CAP_T prHtCap;
+	P_IE_HT_OP_T prHtOp;
+	P_IE_OBSS_SCAN_PARAM_T prObssScnParam;
+	UINT_8 ucERP, ucPrimaryChannel;
+#if CFG_SUPPORT_QUIET && 0
+	BOOLEAN fgHasQuietIE = FALSE;
+#endif
+
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+	ASSERT(pucIE);
+
+	prStaRec = prBssInfo->prStaRecOfAP;
+	ASSERT(prStaRec);
+	if (!prStaRec)
+		return 0;
+
+	prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
+	ucPrimaryChannel = 0;
+	prObssScnParam = NULL;
+
+	/* Note: HT-related members in staRec may not be zero before, so
+	 *       if following IE does not exist, they are still not zero.
+	 *       These HT-related parameters are valid only when the corresponding
+	 *       BssInfo supports 802.11n, i.e., RLM_NET_IS_11N()
+	 */
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_HT_CAP:
+			if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2))
+				break;
+			prHtCap = (P_IE_HT_CAP_T) pucIE;
+			prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
+			prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE;
+
+			prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
+			prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
+			prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
+			prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
+			prStaRec->ucAselCap = prHtCap->ucAselCap;
+			break;
+
+		case ELEM_ID_HT_OP:
+			if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2))
+				break;
+			prHtOp = (P_IE_HT_OP_T) pucIE;
+			/* Workaround that some APs fill primary channel field by its
+			 * secondary channel, but its DS IE is correct 20110610
+			 */
+			if (ucPrimaryChannel == 0)
+				ucPrimaryChannel = prHtOp->ucPrimaryChannel;
+			prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1;
+			prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2;
+			prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3;
+
+			if (!prBssInfo->fg40mBwAllowed)
+				prBssInfo->ucHtOpInfo1 &= ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH);
+
+			if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES)
+				prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)(prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO);
+
+			prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T)
+			    (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION);
+
+			/* To do: process regulatory class 16 */
+			if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT)
+			    && 0 /* && regulatory class is 16 */)
+				prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED;
+			else if (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT)
+				prBssInfo->eGfOperationMode = GF_MODE_PROTECT;
+			else
+				prBssInfo->eGfOperationMode = GF_MODE_NORMAL;
+
+			prBssInfo->eRifsOperationMode =
+			    (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ? RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED;
+
+			break;
+
+		case ELEM_ID_20_40_BSS_COEXISTENCE:
+			if (!RLM_NET_IS_11N(prBssInfo))
+				break;
+			/* To do: store if scanning exemption grant to BssInfo */
+			break;
+
+		case ELEM_ID_OBSS_SCAN_PARAMS:
+			if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2))
+				break;
+			/* Store OBSS parameters to BssInfo */
+			prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE;
+			break;
+
+		case ELEM_ID_EXTENDED_CAP:
+			if (!RLM_NET_IS_11N(prBssInfo))
+				break;
+			/* To do: store extended capability (PSMP, coexist) to BssInfo */
+			break;
+
+		case ELEM_ID_ERP_INFO:
+			if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) || prBssInfo->eBand != BAND_2G4)
+				break;
+			ucERP = ERP_INFO_IE(pucIE)->ucERP;
+			prBssInfo->fgErpProtectMode = (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE;
+
+			if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE)
+				prBssInfo->fgUseShortPreamble = FALSE;
+			break;
+
+		case ELEM_ID_DS_PARAM_SET:
+			if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET)
+				ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
+			break;
+
+#if CFG_SUPPORT_DFS		/* Add by Enlai */
+		case ELEM_ID_CH_SW_ANNOUNCEMENT:
+			{
+				rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) pucIE);
+			}
+			break;
+
+#if CFG_SUPPORT_QUIET && 0
+			/* Note: RRM code should be moved to independent RRM function by
+			 *       component design rule. But we attach it to RLM temporarily
+			 */
+		case ELEM_ID_QUIET:
+			rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE);
+			fgHasQuietIE = TRUE;
+			break;
+#endif
+#endif
+
+		default:
+			break;
+		}		/* end of switch */
+	}			/* end of IE_FOR_EACH */
+
+	/* Some AP will have wrong channel number (255) when running time.
+	 * Check if correct channel number information. 20110501
+	 */
+	if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) ||
+	    (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14)))
+		ucPrimaryChannel = 0;
+#if CFG_SUPPORT_QUIET && 0
+	if (!fgHasQuietIE)
+		rrmQuietIeNotExist(prAdapter, prBssInfo);
+#endif
+
+	/* Check if OBSS scan process will launch */
+	if (!prAdapter->fgEnOnlineScan || !prObssScnParam ||
+	    !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) ||
+	    prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) {
+
+		/* Note: it is ok not to stop rObssScanTimer() here */
+		prBssInfo->u2ObssScanInterval = 0;
+	} else {
+		if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL)
+			prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL;
+		if (prBssInfo->u2ObssScanInterval != prObssScnParam->u2TriggerScanInterval) {
+
+			prBssInfo->u2ObssScanInterval = prObssScnParam->u2TriggerScanInterval;
+
+			/* Start timer to trigger OBSS scanning */
+			cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
+					   prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
+		}
+	}
+
+	return ucPrimaryChannel;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief AIS or P2P GC.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static BOOLEAN
+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter,
+			       P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
+{
+	UINT_16 u2Offset, i;
+	UINT_8 ucPriChannel, ucSecChannel;
+	ENUM_CHNL_EXT_T eSCO;
+	BOOLEAN fgHtBss, fg20mReq;
+
+	if ((prAdapter == NULL)
+		|| (pucIE == NULL)
+		|| (prBssInfo == NULL)
+		|| (prSwRfb == NULL)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	/* Record it to channel list to change 20/40 bandwidth */
+	ucPriChannel = 0;
+	eSCO = CHNL_EXT_SCN;
+
+	fgHtBss = FALSE;
+	fg20mReq = FALSE;
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_HT_CAP:
+			{
+				P_IE_HT_CAP_T prHtCap;
+
+				if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2))
+					break;
+
+				prHtCap = (P_IE_HT_CAP_T) pucIE;
+				if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT)
+					fg20mReq = TRUE;
+				fgHtBss = TRUE;
+				break;
+			}
+		case ELEM_ID_HT_OP:
+			{
+				P_IE_HT_OP_T prHtOp;
+
+				if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2))
+					break;
+
+				prHtOp = (P_IE_HT_OP_T) pucIE;
+				/* Workaround that some APs fill primary channel field by its
+				 * secondary channel, but its DS IE is correct 20110610
+				 */
+				if (ucPriChannel == 0)
+					ucPriChannel = prHtOp->ucPrimaryChannel;
+
+				if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES)
+					eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO);
+				break;
+			}
+		case ELEM_ID_20_40_BSS_COEXISTENCE:
+			{
+				P_IE_20_40_COEXIST_T prCoexist;
+
+				if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2))
+					break;
+
+				prCoexist = (P_IE_20_40_COEXIST_T) pucIE;
+				if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT)
+					fg20mReq = TRUE;
+				break;
+			}
+		case ELEM_ID_DS_PARAM_SET:
+			if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2))
+				break;
+			ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/* To do: Update channel list and 5G band. All channel lists have the same
+	 * update procedure. We should give it the entry pointer of desired
+	 * channel list.
+	 */
+	if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4)
+		return FALSE;
+
+	if (ucPriChannel == 0 || ucPriChannel > 14)
+		ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr);
+
+	if (fgHtBss) {
+		ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G);
+		for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+			if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel)
+				break;
+		}
+		if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
+			prBssInfo->auc2G_PriChnlList[i] = ucPriChannel;
+			prBssInfo->auc2G_PriChnlList[0]++;
+		}
+
+		/* Update secondary channel */
+		if (eSCO != CHNL_EXT_SCN) {
+			ucSecChannel = (eSCO == CHNL_EXT_SCA) ? (ucPriChannel + 4) : (ucPriChannel - 4);
+
+			ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G);
+			for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+				if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel)
+					break;
+			}
+			if ((i > prBssInfo->auc2G_SecChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
+				prBssInfo->auc2G_SecChnlList[i] = ucSecChannel;
+				prBssInfo->auc2G_SecChnlList[0]++;
+			}
+		}
+
+		/* Update 20M bandwidth request channels */
+		if (fg20mReq) {
+			ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
+			for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+				if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel)
+					break;
+			}
+			if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
+				prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel;
+				prBssInfo->auc2G_20mReqChnlList[0]++;
+			}
+		}
+	} else {
+		/* Update non-HT channel list */
+		ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
+		for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
+			if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel)
+				break;
+		}
+		if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
+			prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel;
+			prBssInfo->auc2G_NonHtChnlList[0]++;
+		}
+
+	}
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief AIS or P2P GC.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static BOOLEAN
+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter,
+		       P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
+{
+	if ((prAdapter == NULL)
+		|| (pucIE == NULL)
+		|| (prBssInfo == NULL)
+		|| (prSwRfb == NULL)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+#if 0				/* SW migration 2010/8/20 */
+	/* Note: we shall not update parameters when scanning, otherwise
+	 *       channel and bandwidth will not be correct or asserted failure
+	 *       during scanning.
+	 * Note: remove channel checking. All received Beacons should be processed
+	 *       if measurement or other actions are executed in adjacent channels
+	 *       and Beacon content checking mechanism is not disabled.
+	 */
+	if (IS_SCAN_ACTIVE()
+	    /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */
+	    ) {
+		return FALSE;
+	}
+#endif
+
+	/* Handle change of slot time */
+	prBssInfo->u2CapInfo = ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->u2CapInfo;
+	prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
+
+	rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength);
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
+{
+	P_BSS_INFO_T prBssInfo;
+	BOOLEAN fgNewParameter;
+	UINT_8 ucNetIdx;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+	ASSERT(pucIE);
+
+	fgNewParameter = FALSE;
+
+	/* When concurrent networks exist, GO shall have the same handle as
+	 * the other BSS, so the Beacon shall be processed for bandwidth and
+	 * protection mechanism.
+	 * Note1: we do not have 2 AP (GO) cases simultaneously now.
+	 * Note2: If we are GO, concurrent AIS AP should detect it and reflect
+	 *        action in its Beacon, so AIS STA just follows Beacon from AP.
+	 */
+	RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) {
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
+		ASSERT(prBssInfo);
+
+		if (IS_BSS_ACTIVE(prBssInfo)) {
+			if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE &&
+			    prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+				/* P2P client or AIS infra STA */
+				if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, ((P_WLAN_MAC_MGMT_HEADER_T)
+									 (prSwRfb->pvHeader))->aucBSSID)) {
+
+					fgNewParameter = rlmRecBcnInfoForClient(prAdapter,
+										prBssInfo, prSwRfb, pucIE, u2IELength);
+				} else {
+					fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter,
+											prBssInfo, prSwRfb, pucIE,
+											u2IELength);
+				}
+			}
+#if CFG_ENABLE_WIFI_DIRECT
+			else if (prAdapter->fgIsP2PRegistered &&
+				 (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT ||
+				  prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) {
+				/* AP scan to check if 20/40M bandwidth is permitted */
+				rlmRecBcnFromNeighborForClient(prAdapter, prBssInfo, prSwRfb, pucIE, u2IELength);
+			}
+#endif
+			else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
+				/* Do nothing */
+				/* To do: Ad-hoc */
+			}
+
+			/* Appy new parameters if necessary */
+			if (fgNewParameter) {
+				DBGLOG(RLM, TRACE, "rlmProcessBcn\n");
+				rlmSyncOperationParams(prAdapter, prBssInfo);
+				fgNewParameter = FALSE;
+			}
+		}		/* end of IS_BSS_ACTIVE() */
+	}			/* end of RLM_NET_FOR_EACH_NO_BOW */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function should be invoked after judging successful association.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+	UINT_8 ucPriChannel;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+	ASSERT(pucIE);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+	if (!prStaRec)
+		return;
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
+	ASSERT(prStaRec == prBssInfo->prStaRecOfAP);
+
+	/* To do: the invoked function is used to clear all members. It may be
+	 *        done by center mechanism in invoker.
+	 */
+	rlmBssReset(prAdapter, prBssInfo);
+
+	prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
+
+	ucPriChannel = rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength);
+	if (ucPriChannel > 0)
+		prBssInfo->ucPrimaryChannel = ucPriChannel;
+
+	if (!RLM_NET_IS_11N(prBssInfo) || !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH))
+		prBssInfo->fg40mBwAllowed = FALSE;
+
+	/* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which
+	 *       shall be invoked afterwards.
+	 *       Update channel, bandwidth and protection mode by nicUpdateBss()
+	 */
+#if 1
+	if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
+
+		DBGLOG(P2P, WARN, "Force P2P BW to 20\n");
+		prBssInfo->fgAssoc40mBwAllowed = FALSE;
+	}
+#endif
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function should be invoked after judging successful association.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo)
+{
+	ASSERT(prCmdBody && prBssInfo);
+	if (!prCmdBody || !prBssInfo)
+		return;
+
+	prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex;
+	prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand;
+	prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
+	prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO;
+	prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode;
+	prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode;
+	prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode;
+	prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode;
+	prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3;
+	prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2;
+	prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1;
+	prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble;
+	prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime;
+	prCmdBody->ucCheckId = 0x72;
+
+	if (RLM_NET_PARAM_VALID(prBssInfo)) {
+		DBGLOG(RLM, INFO, "N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n",
+				   prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand,
+				   prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco,
+				   prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode,
+				   prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime,
+				   prCmdBody->ucUseShortPreamble);
+	} else {
+		DBGLOG(RLM, TRACE, "N=%d closed\n", prCmdBody->ucNetTypeIndex);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will operation parameters based on situations of
+*        concurrent networks. Channel, bandwidth, protection mode, supported
+*        rate will be modified.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	P_CMD_SET_BSS_RLM_PARAM_T prCmdBody;
+	WLAN_STATUS rStatus;
+
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+
+	prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T)
+	    cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T));
+	ASSERT(prCmdBody);
+
+	/* To do: exception handle */
+	if (!prCmdBody) {
+		DBGLOG(RLM, WARN, "No buf for sync RLM params (Net=%d)\n", prBssInfo->ucNetTypeIndex);
+		return;
+	}
+
+	rlmFillSyncCmdParam(prCmdBody, prBssInfo);
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_SET_BSS_RLM_PARAM,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL,	/* pfCmdDoneHandler */
+				      NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(CMD_SET_BSS_RLM_PARAM_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdBody,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+
+	cnmMemFree(prAdapter, prCmdBody);
+}
+
+#if CFG_SUPPORT_AAA
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function should be invoked after judging successful association.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2Offset;
+	P_IE_HT_CAP_T prHtCap;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+	ASSERT(pucIE);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+	if (!prStaRec)
+		return;
+	ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_HT_CAP:
+			if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2))
+				break;
+			prHtCap = (P_IE_HT_CAP_T) pucIE;
+			prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
+			prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE;
+
+			prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
+			prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
+			prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
+			prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
+			prStaRec->ucAselCap = prHtCap->ucAselCap;
+			break;
+
+		default:
+			break;
+		}		/* end of switch */
+	}			/* end of IE_FOR_EACH */
+}
+#endif /* CFG_SUPPORT_AAA */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief It is for both STA and AP modes
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prAdapter->fgIsP2PRegistered && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)
+		rlmBssInitForAP(prAdapter, prBssInfo);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief It is for both STA and AP modes
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+
+	rlmBssReset(prAdapter, prBssInfo);
+
+	prBssInfo->fg40mBwAllowed = FALSE;
+	prBssInfo->fgAssoc40mBwAllowed = FALSE;
+
+	/* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so
+	 * the sync CMD is not needed here.
+	 */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief All RLM timers will also be stopped.
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	ASSERT(prAdapter);
+	ASSERT(prBssInfo);
+
+	/* HT related parameters */
+	prBssInfo->ucHtOpInfo1 = 0;	/* RIFS disabled. 20MHz */
+	prBssInfo->u2HtOpInfo2 = 0;
+	prBssInfo->u2HtOpInfo3 = 0;
+
+	prBssInfo->eBssSCO = 0;
+	prBssInfo->fgErpProtectMode = 0;
+	prBssInfo->eHtProtectMode = 0;
+	prBssInfo->eGfOperationMode = 0;
+	prBssInfo->eRifsOperationMode = 0;
+
+	/* OBSS related parameters */
+	prBssInfo->auc2G_20mReqChnlList[0] = 0;
+	prBssInfo->auc2G_NonHtChnlList[0] = 0;
+	prBssInfo->auc2G_PriChnlList[0] = 0;
+	prBssInfo->auc2G_SecChnlList[0] = 0;
+	prBssInfo->auc5G_20mReqChnlList[0] = 0;
+	prBssInfo->auc5G_NonHtChnlList[0] = 0;
+	prBssInfo->auc5G_PriChnlList[0] = 0;
+	prBssInfo->auc5G_SecChnlList[0] = 0;
+
+	/* All RLM timers will also be stopped */
+	cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer);
+	prBssInfo->u2ObssScanInterval = 0;
+
+	prBssInfo->fgObssErpProtectMode = 0;	/* GO only */
+	prBssInfo->eObssHtProtectMode = 0;	/* GO only */
+	prBssInfo->eObssGfOperationMode = 0;	/* GO only */
+	prBssInfo->fgObssRifsOperationMode = 0;	/* GO only */
+	prBssInfo->fgObssActionForcedTo20M = 0;	/* GO only */
+	prBssInfo->fgObssBeaconForcedTo20M = 0;	/* GO only */
+}
+
+#if CFG_SUPPORT_DFS		/* Add by Enlai */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function handle spectrum management action frame
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
+{
+	P_ACTION_CHANNEL_SWITCH_FRAME prRxFrame;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	DBGLOG(RLM, INFO, "[5G DFS]rlmProcessSpecMgtAction \r\n");
+
+	prRxFrame = (P_ACTION_CHANNEL_SWITCH_FRAME) prSwRfb->pvHeader;
+	DBGLOG(RLM, INFO, "[5G DFS]prRxFrame->ucAction[%d] \r\n", prRxFrame->ucAction);
+	if (prRxFrame->ucAction == ACTION_CHNL_SWITCH)
+		rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) prRxFrame->aucInfoElem);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function process Channel Switch IE
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE)
+{
+	P_BSS_INFO_T prAisBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prChannelSwitchIE);
+
+	DBGLOG(RLM, INFO, "[5G DFS] rlmProcessChannelSwitchIE \r\n");
+	DBGLOG(RLM, INFO, "[5G DFS] ucChannelSwitchMode[%d], ucChannelSwitchCount[%d], ucNewChannelNum[%d] \r\n",
+	       prChannelSwitchIE->ucChannelSwitchMode,
+	       prChannelSwitchIE->ucChannelSwitchCount, prChannelSwitchIE->ucNewChannelNum);
+	if (prChannelSwitchIE->ucChannelSwitchMode == 1) {
+		prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+		DBGLOG(RLM, INFO, "[5G DFS] switch channel [%d]->[%d] \r\n", prAisBssInfo->ucPrimaryChannel,
+		       prChannelSwitchIE->ucNewChannelNum);
+		prAisBssInfo->ucPrimaryChannel = prChannelSwitchIE->ucNewChannelNum;
+		nicUpdateBss(prAdapter, prAisBssInfo->ucNetTypeIndex);
+	}
+
+}
+
+#endif
+
+#if (CFG_SUPPORT_TXR_ENC == 1)
+VOID
+rlmTxRateEnhanceConfig(
+	P_ADAPTER_T         prAdapter
+	)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+	CMD_RLM_INFO_T rTxRInfo;
+	UINT_32 u4SetInfoLen = 0;
+
+
+	/* init */
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	/* suggestion from Tsaiyuan.Hsu */
+	kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T));
+	rTxRInfo.fgIsErrRatioEnhanceApplied = TRUE;
+	rTxRInfo.ucErrRatio2LimitMinRate = 3;
+	rTxRInfo.ucMinLegacyRateIdx = 2;
+	rTxRInfo.cMinRssiThreshold = -60;
+	rTxRInfo.fgIsRtsApplied = TRUE;
+	rTxRInfo.ucRecoverTime = 60;
+
+	DBGLOG(RLM, INFO, "Enable tx rate enhance function\n");
+
+	rStatus = kalIoctl(prGlueInfo,
+			wlanoidSetTxRateInfo,
+			&rTxRInfo,
+			sizeof(rTxRInfo),
+			TRUE,
+			TRUE,
+			TRUE,
+			FALSE,
+			&u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(RLM, WARN, "set tx rate advance info fail 0x%lx\n", rStatus);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a command to TX Auto Rate module.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8	*prInBuf, UINT_32 u4InBufLen)
+{
+	UINT_32 u4Subcmd;
+
+
+	/* parse TAR sub-command */
+	u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	DBGLOG(RLM, INFO, "<tar_cmd> sub command = %u\n", (UINT32)u4Subcmd);
+
+	/* handle different sub-command */
+	switch (u4Subcmd) {
+	case 0x00: /* configure */
+		/* iwpriv wlan0 set_str_cmd 1_0_0_1_3_2_60_1_60 */
+		WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+		CMD_RLM_INFO_T rTxRInfo;
+		UINT_32 u4SetInfoLen = 0;
+
+		kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T));
+		rTxRInfo.u4Version = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+		rTxRInfo.fgIsErrRatioEnhanceApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+		rTxRInfo.ucErrRatio2LimitMinRate = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+		rTxRInfo.ucMinLegacyRateIdx = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+		rTxRInfo.cMinRssiThreshold = 0 - CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+		rTxRInfo.fgIsRtsApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+		rTxRInfo.ucRecoverTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+		DBGLOG(RLM, INFO, "<tar_cmd> rlmCmd = %u %u %u %u %d %u %u\n",
+			rTxRInfo.u4Version,
+			rTxRInfo.fgIsErrRatioEnhanceApplied,
+			rTxRInfo.ucErrRatio2LimitMinRate,
+			rTxRInfo.ucMinLegacyRateIdx,
+			rTxRInfo.cMinRssiThreshold,
+			rTxRInfo.fgIsRtsApplied,
+			rTxRInfo.ucRecoverTime));
+
+		rStatus = kalIoctl(prGlueInfo,
+				wlanoidSetTxRateInfo,
+				&rTxRInfo,
+				sizeof(rTxRInfo),
+				TRUE,
+				TRUE,
+				TRUE,
+				FALSE,
+				&u4SetInfoLen);
+		break;
+
+	default:
+		break;
+	}
+}
+#endif /* CFG_SUPPORT_TXR_ENC */
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c
new file mode 100644
index 0000000000000..5e127488ea499
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c
@@ -0,0 +1,1791 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_domain.c#1
+*/
+
+/*! \file   "rlm_domain.c"
+    \brief
+
+*/
+
+/*
+** Log: rlm_domain.c
+ *
+ * 11 10 2011 cm.chang
+ * NULL
+ * Modify debug message for XLOG
+ *
+ * 09 29 2011 cm.chang
+ * NULL
+ * Change the function prototype of rlmDomainGetChnlList()
+ *
+ * 09 23 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Let channel number to zero if band is illegal
+ *
+ * 09 22 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Exclude channel list with illegal band
+ *
+ * 09 15 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Use defined country group to have a change to add new group
+ *
+ * 09 08 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 06 01 2011 cm.chang
+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function
+ * Provide legal channel function based on domain
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
+ * Add beacon timeout support for WiFi Direct Network.
+ *
+ * 03 02 2011 terry.wu
+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
+ * Export rlmDomainGetDomainInfo for p2p driver.
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 03 25 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Filter out not supported RF freq when reporting available chnl list
+ *
+ * 01 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+ *
+ * 01 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Provide query function about full channel list.
+ *
+ * Dec 1 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+#include "rlm_txpwr_init.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/* The following country or domain shall be set from host driver.
+ * And host driver should pass specified DOMAIN_INFO_ENTRY to MT6620 as
+ * the channel list of being a STA to do scanning/searching AP or being an
+ * AP to choose an adequate channel if auto-channel is set.
+ */
+
+/* Define mapping tables between country code and its channel set
+ */
+static const UINT_16 g_u2CountryGroup0[] = {
+	COUNTRY_CODE_AO, COUNTRY_CODE_BZ, COUNTRY_CODE_BJ, COUNTRY_CODE_BT,
+	COUNTRY_CODE_BO, COUNTRY_CODE_BI, COUNTRY_CODE_CM, COUNTRY_CODE_CF,
+	COUNTRY_CODE_TD, COUNTRY_CODE_KM, COUNTRY_CODE_CD, COUNTRY_CODE_CG,
+	COUNTRY_CODE_CI, COUNTRY_CODE_DJ, COUNTRY_CODE_GQ, COUNTRY_CODE_ER,
+	COUNTRY_CODE_FJ, COUNTRY_CODE_GA, COUNTRY_CODE_GM, COUNTRY_CODE_GN,
+	COUNTRY_CODE_GW, COUNTRY_CODE_RKS, COUNTRY_CODE_KG, COUNTRY_CODE_LY,
+	COUNTRY_CODE_MG, COUNTRY_CODE_ML, COUNTRY_CODE_NR, COUNTRY_CODE_NC,
+	COUNTRY_CODE_ST, COUNTRY_CODE_SC, COUNTRY_CODE_SL, COUNTRY_CODE_SB,
+	COUNTRY_CODE_SO, COUNTRY_CODE_SR, COUNTRY_CODE_SZ, COUNTRY_CODE_TJ,
+	COUNTRY_CODE_TG, COUNTRY_CODE_TO, COUNTRY_CODE_TM, COUNTRY_CODE_TV,
+	COUNTRY_CODE_VU, COUNTRY_CODE_YE
+};
+
+static const UINT_16 g_u2CountryGroup1[] = {
+	COUNTRY_CODE_AS, COUNTRY_CODE_AI, COUNTRY_CODE_BM, COUNTRY_CODE_CA,
+	COUNTRY_CODE_KY, COUNTRY_CODE_GU, COUNTRY_CODE_FM, COUNTRY_CODE_PR,
+	COUNTRY_CODE_US, COUNTRY_CODE_VI
+};
+
+static const UINT_16 g_u2CountryGroup2[] = {
+	COUNTRY_CODE_AR, COUNTRY_CODE_AU, COUNTRY_CODE_AZ, COUNTRY_CODE_BW,
+	COUNTRY_CODE_KH, COUNTRY_CODE_CX, COUNTRY_CODE_CO, COUNTRY_CODE_CR,
+#if (CFG_CN_SUPPORT_CLASS121 == 1)
+	COUNTRY_CODE_CN,
+#endif
+	COUNTRY_CODE_EC, COUNTRY_CODE_GD, COUNTRY_CODE_GT, COUNTRY_CODE_HK,
+	COUNTRY_CODE_KI, COUNTRY_CODE_LB, COUNTRY_CODE_LR, COUNTRY_CODE_MN,
+	COUNTRY_CODE_AN, COUNTRY_CODE_NZ, COUNTRY_CODE_NI, COUNTRY_CODE_PW,
+	COUNTRY_CODE_PY, COUNTRY_CODE_PE, COUNTRY_CODE_PH, COUNTRY_CODE_WS,
+	COUNTRY_CODE_SG, COUNTRY_CODE_LK, COUNTRY_CODE_TH, COUNTRY_CODE_TT,
+	COUNTRY_CODE_UY, COUNTRY_CODE_VN
+};
+
+static const UINT_16 g_u2CountryGroup3[] = {
+	COUNTRY_CODE_AW, COUNTRY_CODE_LA, COUNTRY_CODE_SA, COUNTRY_CODE_AE,
+	COUNTRY_CODE_UG
+};
+
+static const UINT_16 g_u2CountryGroup4[] = { COUNTRY_CODE_MM };
+
+static const UINT_16 g_u2CountryGroup5[] = {
+	COUNTRY_CODE_AL, COUNTRY_CODE_DZ, COUNTRY_CODE_AD, COUNTRY_CODE_AT,
+	COUNTRY_CODE_BY, COUNTRY_CODE_BE, COUNTRY_CODE_BA, COUNTRY_CODE_VG,
+	COUNTRY_CODE_BG, COUNTRY_CODE_CV, COUNTRY_CODE_HR, COUNTRY_CODE_CY,
+	COUNTRY_CODE_CZ, COUNTRY_CODE_DK, COUNTRY_CODE_EE, COUNTRY_CODE_ET,
+	COUNTRY_CODE_FI, COUNTRY_CODE_FR, COUNTRY_CODE_GF, COUNTRY_CODE_PF,
+	COUNTRY_CODE_TF, COUNTRY_CODE_GE, COUNTRY_CODE_DE, COUNTRY_CODE_GH,
+	COUNTRY_CODE_GR, COUNTRY_CODE_GP, COUNTRY_CODE_HU, COUNTRY_CODE_IS,
+	COUNTRY_CODE_IQ, COUNTRY_CODE_IE, COUNTRY_CODE_IT, COUNTRY_CODE_KE,
+	COUNTRY_CODE_LV, COUNTRY_CODE_LS, COUNTRY_CODE_LI, COUNTRY_CODE_LT,
+	COUNTRY_CODE_LU, COUNTRY_CODE_MK, COUNTRY_CODE_MT, COUNTRY_CODE_MQ,
+	COUNTRY_CODE_MR, COUNTRY_CODE_MU, COUNTRY_CODE_YT, COUNTRY_CODE_MD,
+	COUNTRY_CODE_MC, COUNTRY_CODE_ME, COUNTRY_CODE_MS, COUNTRY_CODE_NL,
+	COUNTRY_CODE_NO, COUNTRY_CODE_OM, COUNTRY_CODE_PL, COUNTRY_CODE_PT,
+	COUNTRY_CODE_RE, COUNTRY_CODE_RO, COUNTRY_CODE_MF, COUNTRY_CODE_SM,
+	COUNTRY_CODE_SN, COUNTRY_CODE_RS, COUNTRY_CODE_SK, COUNTRY_CODE_SI,
+	COUNTRY_CODE_ZA, COUNTRY_CODE_ES, COUNTRY_CODE_SE, COUNTRY_CODE_CH,
+	COUNTRY_CODE_TR, COUNTRY_CODE_TC, COUNTRY_CODE_GB, COUNTRY_CODE_VA,
+	COUNTRY_CODE_EU
+};
+
+static const UINT_16 g_u2CountryGroup6[] = { COUNTRY_CODE_JP };
+
+static const UINT_16 g_u2CountryGroup7[] = {
+	COUNTRY_CODE_AM, COUNTRY_CODE_IL, COUNTRY_CODE_KW, COUNTRY_CODE_MA,
+	COUNTRY_CODE_NE, COUNTRY_CODE_TN, COUNTRY_CODE_MA
+};
+
+static const UINT_16 g_u2CountryGroup8[] = { COUNTRY_CODE_NP };
+
+static const UINT_16 g_u2CountryGroup9[] = { COUNTRY_CODE_AF };
+
+static const UINT_16 g_u2CountryGroup10[] = {
+	COUNTRY_CODE_AG, COUNTRY_CODE_BS, COUNTRY_CODE_BH, COUNTRY_CODE_BB,
+	COUNTRY_CODE_BN, COUNTRY_CODE_CL, COUNTRY_CODE_EG,
+#if (CFG_CN_SUPPORT_CLASS121 == 0)
+	COUNTRY_CODE_CN,
+#endif
+	COUNTRY_CODE_SV, COUNTRY_CODE_IN, COUNTRY_CODE_MY, COUNTRY_CODE_MV,
+	COUNTRY_CODE_PA, COUNTRY_CODE_VE, COUNTRY_CODE_ZM
+};
+
+static const UINT_16 g_u2CountryGroup11[] = { COUNTRY_CODE_JO, COUNTRY_CODE_PG };
+
+static const UINT_16 g_u2CountryGroup12[] = {
+	COUNTRY_CODE_BF, COUNTRY_CODE_GY, COUNTRY_CODE_HT, COUNTRY_CODE_HN,
+	COUNTRY_CODE_JM, COUNTRY_CODE_MO, COUNTRY_CODE_MW, COUNTRY_CODE_PK,
+	COUNTRY_CODE_QA, COUNTRY_CODE_RW, COUNTRY_CODE_KN, COUNTRY_CODE_TZ
+};
+
+static const UINT_16 g_u2CountryGroup13[] = { COUNTRY_CODE_ID };
+
+static const UINT_16 g_u2CountryGroup14[] = { COUNTRY_CODE_KR };
+
+static const UINT_16 g_u2CountryGroup15[] = { COUNTRY_CODE_NG };
+
+static const UINT_16 g_u2CountryGroup16[] = {
+	COUNTRY_CODE_BD, COUNTRY_CODE_BR, COUNTRY_CODE_DM, COUNTRY_CODE_DO,
+	COUNTRY_CODE_FK, COUNTRY_CODE_KZ, COUNTRY_CODE_MX, COUNTRY_CODE_MZ,
+	COUNTRY_CODE_NA, COUNTRY_CODE_RU, COUNTRY_CODE_LC, COUNTRY_CODE_VC,
+	COUNTRY_CODE_UA, COUNTRY_CODE_UZ, COUNTRY_CODE_ZW
+};
+
+static const UINT_16 g_u2CountryGroup17[] = { COUNTRY_CODE_MP };
+
+static const UINT_16 g_u2CountryGroup18[] = { COUNTRY_CODE_TW };
+
+static const UINT_16 g_u2CountryGroup19[] = {
+	COUNTRY_CODE_CK, COUNTRY_CODE_CU, COUNTRY_CODE_TL, COUNTRY_CODE_FO,
+	COUNTRY_CODE_GI, COUNTRY_CODE_GG, COUNTRY_CODE_IR, COUNTRY_CODE_IM,
+	COUNTRY_CODE_JE, COUNTRY_CODE_KP, COUNTRY_CODE_MH, COUNTRY_CODE_NU,
+	COUNTRY_CODE_NF, COUNTRY_CODE_PS, COUNTRY_CODE_PN, COUNTRY_CODE_PM,
+	COUNTRY_CODE_SS, COUNTRY_CODE_SD, COUNTRY_CODE_SY
+};
+
+static const UINT_16 g_u2CountryGroup20[] = {
+	COUNTRY_CODE_DF, COUNTRY_CODE_FF
+	/* When country code is not found and no matched NVRAM setting,
+	 * this domain info will be used.
+	 */
+};
+
+static const UINT_16 g_u2CountryGroup21[] = {
+	COUNTRY_CODE_UDF
+};
+
+DOMAIN_INFO_ENTRY arSupportedRegDomains[] = {
+	{
+	 (PUINT_16) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_LOW_NA */
+	  {118, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_MID_NA */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_NA */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE}
+	  ,			/* CH_SET_2G4_1_11 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_144 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup2, sizeof(g_u2CountryGroup2) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_144 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_144 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_161 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_144 */
+	  {125, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_NA */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_NA */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+	  {82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE}
+	  ,			/* CH_SET_2G4_14_14 */
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_NA */
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup7, sizeof(g_u2CountryGroup7) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_NA */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup8, sizeof(g_u2CountryGroup8) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_161 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_MID_NA */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_NA */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup10, sizeof(g_u2CountryGroup10) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup11, sizeof(g_u2CountryGroup11) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_MID_NA */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_LOW_NA */
+	  {118, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_MID_NA */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_LOW_NA */
+	  {118, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_MID_NA */
+	  {121, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_WW_NA */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_161 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup14, sizeof(g_u2CountryGroup14) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 8, FALSE}
+	  ,			/* CH_SET_UNII_WW_100_128 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_161 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup15, sizeof(g_u2CountryGroup15) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_NULL, 0, 0, 0, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup16, sizeof(g_u2CountryGroup16) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup17, sizeof(g_u2CountryGroup17) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE}
+	  ,			/* CH_SET_2G4_1_11 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup18, sizeof(g_u2CountryGroup18) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE}
+	  ,			/* CH_SET_2G4_1_11 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 11, FALSE}
+	  ,			/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 (PUINT_16) g_u2CountryGroup19, sizeof(g_u2CountryGroup19) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_144 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 /* Note: Default group if no matched country code */
+	 (PUINT_16) g_u2CountryGroup20, sizeof(g_u2CountryGroup20) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE}
+	  ,			/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE}
+	  ,			/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE}
+	  ,			/* CH_SET_UNII_WW_100_144 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE}
+	  ,			/* CH_SET_UNII_UPPER_149_165 */
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+	,
+	{
+	 /* Note: for customer configured their own scanning list and passive scan list */
+	 (PUINT_16) g_u2CountryGroup21, sizeof(g_u2CountryGroup21) / 2,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 1, 12, FALSE}
+	  ,			/* CH_SET_2G4_1_13 */
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE}
+	  ,
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 0, FALSE}
+	  ,
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 0, FALSE}
+	  ,
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE}
+	  ,
+	  {0, BAND_NULL, 0, 0, 0, FALSE}
+	 }
+	}
+};
+
+static UINT_16 g_u2CountryGroup0_Passive[] = {
+	COUNTRY_CODE_UDF
+};
+
+DOMAIN_INFO_ENTRY arSupportedRegDomains_Passive[] = {
+	{
+	 /* Default passive scan channel table is empty */
+	 COUNTRY_CODE_NULL, 0,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 11, 0, 0},	/* CH_SET_2G4_1_14 */
+	  {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0},
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0},	/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0},	/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0},	/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0},	/* CH_SET_UNII_UPPER_149_173 */
+	 }
+	},
+	{
+	 /* User Defined passive scan channel table */
+	 g_u2CountryGroup0_Passive, 0,
+	 {
+	  {81, BAND_2G4, CHNL_SPAN_5, 12, 1, 0},	/* CH_SET_2G4_1_14 */
+	  {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0},
+
+	  {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0},	/* CH_SET_UNII_LOW_36_48 */
+	  {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0},	/* CH_SET_UNII_MID_52_64 */
+	  {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0},	/* CH_SET_UNII_WW_100_140 */
+	  {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0},	/* CH_SET_UNII_UPPER_149_173 */
+	 }
+	}
+};
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+SUBBAND_CHANNEL_T g_rRlmSubBand[] = {
+
+	{BAND_2G4_LOWER_BOUND, BAND_2G4_UPPER_BOUND, 1, 0}
+	,			/* 2.4G */
+	{UNII1_LOWER_BOUND, UNII1_UPPER_BOUND, 2, 0}
+	,			/* ch36,38,40,..,48 */
+	{UNII2A_LOWER_BOUND, UNII2A_UPPER_BOUND, 2, 0}
+	,			/* ch52,54,56,..,64 */
+	{UNII2C_LOWER_BOUND, UNII2C_UPPER_BOUND, 2, 0}
+	,			/* ch100,102,104,...,144 */
+	{UNII3_LOWER_BOUND, UNII3_UPPER_BOUND, 2, 0}
+				/* ch149,151,153,....,173 */
+};
+#endif
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in/out]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter)
+{
+#define REG_DOMAIN_DEF_IDX             20 /* Default country domain */
+#define REG_DOMAIN_GROUP_NUM  \
+	(sizeof(arSupportedRegDomains) / sizeof(DOMAIN_INFO_ENTRY))
+
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+	P_REG_INFO_T prRegInfo;
+	UINT_16 u2TargetCountryCode;
+	UINT_16 i, j;
+
+	ASSERT(prAdapter);
+
+	if (prAdapter->prDomainInfo)
+		return prAdapter->prDomainInfo;
+
+	prRegInfo = &prAdapter->prGlueInfo->rRegInfo;
+
+	DBGLOG(RLM, TRACE, "eRegChannelListMap=%d, u2CountryCode=0x%04x\n",
+			   prRegInfo->eRegChannelListMap,
+			   prAdapter->rWifiVar.rConnSettings.u2CountryCode);
+
+	/*
+	* Domain info can be specified by given idx of arSupportedRegDomains table,
+	* customized, or searched by country code,
+	* only one is set among these three methods in NVRAM.
+	*/
+	if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX &&
+	    prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) {
+		/* by given table idx */
+	    DBGLOG(RLM, TRACE, "ucRegChannelListIndex=%d\n", prRegInfo->ucRegChannelListIndex);
+		prDomainInfo = &arSupportedRegDomains[prRegInfo->ucRegChannelListIndex];
+	} else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) {
+		/* by customized */
+		prDomainInfo = &prRegInfo->rDomainInfo;
+	} else {
+		/* by country code */
+		u2TargetCountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode;
+
+		for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) {
+			prDomainInfo = &arSupportedRegDomains[i];
+
+			if ((prDomainInfo->u4CountryNum && prDomainInfo->pu2CountryGroup) ||
+			    prDomainInfo->u4CountryNum == 0) {
+				for (j = 0; j < prDomainInfo->u4CountryNum; j++) {
+					if (prDomainInfo->pu2CountryGroup[j] == u2TargetCountryCode)
+						break;
+				}
+				if (j < prDomainInfo->u4CountryNum)
+					break;	/* Found */
+			}
+		}
+
+		/* If no matched country code, use the default country domain */
+		if (i >= REG_DOMAIN_GROUP_NUM) {
+			DBGLOG(RLM, INFO, "No matched country code, use the default country domain\n");
+			prDomainInfo = &arSupportedRegDomains[REG_DOMAIN_DEF_IDX];
+		}
+	}
+
+	prAdapter->prDomainInfo = prDomainInfo;
+	return prDomainInfo;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in/out] The input variable pointed by pucNumOfChannel is the max
+*                arrary size. The return value indciates meaning list size.
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+rlmDomainGetChnlList(P_ADAPTER_T prAdapter,
+		     ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs,
+		     UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList)
+{
+	UINT_8 i, j, ucNum;
+	P_DOMAIN_SUBBAND_INFO prSubband;
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(paucChannelList);
+	ASSERT(pucNumOfChannel);
+
+	prDomainInfo = rlmDomainGetDomainInfo(prAdapter);
+	ASSERT(prDomainInfo);
+
+	ucNum = 0;
+	for (i = 0; i < MAX_SUBBAND_NUM; i++) {
+		prSubband = &prDomainInfo->rSubBand[i];
+
+		if (prSubband->ucBand == BAND_NULL || prSubband->ucBand >= BAND_NUM ||
+		    (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand))
+			continue;
+
+		if (fgNoDfs == TRUE && prSubband->fgDfs == TRUE)
+			continue;
+
+		if (eSpecificBand == BAND_NULL || prSubband->ucBand == eSpecificBand) {
+			for (j = 0; j < prSubband->ucNumChannels; j++) {
+				if (ucNum >= ucMaxChannelNum)
+					break;
+				paucChannelList[ucNum].eBand = prSubband->ucBand;
+				paucChannelList[ucNum].ucChannelNum =
+				    prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan;
+				ucNum++;
+			}
+		}
+	}
+
+	*pucNumOfChannel = ucNum;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid)
+{
+	rlmDomainSendDomainInfoCmd(prAdapter, fgIsOid);
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+	rlmDomainSendPwrLimitCmd(prAdapter);
+#endif
+	rlmDomainSendPassiveScanInfoCmd(prAdapter, fgIsOid);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid)
+{
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+	P_CMD_SET_DOMAIN_INFO_T prCmd;
+	P_DOMAIN_SUBBAND_INFO prSubBand;
+	UINT_8 i;
+
+	prDomainInfo = rlmDomainGetDomainInfo(prAdapter);
+	ASSERT(prDomainInfo);
+
+	prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T));
+	if (!prCmd) {
+		DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n");
+		return;
+	}
+	kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T));
+
+	prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode;
+	prCmd->u2IsSetPassiveScan = 0;
+	prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode;
+	prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode;
+	prCmd->aucReserved[0] = 0;
+	prCmd->aucReserved[1] = 0;
+
+	for (i = 0; i < MAX_SUBBAND_NUM; i++) {
+		prSubBand = &prDomainInfo->rSubBand[i];
+
+		prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass;
+		prCmd->rSubBand[i].ucBand = prSubBand->ucBand;
+
+		if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) {
+			prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan;
+			prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum;
+			prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels;
+		}
+	}
+
+	/* Set domain info to chip */
+	wlanSendSetQueryCmd(prAdapter, /* prAdapter */
+			 CMD_ID_SET_DOMAIN_INFO, /* ucCID */
+			 TRUE,  /* fgSetQuery */
+			 FALSE, /* fgNeedResp */
+			 fgIsOid, /* fgIsOid */
+			 NULL,  /* pfCmdDoneHandler */
+			 NULL,  /* pfCmdTimeoutHandler */
+			 sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */
+			 (PUINT_8)prCmd, /* pucInfoBuffer */
+			 NULL,  /* pvSetQueryBuffer */
+			 0      /* u4SetQueryBufferLen */
+	    );
+
+	cnmMemFree(prAdapter, prCmd);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid)
+{
+#define REG_DOMAIN_PASSIVE_DEF_IDX      0
+#define REG_DOMAIN_PASSIVE_UDF_IDX      1
+
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+	P_CMD_SET_DOMAIN_INFO_T prCmd;
+	P_DOMAIN_SUBBAND_INFO prSubBand;
+	UINT_8 i;
+
+	prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T));
+	if (!prCmd) {
+		DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n");
+		return;
+	}
+	kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T));
+
+	prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode;
+	prCmd->u2IsSetPassiveScan = 1;
+	prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode;
+	prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode;
+	prCmd->aucReserved[0] = 0;
+	prCmd->aucReserved[1] = 0;
+
+	DBGLOG(RLM, TRACE, "u2CountryCode=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCode);
+
+	if (prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_UDF)
+		prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_UDF_IDX];
+	else
+		prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_DEF_IDX];
+
+	for (i = 0; i < MAX_SUBBAND_NUM; i++) {
+		prSubBand = &prDomainInfo->rSubBand[i];
+
+		prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass;
+		prCmd->rSubBand[i].ucBand = prSubBand->ucBand;
+
+		if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) {
+			prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan;
+			prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum;
+			prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels;
+		}
+	}
+
+	/* Set passive scan channel info to chip */
+	wlanSendSetQueryCmd(prAdapter, /* prAdapter */
+			 CMD_ID_SET_DOMAIN_INFO, /* ucCID */
+			 TRUE,  /* fgSetQuery */
+			 FALSE, /* fgNeedResp */
+			 fgIsOid, /* fgIsOid */
+			 NULL,  /* pfCmdDoneHandler */
+			 NULL,  /* pfCmdTimeoutHandler */
+			 sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */
+			 (PUINT_8) prCmd, /* pucInfoBuffer */
+			 NULL,  /* pvSetQueryBuffer */
+			 0      /* u4SetQueryBufferLen */
+	    );
+
+	cnmMemFree(prAdapter, prCmd);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in/out]
+*
+* \return TRUE  Legal channel
+*         FALSE Illegal channel for current regulatory domain
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel)
+{
+	UINT_8 i, j;
+	P_DOMAIN_SUBBAND_INFO prSubband;
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+
+	prDomainInfo = rlmDomainGetDomainInfo(prAdapter);
+	ASSERT(prDomainInfo);
+
+	for (i = 0; i < MAX_SUBBAND_NUM; i++) {
+		prSubband = &prDomainInfo->rSubBand[i];
+
+		if (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand)
+			continue;
+
+		if (prSubband->ucBand == eBand) {
+			for (j = 0; j < prSubband->ucNumChannels; j++) {
+				if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan)
+				    == ucChannel) {
+					return TRUE;
+				}
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in/out]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+
+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf)
+{
+	/*
+	   The Country element should only be included for Status Code 0 (Successful).
+	 */
+	UINT_32 u4IeLen;
+	UINT_8 aucClass[12] = { 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b,
+		0x1c, 0x1e, 0x20, 0x21
+	};
+
+	/*
+	   The Supported Operating Classes element is used by a STA to advertise the
+	   operating classes that it is capable of operating with in this country.
+
+	   The Country element (see 8.4.2.10) allows a STA to configure its PHY and MAC
+	   for operation when the operating triplet of Operating Extension Identifier,
+	   Operating Class, and Coverage Class fields is present.
+	 */
+	SUP_OPERATING_CLASS_IE(pBuf)->ucId = ELEM_ID_SUP_OPERATING_CLASS;
+	SUP_OPERATING_CLASS_IE(pBuf)->ucLength = 1 + sizeof(aucClass);
+	SUP_OPERATING_CLASS_IE(pBuf)->ucCur = 0x0c;	/* 0x51 */
+	kalMemCopy(SUP_OPERATING_CLASS_IE(pBuf)->ucSup, aucClass, sizeof(aucClass));
+	u4IeLen = (SUP_OPERATING_CLASS_IE(pBuf)->ucLength + 2);
+	pBuf += u4IeLen;
+
+	COUNTRY_IE(pBuf)->ucId = ELEM_ID_COUNTRY_INFO;
+	COUNTRY_IE(pBuf)->ucLength = 6;
+	COUNTRY_IE(pBuf)->aucCountryStr[0] = 0x55;
+	COUNTRY_IE(pBuf)->aucCountryStr[1] = 0x53;
+	COUNTRY_IE(pBuf)->aucCountryStr[2] = 0x20;
+	COUNTRY_IE(pBuf)->arCountryStr[0].ucFirstChnlNum = 1;
+	COUNTRY_IE(pBuf)->arCountryStr[0].ucNumOfChnl = 11;
+	COUNTRY_IE(pBuf)->arCountryStr[0].cMaxTxPwrLv = 0x1e;
+	u4IeLen += (COUNTRY_IE(pBuf)->ucLength + 2);
+
+	return u4IeLen;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (fgValid) : 0 -> inValid, 1 -> Valid
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh)
+{
+	BOOLEAN fgValid = FALSE;
+	UINT_8 ucTemp = 0;
+	UINT_8 i;
+	/*Check Power limit table channel efficient or not */
+
+	for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) {
+		if ((ucCentralCh >= g_rRlmSubBand[i].ucStartCh) && (ucCentralCh <= g_rRlmSubBand[i].ucEndCh))
+			ucTemp = (ucCentralCh - g_rRlmSubBand[i].ucStartCh) % g_rRlmSubBand[i].ucInterval;
+	}
+
+#if 0
+	/*2.4G, ex 1, 2, 3 */
+	if (ucCentralCh >= BAND_2G4_LOWER_BOUND && ucCentralCh <= BAND_2G4_UPPER_BOUND)
+		ucTemp = 0;
+	/*FCC- Spec : Band UNII-1, ex 36, 38, 40.... */
+	else if (ucCentralCh >= UNII1_LOWER_BOUND && ucCentralCh <= UNII1_UPPER_BOUND)
+		ucTemp = (ucCentralCh - UNII1_LOWER_BOUND) % 2;
+	/*FCC- Spec : Band UNII-2A, ex 52, 54, 56.... */
+	else if (ucCentralCh >= UNII2A_LOWER_BOUND && ucCentralCh <= UNII2A_UPPER_BOUND)
+		ucTemp = (ucCentralCh - UNII2A_LOWER_BOUND) % 2;
+	/*FCC- Spec : Band UNII-2C, ex 100, 102, 104.... */
+	else if (ucCentralCh >= UNII2C_LOWER_BOUND && ucCentralCh <= UNII2C_UPPER_BOUND)
+		ucTemp = (ucCentralCh - UNII2C_LOWER_BOUND) % 2;
+	/*FCC- Spec : Band UNII-3, ex 149, 151, 153... */
+	else if (ucCentralCh >= UNII3_LOWER_BOUND && ucCentralCh <= UNII3_UPPER_BOUND)
+		ucTemp = (ucCentralCh - UNII3_LOWER_BOUND) % 2;
+#endif
+	if (ucTemp == 0)
+		fgValid = TRUE;
+	return fgValid;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend)
+{
+	UINT_8 ucCenterChannel;
+
+	if (eExtend == CHNL_EXT_SCA)
+		ucCenterChannel = ucPriChannel + 2;
+	else if (eExtend == CHNL_EXT_SCB)
+		ucCenterChannel = ucPriChannel - 2;
+	else
+		ucCenterChannel = ucPriChannel;
+
+	return ucCenterChannel;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter,
+			  ENUM_BAND_T eBand,
+			  UINT_8 ucPriChannel,
+			  ENUM_CHNL_EXT_T eExtend,
+			  ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2)
+{
+	UINT_8 ucCenterChannel;
+	BOOLEAN fgValidChannel = TRUE;
+	BOOLEAN fgValidBW = TRUE;
+	BOOLEAN fgValidRfSetting = TRUE;
+	UINT_32 u4PrimaryOffset;
+
+	/*DBG msg for Channel InValid */
+	if (eChannelWidth == CW_20_40MHZ) {
+		ucCenterChannel = rlmDomainGetCenterChannel(eBand, ucPriChannel, eExtend);
+
+		/* Check Central Channel Valid or Not */
+		fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel);
+		if (fgValidChannel == FALSE)
+			DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel);
+	} else if (eChannelWidth == CW_80MHZ) {
+		ucCenterChannel = ucChannelS1;
+
+		/* Check Central Channel Valid or Not */
+		fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel);
+		if (fgValidChannel == FALSE)
+			DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel);
+	} else if (eChannelWidth == CW_160MHZ) {
+		ucCenterChannel = ucChannelS2;
+
+		/* Check Central Channel Valid or Not */
+		/*TODo */
+	}
+
+	/* Check BW Setting Correct or Not */
+	if (eBand == BAND_2G4) {
+		if (eChannelWidth != CW_20_40MHZ) {
+			fgValidBW = FALSE;
+			DBGLOG(RLM, WARN, "Rf: B=%d, W=%d\n", eBand, eChannelWidth);
+		}
+	} else {
+		if (eChannelWidth == CW_80MHZ) {
+			u4PrimaryOffset = CAL_CH_OFFSET_80M(ucPriChannel, ucCenterChannel);
+			if (u4PrimaryOffset > 4) {
+				fgValidBW = FALSE;
+				DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth);
+			}
+		} else if (eChannelWidth == CW_160MHZ) {
+			u4PrimaryOffset = CAL_CH_OFFSET_160M(ucPriChannel, ucCenterChannel);
+			if (u4PrimaryOffset > 8) {
+				fgValidBW = FALSE;
+				DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth);
+			}
+		}
+	}
+
+	if ((fgValidBW == FALSE) || (fgValidChannel == FALSE))
+		fgValidRfSetting = FALSE;
+
+	return fgValidRfSetting;
+
+}
+
+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (fgValid) : 0 -> inValid, 1 -> Valid
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter,
+			      COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration,
+			      UINT_8 ucPwrLimitNum)
+{
+	UINT_8 i;
+	BOOLEAN fgValid = TRUE;
+	PINT_8 prPwrLimit;
+
+	prPwrLimit = &rPowerLimitTableConfiguration.aucPwrLimit[0];
+
+	for (i = 0; i < ucPwrLimitNum; i++, prPwrLimit++) {
+		if (*prPwrLimit > MAX_TX_POWER || *prPwrLimit < MIN_TX_POWER) {
+			fgValid = FALSE;
+			break;	/*Find out Wrong Power limit */
+		}
+	}
+	return fgValid;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter)
+{
+	UINT_8 i, j;
+	UINT_16 u2CountryCodeTable, u2CountryCodeCheck;
+	BOOLEAN fgChannelValid = FALSE;
+	BOOLEAN fgPowerLimitValid = FALSE;
+	BOOLEAN fgEntryRepetetion = FALSE;
+	BOOLEAN fgTableValid = TRUE;
+
+	/*Configuration Table Check */
+	for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) {
+		/*Table Country Code */
+		WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable);
+
+		/*Repetition Entry Check */
+		for (j = i + 1;
+		     j < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION);
+		     j++) {
+
+			WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[j].aucCountryCode[0], &u2CountryCodeCheck);
+			if (((g_rRlmPowerLimitConfiguration[i].ucCentralCh) ==
+			     g_rRlmPowerLimitConfiguration[j].ucCentralCh)
+			    && (u2CountryCodeTable == u2CountryCodeCheck)) {
+				fgEntryRepetetion = TRUE;
+				DBGLOG(RLM, LOUD, "Domain: Configuration Repetition CC=%c%c, Ch=%d\n",
+						   g_rRlmPowerLimitConfiguration[i].aucCountryCode[0],
+						   g_rRlmPowerLimitConfiguration[i].aucCountryCode[1],
+						   g_rRlmPowerLimitConfiguration[i].ucCentralCh);
+			}
+		}
+
+		/*Channel Number Check */
+		fgChannelValid =
+		    rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh);
+
+		/*Power Limit Check */
+		fgPowerLimitValid =
+		    rlmDomainCheckPowerLimitValid(prAdapter, g_rRlmPowerLimitConfiguration[i], PWR_LIMIT_NUM);
+
+		if (fgChannelValid == FALSE || fgPowerLimitValid == FALSE) {
+			fgTableValid = FALSE;
+			DBGLOG(RLM, LOUD, "Domain: CC=%c%c, Ch=%d, Limit: %d,%d,%d,%d,%d\n",
+					   g_rRlmPowerLimitConfiguration[i].aucCountryCode[0],
+					   g_rRlmPowerLimitConfiguration[i].aucCountryCode[1],
+					   g_rRlmPowerLimitConfiguration[i].ucCentralCh,
+					   g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK],
+					   g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M],
+					   g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M],
+					   g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M],
+					   g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]);
+		}
+
+		if (u2CountryCodeTable == COUNTRY_CODE_NULL) {
+			DBGLOG(RLM, LOUD, "Domain: Full search down\n");
+			break;	/*End of country table entry */
+		}
+
+	}
+
+	if (fgEntryRepetetion == FALSE)
+		DBGLOG(RLM, TRACE, "Domain: Configuration Table no Repetiton.\n");
+
+	/*Configuration Table no error */
+	if (fgTableValid == TRUE)
+		prAdapter->fgIsPowerLimitTableValid = TRUE;
+	else
+		prAdapter->fgIsPowerLimitTableValid = FALSE;
+
+	/*Default Table Check */
+	fgEntryRepetetion = FALSE;
+	for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) {
+
+		WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable);
+
+		for (j = i + 1; j < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); j++) {
+			WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[j].aucCountryCode[0], &u2CountryCodeCheck);
+			if (u2CountryCodeTable == u2CountryCodeCheck) {
+				fgEntryRepetetion = TRUE;
+				DBGLOG(RLM, LOUD,
+				       "Domain: Default Repetition CC=%c%c\n",
+					g_rRlmPowerLimitDefault[j].aucCountryCode[0],
+					g_rRlmPowerLimitDefault[j].aucCountryCode[1]);
+			}
+		}
+	}
+	if (fgEntryRepetetion == FALSE)
+		DBGLOG(RLM, TRACE, "Domain: Default Table no Repetiton.\n");
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (u2TableIndex) : if  0xFFFF -> No Table Match
+*/
+/*----------------------------------------------------------------------------*/
+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode)
+{
+
+	UINT_16 i;
+	UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL;
+	UINT_16 u2TableIndex = POWER_LIMIT_TABLE_NULL;	/* No Table Match */
+
+	/*Default Table Index */
+	for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) {
+
+		WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable);
+
+		if (u2CountryCodeTable == u2CountryCode) {
+			u2TableIndex = i;
+			break;	/*match country code */
+		} else if (u2CountryCodeTable == COUNTRY_CODE_NULL) {
+			u2TableIndex = i;
+			break;	/*find last one country- Default */
+		}
+	}
+
+	DBGLOG(RLM, TRACE, "Domain: Default Table Index = %d\n", u2TableIndex);
+
+	return u2TableIndex;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmDomainBuildCmdByDefaultTable(P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd, UINT_16 u2DefaultTableIndex)
+{
+	UINT_8 i, k;
+	P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT prPwrLimitSubBand;
+	P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit;
+
+	prCmdPwrLimit = &prCmd->rChannelPowerLimit[0];
+	prPwrLimitSubBand = &g_rRlmPowerLimitDefault[u2DefaultTableIndex];
+
+	/*Build power limit cmd by default table information */
+
+	for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) {
+		if (prPwrLimitSubBand->aucPwrLimitSubBand[i] < MAX_TX_POWER) {
+			for (k = g_rRlmSubBand[i].ucStartCh; k <= g_rRlmSubBand[i].ucEndCh;
+			     k += g_rRlmSubBand[i].ucInterval) {
+				if ((prPwrLimitSubBand->ucPwrUnit & BIT(i)) == 0) {
+					prCmdPwrLimit->ucCentralCh = k;
+					prCmdPwrLimit->cPwrLimitCCK =
+						prPwrLimitSubBand->aucPwrLimitSubBand[i];
+					prCmdPwrLimit->cPwrLimit20 =
+						prPwrLimitSubBand->aucPwrLimitSubBand[i];
+					prCmdPwrLimit->cPwrLimit40 =
+						prPwrLimitSubBand->aucPwrLimitSubBand[i];
+					prCmdPwrLimit->cPwrLimit80 =
+						prPwrLimitSubBand->aucPwrLimitSubBand[i];
+					prCmdPwrLimit->cPwrLimit160 =
+						prPwrLimitSubBand->aucPwrLimitSubBand[i];
+					prCmdPwrLimit++;
+					prCmd->ucNum++;
+
+				} else {
+					/* ex:    40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2
+					 * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */
+					prCmdPwrLimit->ucCentralCh = k;
+					prCmdPwrLimit->cPwrLimitCCK = prPwrLimitSubBand->aucPwrLimitSubBand[i];
+					prCmdPwrLimit->cPwrLimit20 = prPwrLimitSubBand->aucPwrLimitSubBand[i];
+					prCmdPwrLimit->cPwrLimit40 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 6;
+					if (prCmdPwrLimit->cPwrLimit40 > MAX_TX_POWER)
+						prCmdPwrLimit->cPwrLimit40 = MAX_TX_POWER;
+					prCmdPwrLimit->cPwrLimit80 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 12;
+					if (prCmdPwrLimit->cPwrLimit80 > MAX_TX_POWER)
+						prCmdPwrLimit->cPwrLimit80 = MAX_TX_POWER;
+					prCmdPwrLimit->cPwrLimit160 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 18;
+					if (prCmdPwrLimit->cPwrLimit160 > MAX_TX_POWER)
+						prCmdPwrLimit->cPwrLimit160 = MAX_TX_POWER;
+					prCmdPwrLimit++;
+					prCmd->ucNum++;
+				}
+			}
+		}
+	}
+
+#if 0
+	if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4] < MAX_TX_POWER) {
+		for (i = BAND_2G4_LOWER_BOUND; i <= BAND_2G4_UPPER_BOUND; i++) {
+			prCmdPwrLimit->ucCentralCh = i;
+			kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4],
+				  PWR_LIMIT_NUM);
+			prCmdPwrLimit++;
+			prCmd->ucNum++;
+		}
+	}
+
+	if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1] < MAX_TX_POWER) {
+		if (prCmd->u2CountryCode != COUNTRY_CODE_KR) {
+			for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) {
+				prCmdPwrLimit->ucCentralCh = i;
+				kalMemSet(&prCmdPwrLimit->cPwrLimitCCK,
+					  prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1], PWR_LIMIT_NUM);
+				prCmdPwrLimit++;
+				prCmd->ucNum++;
+			}
+		} else {
+			for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) {
+				/* ex:    40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2
+				 * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */
+				prCmdPwrLimit->ucCentralCh = i;
+				prCmdPwrLimit->cPwrLimitCCK =
+				    g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1;
+				prCmdPwrLimit->cPwrLimit20 =
+				    g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1;
+				prCmdPwrLimit->cPwrLimit40 =
+				    g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 6;
+				prCmdPwrLimit->cPwrLimit80 =
+				    g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 12;
+				prCmdPwrLimit->cPwrLimit160 =
+				    g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 18;
+				prCmdPwrLimit++;
+				prCmd->ucNum++;
+			}
+		}
+	}
+
+	if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A] < MAX_TX_POWER) {
+		for (i = UNII2A_LOWER_BOUND; i <= UNII2A_UPPER_BOUND; i += 2) {
+			prCmdPwrLimit->ucCentralCh = i;
+			kalMemSet(&prCmdPwrLimit->cPwrLimitCCK,
+				  prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A], PWR_LIMIT_NUM);
+			prCmdPwrLimit++;
+			prCmd->ucNum++;
+		}
+	}
+
+	if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C] < MAX_TX_POWER) {
+		for (i = UNII2C_LOWER_BOUND; i <= UNII2C_UPPER_BOUND; i += 2) {
+			prCmdPwrLimit->ucCentralCh = i;
+			kalMemSet(&prCmdPwrLimit->cPwrLimitCCK,
+				  prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C], PWR_LIMIT_NUM);
+			prCmdPwrLimit++;
+			prCmd->ucNum++;
+		}
+	}
+	if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3] < MAX_TX_POWER) {
+		for (i = UNII3_LOWER_BOUND; i <= UNII3_UPPER_BOUND; i += 2) {
+			prCmdPwrLimit->ucCentralCh = i;
+			kalMemSet(&prCmdPwrLimit->cPwrLimitCCK,
+				  prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3], PWR_LIMIT_NUM);
+			prCmdPwrLimit++;
+			prCmd->ucNum++;
+		}
+	}
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmDomainBuildCmdByConfigTable(P_ADAPTER_T prAdapter, P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd)
+{
+	UINT_8 i, k;
+	UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL;
+	P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit;
+	BOOLEAN fgChannelValid;
+
+	/*Build power limit cmd by configuration table information */
+
+	for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) {
+
+		WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable);
+
+		fgChannelValid =
+		    rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh);
+
+		if (u2CountryCodeTable == COUNTRY_CODE_NULL) {
+			DBGLOG(RLM, TRACE, "Domain: full search configuration table done.\n");
+			break;	/*end of configuration table */
+		} else if ((u2CountryCodeTable == prCmd->u2CountryCode) && (fgChannelValid == TRUE)) {
+
+			prCmdPwrLimit = &prCmd->rChannelPowerLimit[0];
+
+			if (prCmd->ucNum != 0) {
+				for (k = 0; k < prCmd->ucNum; k++) {
+					if (prCmdPwrLimit->ucCentralCh ==
+						g_rRlmPowerLimitConfiguration[i].ucCentralCh) {
+
+						/*Cmd setting (Default table information) and
+						   Configuration table has repetition channel entry,
+						   ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm,
+						   Configuration table (ex: ch1, limit = 22dBm) --> ch 1 = 22 dBm
+						   Cmd final setting -->  ch1 = 22dBm, ch12~14 = 20dBm
+						 */
+						prCmdPwrLimit->cPwrLimitCCK =
+							g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK];
+						prCmdPwrLimit->cPwrLimit20 =
+							g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M];
+						prCmdPwrLimit->cPwrLimit40 =
+							g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M];
+						prCmdPwrLimit->cPwrLimit80 =
+							g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M];
+						prCmdPwrLimit->cPwrLimit160 =
+							g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M];
+
+						DBGLOG(RLM, LOUD,
+						       "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n",
+							((prCmd->u2CountryCode & 0xff00) >> 8),
+							(prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh,
+							prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20,
+							prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80,
+							prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag);
+
+						break;
+					}
+					prCmdPwrLimit++;
+				}
+				if (k == prCmd->ucNum) {
+
+					/*Full search cmd (Default table setting) no match channey,
+					   ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm,
+					   Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm
+					   Cmd final setting -->  ch1~14 = 20dBm, ch36= 22dBm
+					 */
+					prCmdPwrLimit->cPwrLimitCCK =
+						g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK];
+					prCmdPwrLimit->cPwrLimit20 =
+						g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M];
+					prCmdPwrLimit->cPwrLimit40 =
+						g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M];
+					prCmdPwrLimit->cPwrLimit80 =
+						g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M];
+					prCmdPwrLimit->cPwrLimit160 =
+						g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M];
+					prCmd->ucNum++;
+
+					DBGLOG(RLM, LOUD,
+					       "Domain: Full CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n",
+						((prCmd->u2CountryCode & 0xff00) >> 8), (prCmd->u2CountryCode & 0x00ff),
+						prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK,
+						prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40,
+						prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160,
+						prCmdPwrLimit->ucFlag);
+
+				}
+			} else {
+
+				/*Default table power limit value are 63--> cmd table no channel entry
+				   ex : Default table (ex: 2.4G, limit = 63Bm) --> no channel entry in cmd,
+				   Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm
+				   Cmd final setting -->   ch36= 22dBm
+				 */
+				prCmdPwrLimit->ucCentralCh = g_rRlmPowerLimitConfiguration[i].ucCentralCh;
+				prCmdPwrLimit->cPwrLimitCCK =
+					g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK];
+				prCmdPwrLimit->cPwrLimit20 =
+					g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M];
+				prCmdPwrLimit->cPwrLimit40 =
+					g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M];
+				prCmdPwrLimit->cPwrLimit80 =
+					g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M];
+				prCmdPwrLimit->cPwrLimit160 =
+					g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M];
+				prCmd->ucNum++;
+
+				DBGLOG(RLM, LOUD, "Domain: Default table power limit value are 63.\n");
+				DBGLOG(RLM, LOUD, "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n",
+						   ((prCmd->u2CountryCode & 0xff00) >> 8),
+						   (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh,
+						   prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20,
+						   prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80,
+						   prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag);
+
+			}
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param[in]
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter)
+{
+	P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd;
+	UINT_8 i;
+	UINT_16 u2DefaultTableIndex;
+	UINT_32 u4SetCmdTableMaxSize;
+	UINT_32 u4SetQueryInfoLen;
+	P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit;	/* for print usage */
+
+	u4SetCmdTableMaxSize =
+	    sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) +
+	    MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT);
+
+	prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize);
+
+	if (!prCmd) {
+		DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n");
+		return;
+	}
+	kalMemZero(prCmd, u4SetCmdTableMaxSize);
+
+	u2DefaultTableIndex =
+	    rlmDomainPwrLimitDefaultTableDecision(prAdapter, prAdapter->rWifiVar.rConnSettings.u2CountryCode);
+
+	if (u2DefaultTableIndex != POWER_LIMIT_TABLE_NULL) {
+
+		WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[u2DefaultTableIndex].aucCountryCode[0],
+				    &prCmd->u2CountryCode);
+
+		prCmd->ucNum = 0;
+
+		if (prCmd->u2CountryCode != COUNTRY_CODE_NULL) {
+			/*Command - default table information */
+			rlmDomainBuildCmdByDefaultTable(prCmd, u2DefaultTableIndex);
+
+			/*Command - configuration table information */
+			rlmDomainBuildCmdByConfigTable(prAdapter, prCmd);
+		}
+	}
+#if 0
+	u4SetCmdTableMaxSize =
+	    sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) +
+	    MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT);
+
+	prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize);
+	ASSERT(prCmd);
+
+	/* To do: exception handle */
+	if (!prCmd) {
+		DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n");
+		return;
+	}
+	kalMemZero(prCmd, u4SetCmdTableMaxSize);	/* TODO memzero */
+
+	if (u2TableIndex != POWER_LIMIT_TABLE_NULL && u2TableIndex < MAX_DEFAULT_TABLE_COUNTRY_NUM) {
+
+		prCmd->u2CountryCode = (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[0]) << 8) |
+		    (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[1]) & BITS(0, 7));
+		prChPwrLimit = &g_rRlmCountryPowerLimitTable[u2TableIndex].rChannelPowerLimit[0];
+		prCmdPwrLimit = &prCmd->rChannelPowerLimit[0];
+		prCmd->ucNum = 0;
+		for (i = 0; i < MAX_CMD_SUPPORT_CHANNEL_NUM; i++) {
+
+			if (prChPwrLimit->ucCentralCh != ENDCH) {
+
+				/*Check Power limit table channel efficient or not */
+				fgChannelValid = rlmDomainCheckChannelEntryValid(prAdapter, prChPwrLimit->ucCentralCh);
+
+				/*Cmd set up */
+				if (fgChannelValid) {
+					kalMemCopy(prCmdPwrLimit, prChPwrLimit, sizeof(CMD_CHANNEL_POWER_LIMIT));
+					DBGLOG(RLM, INFO,
+					       "Domain: ValidCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n",
+						prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK,
+						prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40,
+						prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160,
+						prCmdPwrLimit->ucFlag);
+					prCmd->ucNum++;
+					prCmdPwrLimit++;
+				} else {
+					DBGLOG(RLM, INFO,
+					       "Domain: Non-Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n",
+						prChPwrLimit->ucCentralCh, prChPwrLimit->cPwrLimitCCK,
+						prChPwrLimit->cPwrLimit20, prChPwrLimit->cPwrLimit40,
+						prChPwrLimit->cPwrLimit80, prChPwrLimit->cPwrLimit160,
+						prChPwrLimit->ucFlag);
+				}
+				prChPwrLimit++;
+			} else {
+				/*End of the chanel entry */
+				break;
+			}
+		};
+	}
+#endif
+
+	if (prCmd->u2CountryCode != 0) {
+		DBGLOG(RLM, INFO,
+		       "Domain: ValidCC =%c%c, ChNum=%d\n", ((prCmd->u2CountryCode & 0xff00) >> 8),
+			(prCmd->u2CountryCode & 0x00ff), prCmd->ucNum);
+	} else {
+		DBGLOG(RLM, INFO, "Domain: ValidCC =0x%04x, ucNum=%d\n", prCmd->u2CountryCode, prCmd->ucNum);
+	}
+	prCmdPwrLimit = &prCmd->rChannelPowerLimit[0];
+
+	for (i = 0; i < prCmd->ucNum; i++) {
+		DBGLOG(RLM, TRACE, "Domain: Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", prCmdPwrLimit->ucCentralCh,
+				   prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40,
+				   prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag);
+		prCmdPwrLimit++;
+	}
+
+	u4SetQueryInfoLen =
+	    (sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + (prCmd->ucNum) * sizeof(CMD_CHANNEL_POWER_LIMIT));
+
+	/* Update domain info to chip */
+	if (prCmd->ucNum <= MAX_CMD_SUPPORT_CHANNEL_NUM) {
+		wlanSendSetQueryCmd(prAdapter, /* prAdapter */
+			     CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */
+			     TRUE,  /* fgSetQuery */
+			     FALSE, /* fgNeedResp */
+			     FALSE, /* fgIsOid */
+			     NULL,  /* pfCmdDoneHandler */
+			     NULL,  /* pfCmdTimeoutHandler */
+			     u4SetQueryInfoLen, /* u4SetQueryInfoLen */
+			     (PUINT_8) prCmd, /* pucInfoBuffer */
+			     NULL,  /* pvSetQueryBuffer */
+			     0      /* u4SetQueryBufferLen */
+		    );
+	} else
+		DBGLOG(RLM, ERROR, "Domain: illegal power limit table");
+
+	cnmMemFree(prAdapter, prCmd);
+
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c
new file mode 100644
index 0000000000000..8450124a3f38e
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c
@@ -0,0 +1,436 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2
+*/
+
+/*! \file   "rlm_obss.c"
+    \brief
+
+*/
+
+/*
+** Log: rlm_obss.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 11 15 2011 cm.chang
+ * NULL
+ * Avoid possible OBSS scan when BSS is switched
+ *
+ * 11 08 2011 cm.chang
+ * NULL
+ * Add RLM and CNM debug message for XLOG
+ *
+ * 10 25 2011 cm.chang
+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
+ * Regulation class is changed to 81 in 20_40_coexistence action frame
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 03 29 2011 cm.chang
+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning
+ * As CR title
+ *
+ * 01 24 2011 cm.chang
+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame
+ * in AP mode and stop ampdu timer when sta_rec is freed
+ * Process received 20/40 coexistence action frame for AP mode
+ *
+ * 01 13 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Refine function when rcv a 20/40M public action frame
+ *
+ * 01 13 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * Use SCO of BSS_INFO to replace user-defined setting variables
+ *
+ * 01 12 2011 cm.chang
+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting
+ * User-defined bandwidth is for 2.4G and 5G individually
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * use definition macro to replace hard-coded constant
+ *
+ * 09 16 2010 cm.chang
+ * NULL
+ * Change conditional compiling options for BOW
+ *
+ * 09 10 2010 cm.chang
+ * NULL
+ * Always update Beacon content if FW sync OBSS info
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Fix compile error while enabling WiFi Direct function.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add P2P Scan & Scan Result Parsing & Saving.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 05 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Process 20/40 coexistence public action frame in AP mode
+ *
+ * 05 05 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft support for 20/40M bandwidth for AP mode
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add more ASSERT to check exception
+ *
+ * 04 07 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add virtual test for OBSS scan
+ *
+ * 03 30 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support 2.4G OBSS scan
+ *
+ * 03 03 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * To support CFG_SUPPORT_BCM_STP
+ *
+ * 02 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support PCO in STA mode
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Use bss info array for concurrent handle
+ *
+ * 02 05 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 25 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmObssInit(P_ADAPTER_T prAdapter)
+{
+	P_BSS_INFO_T prBssInfo;
+	UINT_8 ucNetIdx;
+
+	RLM_NET_FOR_EACH(ucNetIdx) {
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
+		ASSERT(prBssInfo);
+
+		cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, rlmObssScanTimeout, (ULONG) prBssInfo);
+	}			/* end of RLM_NET_FOR_EACH */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rlmObssUpdateChnlLists(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
+{
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_SCN_SCAN_DONE prScanDoneMsg;
+	P_BSS_INFO_T prBssInfo;
+	P_MSDU_INFO_T prMsduInfo;
+	P_ACTION_20_40_COEXIST_FRAME prTxFrame;
+	UINT_16 i, u2PayloadLen;
+
+	ASSERT(prMsgHdr);
+
+	prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr;
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex];
+	ASSERT(prBssInfo);
+
+	DBGLOG(RLM, INFO, "OBSS Scan Done (NetIdx=%d, Mode=%d)\n",
+			   prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode);
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	/* AP mode */
+	if ((prAdapter->fgIsP2PRegistered) &&
+	    (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) &&
+	    (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
+		return;
+	}
+#endif
+
+	/* STA mode */
+	if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE ||
+	    !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) {
+		DBGLOG(RLM, WARN, "OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex);
+		return;
+	}
+
+	/* To do: check 2.4G channel list to decide if obss mgmt should be
+	 *        sent to associated AP. Note: how to handle concurrent network?
+	 * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence
+	 *        management frame is needed.
+	 */
+	prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
+	if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && prMsduInfo != NULL) {
+		DBGLOG(RLM, INFO, "Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n",
+				   prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0]);
+
+		prTxFrame = (P_ACTION_20_40_COEXIST_FRAME)
+		    ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+		prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
+		COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
+		COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
+		COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
+
+		prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
+		prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;
+
+		/* To do: find correct algorithm */
+		prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
+		prTxFrame->rBssCoexist.ucLength = 1;
+		prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0;
+
+		u2PayloadLen = 2 + 3;
+
+		if (prBssInfo->auc2G_NonHtChnlList[0] > 0) {
+			ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
+
+			prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT;
+			prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1;
+			prTxFrame->rChnlReport.ucRegulatoryClass = 81;	/* 2.4GHz, ch1~13 */
+			for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++)
+				prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i + 1];
+
+			u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport);
+		}
+		ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN);
+
+		/* Clear up channel lists in 2.4G band */
+		prBssInfo->auc2G_20mReqChnlList[0] = 0;
+		prBssInfo->auc2G_NonHtChnlList[0] = 0;
+
+		/* 4 Update information of MSDU_INFO_T */
+		prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;	/* Management frame */
+		prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
+		prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
+		prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+		prMsduInfo->fgIs802_1x = FALSE;
+		prMsduInfo->fgIs802_11 = TRUE;
+		prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+		prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+		prMsduInfo->pfTxDoneHandler = NULL;
+		prMsduInfo->fgIsBasicRate = FALSE;
+
+		/* 4 Enqueue the frame to send this action frame. */
+		nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+	}
+	/* end of prMsduInfo != NULL */
+	if (prBssInfo->u2ObssScanInterval > 0) {
+		DBGLOG(RLM, INFO, "Set OBSS timer (NetIdx=%d, %d sec)\n",
+				   prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval);
+
+		cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	prBssInfo = (P_BSS_INFO_T) ulData;
+	ASSERT(prBssInfo);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prAdapter->fgIsP2PRegistered && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex))) {
+
+		/* AP mode */
+		if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
+
+			prBssInfo->fgObssActionForcedTo20M = FALSE;
+
+			/* Check if Beacon content need to be updated */
+			rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE);
+
+			return;
+		}
+#if CFG_SUPPORT_WFD
+		/* WFD streaming */
+		else {
+			P_WFD_CFG_SETTINGS_T prWfdCfgSettings =
+			    &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
+			P_BSS_INFO_T prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
+
+			/* If WFD is enabled & connected */
+			if (prWfdCfgSettings->ucWfdEnable &&
+			    (prWfdCfgSettings->u4WfdFlag & BIT(0)) && RLM_NET_PARAM_VALID(prP2pBssInfo)) {
+
+				/* Skip OBSS scan */
+				prBssInfo->u2ObssScanInterval = 0;
+
+				DBGLOG(RLM, INFO, "WFD is running. Stop net[%u] OBSS scan.\n",
+						   (UINT_32) prBssInfo->ucNetTypeIndex);
+
+				return;
+			}
+		}
+#endif
+	}
+#endif /* end of CFG_ENABLE_WIFI_DIRECT */
+
+	/* STA mode */
+	if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE ||
+	    !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) {
+		DBGLOG(RLM, WARN, "OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex);
+		return;
+	}
+
+	rlmObssTriggerScan(prAdapter, prBssInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+	P_MSG_SCN_SCAN_REQ prScanReqMsg;
+
+	ASSERT(prBssInfo);
+
+	prScanReqMsg = (P_MSG_SCN_SCAN_REQ)
+	    cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ));
+	ASSERT(prScanReqMsg);
+
+	if (!prScanReqMsg) {
+		DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex);
+
+		cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
+		return;
+	}
+
+	/* It is ok that ucSeqNum is set to fixed value because the same network
+	 * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec)
+	 * and scan module don't care seqNum of OBSS scanning
+	 */
+	prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ;
+	prScanReqMsg->ucSeqNum = 0x33;
+	prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex;
+	prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN;
+	prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD;
+	prScanReqMsg->ucSSIDLength = 0;
+	prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4;
+	prScanReqMsg->u2IELen = 0;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF);
+
+	DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex);
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c
new file mode 100644
index 0000000000000..d3c5133970956
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c
@@ -0,0 +1,105 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_protection.c#1
+*/
+
+/*! \file   "rlm_protection.c"
+    \brief
+
+*/
+
+/*
+** Log: rlm_protection.c
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Check draft RLM code for HT cap
+ *
+ * 05 28 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Set RTS threshold of 2K bytes initially
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * First draft code to support protection in AP mode
+ *
+ * 03 31 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Enable RTS threshold temporarily for AMPDU
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 03 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * To support CFG_SUPPORT_BCM_STP
+ *
+ * 02 13 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support PCO in STA mode
+ *
+ * 02 12 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Use bss info array for concurrent handle
+ *
+ * 01 25 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c
new file mode 100644
index 0000000000000..3f088c2839936
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c
@@ -0,0 +1,539 @@
+/*
+** Id:
+*/
+
+/*! \file   "roaming_fsm.c"
+    \brief  This file defines the FSM for Roaming MODULE.
+
+    This file defines the FSM for Roaming MODULE.
+*/
+
+/*
+** Log: roaming_fsm.c
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 08 31 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * remove obsolete code.
+ *
+ * 08 15 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * add swcr in driver reg, 0x9fxx0000, to disable roaming .
+ *
+ * 03 16 2011 tsaiyuan.hsu
+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming
+ * remove obsolete definition and unused variables.
+ *
+ * 02 26 2011 tsaiyuan.hsu
+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support
+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming.
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_SUPPORT_ROAMING
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+#if DBG
+/*lint -save -e64 Type mismatch */
+static PUINT_8 apucDebugRoamingState[ROAMING_STATE_NUM] = {
+	(PUINT_8) DISP_STRING("ROAMING_STATE_IDLE"),
+	(PUINT_8) DISP_STRING("ROAMING_STATE_DECISION"),
+	(PUINT_8) DISP_STRING("ROAMING_STATE_DISCOVERY"),
+	(PUINT_8) DISP_STRING("ROAMING_STATE_ROAM")
+};
+
+/*lint -restore */
+#endif /* DBG */
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/*
+#define ROAMING_ENABLE_CHECK(_roam) \
+{ \
+	if (!(_roam->fgIsEnableRoaming)) \
+		return; \
+}
+*/
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	DBGLOG(ROAMING, LOUD, "->roamingFsmInit(): Current Time = %u\n", kalGetTimeTick());
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	/* 4 <1> Initiate FSM */
+	prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming;
+	prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE;
+	prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0;
+
+}				/* end of roamingFsmInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+
+	DBGLOG(ROAMING, LOUD, "->roamingFsmUninit(): Current Time = %u\n", kalGetTimeTick());
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE;
+
+}				/* end of roamingFsmUninit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Send commands to firmware
+*
+* @param [IN P_ADAPTER_T]       prAdapter
+*        [IN P_ROAMING_PARAM_T] prParam
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	WLAN_STATUS rStatus;
+
+	DBGLOG(ROAMING, LOUD, "->roamingFsmSendCmd(): Current Time = %u\n", kalGetTimeTick());
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_ROAMING_TRANSIT,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL,	/* pfCmdDoneHandler */
+				      NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(ROAMING_PARAM_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prParam,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+
+}				/* end of roamingFsmSendCmd() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Update the recent time when ScanDone occurred
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	/* Check Roaming Conditions */
+	if (!(prRoamingFsmInfo->fgIsEnableRoaming))
+		return;
+
+	DBGLOG(ROAMING, LOUD, "->roamingFsmScanResultsUpdate(): Current Time = %u", kalGetTimeTick());
+
+	GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime);
+
+}				/* end of roamingFsmScanResultsUpdate() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief The Core FSM engine of ROAMING for AIS Infra.
+*
+* @param [IN P_ADAPTER_T]          prAdapter
+*        [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	ENUM_ROAMING_STATE_T ePreviousState;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	do {
+
+		/* Do entering Next State */
+#if DBG
+		DBGLOG(ROAMING, STATE, "TRANSITION: [%s] -> [%s]\n",
+					apucDebugRoamingState[prRoamingFsmInfo->eCurrentState],
+					apucDebugRoamingState[eNextState]);
+#else
+		DBGLOG(ROAMING, STATE, "[%d] TRANSITION: [%d] -> [%d]\n",
+					DBG_ROAMING_IDX, prRoamingFsmInfo->eCurrentState, eNextState);
+#endif
+		/* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */
+		ePreviousState = prRoamingFsmInfo->eCurrentState;
+		prRoamingFsmInfo->eCurrentState = eNextState;
+
+		fgIsTransition = (BOOLEAN) FALSE;
+
+		/* Do tasks of the State that we just entered */
+		switch (prRoamingFsmInfo->eCurrentState) {
+			/* NOTE(Kevin): we don't have to rearrange the sequence of following
+			 * switch case. Instead I would like to use a common lookup table of array
+			 * of function pointer to speed up state search.
+			 */
+		case ROAMING_STATE_IDLE:
+		case ROAMING_STATE_DECISION:
+			break;
+
+		case ROAMING_STATE_DISCOVERY:
+			{
+				OS_SYSTIME rCurrentTime;
+
+				GET_CURRENT_SYSTIME(&rCurrentTime);
+				if (CHECK_FOR_TIMEOUT(rCurrentTime, prRoamingFsmInfo->rRoamingDiscoveryUpdateTime,
+						      SEC_TO_SYSTIME(ROAMING_DISCOVERY_TIMEOUT_SEC))) {
+					DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Timeout");
+					aisFsmRunEventRoamingDiscovery(prAdapter, TRUE);
+				} else {
+					DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Updated");
+#if CFG_SUPPORT_ROAMING_ENC
+					if (prAdapter->fgIsRoamingEncEnabled == TRUE)
+						aisFsmRunEventRoamingDiscovery(prAdapter, TRUE);
+					else
+#endif /* CFG_SUPPORT_ROAMING_ENC */
+						aisFsmRunEventRoamingDiscovery(prAdapter, FALSE);
+				}
+			}
+			break;
+
+		case ROAMING_STATE_ROAM:
+			break;
+
+		default:
+			ASSERT(0);	/* Make sure we have handle all STATEs */
+		}
+	} while (fgIsTransition);
+
+	return;
+
+}				/* end of roamingFsmSteps() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Transit to Decision state after join completion
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	ENUM_ROAMING_STATE_T eNextState;
+	P_BSS_INFO_T prAisBssInfo;
+	ROAMING_PARAM_T rParam;
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	/* Check Roaming Conditions */
+	if (!(prRoamingFsmInfo->fgIsEnableRoaming))
+		return;
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE)
+		return;
+
+	DBGLOG(ROAMING, EVENT, "EVENT-ROAMING START: Current Time = %u\n", kalGetTimeTick());
+
+	/* IDLE, ROAM -> DECISION */
+	/* Errors as DECISION, DISCOVERY -> DECISION */
+	if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE ||
+		prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM))
+		return;
+
+	eNextState = ROAMING_STATE_DECISION;
+	if (eNextState != prRoamingFsmInfo->eCurrentState) {
+		rParam.u2Event = ROAMING_EVENT_START;
+		roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam);
+
+		/* Step to next state */
+		roamingFsmSteps(prAdapter, eNextState);
+	}
+
+}				/* end of roamingFsmRunEventStart() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Transit to Discovery state when deciding to find a candidate
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	ENUM_ROAMING_STATE_T eNextState;
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	/* Check Roaming Conditions */
+	if (!(prRoamingFsmInfo->fgIsEnableRoaming))
+		return;
+
+	DBGLOG(ROAMING, EVENT, "EVENT-ROAMING DISCOVERY: Current Time = %u Reason = %u\n",
+		kalGetTimeTick(), prParam->u2Reason);
+
+	/* DECISION -> DISCOVERY */
+	/* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */
+	if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION)
+		return;
+#if CFG_SUPPORT_ROAMING_ENC
+	prRoamingFsmInfo->RoamingEntryTimeoutSkipCount = 0;
+#endif
+
+	eNextState = ROAMING_STATE_DISCOVERY;
+	/* DECISION -> DISCOVERY */
+	if (eNextState != prRoamingFsmInfo->eCurrentState) {
+		P_BSS_INFO_T prAisBssInfo;
+		P_BSS_DESC_T prBssDesc;
+
+		/* sync. rcpi with firmware */
+		prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+		prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
+		if (prBssDesc)
+			prBssDesc->ucRCPI = (UINT_8) (prParam->u2Data & 0xff);
+
+		roamingFsmSteps(prAdapter, eNextState);
+	}
+
+}				/* end of roamingFsmRunEventDiscovery() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Transit to Roam state after Scan Done
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	ENUM_ROAMING_STATE_T eNextState;
+	ROAMING_PARAM_T rParam;
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	/* Check Roaming Conditions */
+	if (!(prRoamingFsmInfo->fgIsEnableRoaming))
+		return;
+
+	DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ROAM: Current Time = %u\n", kalGetTimeTick());
+
+	/* IDLE, ROAM -> DECISION */
+	/* Errors as IDLE, DECISION, ROAM -> ROAM */
+	if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY)
+		return;
+
+	eNextState = ROAMING_STATE_ROAM;
+	/* DISCOVERY -> ROAM */
+	if (eNextState != prRoamingFsmInfo->eCurrentState) {
+		rParam.u2Event = ROAMING_EVENT_ROAM;
+		roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam);
+
+		/* Step to next state */
+		roamingFsmSteps(prAdapter, eNextState);
+	}
+
+}				/* end of roamingFsmRunEventRoam() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Transit to Decision state as being failed to find out any candidate
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	ENUM_ROAMING_STATE_T eNextState;
+	ROAMING_PARAM_T rParam;
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	/* Check Roaming Conditions */
+	if (!(prRoamingFsmInfo->fgIsEnableRoaming))
+		return;
+
+	DBGLOG(ROAMING, EVENT, "EVENT-ROAMING FAIL: reason %x Current Time = %u\n", u4Param, kalGetTimeTick());
+
+	/* IDLE, ROAM -> DECISION */
+	/* Errors as IDLE, DECISION, DISCOVERY -> DECISION */
+	if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM)
+		return;
+
+	eNextState = ROAMING_STATE_DECISION;
+	/* ROAM -> DECISION */
+	if (eNextState != prRoamingFsmInfo->eCurrentState) {
+		rParam.u2Event = ROAMING_EVENT_FAIL;
+		rParam.u2Data = (UINT_16) (u4Param & 0xffff);
+		roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam);
+
+		/* Step to next state */
+		roamingFsmSteps(prAdapter, eNextState);
+	}
+
+}				/* end of roamingFsmRunEventFail() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Transit to Idle state as beging aborted by other moduels, AIS
+*
+* @param [IN P_ADAPTER_T] prAdapter
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter)
+{
+	P_ROAMING_INFO_T prRoamingFsmInfo;
+	ENUM_ROAMING_STATE_T eNextState;
+	ROAMING_PARAM_T rParam;
+
+	prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+
+	if (!(prRoamingFsmInfo->fgIsEnableRoaming))
+		return;
+
+	DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ABORT: Current Time = %u\n", kalGetTimeTick());
+
+	eNextState = ROAMING_STATE_IDLE;
+	/* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */
+	if (eNextState != prRoamingFsmInfo->eCurrentState) {
+		rParam.u2Event = ROAMING_EVENT_ABORT;
+		roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam);
+
+		/* Step to next state */
+		roamingFsmSteps(prAdapter, eNextState);
+	}
+
+}				/* end of roamingFsmRunEventAbort() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process events from firmware
+*
+* @param [IN P_ADAPTER_T]       prAdapter
+*        [IN P_ROAMING_PARAM_T] prParam
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam)
+{
+	DBGLOG(ROAMING, LOUD, "ROAMING Process Events: Current Time = %u\n", kalGetTimeTick());
+
+	if (ROAMING_EVENT_DISCOVERY == prParam->u2Event)
+		roamingFsmRunEventDiscovery(prAdapter, prParam);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c
new file mode 100644
index 0000000000000..eedd8d12f2fd3
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c
@@ -0,0 +1,2533 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#2
+*/
+
+/*! \file   "rsn.c"
+    \brief  This file including the 802.11i, wpa and wpa2(rsn) related function.
+
+    This file provided the macros and functions library support the wpa/rsn ie parsing,
+    cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support.
+*/
+
+/*
+** Log: rsn.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 03 09 2012 chinglan.wang
+ * NULL
+ * Fix the condition error.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the debug module level.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 02 09 2011 wh.su
+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
+ * adding the code for check STA privacy bit at AP mode, .
+ *
+ * 12 24 2010 chinglan.wang
+ * NULL
+ * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function.
+ *
+ * 12 13 2010 cp.wu
+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
+ * create branch for Wi-Fi driver v1.1
+ *
+ * 11 05 2010 wh.su
+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value
+ * fixed the.pmkid value mismatch issue
+ *
+ * 11 03 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Refine the HT rate disallow TKIP pairwise cipher .
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T
+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 29 2010 yuche.tsai
+ * NULL
+ * Fix compile error, remove unused pointer in rsnGenerateRSNIE().
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 24 2010 wh.su
+ * NULL
+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
+ *
+ * 09 06 2010 wh.su
+ * NULL
+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
+ *
+ * 08 30 2010 wh.su
+ * NULL
+ * remove non-used code.
+ *
+ * 08 19 2010 wh.su
+ * NULL
+ * adding the tx pkt call back handle for countermeasure.
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * modify some code for concurrent network.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * enable RX management frame handling.
+ *
+ * 06 19 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * consdier the concurrent network setting.
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * [WPD00003840] [MT6620 5931] Security migration
+ * migration from firmware.
+ *
+ * 05 27 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * not indicate pmkid candidate while no new one scanned.
+ *
+ * 04 29 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * adjsut the pre-authentication code.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * move the AIS specific variable for security to AIS specific structure.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * Fixed the pre-authentication timer not correctly init issue,
+ * and modify the security related callback function prototype.
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 8 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * change the name
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * using the Rx0 port to indicate event
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * refine the code for generate the WPA/RSN IE for assoc req
+ *
+ * Dec 3 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust code for pmkid event
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the code for event (mic error and pmkid indicate) and do some function rename
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding some security function
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding some security feature, including pmkid
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_RSN_MIGRATION
+
+/* extern PHY_ATTRIBUTE_T rPhyAttributes[]; */
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to parse RSN IE.
+*
+* \param[in]  prInfoElem Pointer to the RSN IE
+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the
+**                  RSN information from the given RSN IE
+*
+* \retval TRUE - Succeeded
+* \retval FALSE - Failed
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo)
+{
+	UINT_32 i;
+	INT_32 u4RemainRsnIeLen;
+	UINT_16 u2Version;
+	UINT_16 u2Cap = 0;
+	UINT_32 u4GroupSuite = RSN_CIPHER_SUITE_CCMP;
+	UINT_16 u2PairSuiteCount = 0;
+	UINT_16 u2AuthSuiteCount = 0;
+	PUINT_8 pucPairSuite = NULL;
+	PUINT_8 pucAuthSuite = NULL;
+	PUINT_8 cp;
+
+	DEBUGFUNC("rsnParseRsnIE");
+
+	ASSERT(prInfoElem);
+	ASSERT(prRsnInfo);
+
+	/* Verify the length of the RSN IE. */
+	if (prInfoElem->ucLength < 2) {
+		DBGLOG(RSN, TRACE, "RSN IE length too short (length=%d)\n", prInfoElem->ucLength);
+		return FALSE;
+	}
+
+	/* Check RSN version: currently, we only support version 1. */
+	WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
+	if (u2Version != 1) {
+		DBGLOG(RSN, TRACE, "Unsupported RSN IE version: %d\n", u2Version);
+		return FALSE;
+	}
+
+	cp = (PUCHAR) & prInfoElem->u4GroupKeyCipherSuite;
+	u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2;
+
+	do {
+		if (u4RemainRsnIeLen == 0)
+			break;
+
+		/* Parse the Group Key Cipher Suite field. */
+		if (u4RemainRsnIeLen < 4) {
+			DBGLOG(RSN, TRACE, "Fail to parse RSN IE in group cipher suite (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_32(cp, &u4GroupSuite);
+		cp += 4;
+		u4RemainRsnIeLen -= 4;
+
+		if (u4RemainRsnIeLen == 0)
+			break;
+
+		/* Parse the Pairwise Key Cipher Suite Count field. */
+		if (u4RemainRsnIeLen < 2) {
+			DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
+		cp += 2;
+		u4RemainRsnIeLen -= 2;
+
+		/* Parse the Pairwise Key Cipher Suite List field. */
+		i = (UINT_32) u2PairSuiteCount * 4;
+		if (u4RemainRsnIeLen < (INT_32) i) {
+			DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		pucPairSuite = cp;
+
+		cp += i;
+		u4RemainRsnIeLen -= (INT_32) i;
+
+		if (u4RemainRsnIeLen == 0)
+			break;
+
+		/* Parse the Authentication and Key Management Cipher Suite Count field. */
+		if (u4RemainRsnIeLen < 2) {
+			DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
+		cp += 2;
+		u4RemainRsnIeLen -= 2;
+
+		/* Parse the Authentication and Key Management Cipher Suite List
+		   field. */
+		i = (UINT_32) u2AuthSuiteCount * 4;
+		if (u4RemainRsnIeLen < (INT_32) i) {
+			DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		pucAuthSuite = cp;
+
+		cp += i;
+		u4RemainRsnIeLen -= (INT_32) i;
+
+		if (u4RemainRsnIeLen == 0)
+			break;
+
+		/* Parse the RSN u2Capabilities field. */
+		if (u4RemainRsnIeLen < 2) {
+			DBGLOG(RSN, TRACE, "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2Cap);
+	} while (FALSE);
+
+	/* Save the RSN information for the BSS. */
+	prRsnInfo->ucElemId = ELEM_ID_RSN;
+
+	prRsnInfo->u2Version = u2Version;
+
+	prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite;
+
+	DBGLOG(RSN, LOUD, "RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
+			   u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
+			   (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
+			   (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF));
+
+	if (pucPairSuite) {
+		/* The information about the pairwise key cipher suites is present. */
+		if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES)
+			u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
+
+		prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
+
+		for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
+			WLAN_GET_FIELD_32(pucPairSuite, &prRsnInfo->au4PairwiseKeyCipherSuite[i]);
+			pucPairSuite += 4;
+
+			DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
+					   (UINT_8) i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
+					   (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
+					   (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
+					   (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF));
+		}
+	} else {
+		/* The information about the pairwise key cipher suites is not present.
+		   Use the default chipher suite for RSN: CCMP. */
+		prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1;
+		prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP;
+
+		DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
+				   (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
+				   (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
+				   (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
+				   (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF));
+	}
+
+	if (pucAuthSuite) {
+		/* The information about the authentication and key management suites
+		   is present. */
+		if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES)
+			u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
+
+		prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
+
+		for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
+			WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]);
+			pucAuthSuite += 4;
+
+			DBGLOG(RSN, LOUD, "RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
+					   (UINT_8) i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
+					   (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
+					   (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
+					   (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF));
+		}
+	} else {
+		/* The information about the authentication and key management suites
+		   is not present. Use the default AKM suite for RSN. */
+		prRsnInfo->u4AuthKeyMgtSuiteCount = 1;
+		prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X;
+
+		DBGLOG(RSN, LOUD, "RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n",
+				   (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
+				   (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
+				   (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
+				   (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF));
+	}
+
+	prRsnInfo->u2RsnCap = u2Cap;
+#if CFG_SUPPORT_802_11W
+	prRsnInfo->fgRsnCapPresent = TRUE;
+#endif
+	DBGLOG(RSN, LOUD, "RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap);
+
+	return TRUE;
+}				/* rsnParseRsnIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to parse WPA IE.
+*
+* \param[in]  prInfoElem Pointer to the WPA IE.
+* \param[out] prWpaInfo Pointer to the BSSDescription structure to store the
+*                       WPA information from the given WPA IE.
+*
+* \retval TRUE Succeeded.
+* \retval FALSE Failed.
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo)
+{
+	UINT_32 i;
+	INT_32 u4RemainWpaIeLen;
+	UINT_16 u2Version;
+	UINT_16 u2Cap = 0;
+	UINT_32 u4GroupSuite = WPA_CIPHER_SUITE_TKIP;
+	UINT_16 u2PairSuiteCount = 0;
+	UINT_16 u2AuthSuiteCount = 0;
+	PUCHAR pucPairSuite = NULL;
+	PUCHAR pucAuthSuite = NULL;
+	PUCHAR cp;
+	BOOLEAN fgCapPresent = FALSE;
+
+	DEBUGFUNC("rsnParseWpaIE");
+
+	ASSERT(prInfoElem);
+	ASSERT(prWpaInfo);
+
+	/* Verify the length of the WPA IE. */
+	if (prInfoElem->ucLength < 6) {
+		DBGLOG(RSN, TRACE, "WPA IE length too short (length=%d)\n", prInfoElem->ucLength);
+		return FALSE;
+	}
+
+	/* Check WPA version: currently, we only support version 1. */
+	WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
+	if (u2Version != 1) {
+		DBGLOG(RSN, TRACE, "Unsupported WPA IE version: %d\n", u2Version);
+		return FALSE;
+	}
+
+	cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite;
+	u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6;
+
+	do {
+		if (u4RemainWpaIeLen == 0)
+			break;
+
+		/* WPA_OUI      : 4
+		   Version      : 2
+		   GroupSuite   : 4
+		   PairwiseCount: 2
+		   PairwiseSuite: 4 * pairSuiteCount
+		   AuthCount    : 2
+		   AuthSuite    : 4 * authSuiteCount
+		   Cap          : 2 */
+
+		/* Parse the Group Key Cipher Suite field. */
+		if (u4RemainWpaIeLen < 4) {
+			DBGLOG(RSN, TRACE, "Fail to parse WPA IE in group cipher suite (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_32(cp, &u4GroupSuite);
+		cp += 4;
+		u4RemainWpaIeLen -= 4;
+
+		if (u4RemainWpaIeLen == 0)
+			break;
+
+		/* Parse the Pairwise Key Cipher Suite Count field. */
+		if (u4RemainWpaIeLen < 2) {
+			DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
+		cp += 2;
+		u4RemainWpaIeLen -= 2;
+
+		/* Parse the Pairwise Key Cipher Suite List field. */
+		i = (UINT_32) u2PairSuiteCount * 4;
+		if (u4RemainWpaIeLen < (INT_32) i) {
+			DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		pucPairSuite = cp;
+
+		cp += i;
+		u4RemainWpaIeLen -= (INT_32) i;
+
+		if (u4RemainWpaIeLen == 0)
+			break;
+
+		/* Parse the Authentication and Key Management Cipher Suite Count
+		   field. */
+		if (u4RemainWpaIeLen < 2) {
+			DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
+		cp += 2;
+		u4RemainWpaIeLen -= 2;
+
+		/* Parse the Authentication and Key Management Cipher Suite List
+		   field. */
+		i = (UINT_32) u2AuthSuiteCount * 4;
+		if (u4RemainWpaIeLen < (INT_32) i) {
+			DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		pucAuthSuite = cp;
+
+		cp += i;
+		u4RemainWpaIeLen -= (INT_32) i;
+
+		if (u4RemainWpaIeLen == 0)
+			break;
+
+		/* Parse the WPA u2Capabilities field. */
+		if (u4RemainWpaIeLen < 2) {
+			DBGLOG(RSN, TRACE, "Fail to parse WPA IE in WPA capabilities (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		fgCapPresent = TRUE;
+		WLAN_GET_FIELD_16(cp, &u2Cap);
+		u4RemainWpaIeLen -= 2;
+	} while (FALSE);
+
+	/* Save the WPA information for the BSS. */
+
+	prWpaInfo->ucElemId = ELEM_ID_WPA;
+
+	prWpaInfo->u2Version = u2Version;
+
+	prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite;
+
+	DBGLOG(RSN, LOUD, "WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
+			   u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
+			   (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
+			   (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF));
+
+	if (pucPairSuite) {
+		/* The information about the pairwise key cipher suites is present. */
+		if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES)
+			u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
+
+		prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
+
+		for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
+			WLAN_GET_FIELD_32(pucPairSuite, &prWpaInfo->au4PairwiseKeyCipherSuite[i]);
+			pucPairSuite += 4;
+
+			DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
+					   (UINT_8) i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
+					   (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
+					   (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
+					   (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF));
+		}
+	} else {
+		/* The information about the pairwise key cipher suites is not present.
+		   Use the default chipher suite for WPA: TKIP. */
+		prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1;
+		prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP;
+
+		DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
+				   (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
+				   (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
+				   (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
+				   (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF));
+	}
+
+	if (pucAuthSuite) {
+		/* The information about the authentication and key management suites
+		   is present. */
+		if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES)
+			u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
+
+		prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
+
+		for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
+			WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]);
+			pucAuthSuite += 4;
+
+			DBGLOG(RSN, LOUD, "WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
+					   (UINT_8) i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
+					   (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
+					   (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
+					   (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF));
+		}
+	} else {
+		/* The information about the authentication and key management suites
+		   is not present. Use the default AKM suite for WPA. */
+		prWpaInfo->u4AuthKeyMgtSuiteCount = 1;
+		prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X;
+
+		DBGLOG(RSN, LOUD, "WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n",
+				   (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
+				   (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
+				   (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
+				   (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF));
+	}
+
+	if (fgCapPresent) {
+		prWpaInfo->fgRsnCapPresent = TRUE;
+		prWpaInfo->u2RsnCap = u2Cap;
+		DBGLOG(RSN, LOUD, "WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap);
+	} else {
+		prWpaInfo->fgRsnCapPresent = FALSE;
+		prWpaInfo->u2RsnCap = 0;
+	}
+
+	return TRUE;
+}				/* rsnParseWpaIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to search the desired pairwise
+*        cipher suite from the MIB Pairwise Cipher Suite
+*        configuration table.
+*
+* \param[in] u4Cipher The desired pairwise cipher suite to be searched
+* \param[out] pu4Index Pointer to the index of the desired pairwise cipher in
+*                      the table
+*
+* \retval TRUE - The desired pairwise cipher suite is found in the table.
+* \retval FALSE - The desired pairwise cipher suite is not found in the
+*                 table.
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index)
+{
+	UINT_8 i;
+	P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry;
+
+	DEBUGFUNC("rsnSearchSupportedCipher");
+
+	ASSERT(pu4Index);
+
+	for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) {
+		prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i];
+		if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher &&
+			prEntry->dot11RSNAConfigPairwiseCipherEnabled) {
+			*pu4Index = i;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}				/* rsnSearchSupportedCipher */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Whether BSS RSN is matched from upper layer set.
+*
+* \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information
+*
+* \retval BOOLEAN
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo)
+{
+	UINT_8 i = 0;
+
+	DEBUGFUNC("rsnIsSuitableBSS");
+
+	do {
+
+		if ((prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite & 0x000000FF) !=
+		    GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)) {
+			DBGLOG(RSN, TRACE, "Break by GroupKeyCipherSuite\n");
+			break;
+		}
+		for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
+			if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] & 0x000000FF) !=
+			     GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]))
+			    && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1)) {
+				DBGLOG(RSN, TRACE, "Break by PairwiseKeyCipherSuite\n");
+				break;
+			}
+		}
+		for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) {
+			if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] & 0x000000FF) !=
+			     GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0]))
+			    && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)) {
+				DBGLOG(RSN, TRACE, "Break by AuthKeyMgtSuite\n");
+				break;
+			}
+		}
+		return TRUE;
+	} while (FALSE);
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to search the desired
+*        authentication and key management (AKM) suite from the
+*        MIB Authentication and Key Management Suites table.
+*
+* \param[in]  u4AkmSuite The desired AKM suite to be searched
+* \param[out] pu4Index   Pointer to the index of the desired AKM suite in the
+*                        table
+*
+* \retval TRUE  The desired AKM suite is found in the table.
+* \retval FALSE The desired AKM suite is not found in the table.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index)
+{
+	UINT_8 i;
+	P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry;
+
+	DEBUGFUNC("rsnSearchAKMSuite");
+
+	ASSERT(pu4Index);
+
+	for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
+		prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
+		if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite &&
+		    prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) {
+			*pu4Index = i;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}				/* rsnSearchAKMSuite */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to perform RSNA or TSN policy
+*        selection for a given BSS.
+*
+* \param[in]  prBss Pointer to the BSS description
+*
+* \retval TRUE - The RSNA/TSN policy selection for the given BSS is
+*                successful. The selected pairwise and group cipher suites
+*                are returned in the BSS description.
+* \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed.
+*                 The driver shall not attempt to join the given BSS.
+*
+* \note The Encrypt status matched score will save to bss for final ap select.
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss)
+{
+#if CFG_SUPPORT_802_11W
+	INT_32 i;
+	UINT_32 j;
+#else
+	UINT_32 i, j;
+#endif
+	BOOLEAN fgSuiteSupported;
+	UINT_32 u4PairwiseCipher = 0;
+	UINT_32 u4GroupCipher = 0;
+	UINT_32 u4AkmSuite = 0;
+	P_RSN_INFO_T prBssRsnInfo;
+	ENUM_NETWORK_TYPE_INDEX_T eNetwotkType;
+	BOOLEAN fgIsWpsActive = (BOOLEAN) FALSE;
+
+	DEBUGFUNC("rsnPerformPolicySelection");
+
+	ASSERT(prBss);
+
+	DBGLOG(RSN, TRACE, "rsnPerformPolicySelection\n");
+	/* Todo:: */
+	eNetwotkType = NETWORK_TYPE_AIS_INDEX;
+
+	prBss->u4RsnSelectedPairwiseCipher = 0;
+	prBss->u4RsnSelectedGroupCipher = 0;
+	prBss->u4RsnSelectedAKMSuite = 0;
+	prBss->ucEncLevel = 0;
+
+#if CFG_SUPPORT_WPS
+	fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo);
+
+	/* CR1640, disable the AP select privacy check */
+	if (fgIsWpsActive &&
+	    (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) &&
+	    (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) {
+		DBGLOG(RSN, TRACE, "-- Skip the Protected BSS check\n");
+		return TRUE;
+	}
+#endif
+
+	/* Protection is not required in this BSS. */
+	if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) {
+
+		if (secEnabledInAis(prAdapter) == FALSE) {
+			DBGLOG(RSN, TRACE, "-- No Protected BSS\n");
+			return TRUE;
+		}
+		DBGLOG(RSN, TRACE, "-- Protected BSS\n");
+		return FALSE;
+
+	}
+
+	/* Protection is required in this BSS. */
+	if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) {
+		if (secEnabledInAis(prAdapter) == FALSE) {
+			DBGLOG(RSN, TRACE, "-- Protected BSS\n");
+			return FALSE;
+		}
+	}
+
+	if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA ||
+	    prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK ||
+	    prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) {
+
+		if (prBss->fgIEWPA) {
+			prBssRsnInfo = &prBss->rWPAInfo;
+		} else {
+			DBGLOG(RSN, TRACE, "WPA Information Element does not exist.\n");
+			return FALSE;
+		}
+	} else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 ||
+		   prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) {
+
+		if (prBss->fgIERSN) {
+			prBssRsnInfo = &prBss->rRSNInfo;
+		} else {
+			DBGLOG(RSN, TRACE, "RSN Information Element does not exist.\n");
+			return FALSE;
+		}
+	} else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) {
+		/* If the driver is configured to use WEP only, ignore this BSS. */
+		DBGLOG(RSN, TRACE, "-- Not WEP-only legacy BSS %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus);
+		return FALSE;
+	} else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) {
+		/* If the driver is configured to use WEP only, use this BSS. */
+		DBGLOG(RSN, TRACE, "-- WEP-only legacy BSS, fgIERSN %d, fgIEWPA %d\n",
+				    prBss->fgIERSN, prBss->fgIEWPA);
+		/* if this BSS was configured to WPA/WPA2, don't select this AP */
+		return (prBss->fgIERSN || prBss->fgIEWPA) ? FALSE : TRUE;
+	}
+
+	if (!rsnIsSuitableBSS(prAdapter, prBssRsnInfo)) {
+		DBGLOG(RSN, TRACE, "RSN info check no matched\n");
+		return FALSE;
+	}
+
+	if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 &&
+	    GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == CIPHER_SUITE_NONE) {
+		/* Since the pairwise cipher use the same cipher suite as the group
+		   cipher in the BSS, we check the group cipher suite against the
+		   current encryption status. */
+		fgSuiteSupported = FALSE;
+
+		switch (prBssRsnInfo->u4GroupKeyCipherSuite) {
+		case WPA_CIPHER_SUITE_CCMP:
+		case RSN_CIPHER_SUITE_CCMP:
+			if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED)
+				fgSuiteSupported = TRUE;
+			break;
+
+		case WPA_CIPHER_SUITE_TKIP:
+		case RSN_CIPHER_SUITE_TKIP:
+			if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED)
+				fgSuiteSupported = TRUE;
+			break;
+
+		case WPA_CIPHER_SUITE_WEP40:
+		case WPA_CIPHER_SUITE_WEP104:
+			if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED)
+				fgSuiteSupported = TRUE;
+			break;
+		}
+
+		if (fgSuiteSupported) {
+			u4PairwiseCipher = WPA_CIPHER_SUITE_NONE;
+			u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
+		}
+#if DBG
+		else {
+			DBGLOG(RSN, TRACE, "Inproper encryption status %d for group-key-only BSS\n",
+					    prAdapter->rWifiVar.rConnSettings.eEncStatus);
+		}
+#endif
+	} else {
+		fgSuiteSupported = FALSE;
+
+		DBGLOG(RSN, TRACE, "eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus,
+				    (UINT_32) prBssRsnInfo->u4PairwiseKeyCipherSuiteCount,
+				    (UINT_32) prBssRsnInfo->au4PairwiseKeyCipherSuite[0]);
+		/* Select pairwise/group ciphers */
+		switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) {
+		case ENUM_ENCRYPTION3_ENABLED:
+			for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
+				if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
+				    == CIPHER_SUITE_CCMP) {
+					u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
+				}
+			}
+			u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
+			break;
+
+		case ENUM_ENCRYPTION2_ENABLED:
+			for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
+				if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
+				    == CIPHER_SUITE_TKIP) {
+					u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
+				}
+			}
+			if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_CCMP)
+				DBGLOG(RSN, TRACE, "Cannot join CCMP BSS\n");
+			else
+				u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
+			break;
+
+		case ENUM_ENCRYPTION1_ENABLED:
+			for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
+				if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
+				    == CIPHER_SUITE_WEP40 ||
+				    GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
+				    == CIPHER_SUITE_WEP104) {
+					u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
+				}
+			}
+			if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
+			    CIPHER_SUITE_CCMP ||
+			    GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) {
+				DBGLOG(RSN, TRACE, "Cannot join CCMP/TKIP BSS\n");
+			} else {
+				u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/* Exception handler */
+	/* If we cannot find proper pairwise and group cipher suites to join the
+	   BSS, do not check the supported AKM suites. */
+	if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
+		DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n",
+				    u4PairwiseCipher, u4GroupCipher);
+		return FALSE;
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	if ((prAdapter->fgIsP2PRegistered) && (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) {
+		if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
+		    u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) {
+			DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher for P2P network (0x%08x/0x%08x)\n",
+					    u4PairwiseCipher, u4GroupCipher);
+			return FALSE;
+		}
+	}
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) {
+		if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
+			u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) {
+			/* Do nothing */
+		}
+		DBGLOG(RSN, TRACE,
+		       "Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08x/0x%08x)\n",
+			u4PairwiseCipher, u4GroupCipher);
+		return FALSE;
+	}
+#endif
+
+	/* Verify if selected pairwisse cipher is supported */
+	fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i);
+
+	/* Verify if selected group cipher is supported */
+	if (fgSuiteSupported)
+		fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i);
+
+	if (!fgSuiteSupported) {
+		DBGLOG(RSN, TRACE, "Failed to support selected pairwise/group cipher (0x%08x/0x%08x)\n",
+				    u4PairwiseCipher, u4GroupCipher);
+		return FALSE;
+	}
+
+	/* Select AKM */
+	/* If the driver cannot support any authentication suites advertised in
+	   the given BSS, we fail to perform RSNA policy selection. */
+	/* Attempt to find any overlapping supported AKM suite. */
+#if CFG_SUPPORT_802_11W
+	if (i != 0)
+		for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--) {
+#else
+	for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) {
+#endif
+		if (rsnSearchAKMSuite(prAdapter, prBssRsnInfo->au4AuthKeyMgtSuite[i], &j)) {
+			u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i];
+			break;
+		}
+	}
+
+	if (u4AkmSuite == 0) {
+		DBGLOG(RSN, TRACE, "Cannot support any AKM suites\n");
+		return FALSE;
+	}
+
+	DBGLOG(RSN, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
+			    (UINT_8) (u4PairwiseCipher & 0x000000FF),
+			    (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
+			    (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
+			    (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
+			    (UINT_8) (u4GroupCipher & 0x000000FF),
+			    (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
+			    (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
+			    (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF));
+
+	DBGLOG(RSN, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n",
+			    (UINT_8) (u4AkmSuite & 0x000000FF),
+			    (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
+			    (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF));
+
+#if CFG_SUPPORT_802_11W
+	DBGLOG(RSN, TRACE, "MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo));
+
+	if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
+		if (!prBssRsnInfo->fgRsnCapPresent) {
+			DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability.\n");
+			return FALSE;
+		} else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) {
+			DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required\n");
+			return FALSE;
+		}
+		prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
+	} else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
+		if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) ||
+					       (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) {
+			prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
+		} else {
+			prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
+		}
+	} else {
+		if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) {
+			DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability\n");
+			return FALSE;
+		}
+		prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
+	}
+	DBGLOG(RSN, TRACE, "fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection);
+#endif
+
+	if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) {
+		prBss->ucEncLevel = 3;
+	} else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) {
+		prBss->ucEncLevel = 2;
+	} else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 ||
+		   GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) {
+		prBss->ucEncLevel = 1;
+	} else {
+		ASSERT(FALSE);
+	}
+	prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher;
+	prBss->u4RsnSelectedGroupCipher = u4GroupCipher;
+	prBss->u4RsnSelectedAKMSuite = u4AkmSuite;
+
+	return TRUE;
+
+}				/* rsnPerformPolicySelection */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to generate WPA IE for beacon frame.
+*
+* \param[in] pucIeStartAddr Pointer to put the generated WPA IE.
+*
+* \return The append WPA-None IE length
+* \note
+*      Called by: JOIN module, compose beacon IE
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	UINT_32 i;
+	P_WPA_INFO_ELEM_T prWpaIE;
+	UINT_32 u4Suite;
+	UINT_16 u2SuiteCount;
+	PUINT_8 cp, cp2;
+	UINT_8 ucExpendedLen = 0;
+	PUINT_8 pucBuffer;
+	ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
+
+	DEBUGFUNC("rsnGenerateWpaNoneIE");
+
+	ASSERT(prMsduInfo);
+
+	if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE)
+		return;
+
+	eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType;
+
+	if (eNetworkId != NETWORK_TYPE_AIS_INDEX)
+		return;
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+	ASSERT(pucBuffer);
+
+	prWpaIE = (P_WPA_INFO_ELEM_T) (pucBuffer);
+
+	/* Start to construct a WPA IE. */
+	/* Fill the Element ID field. */
+	prWpaIE->ucElemId = ELEM_ID_WPA;
+
+	/* Fill the OUI and OUI Type fields. */
+	prWpaIE->aucOui[0] = 0x00;
+	prWpaIE->aucOui[1] = 0x50;
+	prWpaIE->aucOui[2] = 0xF2;
+	prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA;
+
+	/* Fill the Version field. */
+	WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1);	/* version 1 */
+	ucExpendedLen = 6;
+
+	/* Fill the Pairwise Key Cipher Suite List field. */
+	u2SuiteCount = 0;
+	cp = (PUINT_8) &prWpaIE->aucPairwiseKeyCipherSuite1[0];
+
+	if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i))
+		u4Suite = WPA_CIPHER_SUITE_CCMP;
+	else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i))
+		u4Suite = WPA_CIPHER_SUITE_TKIP;
+	else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i))
+		u4Suite = WPA_CIPHER_SUITE_WEP104;
+	else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i))
+		u4Suite = WPA_CIPHER_SUITE_WEP40;
+	else
+		u4Suite = WPA_CIPHER_SUITE_TKIP;
+
+	WLAN_SET_FIELD_32(cp, u4Suite);
+	u2SuiteCount++;
+	ucExpendedLen += 4;
+	cp += 4;
+
+	/* Fill the Group Key Cipher Suite field as the same in pair-wise key. */
+	WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite);
+	ucExpendedLen += 4;
+
+	/* Fill the Pairwise Key Cipher Suite Count field. */
+	WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount);
+	ucExpendedLen += 2;
+
+	cp2 = cp;
+
+	/* Fill the Authentication and Key Management Suite List field. */
+	u2SuiteCount = 0;
+	cp += 2;
+
+	if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i))
+		u4Suite = WPA_AKM_SUITE_802_1X;
+	else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i))
+		u4Suite = WPA_AKM_SUITE_PSK;
+	else
+		u4Suite = WPA_AKM_SUITE_NONE;
+
+	/* This shall be the only available value for current implementation */
+	ASSERT(u4Suite == WPA_AKM_SUITE_NONE);
+
+	WLAN_SET_FIELD_32(cp, u4Suite);
+	u2SuiteCount++;
+	ucExpendedLen += 4;
+	cp += 4;
+
+	/* Fill the Authentication and Key Management Suite Count field. */
+	WLAN_SET_FIELD_16(cp2, u2SuiteCount);
+	ucExpendedLen += 2;
+
+	/* Fill the Length field. */
+	prWpaIE->ucLength = (UINT_8) ucExpendedLen;
+
+	/* Increment the total IE length for the Element ID and Length fields. */
+	prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+
+}				/* rsnGenerateWpaNoneIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to generate WPA IE for
+*        associate request frame.
+*
+* \param[in]  prCurrentBss     The Selected BSS description
+*
+* \retval The append WPA IE length
+*
+* \note
+*      Called by: AIS module, Associate request
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	PUCHAR cp;
+	PUINT_8 pucBuffer;
+	ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;
+
+	DEBUGFUNC("rsnGenerateWPAIE");
+
+	ASSERT(prMsduInfo);
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+	ASSERT(pucBuffer);
+
+	eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType;
+	prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+	/* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */
+	/* return; */
+
+#if CFG_ENABLE_WIFI_DIRECT
+	if ((1 /* prCurrentBss->fgIEWPA */  &&
+		((prAdapter->fgIsP2PRegistered) &&
+		(eNetworkId == NETWORK_TYPE_P2P_INDEX) &&
+		(kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) ||
+		((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) ||
+		(prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) {
+#else
+	if ((1 /* prCurrentBss->fgIEWPA */ &&
+		((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) ||
+		(prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) {
+#endif
+		if (prP2pSpecificBssInfo->u2WpaIeLen != 0) {
+			kalMemCopy(pucBuffer, prP2pSpecificBssInfo->aucWpaIeBuffer, prP2pSpecificBssInfo->u2WpaIeLen);
+			prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen;
+			return;
+		}
+
+		/* Construct a WPA IE for association request frame. */
+		WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA;
+		WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
+		WPA_IE(pucBuffer)->aucOui[0] = 0x00;
+		WPA_IE(pucBuffer)->aucOui[1] = 0x50;
+		WPA_IE(pucBuffer)->aucOui[2] = 0xF2;
+		WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA;
+		WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1);
+
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) {
+			WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP);
+		} else
+#endif
+			WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite,
+					  prAdapter->rWifiVar.
+					  arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher);
+
+		cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
+
+		WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) {
+			WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP);
+		} else
+#endif
+			WLAN_SET_FIELD_32(cp,
+					  prAdapter->rWifiVar.
+					  arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher);
+		cp += 4;
+
+		WLAN_SET_FIELD_16(cp, 1);
+		cp += 2;
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) {
+			WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK);
+		} else
+#endif
+			WLAN_SET_FIELD_32(cp,
+					  prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite);
+		cp += 4;
+
+		WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
+
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+	}
+
+}				/* rsnGenerateWPAIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to generate RSN IE for
+*        associate request frame.
+*
+* \param[in]  prMsduInfo     The Selected BSS description
+*
+* \retval The append RSN IE length
+*
+* \note
+*      Called by: AIS module, P2P module, BOW module Associate request
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	UINT_32 u4Entry;
+	PUCHAR cp;
+	/* UINT_8                ucExpendedLen = 0; */
+	PUINT_8 pucBuffer;
+	ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("rsnGenerateRSNIE");
+
+	ASSERT(prMsduInfo);
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+	ASSERT(pucBuffer);
+
+	/* Todo:: network id */
+	eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType;
+
+	if (
+#if CFG_ENABLE_WIFI_DIRECT
+		   ((prAdapter->fgIsP2PRegistered) &&
+		    (eNetworkId == NETWORK_TYPE_P2P_INDEX) && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) ||
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+		   (eNetworkId == NETWORK_TYPE_BOW_INDEX) ||
+#endif
+		   (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */  &&
+		    ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) ||
+		     (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK)))) {
+		/* Construct a RSN IE for association request frame. */
+		RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN;
+		RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED;
+		WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1);	/* Version */
+		WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite,
+			prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher);	/* Group key suite */
+		cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
+		WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
+		WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher);
+		cp += 4;
+		WLAN_SET_FIELD_16(cp, 1);	/* AKM suite count */
+		cp += 2;
+		WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite);	/* AKM suite */
+		cp += 4;
+		WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo);/* Capabilities */
+#if CFG_SUPPORT_802_11W
+		if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) {
+			if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED)
+				WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR);	/* Capabilities */
+			else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL)
+				WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC);	/* Capabilities */
+		}
+#endif
+		cp += 2;
+
+		if (eNetworkId == NETWORK_TYPE_AIS_INDEX) {
+			prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+			if (!prStaRec) {
+				DBGLOG(RSN, TRACE, "rsnGenerateRSNIE: prStaRec is NULL\n");
+				return;
+			}
+		}
+
+		if (eNetworkId == NETWORK_TYPE_AIS_INDEX &&
+		    rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) {
+			/* DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); */
+			/* DBGLOG(RSN, TRACE, ("addr %pM PMKID %pM\n", */
+			/* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID),*/
+		/* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID))); */
+			if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) {
+				RSN_IE(pucBuffer)->ucLength = 38;
+				WLAN_SET_FIELD_16(cp, 1);	/* PMKID count */
+				cp += 2;
+				DBGLOG(RSN, TRACE,
+				       "BSSID %pM ind=%d\n", prStaRec->aucMacAddr, (UINT_32) u4Entry);
+				DBGLOG(RSN, TRACE, "use PMKID %pM\n",
+					(prAdapter->rWifiVar.rAisSpecificBssInfo.
+						arPmkidCache[u4Entry].rBssidInfo.arPMKID));
+				kalMemCopy(cp,
+					   (PVOID) prAdapter->rWifiVar.rAisSpecificBssInfo.
+					   arPmkidCache[u4Entry].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE));
+				/* ucExpendedLen = 40; */
+			} else {
+				WLAN_SET_FIELD_16(cp, 0);	/* PMKID count */
+				/* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */
+#if CFG_SUPPORT_802_11W
+				cp += 2;
+				RSN_IE(pucBuffer)->ucLength += 2;
+#endif
+			}
+		} else {
+			WLAN_SET_FIELD_16(cp, 0);	/* PMKID count */
+			/* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */
+#if CFG_SUPPORT_802_11W
+			cp += 2;
+			RSN_IE(pucBuffer)->ucLength += 2;
+#endif
+		}
+
+#if CFG_SUPPORT_802_11W
+		if ((eNetworkId == NETWORK_TYPE_AIS_INDEX)
+		    && (kalGetMfpSetting(prAdapter->prGlueInfo) !=
+			RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */) {
+			WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC);
+			cp += 4;
+			RSN_IE(pucBuffer)->ucLength += 4;
+		}
+#endif
+		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
+	}
+
+}				/* rsnGenerateRSNIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Parse the given IE buffer and check if it is WFA IE and return Type and
+*        SubType for further process.
+*
+* \param[in] pucBuf             Pointer to the buffer of WFA Information Element.
+* \param[out] pucOuiType        Pointer to the storage of OUI Type.
+* \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version.
+
+* \retval TRUE  Parse IE ok
+* \retval FALSE Parse IE fail
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter,
+			    IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion)
+{
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+	P_IE_WFA_T prWfaIE;
+
+	ASSERT(pucBuf);
+	ASSERT(pucOuiType);
+	ASSERT(pu2SubTypeVersion);
+	prWfaIE = (P_IE_WFA_T) pucBuf;
+
+	do {
+		if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) {
+			break;
+		} else if (prWfaIE->aucOui[0] != aucWfaOui[0] ||
+			   prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) {
+			break;
+		}
+
+		*pucOuiType = prWfaIE->ucOuiType;
+		WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion);
+
+		return TRUE;
+	} while (FALSE);
+
+	return FALSE;
+
+}				/* end of rsnParseCheckForWFAInfoElem() */
+
+#if CFG_SUPPORT_AAA
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK
+*
+* \param[in] prAdapter             Pointer to Adapter
+* \param[in] prSwRfb               Pointer to the rx buffer
+* \param[in] pIE                      Pointer rthe buffer of Information Element.
+* \param[out] prStatusCode     Pointer to the return status code.
+
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode)
+{
+
+	RSN_INFO_T rRsnIe;
+
+	ASSERT(prAdapter);
+	ASSERT(prIe);
+	ASSERT(pu2StatusCode);
+
+	*pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
+
+	if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) {
+		if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1)
+		    || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) {
+			*pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER;
+			return;
+		}
+		if (rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP) {
+			*pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER;
+			return;
+		}
+		if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) {
+			*pu2StatusCode = STATUS_CODE_INVALID_AKMP;
+			return;
+		}
+
+		DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n");
+		*pu2StatusCode = WLAN_STATUS_SUCCESS;
+	}
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to generate an authentication event to NDIS.
+*
+* \param[in] u4Flags Authentication event: \n
+*                     PARAM_AUTH_REQUEST_REAUTH 0x01 \n
+*                     PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n
+*                     PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n
+*                     PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnGenMicErrorEvent(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgFlags)
+{
+	P_PARAM_AUTH_EVENT_T prAuthEvent;
+
+	DEBUGFUNC("rsnGenMicErrorEvent");
+
+	prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer;
+
+	/* Status type: Authentication Event */
+	prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION;
+
+	/* Authentication request */
+	prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T);
+	kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid,
+		   (PVOID) prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN);
+
+	if (fgFlags == TRUE)
+		prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR;
+	else
+		prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR;
+
+	kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+				     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+				     (PVOID) prAuthEvent,
+				     sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T));
+
+}				/* rsnGenMicErrorEvent */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to handle TKIP MIC failures.
+*
+* \param[in] adapter_p Pointer to the adapter object data area.
+* \param[in] prSta Pointer to the STA which occur MIC Error
+* \param[in] fgErrorKeyType type of error key
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType)
+{
+	/* UINT_32               u4RsnaCurrentMICFailTime; */
+	/* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */
+
+	DEBUGFUNC("rsnTkipHandleMICFailure");
+
+	ASSERT(prAdapter);
+#if 1
+	rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType);
+
+	nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, Param_PowerModeCAM, FALSE);
+
+	/* Generate authentication request event. */
+	DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType);
+#else
+	ASSERT(prSta);
+
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	/* Record the MIC error occur time. */
+	GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime);
+
+	/* Generate authentication request event. */
+	DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType);
+
+	/* If less than 60 seconds have passed since a previous TKIP MIC failure,
+	   disassociate from the AP and wait for 60 seconds before (re)associating
+	   with the same AP. */
+	if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 &&
+	    !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime,
+			       prAisSpecBssInfo->u4RsnaLastMICFailTime, SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) {
+		/* If less than 60 seconds expired since last MIC error, we have to
+		   block traffic. */
+
+		DBGLOG(RSN, INFO, "Start blocking traffic!\n");
+		rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType);
+
+		secFsmEventStartCounterMeasure(prAdapter, prSta);
+	} else {
+		rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType);
+		DBGLOG(RSN, INFO, "First TKIP MIC error!\n");
+	}
+
+	COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime);
+#endif
+}				/* rsnTkipHandleMICFailure */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to select a list of BSSID from
+*        the scan results for PMKID candidate list.
+*
+* \param[in] prBssDesc the BSS Desc at scan result list
+* \param[out] pu4CandidateCount Pointer to the number of selected candidates.
+*                         It is set to zero if no BSSID matches our requirement.
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_AIS_BSS_INFO_T prAisBssInfo;
+
+	DEBUGFUNC("rsnSelectPmkidCandidateList");
+
+	ASSERT(prBssDesc);
+
+	prConnSettings = &prAdapter->rWifiVar.rConnSettings;
+	prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+
+	/* Search a BSS with the same SSID from the given BSS description set. */
+	/* DBGLOG(RSN, TRACE, ("Check scan result [%pM]\n", */
+	/* prBssDesc->aucBSSID)); */
+
+	if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
+			prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
+		DBGLOG(RSN, TRACE, "-- SSID not matched\n");
+		return;
+	}
+#if 0
+	if ((prBssDesc->u2BSSBasicRateSet &
+	     ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) || prBssDesc->fgIsUnknownBssBasicRate) {
+		DBGLOG(RSN, TRACE, "-- Rate set not matched\n");
+		return;
+	}
+
+	if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher || */
+		   prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher	/*||
+		   prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) {
+		DBGLOG(RSN, TRACE, "-- Encrypt status not matched for PMKID\n");
+		return;
+	}
+#endif
+
+	rsnUpdatePmkidCandidateList(prAdapter, prBssDesc);
+
+}				/* rsnSelectPmkidCandidateList */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to select a list of BSSID from
+*        the scan results for PMKID candidate list.
+*
+* \param[in] prBssDesc the BSS DESC at scan result list
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
+{
+	UINT_32 i;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+	DEBUGFUNC("rsnUpdatePmkidCandidateList");
+
+	ASSERT(prBssDesc);
+
+	prConnSettings = &prAdapter->rWifiVar.rConnSettings;
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
+		prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
+		DBGLOG(RSN, TRACE, "-- SSID not matched\n");
+		return;
+	}
+
+	for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) {
+		if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))
+			return;
+	}
+
+	/* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16),
+	   then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */
+	if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1) > CFG_MAX_PMKID_CACHE)
+		prAisSpecBssInfo->u4PmkidCandicateCount--;
+
+	i = prAisSpecBssInfo->u4PmkidCandicateCount;
+
+	COPY_MAC_ADDR((PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, (PVOID) prBssDesc->aucBSSID);
+
+	if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) {
+		prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1;
+		DBGLOG(RSN, TRACE, "Add %pM with pre-auth to candidate list\n",
+				    (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid));
+	} else {
+		prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0;
+		DBGLOG(RSN, TRACE, "Add %pM without pre-auth to candidate list\n",
+				    (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid));
+	}
+
+	prAisSpecBssInfo->u4PmkidCandicateCount++;
+
+}				/* rsnUpdatePmkidCandidateList */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to search the desired entry in
+*        PMKID cache according to the BSSID
+*
+* \param[in] pucBssid Pointer to the BSSID
+* \param[out] pu4EntryIndex Pointer to place the found entry index
+*
+* \retval TRUE, if found one entry for specified BSSID
+* \retval FALSE, if not found
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex)
+{
+	UINT_32 i;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+	DEBUGFUNC("rsnSearchPmkidEntry");
+
+	ASSERT(pucBssid);
+	ASSERT(pu4EntryIndex);
+
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE)
+		return FALSE;
+
+	ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE);
+
+	/* Search for desired BSSID */
+	for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) {
+		if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid, MAC_ADDR_LEN))
+			break;
+	}
+
+	/* If desired BSSID is found, then set the PMKID */
+	if (i < prAisSpecBssInfo->u4PmkidCacheCount) {
+		*pu4EntryIndex = i;
+
+		return TRUE;
+	}
+
+	return FALSE;
+}				/* rsnSearchPmkidEntry */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to check if there is difference
+*        between PMKID candicate list and PMKID cache. If there
+*        is new candicate that no cache entry is available, then
+*        add a new entry for the new candicate in the PMKID cache
+*        and set the PMKID indication flag to TRUE.
+*
+* \retval TRUE, if new member in the PMKID candicate list
+* \retval FALSe, if no new member in the PMKID candicate list
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+	UINT_32 i;		/* Index for PMKID candicate */
+	UINT_32 j;		/* Indix for PMKID cache */
+	BOOLEAN status = FALSE;
+
+	DEBUGFUNC("rsnCheckPmkidCandicate");
+
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	/* Check for each candicate */
+	for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) {
+		for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) {
+			if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
+				       prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN)) {
+				/* DBGLOG(RSN, TRACE, ("%pM at PMKID cache!!\n",
+				   (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); */
+				break;
+			}
+		}
+
+		/* No entry found in PMKID cache for the candicate, add new one */
+		if (j == prAisSpecBssInfo->u4PmkidCacheCount
+		    && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) {
+			DBGLOG(RSN, TRACE,
+			       "Add %pM to PMKID cache!!\n",
+				(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid));
+			kalMemCopy((PVOID) prAisSpecBssInfo->
+				   arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID,
+				   (PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN);
+			prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE;
+			prAisSpecBssInfo->u4PmkidCacheCount++;
+
+			status = TRUE;
+		}
+	}
+
+	return status;
+}				/* rsnCheckPmkidCandicate */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to wait a duration to indicate the pre-auth AP candicate
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm)
+{
+	DBGLOG(RSN, EVENT, "Security - Time to indicate the PMKID cand.\n");
+
+	/* If the authentication mode is WPA2 and indication PMKID flag
+	   is available, then we indicate the PMKID candidate list to NDIS and
+	   clear the flag, indicatePMKID */
+
+	if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
+	    prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
+		rsnGeneratePmkidIndication(prAdapter);
+	}
+
+}				/* end of rsnIndicatePmkidCand() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to check the BSS Desc at scan result
+*             with pre-auth cap at wpa2 mode. If there
+*             is candicate that no cache entry is available, then
+*             add a new entry for the new candicate in the PMKID cache
+*             and set the PMKID indication flag to TRUE.
+*
+* \param[in] prBss The BSS Desc at scan result
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss)
+{
+	P_AIS_BSS_INFO_T prAisBssInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	DEBUGFUNC("rsnCheckPmkidCandicate");
+
+	ASSERT(prBss);
+
+	prConnSettings = &prAdapter->rWifiVar.rConnSettings;
+	prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+	prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) &&
+	    (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) {
+		rsnSelectPmkidCandidateList(prAdapter, prBss);
+
+		/* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection()
+		   will indicate this later */
+		if (rsnCheckPmkidCandicate(prAdapter)) {
+			DBGLOG(RSN, TRACE, "Prepare a timer to indicate candidate PMKID Candidate\n");
+			cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer);
+			cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer,
+					   SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to generate an PMKID candidate list
+*        indication to NDIS.
+*
+* \param[in] prAdapter Pointer to the adapter object data area.
+* \param[in] u4Flags PMKID candidate list event:
+*                    PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter)
+{
+	P_PARAM_STATUS_INDICATION_T prStatusEvent;
+	P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
+	UINT_8 i, j = 0, count = 0;
+	UINT_32 u4LenOfUsedBuffer;
+
+	DEBUGFUNC("rsnGeneratePmkidIndication");
+
+	ASSERT(prAdapter);
+
+	prStatusEvent = (P_PARAM_STATUS_INDICATION_T) prAdapter->aucIndicationEventBuffer;
+
+	/* Status type: PMKID Candidatelist Event */
+	prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST;
+	ASSERT(prStatusEvent);
+
+	prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T) (&prStatusEvent->eStatusType + 1);
+	ASSERT(prPmkidEvent);
+
+	prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+	ASSERT(prAisSpecificBssInfo);
+
+	for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) {
+		for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) {
+			if (EQUAL_MAC_ADDR(prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
+					   prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) &&
+			    (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)) {
+				break;
+			}
+		}
+		if (count >= CFG_MAX_PMKID_CACHE)
+			break;
+
+		if (j == prAisSpecificBssInfo->u4PmkidCacheCount) {
+			kalMemCopy((PVOID) prPmkidEvent->arCandidateList[count].arBSSID,
+				   (PVOID) prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid, PARAM_MAC_ADDR_LEN);
+			prPmkidEvent->arCandidateList[count].u4Flags =
+			    prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags;
+			DBGLOG(RSN, TRACE, "%pM %d\n", (prPmkidEvent->arCandidateList[count].arBSSID),
+					    (UINT_32) prPmkidEvent->arCandidateList[count].u4Flags);
+			count++;
+		}
+	}
+
+	/* PMKID Candidate List */
+	prPmkidEvent->u4Version = 1;
+	prPmkidEvent->u4NumCandidates = count;
+	DBGLOG(RSN, TRACE, "rsnGeneratePmkidIndication #%d\n", (UINT_32) prPmkidEvent->u4NumCandidates);
+	u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) +
+	    (count * sizeof(PARAM_PMKID_CANDIDATE_T));
+	/* dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); */
+
+	kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+				     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+				     (PVOID) prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer);
+
+}				/* rsnGeneratePmkidIndication */
+#endif
+
+#if CFG_SUPPORT_WPS2
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to generate WSC IE for
+*        associate request frame.
+*
+* \param[in]  prCurrentBss     The Selected BSS description
+*
+* \retval The append WSC IE length
+*
+* \note
+*      Called by: AIS module, Associate request
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	PUINT_8 pucBuffer;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
+		return;
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength);
+
+	/* ASSOC INFO IE ID: 221 :0xDD */
+	if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) {
+		kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE,
+			   prAdapter->prGlueInfo->u2WSCAssocInfoIELen);
+		prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen;
+	}
+
+}
+#endif
+
+#if CFG_SUPPORT_802_11W
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to check if the Bip Key installed or not
+*
+* \param[in]
+*           prAdapter
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX)
+		return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled;
+	else
+		return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to check the Sa query timeout.
+*
+*
+* \note
+*      Called by: AIS module, Handle by Sa Quert timeout
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
+	UINT_32 now;
+
+	prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+	ASSERT(prBssSpecInfo);
+
+	GET_CURRENT_SYSTIME(&now);
+
+	if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, TU_TO_MSEC(1000))) {
+		LOG_FUNC("association SA Query timed out\n");
+
+		prBssSpecInfo->ucSaQueryTimedOut = 1;
+		kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE,
+			   prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
+		prBssSpecInfo->pucSaQueryTransId = NULL;
+		prBssSpecInfo->u4SaQueryCount = 0;
+		cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
+		/* Re-connect */
+		DBGLOG(RSN, TRACE, "DisBy11w\n");
+		kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to start the 802.11w sa query timer.
+*
+*
+* \note
+*      Called by: AIS module, Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
+	P_MSDU_INFO_T prMsduInfo;
+	P_ACTION_SA_QUERY_FRAME prTxFrame;
+	UINT_16 u2PayloadLen;
+	PUINT_8 pucTmp = NULL;
+	UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN];
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+	ASSERT(prBssInfo);
+
+	prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+	ASSERT(prBssSpecInfo);
+
+	LOG_FUNC("MFP: Start Sa Query\n");
+
+	if (prBssSpecInfo->u4SaQueryCount > 0 && rsnCheckSaQueryTimeout(prAdapter)) {
+		LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount);
+		return;
+	}
+
+	prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
+
+	if (!prMsduInfo)
+		return;
+
+	prTxFrame = (P_ACTION_SA_QUERY_FRAME)
+	    ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+	prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
+	prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+
+	COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
+	COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
+	COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
+
+	prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
+	prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST;
+
+	if (prBssSpecInfo->u4SaQueryCount == 0)
+		GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart);
+
+	if (prBssSpecInfo->u4SaQueryCount) {
+		pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
+		if (!pucTmp) {
+			DBGLOG(RSN, ERROR, "MFP: Fail to alloc tmp buffer for backup sa query id\n");
+			return;
+		}
+		kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId,
+			   prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
+	}
+
+	kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE,
+		   prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
+
+	ucTransId[0] = (UINT_8) (kalRandomNumber() & 0xFF);
+	ucTransId[1] = (UINT_8) (kalRandomNumber() & 0xFF);
+
+	kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+
+	prBssSpecInfo->u4SaQueryCount++;
+
+	prBssSpecInfo->pucSaQueryTransId =
+	    kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
+	if (!prBssSpecInfo->pucSaQueryTransId) {
+		DBGLOG(RSN, ERROR, "MFP: Fail to alloc buffer for sa query id list\n");
+		return;
+	}
+
+	if (pucTmp) {
+		kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp,
+			   (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
+		kalMemCopy(&prBssSpecInfo->pucSaQueryTransId
+			   [(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN], ucTransId,
+			   ACTION_SA_QUERY_TR_ID_LEN);
+		kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
+	} else {
+		kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+	}
+
+	u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
+
+	/* 4 Update information of MSDU_INFO_T */
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;	/* Management frame */
+	prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
+	prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = NULL;
+	prMsduInfo->fgIsBasicRate = FALSE;
+
+	/* 4 Enqueue the frame to send this action frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	DBGLOG(RSN, TRACE,
+	       "Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval);
+
+	cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, TU_TO_MSEC(201));
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to start the 802.11w sa query.
+*
+*
+* \note
+*      Called by: AIS module, Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter)
+{
+	rsnStartSaQueryTimer(prAdapter);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to stop the 802.11w sa query.
+*
+*
+* \note
+*      Called by: AIS module, Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter)
+{
+	P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
+
+	prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+	ASSERT(prBssSpecInfo);
+
+	cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
+	kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE,
+		   prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
+	prBssSpecInfo->pucSaQueryTransId = NULL;
+	prBssSpecInfo->u4SaQueryCount = 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to process the 802.11w sa query action frame.
+*
+*
+* \note
+*      Called by: AIS module, Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_MSDU_INFO_T prMsduInfo;
+	P_ACTION_SA_QUERY_FRAME prRxFrame = NULL;
+	UINT_16 u2PayloadLen;
+	P_STA_RECORD_T prStaRec;
+	P_ACTION_SA_QUERY_FRAME prTxFrame;
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
+	ASSERT(prBssInfo);
+
+	prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
+	if (!prRxFrame)
+		return;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+	DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Request from %pM\n", prStaRec->aucMacAddr);
+
+	DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) {
+		DBGLOG(RSN, TRACE, "IEEE 802.11: Ignore SA Query Request from unassociated STA %pM\n",
+				    prStaRec->aucMacAddr);
+		return;
+	}
+	DBGLOG(RSN, TRACE, "IEEE 802.11: Sending SA Query Response to %pM\n", prStaRec->aucMacAddr);
+
+	prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
+
+	if (!prMsduInfo)
+		return;
+
+	prTxFrame = (P_ACTION_SA_QUERY_FRAME)
+	    ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+	prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
+	/* SA Query always with protected */
+	prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+
+	COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
+	COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
+	COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
+
+	prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
+	prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE;
+
+	kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+
+	u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
+
+	/* 4 Update information of MSDU_INFO_T */
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;	/* Management frame */
+	prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
+	prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = NULL;
+	prMsduInfo->fgIsBasicRate = FALSE;
+
+	/* 4 Enqueue the frame to send this action frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to process the 802.11w sa query action frame.
+*
+*
+* \note
+*      Called by: AIS module, Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
+	P_ACTION_SA_QUERY_FRAME prRxFrame;
+	P_STA_RECORD_T prStaRec;
+	UINT_32 i;
+
+	prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+	ASSERT(prBssSpecInfo);
+
+	prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+	if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) {
+		DBGLOG(RSN, TRACE, "IEEE 802.11: Too short SA Query Action frame (len=%u)\n",
+				    prSwRfb->u2PacketLen);
+		return;
+	}
+
+	if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) {
+		rsnSaQueryRequest(prAdapter, prSwRfb);
+		return;
+	}
+
+	if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) {
+		DBGLOG(RSN, TRACE, "IEEE 802.11: Unexpected SA Query " "Action %d\n", prRxFrame->ucAction);
+		return;
+	}
+
+	DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Response from %pM\n", prStaRec->aucMacAddr);
+
+	DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+
+	/* MLME-SAQuery.confirm */
+
+	for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) {
+		if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId +
+			      i * ACTION_SA_QUERY_TR_ID_LEN, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0)
+			break;
+	}
+
+	if (i >= prBssSpecInfo->u4SaQueryCount) {
+		DBGLOG(RSN, TRACE, "IEEE 802.11: No matching SA Query " "transaction identifier found\n");
+		return;
+	}
+
+	DBGLOG(RSN, TRACE, "Reply to pending SA Query received\n");
+
+	rsnStopSaQuery(prAdapter);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to process the 802.11w mgmt frame.
+*
+*
+* \note
+*      Called by: AIS module, Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype)
+{
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	BOOLEAN fgUnicast = TRUE;
+	BOOLEAN fgRobustAction = FALSE;
+
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+
+	if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) &&
+	    prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) {
+
+		P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
+
+		prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
+
+		if (prAssocReqFrame->aucDestAddr[0] & BIT(0))
+			fgUnicast = FALSE;
+
+		LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved,
+			 (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype);
+
+		if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) {
+			/* "Dropped unprotected Robust Action frame from an MFP STA" */
+			/* exclude Public Action */
+			if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */) {
+				UINT_8 ucAction = *prSwRfb->pucRecvBuff;
+
+				if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) {
+#if DBG && CFG_RX_PKTS_DUMP
+					LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction);
+#endif
+					fgRobustAction = TRUE;
+					return TRUE;
+				}
+			}
+			if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */)
+					  || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) {
+				LOG_FUNC("QM RX MGT: rsnStartSaQuery\n");
+				/* MFP test plan 5.3.3.5 */
+				rsnStartSaQuery(prAdapter);
+				return TRUE;
+			}
+		}
+#if 0
+		else {
+			if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) {
+				/* This done by function handler */
+				/* kalIndicateStatusAndComplete(prAdapter->prGlueInfo, */
+				/* WLAN_STATUS_MEDIA_DISCONNECT, */
+				/* NULL, */
+				/* 0); */
+			}
+		}
+#endif
+	}
+	return FALSE;
+}
+#endif
+
+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE
+static BOOLEAN rsnCheckWpaRsnInfo(P_BSS_INFO_T prBss, P_RSN_INFO_T prWpaRsnInfo)
+{
+	UINT_32 i = 0;
+
+	if (prWpaRsnInfo->u4GroupKeyCipherSuite != prBss->u4RsnSelectedGroupCipher) {
+		DBGLOG(RSN, INFO, "GroupCipherSuite change, old=0x%04x, new=0x%04x\n",
+				   prBss->u4RsnSelectedGroupCipher, prWpaRsnInfo->u4GroupKeyCipherSuite);
+		return TRUE;
+	}
+	for (; i < prWpaRsnInfo->u4AuthKeyMgtSuiteCount; i++)
+		if (prBss->u4RsnSelectedAKMSuite == prWpaRsnInfo->au4AuthKeyMgtSuite[i])
+			break;
+	if (i == prWpaRsnInfo->u4AuthKeyMgtSuiteCount) {
+		DBGLOG(RSN, INFO, "KeyMgmt change, not find 0x%04x in new beacon\n", prBss->u4RsnSelectedAKMSuite);
+		return TRUE;
+	}
+
+	for (i = 0; i < prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount; i++)
+		if (prBss->u4RsnSelectedPairwiseCipher == prWpaRsnInfo->au4PairwiseKeyCipherSuite[i])
+			break;
+	if (i == prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount) {
+		DBGLOG(RSN, INFO, "Pairwise Cipher change, not find 0x%04x in new beacon\n",
+				   prBss->u4RsnSelectedPairwiseCipher);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc)
+{
+	ENUM_PARAM_AUTH_MODE_T eAuthMode = prAdapter->rWifiVar.rConnSettings.eAuthMode;
+
+	switch (eAuthMode) {
+	case AUTH_MODE_OPEN:	/* original is open system */
+		if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) && !prAdapter->prGlueInfo->rWpaInfo.fgPrivacyInvoke) {
+			DBGLOG(RSN, INFO, "security change, open->privacy\n");
+			return TRUE;
+		}
+		break;
+	case AUTH_MODE_SHARED:	/* original is WEP */
+	case AUTH_MODE_AUTO_SWITCH:
+		if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) == 0) {
+			DBGLOG(RSN, INFO, "security change, WEP->open\n");
+			return TRUE;
+		} else if (prBssDesc->fgIERSN || prBssDesc->fgIEWPA) {
+			DBGLOG(RSN, INFO, "security change, WEP->WPA/WPA2\n");
+			return TRUE;
+		}
+		break;
+	case AUTH_MODE_WPA:	/*original is WPA */
+	case AUTH_MODE_WPA_PSK:
+	case AUTH_MODE_WPA_NONE:
+		if (prBssDesc->fgIEWPA)
+			return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rWPAInfo);
+		DBGLOG(RSN, INFO, "security change, WPA->%s\n",
+				   prBssDesc->fgIERSN ? "WPA2" :
+				   (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN"));
+		return TRUE;
+	case AUTH_MODE_WPA2:	/*original is WPA2 */
+	case AUTH_MODE_WPA2_PSK:
+		if (prBssDesc->fgIERSN)
+			return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rRSNInfo);
+		DBGLOG(RSN, INFO, "security change, WPA2->%s\n",
+				   prBssDesc->fgIEWPA ? "WPA" :
+				   (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN"));
+		return TRUE;
+	default:
+		DBGLOG(RSN, WARN, "unknowned eAuthMode=%d\n", eAuthMode);
+		break;
+	}
+	/*DBGLOG(RSN, INFO, ("rsnCheckSecurityModeChanged, eAuthMode=%d, u2CapInfo=0x%02x, fgIEWPA=%d, fgIERSN=%d\n",
+	  eAuthMode, prBssDesc->u2CapInfo, prBssDesc->fgIEWPA, prBssDesc->fgIERSN)); */
+	return FALSE;
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c
new file mode 100644
index 0000000000000..596ede60d7887
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c
@@ -0,0 +1,1788 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2
+*/
+
+/*! \file   "saa_fsm.c"
+    \brief  This file defines the FSM for SAA MODULE.
+
+    This file defines the FSM for SAA MODULE.
+*/
+
+/*
+** Log: saa_fsm.c
+**
+** 09 04 2013 cp.wu
+** fix typo
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 04 20 2012 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * correct macro
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 04 2011 cp.wu
+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT
+ * for REASSOCIATED cases as an explicit trigger for Android framework
+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately.
+ * 2. (Android only) when reassociation-and-non-roaming cases happened,
+ * indicate an extra DISCONNECT indication to Android Wi-Fi framework
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 09 30 2011 cm.chang
+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band
+ * Add debug message about 40MHz bandwidth allowed
+ *
+ * 05 12 2011 cp.wu
+ * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC
+ * has been invalidated before SAA-FSM starts to roll
+ * check for valid STA-REC before SAA-FSM starts to roll.
+ *
+ * 04 21 2011 terry.wu
+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
+ * Add network type parameter to authSendAuthFrame.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW short range mode.
+ *
+ * 04 14 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 03 31 2011 puff.wen
+ * NULL
+ * .
+ *
+ * 02 10 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add RX deauthentication & disassociation process under Hot-Spot mode.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Fix compile error of after Station Type Macro modification.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 11 29 2010 cp.wu
+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC
+ * for initial TX rate selection of auto-rate algorithm
+ * update ucRcpi of STA_RECORD_T for AIS when
+ * 1) Beacons for IBSS merge is received
+ * 2) Associate Response for a connecting peer is received
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete
+ * and might leads to BSOD when entering RF test with AIS associated
+ * 1. remove redundant variables in STA_REC structure
+ * 2. add STA-REC uninitialization routine for clearing pending events
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy.
+ * Update saa_fsm for BOW.
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
+ * There is no CFG_SUPPORT_BOW in driver domain source.
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * Add support for P2P join event start.
+ *
+ * 07 12 2010 cp.wu
+ *
+ * SAA will take a record for tracking request sequence number.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * AIS-FSM integration with CNM channel request messages
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * sync. with main branch for resetting to state 1 when associating with another AP
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * refine TX-DONE callback.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * remove duplicate variable for migration.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration the security related function from firmware.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Fix compile error when enable WiFi Direct function.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * saa_fsm.c is migrated.
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ *
+ *  *  * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add support of Driver STA_RECORD_T activation
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 01 12 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Fix compile warning due to declared but not used
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 08 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Refine Debug Label
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Update comment
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * rename the function
+ *
+ * Nov 24 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Revise MGMT Handler with Retain Status
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if DBG
+/*lint -save -e64 Type mismatch */
+static PUINT_8 apucDebugAAState[AA_STATE_NUM] = {
+	(PUINT_8) DISP_STRING("AA_STATE_IDLE"),
+	(PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH1"),
+	(PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH2"),
+	(PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH3"),
+	(PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH4"),
+	(PUINT_8) DISP_STRING("SAA_STATE_SEND_ASSOC1"),
+	(PUINT_8) DISP_STRING("SAA_STATE_WAIT_ASSOC2"),
+	(PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH2"),
+	(PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH4"),
+	(PUINT_8) DISP_STRING("AAA_STATE_SEND_ASSOC2"),
+	(PUINT_8) DISP_STRING("AA_STATE_RESOURCE")
+};
+
+/*lint -restore */
+#endif /* DBG */
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief The Core FSM engine of SAA Module.
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+* @param[in] eNextState         The value of Next State
+* @param[in] prRetainedSwRfb    Pointer to the retained SW_RFB_T for JOIN Success
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+saaFsmSteps(IN P_ADAPTER_T prAdapter,
+	    IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb)
+{
+	ENUM_AA_STATE_T ePreviousState;
+	BOOLEAN fgIsTransition;
+
+	ASSERT(prStaRec);
+	if (!prStaRec) {
+		return;
+	}
+
+	do {
+
+#if DBG
+		DBGLOG(SAA, STATE, "TRANSITION: [%s] -> [%s]\n",
+				    apucDebugAAState[prStaRec->eAuthAssocState], apucDebugAAState[eNextState]);
+#else
+		DBGLOG(SAA, STATE, "[%d] TRANSITION: [%d] -> [%d]\n",
+				    DBG_SAA_IDX, prStaRec->eAuthAssocState, eNextState);
+#endif
+		ePreviousState = prStaRec->eAuthAssocState;
+
+		/* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */
+		prStaRec->eAuthAssocState = eNextState;
+
+		fgIsTransition = (BOOLEAN) FALSE;
+		switch (prStaRec->eAuthAssocState) {
+		case AA_STATE_IDLE:
+			if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */
+
+				if (prRetainedSwRfb) {
+					if (saaFsmSendEventJoinComplete(prAdapter,
+						WLAN_STATUS_SUCCESS,
+						prStaRec,
+						prRetainedSwRfb) == WLAN_STATUS_SUCCESS) {
+						/* Do nothing */
+					} else {
+						eNextState = AA_STATE_RESOURCE;
+						fgIsTransition = TRUE;
+					}
+				} else {
+					if (saaFsmSendEventJoinComplete(prAdapter,
+									WLAN_STATUS_FAILURE,
+									prStaRec,
+									NULL) == WLAN_STATUS_RESOURCES) {
+						eNextState = AA_STATE_RESOURCE;
+						fgIsTransition = TRUE;
+					}
+				}
+
+			}
+
+			/* Free allocated TCM memory */
+			if (prStaRec->prChallengeText) {
+				cnmMemFree(prAdapter, prStaRec->prChallengeText);
+				prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL;
+			}
+			break;
+
+		case SAA_STATE_SEND_AUTH1:
+			{
+				/* Do tasks in INIT STATE */
+				if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) {
+
+					/* Record the Status Code of Authentication Request */
+					prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
+
+					eNextState = AA_STATE_IDLE;
+					fgIsTransition = TRUE;
+				} else {
+					prStaRec->ucTxAuthAssocRetryCount++;
+
+					/* Update Station Record - Class 1 Flag */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+#if !CFG_SUPPORT_AAA
+					if (authSendAuthFrame(prAdapter,
+						prStaRec, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) {
+#else
+					if (authSendAuthFrame(prAdapter,
+						prStaRec,
+						prStaRec->ucNetTypeIndex,
+						NULL,
+						AUTH_TRANSACTION_SEQ_1,
+						STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) {
+#endif /* CFG_SUPPORT_AAA */
+						cnmTimerInitTimer(prAdapter,
+								  &prStaRec->rTxReqDoneOrRxRespTimer,
+								  (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut,
+								  (ULONG) prStaRec);
+
+						cnmTimerStartTimer(prAdapter,
+								   &prStaRec->rTxReqDoneOrRxRespTimer,
+								   TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
+					}
+				}
+			}
+			break;
+
+		case SAA_STATE_WAIT_AUTH2:
+			break;
+
+		case SAA_STATE_SEND_AUTH3:
+			{
+				/* Do tasks in INIT STATE */
+				if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) {
+
+					/* Record the Status Code of Authentication Request */
+					prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
+
+					eNextState = AA_STATE_IDLE;
+					fgIsTransition = TRUE;
+				} else {
+					prStaRec->ucTxAuthAssocRetryCount++;
+
+#if !CFG_SUPPORT_AAA
+					if (authSendAuthFrame(prAdapter,
+						prStaRec, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) {
+#else
+					if (authSendAuthFrame(prAdapter,
+						prStaRec,
+						prStaRec->ucNetTypeIndex,
+						NULL,
+						AUTH_TRANSACTION_SEQ_3,
+						STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) {
+#endif /* CFG_SUPPORT_AAA */
+
+						cnmTimerInitTimer(prAdapter,
+								  &prStaRec->rTxReqDoneOrRxRespTimer,
+								  (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut,
+								  (ULONG) prStaRec);
+
+						cnmTimerStartTimer(prAdapter,
+								   &prStaRec->rTxReqDoneOrRxRespTimer,
+								   TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
+					}
+				}
+			}
+			break;
+
+		case SAA_STATE_WAIT_AUTH4:
+			break;
+
+		case SAA_STATE_SEND_ASSOC1:
+			/* Do tasks in INIT STATE */
+			if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) {
+
+				/* Record the Status Code of Authentication Request */
+				prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
+
+				eNextState = AA_STATE_IDLE;
+				fgIsTransition = TRUE;
+			} else {
+				prStaRec->ucTxAuthAssocRetryCount++;
+
+				if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) {
+
+					cnmTimerInitTimer(prAdapter,
+							  &prStaRec->rTxReqDoneOrRxRespTimer,
+							  (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut,
+							  (ULONG) prStaRec);
+
+					cnmTimerStartTimer(prAdapter,
+							   &prStaRec->rTxReqDoneOrRxRespTimer,
+							   TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU));
+				}
+			}
+
+			break;
+
+		case SAA_STATE_WAIT_ASSOC2:
+			break;
+
+		case AA_STATE_RESOURCE:
+			/* TODO(Kevin) Can setup a timer and send message later */
+			break;
+
+		default:
+			DBGLOG(SAA, ERROR, "Unknown AA STATE\n");
+			ASSERT(0);
+			break;
+		}
+
+	} while (fgIsTransition);
+
+	return;
+
+}				/* end of saaFsmSteps() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send Event to AIS/BOW/P2P
+*
+* @param[in] rJoinStatus        To indicate JOIN success or failure.
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+* @param[in] prSwRfb            Pointer to the SW_RFB_T
+
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter,
+			    IN WLAN_STATUS rJoinStatus, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb)
+{
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prStaRec);
+	if (!prStaRec)
+		return WLAN_STATUS_INVALID_PACKET;
+
+	/* Store limitation about 40Mhz bandwidth capability during association */
+	if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) {
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
+
+		if (rJoinStatus == WLAN_STATUS_SUCCESS)
+			prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed;
+		prBssInfo->fgAssoc40mBwAllowed = FALSE;
+	}
+
+	if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
+		P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
+
+		prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
+		if (!prSaaFsmCompMsg)
+			return WLAN_STATUS_RESOURCES;
+
+		prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE;
+		prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
+		prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
+		prSaaFsmCompMsg->prStaRec = prStaRec;
+		prSaaFsmCompMsg->prSwRfb = prSwRfb;
+
+		/* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF);
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {
+		P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
+
+		prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
+		if (!prSaaFsmCompMsg)
+			return WLAN_STATUS_RESOURCES;
+
+		prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE;
+		prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
+		prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
+		prSaaFsmCompMsg->prStaRec = prStaRec;
+		prSaaFsmCompMsg->prSwRfb = prSwRfb;
+
+		/* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF);
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+	else if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) {
+		/* @TODO: BOW handler */
+
+		P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
+
+		prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
+		if (!prSaaFsmCompMsg)
+			return WLAN_STATUS_RESOURCES;
+
+		prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE;
+		prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
+		prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
+		prSaaFsmCompMsg->prStaRec = prStaRec;
+		prSaaFsmCompMsg->prSwRfb = prSwRfb;
+
+		/* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF);
+
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+	else {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+}				/* end of saaFsmSendEventJoinComplete() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Start Event to SAA FSM.
+*
+* @param[in] prMsgHdr   Message of Join Request for a particular STA.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_SAA_FSM_START_T prSaaFsmStartMsg;
+	P_STA_RECORD_T prStaRec;
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsgHdr);
+
+	prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T) prMsgHdr;
+	prStaRec = prSaaFsmStartMsg->prStaRec;
+
+	if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) {
+		cnmMemFree(prAdapter, prMsgHdr);
+		return;
+	}
+
+	ASSERT(prStaRec);
+
+	DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n");
+
+	/* record sequence number of request message */
+	prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum;
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+	/* 4 <1> Validation of SAA Start Event */
+	if (!IS_AP_STA(prStaRec)) {
+
+		DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType);
+
+		/* Ignore the return value because don't care the prSwRfb */
+		saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL);
+
+		return;
+	}
+	/* 4 <2> The previous JOIN process is not completed ? */
+	if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
+		DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n");
+		prStaRec->eAuthAssocState = AA_STATE_IDLE;
+	}
+	/* 4 <3> Reset Status Code and Time */
+	/* Update Station Record - Status/Reason Code */
+	prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
+
+	/* Update the record join time. */
+	GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime);
+
+	prStaRec->ucTxAuthAssocRetryCount = 0;
+
+	if (prStaRec->prChallengeText) {
+		cnmMemFree(prAdapter, prStaRec->prChallengeText);
+		prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL;
+	}
+
+	cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+#if CFG_PRIVACY_MIGRATION
+	/* 4 <4> Init the sec fsm */
+	secFsmInit(prAdapter, prStaRec);
+#endif
+
+	/* 4 <5> Reset the STA STATE */
+	/* Update Station Record - Class 1 Flag */
+	/* NOTE(Kevin): Moved to AIS FSM for Reconnect issue -
+	 * We won't deactivate the same STA_RECORD_T and then activate it again for the
+	 * case of reconnection.
+	 */
+	/* cnmStaRecChangeState(prStaRec, STA_STATE_1); */
+
+	/* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */
+	if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) {
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
+
+		if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)
+		    && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
+			prBssInfo->fgAssoc40mBwAllowed = cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex);
+		} else {
+			prBssInfo->fgAssoc40mBwAllowed = FALSE;
+		}
+		DBGLOG(RLM, INFO, "STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed);
+	}
+	/* 4 <7> Trigger SAA FSM */
+	if (prStaRec->ucStaState == STA_STATE_1)
+		saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL);
+	else if (prStaRec->ucStaState == STA_STATE_2 || prStaRec->ucStaState == STA_STATE_3)
+		saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, (P_SW_RFB_T) NULL);
+
+}				/* end of saaFsmRunEventStart() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM.
+*
+* @param[in] prMsduInfo     Pointer to the MSDU_INFO_T.
+* @param[in] rTxDoneStatus  Return TX status of the Auth1/Auth3/AssocReq frame.
+*
+* @retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+
+	P_STA_RECORD_T prStaRec;
+	ENUM_AA_STATE_T eNextState;
+
+	ASSERT(prMsduInfo);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if (!prStaRec) {
+		DBGLOG(SAA, INFO, "EVENT-TX DONE: Status %d, Invalid StaRec\n", rTxDoneStatus);
+		return WLAN_STATUS_INVALID_PACKET;
+	}
+
+	ASSERT(prStaRec);
+
+	DBGLOG(SAA, INFO, "EVENT-TX DONE: Status: %d, eAuthAssocState: %d , SeqNO: %d ",
+		rTxDoneStatus, prStaRec->eAuthAssocState,
+		prMsduInfo->ucTxSeqNum);
+
+	eNextState = prStaRec->eAuthAssocState;
+
+	switch (prStaRec->eAuthAssocState) {
+	case SAA_STATE_SEND_AUTH1:
+		{
+			/* Strictly check the outgoing frame is matched with current AA STATE */
+			if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS)
+				break;
+
+			if (rTxDoneStatus == TX_RESULT_SUCCESS) {
+				eNextState = SAA_STATE_WAIT_AUTH2;
+
+				cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+				cnmTimerInitTimer(prAdapter,
+						  &prStaRec->rTxReqDoneOrRxRespTimer,
+						  (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut,
+						  (ULONG) prStaRec);
+
+				cnmTimerStartTimer(prAdapter,
+						   &prStaRec->rTxReqDoneOrRxRespTimer,
+						   TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
+			}
+
+			/* if TX was successful, change to next state.
+			 * if TX was failed, do retry if possible.
+			 */
+			saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
+		}
+		break;
+
+	case SAA_STATE_SEND_AUTH3:
+		{
+			/* Strictly check the outgoing frame is matched with current JOIN STATE */
+			if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS)
+				break;
+
+			if (rTxDoneStatus == TX_RESULT_SUCCESS) {
+				eNextState = SAA_STATE_WAIT_AUTH4;
+
+				cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+				cnmTimerInitTimer(prAdapter,
+						  &prStaRec->rTxReqDoneOrRxRespTimer,
+						  (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut,
+						  (ULONG) prStaRec);
+
+				cnmTimerStartTimer(prAdapter,
+						   &prStaRec->rTxReqDoneOrRxRespTimer,
+						   TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
+			}
+
+			/* if TX was successful, change to next state.
+			 * if TX was failed, do retry if possible.
+			 */
+			saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
+		}
+		break;
+
+	case SAA_STATE_SEND_ASSOC1:
+		{
+			/* Strictly check the outgoing frame is matched with current SAA STATE */
+			if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS)
+				break;
+
+			if (rTxDoneStatus == TX_RESULT_SUCCESS) {
+				eNextState = SAA_STATE_WAIT_ASSOC2;
+
+				cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+				cnmTimerInitTimer(prAdapter,
+						  &prStaRec->rTxReqDoneOrRxRespTimer,
+						  (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut,
+						  (ULONG) prStaRec);
+
+				cnmTimerStartTimer(prAdapter,
+						   &(prStaRec->rTxReqDoneOrRxRespTimer),
+						   TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU));
+			}
+			/* if TX was successful, change to next state.
+			 * if TX was failed, do retry if possible.
+			 */
+			saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
+		}
+		break;
+
+	default:
+		break;		/* Ignore other cases */
+	}
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of saaFsmRunEventTxDone() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send Tx Request Timeout Event to SAA FSM.
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	ASSERT(prStaRec);
+	if (!prStaRec)
+		return;
+
+	DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %u\n", kalGetTimeTick());
+
+	switch (prStaRec->eAuthAssocState) {
+	case SAA_STATE_SEND_AUTH1:
+	case SAA_STATE_SEND_AUTH3:
+	case SAA_STATE_SEND_ASSOC1:
+		saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T) NULL);
+		break;
+
+	default:
+		return;
+	}
+
+}				/* end of saaFsmRunEventTxReqTimeOut() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will send Rx Response Timeout Event to SAA FSM.
+*
+* @param[in] prStaRec           Pointer to the STA_RECORD_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+	ENUM_AA_STATE_T eNextState;
+
+	DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %u\n", kalGetTimeTick());
+
+	ASSERT(prStaRec);
+	if (!prStaRec)
+		return;
+
+	eNextState = prStaRec->eAuthAssocState;
+
+	switch (prStaRec->eAuthAssocState) {
+	case SAA_STATE_WAIT_AUTH2:
+		/* Record the Status Code of Authentication Request */
+		prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
+
+		/* Pull back to earlier state to do retry */
+		eNextState = SAA_STATE_SEND_AUTH1;
+		break;
+
+	case SAA_STATE_WAIT_AUTH4:
+		/* Record the Status Code of Authentication Request */
+		prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
+
+		/* Pull back to earlier state to do retry */
+		eNextState = SAA_STATE_SEND_AUTH3;
+		break;
+
+	case SAA_STATE_WAIT_ASSOC2:
+		/* Record the Status Code of Authentication Request */
+		prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
+
+		/* Pull back to earlier state to do retry */
+		eNextState = SAA_STATE_SEND_ASSOC1;
+		break;
+
+	default:
+		break;		/* Ignore other cases */
+	}
+
+	if (eNextState != prStaRec->eAuthAssocState)
+		saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
+
+}				/* end of saaFsmRunEventRxRespTimeOut() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will process the Rx Auth Response Frame and then
+*        trigger SAA FSM.
+*
+* @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2StatusCode;
+	ENUM_AA_STATE_T eNextState;
+
+	ASSERT(prSwRfb);
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+	/* We should have the corresponding Sta Record. */
+	if (!prStaRec) {
+		/* Peter: we can handle the packet without station record */
+		/* ASSERT(0); */
+		return;
+	}
+
+	if (!IS_AP_STA(prStaRec))
+		return;
+
+	switch (prStaRec->eAuthAssocState) {
+	case SAA_STATE_SEND_AUTH1:
+	case SAA_STATE_WAIT_AUTH2:
+		/* Check if the incoming frame is what we are waiting for */
+		if (authCheckRxAuthFrameStatus(prAdapter,
+					       prSwRfb, AUTH_TRANSACTION_SEQ_2, &u2StatusCode) == WLAN_STATUS_SUCCESS) {
+
+			cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+			/* Record the Status Code of Authentication Request */
+			prStaRec->u2StatusCode = u2StatusCode;
+
+			if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
+
+				authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb);
+
+				if (prStaRec->ucAuthAlgNum == (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY) {
+
+					eNextState = SAA_STATE_SEND_AUTH3;
+				} else {
+					/* Update Station Record - Class 2 Flag */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+
+					eNextState = SAA_STATE_SEND_ASSOC1;
+				}
+			} else {
+				DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n",
+						   (prStaRec->aucMacAddr), u2StatusCode);
+
+				eNextState = AA_STATE_IDLE;
+			}
+
+			/* Reset Send Auth/(Re)Assoc Frame Count */
+			prStaRec->ucTxAuthAssocRetryCount = 0;
+
+			saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
+		}
+		break;
+
+	case SAA_STATE_SEND_AUTH3:
+	case SAA_STATE_WAIT_AUTH4:
+		/* Check if the incoming frame is what we are waiting for */
+		if (authCheckRxAuthFrameStatus(prAdapter,
+					       prSwRfb, AUTH_TRANSACTION_SEQ_4, &u2StatusCode) == WLAN_STATUS_SUCCESS) {
+
+			cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+			/* Record the Status Code of Authentication Request */
+			prStaRec->u2StatusCode = u2StatusCode;
+
+			if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
+
+				authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb);	/* Add for 802.11r handling */
+
+				/* Update Station Record - Class 2 Flag */
+				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+
+				eNextState = SAA_STATE_SEND_ASSOC1;
+			} else {
+				DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n",
+						   (prStaRec->aucMacAddr), u2StatusCode);
+
+				eNextState = AA_STATE_IDLE;
+			}
+
+			/* Reset Send Auth/(Re)Assoc Frame Count */
+			prStaRec->ucTxAuthAssocRetryCount = 0;
+
+			saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
+		}
+		break;
+
+	default:
+		break;		/* Ignore other cases */
+	}
+
+}				/* end of saaFsmRunEventRxAuth() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will process the Rx (Re)Association Response Frame and then
+*        trigger SAA FSM.
+*
+* @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS           if the status code was not success
+* @retval WLAN_STATUS_BUFFER_RETAINED   if the status code was success
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2StatusCode;
+	ENUM_AA_STATE_T eNextState;
+	P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T) NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prSwRfb);
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+	/* We should have the corresponding Sta Record. */
+	if (!prStaRec) {
+		ASSERT(0);
+		return rStatus;
+	}
+
+	if (!IS_AP_STA(prStaRec))
+		return rStatus;
+
+	switch (prStaRec->eAuthAssocState) {
+	case SAA_STATE_SEND_ASSOC1:
+	case SAA_STATE_WAIT_ASSOC2:
+		/* TRUE if the incoming frame is what we are waiting for */
+		if (assocCheckRxReAssocRspFrameStatus(prAdapter, prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) {
+
+			cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+			/* Record the Status Code of Authentication Request */
+			prStaRec->u2StatusCode = u2StatusCode;
+
+			if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
+
+				/* Update Station Record - Class 3 Flag */
+				/* NOTE(Kevin): Moved to AIS FSM for roaming issue -
+				 * We should deactivate the STA_RECORD_T of previous AP before
+				 * activate new one in Driver.
+				 */
+				/* cnmStaRecChangeState(prStaRec, STA_STATE_3); */
+
+				prStaRec->ucJoinFailureCount = 0;	/* Clear history. */
+
+				prRetainedSwRfb = prSwRfb;
+				rStatus = WLAN_STATUS_PENDING;
+			} else {
+				DBGLOG(SAA, INFO, "Assoc Req was rejected by [ %pM ], Status Code = %d\n",
+						   (prStaRec->aucMacAddr), u2StatusCode);
+			}
+
+			/* Reset Send Auth/(Re)Assoc Frame Count */
+			prStaRec->ucTxAuthAssocRetryCount = 0;
+
+			/* update RCPI */
+			prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
+
+			eNextState = AA_STATE_IDLE;
+
+			saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb);
+		}
+		break;
+
+	default:
+		break;		/* Ignore other cases */
+	}
+
+	return rStatus;
+
+}				/* end of saaFsmRunEventRxAssoc() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will check the incoming Deauth Frame.
+*
+* @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Always not retain deauthentication frames
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_STA_RECORD_T prStaRec;
+	P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
+
+	ASSERT(prSwRfb);
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	if (prStaRec == NULL)
+		return WLAN_STATUS_FAILURE;
+
+	prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
+	DBGLOG(SAA, INFO, "Rx Deauth frame from BSSID=[ %pM ].\n", prDeauthFrame->aucBSSID);
+
+	do {
+		if (IS_STA_IN_AIS(prStaRec)) {
+			P_AIS_BSS_INFO_T prAisBssInfo;
+
+			if (!IS_AP_STA(prStaRec))
+				break;
+
+			prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+			if (prStaRec->ucStaState <= STA_STATE_1)
+				break;
+
+			/* Check if this is the AP we are associated or associating with */
+			if (authProcessRxDeauthFrame(prSwRfb,
+						     prStaRec->aucMacAddr,
+						     &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+
+				DBGLOG(SAA, INFO, "Deauth reason = %d\n", prStaRec->u2ReasonCode);
+
+				if (STA_STATE_2 <= prStaRec->ucStaState) {
+					P_MSG_AIS_ABORT_T prAisAbortMsg;
+
+					/* NOTE(Kevin): Change state immediately to avoid starvation of
+					 * MSG buffer because of too many deauth frames before changing
+					 * the STA state.
+					 */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+					prAisAbortMsg =
+					    (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG,
+									    sizeof(MSG_AIS_ABORT_T));
+					if (!prAisAbortMsg)
+						break;
+
+					prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
+					prAisAbortMsg->ucReasonOfDisconnect =
+					    DISCONNECT_REASON_CODE_DEAUTHENTICATED;
+					prAisAbortMsg->fgDelayIndication = FALSE;
+
+					mboxSendMsg(prAdapter,
+						    MBOX_ID_0,
+						    (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
+				} else {
+
+					/* TODO(Kevin): Joining Abort */
+				}
+				prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode;
+
+			}
+
+		}
+#if CFG_ENABLE_WIFI_DIRECT
+		else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
+			/* TODO(Kevin) */
+			p2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb);
+		}
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+		else if (IS_STA_IN_BOW(prStaRec))
+			bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb);
+#endif
+		else
+			ASSERT(0);
+
+	} while (FALSE);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of saaFsmRunEventRxDeauth() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will check the incoming Disassociation Frame.
+*
+* @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Always not retain disassociation frames
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_STA_RECORD_T prStaRec;
+	P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
+
+	ASSERT(prSwRfb);
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	if (prStaRec == NULL)
+		return WLAN_STATUS_FAILURE;
+
+	prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader;
+	DBGLOG(SAA, INFO, "Rx Disassoc frame from BSSID=[ %pM ].\n", (prDisassocFrame->aucBSSID));
+
+	do {
+		if (IS_STA_IN_AIS(prStaRec)) {
+			P_AIS_BSS_INFO_T prAisBssInfo;
+
+			if (!IS_AP_STA(prStaRec))
+				break;
+
+			prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+			if (prStaRec->ucStaState <= STA_STATE_1)
+				break;
+
+			/* Check if this is the AP we are associated or associating with */
+			if (assocProcessRxDisassocFrame(prAdapter,
+							prSwRfb,
+							prStaRec->aucMacAddr,
+							&prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+
+				DBGLOG(SAA, INFO, "Disassoc reason = %d\n", prStaRec->u2ReasonCode);
+
+				if (STA_STATE_3 <= prStaRec->ucStaState) {
+					P_MSG_AIS_ABORT_T prAisAbortMsg;
+					/* NOTE(Chaozhong): Change state immediately to avoid starvation of
+					 * MSG buffer because of too many disassoc frames before changing
+					 * the STA state.
+					 */
+					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+
+					prAisAbortMsg =
+					    (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG,
+									    sizeof(MSG_AIS_ABORT_T));
+					if (!prAisAbortMsg)
+						break;
+
+					prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
+					prAisAbortMsg->ucReasonOfDisconnect =
+					    DISCONNECT_REASON_CODE_DISASSOCIATED;
+					prAisAbortMsg->fgDelayIndication = FALSE;
+
+					mboxSendMsg(prAdapter,
+						    MBOX_ID_0,
+						    (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
+				} else {
+
+					/* TODO(Kevin): Joining Abort */
+				}
+				prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode;
+
+			}
+
+		}
+#if CFG_ENABLE_WIFI_DIRECT
+		else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
+			/* TODO(Kevin) */
+			p2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb);
+		}
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+		else if (IS_STA_IN_BOW(prStaRec)) {
+			/* Do nothing */
+			/* TODO(Kevin) */
+		}
+#endif
+		else
+			ASSERT(0);
+
+	} while (FALSE);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of saaFsmRunEventRxDisassoc() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle the Abort Event to SAA FSM.
+*
+* @param[in] prMsgHdr   Message of Abort Request for a particular STA.
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg;
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prMsgHdr);
+
+	prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T) prMsgHdr;
+	prStaRec = prSaaFsmAbortMsg->prStaRec;
+
+	ASSERT(prStaRec);
+	if (!prStaRec) {
+		cnmMemFree(prAdapter, prMsgHdr);
+		return;
+	}
+
+	DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n");
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+	/* Reset Send Auth/(Re)Assoc Frame Count */
+	prStaRec->ucTxAuthAssocRetryCount = 0;
+
+	/* Cancel JOIN relative Timer */
+	cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
+
+	if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
+#if DBG
+		DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %s.\n",
+				   apucDebugAAState[prStaRec->eAuthAssocState]);
+#else
+		DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %d.\n", prStaRec->eAuthAssocState);
+#endif
+	}
+#if 0
+	/* For the Auth/Assoc State to IDLE */
+	prStaRec->eAuthAssocState = AA_STATE_IDLE;
+#else
+	/* Free this StaRec */
+	cnmStaRecFree(prAdapter, prStaRec, FALSE);
+#endif
+
+}				/* end of saaFsmRunEventAbort() */
+
+/* TODO(Kevin): following code will be modified and move to AIS FSM */
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will send Join Timeout Event to JOIN FSM.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \retval WLAN_STATUS_FAILURE   Fail because of Join Timeout
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter)
+{
+	P_JOIN_INFO_T prJoinInfo;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("joinFsmRunEventJoinTimeOut");
+
+	ASSERT(prAdapter);
+	prJoinInfo = &prAdapter->rJoinInfo;
+
+	DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n");
+
+	/* Get a Station Record if possible, TA == BSSID for AP */
+	prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID);
+
+	/* We have renew this Sta Record when in JOIN_STATE_INIT */
+	ASSERT(prStaRec);
+
+	/* Record the Status Code of Authentication Request */
+	prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT;
+
+	/* Increase Failure Count */
+	prStaRec->ucJoinFailureCount++;
+
+	/* Reset Send Auth/(Re)Assoc Frame Count */
+	prJoinInfo->ucTxAuthAssocRetryCount = 0;
+
+	/* Cancel other JOIN relative Timer */
+	ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer);
+
+	ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer);
+
+	/* Restore original setting from current BSS_INFO_T */
+	if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)
+		joinAdoptParametersFromCurrentBss(prAdapter);
+
+	/* Pull back to IDLE */
+	joinFsmSteps(prAdapter, JOIN_STATE_IDLE);
+
+	return WLAN_STATUS_FAILURE;
+
+}				/* end of joinFsmRunEventJoinTimeOut() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will adopt the parameters from Peer BSS.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter)
+{
+	P_JOIN_INFO_T prJoinInfo;
+	P_BSS_DESC_T prBssDesc;
+
+	DEBUGFUNC("joinAdoptParametersFromPeerBss");
+
+	ASSERT(prAdapter);
+	prJoinInfo = &prAdapter->rJoinInfo;
+	prBssDesc = prJoinInfo->prBssDesc;
+
+	/* 4 <1> Adopt Peer BSS' PHY TYPE */
+	prAdapter->eCurrentPhyType = prBssDesc->ePhyType;
+
+	DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n",
+			    prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS");
+
+	/* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */
+	DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand);
+
+	nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10);
+
+	prJoinInfo->fgIsParameterAdopted = TRUE;
+
+}				/* end of joinAdoptParametersFromPeerBss() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will adopt the parameters from current associated BSS.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter)
+{
+	/* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	prBssInfo = &prAdapter->rBssInfo;
+
+	/* 4 <1> Adopt current BSS' PHY TYPE */
+	prAdapter->eCurrentPhyType = prBssInfo->ePhyType;
+
+	/* 4 <2> Adopt current BSS' Frequency(Band/Channel) */
+	DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand);
+
+	nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10);
+}				/* end of joinAdoptParametersFromCurrentBss() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will update all the SW variables and HW MCR registers after
+*        the association with target BSS.
+*
+* \param[in] prAdapter      Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID joinComplete(IN P_ADAPTER_T prAdapter)
+{
+	P_JOIN_INFO_T prJoinInfo;
+	P_BSS_DESC_T prBssDesc;
+	P_PEER_BSS_INFO_T prPeerBssInfo;
+	P_BSS_INFO_T prBssInfo;
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_STA_RECORD_T prStaRec;
+	P_TX_CTRL_T prTxCtrl;
+#if CFG_SUPPORT_802_11D
+	P_IE_COUNTRY_T prIECountry;
+#endif
+
+	DEBUGFUNC("joinComplete");
+
+	ASSERT(prAdapter);
+	prJoinInfo = &prAdapter->rJoinInfo;
+	prBssDesc = prJoinInfo->prBssDesc;
+	prPeerBssInfo = &prAdapter->rPeerBssInfo;
+	prBssInfo = &prAdapter->rBssInfo;
+	prConnSettings = &prAdapter->rConnSettings;
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */
+	/* Remove previous AP's Connection Flags if have */
+	scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID);
+
+	prBssDesc->fgIsConnected = TRUE;	/* Mask as Connected */
+
+	if (prBssDesc->fgIsHiddenSSID) {
+		/* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't
+		 * broadcast SSID on its Beacon Frame.
+		 */
+		COPY_SSID(prBssDesc->aucSSID,
+			  prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen);
+
+		if (prBssDesc->ucSSIDLen)
+			prBssDesc->fgIsHiddenSSID = FALSE;
+#if DBG
+		else
+			ASSERT(0);
+#endif /* DBG */
+
+		DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID);
+	}
+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */
+	/* 4 <2.A> PHY Type */
+	prBssInfo->ePhyType = prBssDesc->ePhyType;
+
+	/* 4 <2.B> BSS Type */
+	prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE;
+
+	/* 4 <2.C> BSSID */
+	COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID);
+
+	DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID);
+
+	/* 4 <2.D> SSID */
+	COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+
+	/* 4 <2.E> Channel / Band information. */
+	prBssInfo->eBand = prBssDesc->eBand;
+	prBssInfo->ucChnl = prBssDesc->ucChannelNum;
+
+	/* 4 <2.F> RSN/WPA information. */
+	secFsmRunEventStart(prAdapter);
+	prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher;
+	prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher;
+	prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite;
+
+	if (secRsnKeyHandshakeEnabled())
+		prBssInfo->fgIsWPAorWPA2Enabled = TRUE;
+	else
+		prBssInfo->fgIsWPAorWPA2Enabled = FALSE;
+
+	/* 4 <2.G> Beacon interval. */
+	prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
+
+	/* 4 <2.H> DTIM period. */
+	prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod;
+
+	/* 4 <2.I> ERP Information */
+	if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) &&	/* Our BSS's PHY_TYPE is ERP now. */
+	    (prBssDesc->fgIsERPPresent)) {
+
+		prBssInfo->fgIsERPPresent = TRUE;
+		prBssInfo->ucERP = prBssDesc->ucERP;	/* Save the ERP for later check */
+	} else {	/* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */
+		prBssInfo->fgIsERPPresent = FALSE;
+		prBssInfo->ucERP = 0;
+	}
+
+#if CFG_SUPPORT_802_11D
+	/* 4 <2.J> Country inforamtion of the associated AP */
+	if (prConnSettings->fgMultiDomainCapabilityEnabled) {
+		DOMAIN_INFO_ENTRY rDomainInfo;
+
+		if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) {
+			if (prBssDesc->prIECountry) {
+				prIECountry = prBssDesc->prIECountry;
+
+				domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo);
+
+				/* use the domain get from the BSS info */
+				prBssInfo->fgIsCountryInfoPresent = TRUE;
+				nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE);
+			} else {
+				/* use the domain get from the scan result */
+				prBssInfo->fgIsCountryInfoPresent = TRUE;
+				nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE);
+			}
+		}
+	}
+#endif
+
+	/* 4 <2.K> Signal Power of the associated AP */
+	prBssInfo->rRcpi = prBssDesc->rRcpi;
+	prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi);
+	GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime);
+
+	/* 4 <2.L> Capability Field of the associated AP */
+	prBssInfo->u2CapInfo = prBssDesc->u2CapInfo;
+
+	DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n",
+			    prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi);
+
+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */
+	/* 4 <3.A> Association ID */
+	prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId;
+
+	/* 4 <3.B> WMM Information */
+	if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) {
+
+		prBssInfo->fgIsWmmAssoc = TRUE;
+		prTxCtrl->rTxQForVoipAccess = TXQ_AC3;
+
+		qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE);
+
+		if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) {
+			kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
+		} else {
+			kalMemCopy(&prBssInfo->rWmmInfo,
+				   &prPeerBssInfo->rWmmInfo,
+				   sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams));
+		}
+	} else {
+		prBssInfo->fgIsWmmAssoc = FALSE;
+		prTxCtrl->rTxQForVoipAccess = TXQ_AC1;
+
+		kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
+	}
+
+	/* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */
+	prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet;
+	prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet;
+
+	/* 4 <3.D> Short Preamble */
+	if (prBssInfo->fgIsERPPresent) {
+
+		/* NOTE(Kevin 2007/12/24): Truth Table.
+		 * Short Preamble Bit in
+		 * <AssocReq> <AssocResp w/i ERP> <BARKER(Long)>  Final Driver Setting(Short)
+		 * TRUE         FALSE               FALSE    FALSE(shouldn't have such case, use the AssocResp)
+		 * TRUE         FALSE               TRUE     FALSE
+		 * FALSE        FALSE               FALSE    FALSE(shouldn't have such case, use the AssocResp)
+		 * FALSE        FALSE               TRUE     FALSE
+		 * TRUE         TRUE                FALSE    TRUE(follow ERP)
+		 * TRUE         TRUE                TRUE     FALSE(follow ERP)
+		 * FALSE        TRUE                FALSE    FALSE(shouldn't have such case, and we should set to FALSE)
+		 * FALSE        TRUE                TRUE     FALSE(we should set to FALSE)
+		 */
+		if ((prPeerBssInfo->fgIsShortPreambleAllowed) &&
+			((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) ||
+			((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) &&
+			(prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) {
+
+			prBssInfo->fgIsShortPreambleAllowed = TRUE;
+
+			if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE)
+				prBssInfo->fgUseShortPreamble = FALSE;
+			else
+				prBssInfo->fgUseShortPreamble = TRUE;
+		} else {
+			prBssInfo->fgIsShortPreambleAllowed = FALSE;
+			prBssInfo->fgUseShortPreamble = FALSE;
+		}
+	} else {
+		/* NOTE(Kevin 2007/12/24): Truth Table.
+		 * Short Preamble Bit in
+		 * <AssocReq>     <AssocResp w/o ERP>     Final Driver Setting(Short)
+		 * TRUE            FALSE                  FALSE
+		 * FALSE           FALSE                  FALSE
+		 * TRUE            TRUE                   TRUE
+		 * FALSE           TRUE(status success)   TRUE
+		 * --> Honor the result of prPeerBssInfo.
+		 */
+
+		prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble =
+		    prPeerBssInfo->fgIsShortPreambleAllowed;
+	}
+
+	DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n",
+			    prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble);
+
+	/* 4 <3.E> Short Slot Time */
+	prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime;	/* AP support Short Slot Time */
+
+	DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime);
+
+	nicSetSlotTime(prAdapter,
+		       prBssInfo->ePhyType,
+		       ((prConnSettings->fgIsShortSlotTimeOptionEnable &&
+			 prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE));
+
+	/* 4 <3.F> Update Tx Rate for Control Frame */
+	bssUpdateTxRateForControlFrame(prAdapter);
+
+	/* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */
+	/* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */
+	{
+
+		if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM)
+			prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM;
+		else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)
+			prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY;
+
+		prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes;
+
+		/* Set the stable time of the associated BSS. We won't do roaming decision
+		 * during the stable time.
+		 */
+		SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime,
+				    SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC));
+	}
+
+	/* 4 <3.H> Update Parameter for TX Fragmentation Threshold */
+#if CFG_TX_FRAGMENT
+	txFragInfoUpdate(prAdapter);
+#endif /* CFG_TX_FRAGMENT */
+
+/* 4 <4> Update STA_RECORD_T */
+	/* Get a Station Record if possible */
+	prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID);
+
+	if (prStaRec) {
+		UINT_16 u2OperationalRateSet, u2DesiredRateSet;
+
+		/* 4 <4.A> Desired Rate Set */
+		u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet &
+					prBssInfo->u2OperationalRateSet);
+
+		u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet);
+		if (u2DesiredRateSet) {
+			prStaRec->u2DesiredRateSet = u2DesiredRateSet;
+		} else {
+			/* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */
+			prStaRec->u2DesiredRateSet = u2OperationalRateSet;
+		}
+
+		/* Try to set the best initial rate for this entry */
+		if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet,
+						 prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) {
+
+			if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index))
+				ASSERT(0);
+		}
+
+		DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index);
+
+		/* 4 <4.B> Preamble Mode */
+		prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble;
+
+		/* 4 <4.C> QoS Flag */
+		prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc;
+	}
+#if DBG
+	else
+		ASSERT(0);
+#endif /* DBG */
+
+/* 4 <5> Update NIC */
+	/* 4 <5.A> Update BSSID & Operation Mode */
+	nicSetupBSS(prAdapter, prBssInfo);
+
+	/* 4 <5.B> Update WLAN Table. */
+	if (nicSetHwBySta(prAdapter, prStaRec) == FALSE)
+		ASSERT(FALSE);
+	/* 4 <5.C> Update Desired Rate Set for BT. */
+#if CFG_TX_FRAGMENT
+	if (prConnSettings->fgIsEnableTxAutoFragmentForBT)
+		txRateSetInitForBT(prAdapter, prStaRec);
+#endif /* CFG_TX_FRAGMENT */
+
+	/* 4 <5.D> TX AC Parameter and TX/RX Queue Control */
+	if (prBssInfo->fgIsWmmAssoc) {
+
+#if CFG_TX_AGGREGATE_HW_FIFO
+		nicTxAggregateTXQ(prAdapter, FALSE);
+#endif /* CFG_TX_AGGREGATE_HW_FIFO */
+
+		qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo);
+	} else {
+
+#if CFG_TX_AGGREGATE_HW_FIFO
+		nicTxAggregateTXQ(prAdapter, TRUE);
+#endif /* CFG_TX_AGGREGATE_HW_FIFO */
+
+		nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter);
+
+		nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType);
+	}
+
+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN
+	{
+		prTxCtrl->fgBlockTxDuringJoin = FALSE;
+
+#if !CFG_TX_AGGREGATE_HW_FIFO	/* TX FIFO AGGREGATE already do flush once */
+		nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL);
+#endif /* CFG_TX_AGGREGATE_HW_FIFO */
+
+		nicTxRetransmitOfSendWaitQue(prAdapter);
+
+		if (prTxCtrl->fgIsPacketInOsSendQueue)
+			nicTxRetransmitOfOsSendQue(prAdapter);
+#if CFG_SDIO_TX_ENHANCE
+		halTxLeftClusteredMpdu(prAdapter);
+#endif /* CFG_SDIO_TX_ENHANCE */
+
+	}
+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */
+
+/* 4 <6> Setup CONNECTION flag. */
+	prAdapter->eConnectionState = MEDIA_STATE_CONNECTED;
+	prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED;
+
+	if (prJoinInfo->fgIsReAssoc)
+		prAdapter->fgBypassPortCtrlForRoaming = TRUE;
+	else
+		prAdapter->fgBypassPortCtrlForRoaming = FALSE;
+
+	kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0);
+
+}				/* end of joinComplete() */
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c
new file mode 100644
index 0000000000000..2c9ccbe82dd1b
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c
@@ -0,0 +1,3103 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3
+*/
+
+/*! \file   "scan.c"
+    \brief  This file defines the scan profile and the processing function of
+	    scan result for SCAN Module.
+
+    The SCAN Profile selection is part of SCAN MODULE and responsible for defining
+    SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels.
+    In this file we also define the process of SCAN Result including adding, searching
+    and removing SCAN record from the list.
+*/
+
+/*
+** Log: scan.c
+**
+** 01 30 2013 yuche.tsai
+** [ALPS00451578] [JB2][WFD][Case Fail][JE][MR1]?????????[Java (JE),660,-1361051648,99,
+** /data/core/,0,system_server_crash,system_server]JE happens when try to connect WFD.(4/5)
+** Fix possible old scan result indicate to supplicant after formation.
+**
+** 01 16 2013 yuche.tsai
+** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect
+** Fix possible FW assert issue.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 25 2012 cp.wu
+ * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target
+ * drop off scan result which is older than 5 seconds when choosing which BSS to join
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 16 2012 cp.wu
+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band
+ * configuration with corresponding network configuration
+ * correct typo.
+ *
+ * 01 16 2012 cp.wu
+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration
+ * with corresponding network configuration
+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred
+ * band configuration corresponding to network type.
+ *
+ * 12 05 2011 cp.wu
+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
+ * add CONNECT_BY_BSSID policy
+ *
+ * 11 23 2011 cp.wu
+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection
+ * add compile option to disable beacon content change detection.
+ *
+ * 11 04 2011 cp.wu
+ * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp
+ * is reset with received beacon/probe response frames
+ * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before
+ *
+ * 10 11 2011 cm.chang
+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter
+ * Ignore HT OP IE if its length field is not valid
+ *
+ * 09 30 2011 cp.wu
+ * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode
+ * correct type casting issue.
+ *
+ * 08 23 2011 yuche.tsai
+ * NULL
+ * Fix multicast address list issue.
+ *
+ * 08 11 2011 cp.wu
+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
+ * sparse channel detection:
+ * driver: collect sparse channel information with scan-done event
+ *
+ * 08 10 2011 cp.wu
+ * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing
+ * traverse whole BSS-DESC list because BSSID is not unique anymore.
+ *
+ * 07 12 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
+ * SSID settings to work around some tricky AP which use space character as hidden SSID
+ * for multiple BSS descriptior detecting issue:
+ * 1) check BSSID for infrastructure network
+ * 2) check SSID for AdHoc network
+ *
+ * 07 12 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
+ * SSID settings to work around some tricky AP which use space character as hidden SSID
+ * check for BSSID for beacons used to update DTIM
+ *
+ * 07 12 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
+ * SSID settings to work around some tricky AP which use space character as hidden SSID
+ * do not check BSS descriptor for connected flag due to linksys's hidden
+ * SSID will use another BSS descriptor and never connected
+ *
+ * 07 11 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
+ * SSID settings to work around some tricky AP which use space character as hidden SSID
+ * just pass beacons with the same BSSID.
+ *
+ * 07 11 2011 wh.su
+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define
+ * for make sure the value is initialize, for customer not enable WAPI
+ * For make sure wapi initial value is set.
+ *
+ * 06 28 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
+ * SSID settings to work around some tricky AP which use space character as hidden SSID
+ * Do not check for SSID as beacon content change due to the existence of
+ * single BSSID with multiple SSID AP configuration
+ *
+ * 06 27 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
+ * SSID settings to work around some tricky AP which use space character as hidden SSID
+ * 1. correct logic
+ * 2. replace only BSS-DESC which doesn't have a valid SSID.
+ *
+ * 06 27 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID
+ * settings to work around some tricky AP which use space character as hidden SSID
+ * remove unused temporal variable reference.
+ *
+ * 06 27 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID
+ * settings to work around some tricky AP which use space character as hidden SSID
+ * allow to have a single BSSID with multiple SSID to be presented in scanning result
+ *
+ * 06 02 2011 cp.wu
+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels
+ * filter out BSS in disallowed channel by
+ * 1. do not add to scan result array if BSS is at disallowed channel
+ * 2. do not allow to search for BSS-DESC in disallowed channels
+ *
+ * 05 02 2011 cm.chang
+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
+ * Refine range of valid channel number
+ *
+ * 05 02 2011 cp.wu
+ * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of
+ * hardware channel number passed from firmware domain
+ * take parsed result for generating scanning result with channel information.
+ *
+ * 05 02 2011 cm.chang
+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
+ * Check if channel is valided before record ing BSS channel
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 14 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 12 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix the sta index in processing security frame
+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
+ * Add debug message.
+ *
+ * 03 25 2011 yuche.tsai
+ * NULL
+ * Always update Bss Type, for Bss Type for P2P Network is changing every time.
+ *
+ * 03 23 2011 yuche.tsai
+ * NULL
+ * Fix concurrent issue when AIS scan result would overwrite p2p scan result.
+ *
+ * 03 14 2011 cp.wu
+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
+ * filtering out other BSS coming from adjacent channels
+ *
+ * 03 11 2011 chinglan.wang
+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security.
+ * .
+ *
+ * 03 11 2011 cp.wu
+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel
+ *
+ * 02 24 2011 cp.wu
+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep()
+ * won't sleep long enough for specified interval such as 500ms
+ * implement beacon change detection by checking SSID and supported rate.
+ *
+ * 02 22 2011 yuche.tsai
+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
+ * Fix WSC big endian issue.
+ *
+ * 02 21 2011 terry.wu
+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
+ * Clean P2P scan list while removing P2P.
+ *
+ * 01 27 2011 yuche.tsai
+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
+ * Fix scan channel extension issue when p2p module is not registered.
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * .
+ *
+ * 01 21 2011 cp.wu
+ * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered
+ * BSS_DESC_T rather than using beacon-carried information
+ * SSID should come from buffered prBssDesc rather than beacon-carried information
+ *
+ * 01 14 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Fix compile error.
+ *
+ * 01 14 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Memfree for P2P Descriptor & P2P Descriptor List.
+ *
+ * 01 14 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * Free P2P Descriptor List & Descriptor under BSS Descriptor.
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc
+ * and vmalloc implementations to ease physically continuous memory demands
+ * 1) correct typo in scan.c
+ * 2) TX descriptors, RX descriptos and management buffer should use virtually
+ * continuous buffer instead of physically continuous one
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc
+ * and vmalloc implementations to ease physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
+ * while being unloaded, clear all pending interrupt then set LP-own to firmware
+ *
+ * 12 21 2010 cp.wu
+ * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module
+ * SCN: enable BEST RSSI selection policy support
+ *
+ * 11 29 2010 cp.wu
+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC
+ * for initial TX rate selection of auto-rate algorithm
+ * update ucRcpi of STA_RECORD_T for AIS when
+ * 1) Beacons for IBSS merge is received
+ * 2) Associate Response for a connecting peer is received
+ *
+ * 11 03 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Refine the HT rate disallow TKIP pairwise cipher .
+ *
+ * 10 12 2010 cp.wu
+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out
+ * beacons which is received on the folding frequency
+ * trust HT IE if available for 5GHz band
+ *
+ * 10 11 2010 cp.wu
+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out
+ * beacons which is received on the folding frequency
+ * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels
+ *
+ * 10 08 2010 wh.su
+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
+ * update the frog's new p2p state machine.
+ *
+ * 10 01 2010 yuche.tsai
+ * NULL
+ * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV.
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * eliminate unused variables which lead gcc to argue
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * When indicate scan result, append IE buffer information in the scan result.
+ *
+ * 09 03 2010 yuche.tsai
+ * NULL
+ * 1. Update Beacon RX count when running SLT.
+ * 2. Ignore Beacon when running SLT, would not update information from Beacon.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 29 2010 yuche.tsai
+ * NULL
+ * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free.
+ * 2.. Fix P2P Device Name Length BE issue.
+ *
+ * 08 23 2010 yuche.tsai
+ * NULL
+ * Add P2P Device Found Indication to supplicant
+ *
+ * 08 20 2010 cp.wu
+ * NULL
+ * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured.
+ *
+ * 08 20 2010 yuche.tsai
+ * NULL
+ * Workaround for P2P Descriptor Infinite loop issue.
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
+ * There is no CFG_SUPPORT_BOW in driver domain source.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Modify code of processing Probe Resonse frame for P2P.
+ *
+ * 08 12 2010 yuche.tsai
+ * NULL
+ * Add function to get P2P descriptor of BSS descriptor directly.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Modify Scan result processing for P2P module.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Update P2P Device Discovery result add function.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Add support for Probe Request & Response parsing.
+ *
+ * 07 21 2010 cp.wu
+ *
+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term
+ * 2) only clear scanning result when scan is permitted to do
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Fix compile error for SCAN module while disabling P2P feature.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add P2P Scan & Scan Result Parsing & Saving.
+ *
+ * 07 19 2010 wh.su
+ *
+ * update for security supporting.
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Add Ad-Hoc support to AIS-FSM
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * SCN module is now able to handle multiple concurrent scanning requests
+ *
+ * 07 15 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * driver no longer generates probe request frames
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * remove timer in DRV-SCN.
+ *
+ * 07 09 2010 cp.wu
+ *
+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
+ * 3) implment DRV-SCN module, currently only accepts single scan request,
+ * other request will be directly dropped by returning BUSY
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * take use of RLM module for parsing/generating HT IEs for 11n capability
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) ignore RSN checking when RSN is not turned on.
+ * 2) set STA-REC deactivation callback as NULL
+ * 3) add variable initialization API based on PHY configuration
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * correct BSS_DESC_T initialization after allocated.
+ *
+ * 07 02 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) for event packet, no need to fill RFB.
+ * 2) when wlanAdapterStart() failed, no need to initialize state machines
+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan uninitialization procedure
+ *
+ * 06 30 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available,
+ * trust IE instead of RMAC information
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) sync to. CMD/EVENT document v0.03
+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
+ * 3) send command packet to indicate FW-PM after
+ *     a) 1st beacon is received after AIS has connected to an AP
+ *     b) IBSS-ALONE has been created
+ *     c) IBSS-MERGE has occurred
+ *
+ * 06 28 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * send MMPDU in basic rate.
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * modify Beacon/ProbeResp to complete parsing,
+ * because host software has looser memory usage restriction
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * integrate .
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * comment out RLM APIs by CFG_RLM_MIGRATION.
+ *
+ * 06 21 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Update P2P Function call.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * RSN/PRIVACY compilation flag awareness correction
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * specify correct value for management frames.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 18 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * migration from MT6620 firmware.
+ *
+ * 06 17 2010 yuche.tsai
+ * [WPD00003839][MT6620 5931][P2P] Feature migration
+ * Fix compile error when enable P2P function.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * correct when ADHOC support is turned on.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan.c.
+ *
+ * 06 04 2010 george.huang
+ * [BORA00000678][MT6620]WiFi LP integration
+ * [PM] Support U-APSD for STA mode
+ *
+ * 05 28 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * adding the TKIP disallow join a HT AP code.
+ *
+ * 05 14 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add more chance of JOIN retry for BG_SCAN
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 04 29 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * adjsut the pre-authentication code.
+ *
+ * 04 27 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 19 2010 kevin.huang
+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
+ * Add Beacon Timeout Support and will send Null frame to diagnose connection
+ *
+ * 04 13 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add new HW CH macro support
+ *
+ * 04 06 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * fixed the firmware return the broadcast frame at wrong tc.
+ *
+ * 03 29 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * let the rsn wapi IE always parsing.
+ *
+ * 03 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Not carry  HT cap when being associated with b/g only AP
+ *
+ * 03 18 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Solve the compile warning for 'return non-void' function
+ *
+ * 03 16 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Add AdHoc Mode
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ *
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * move the AIS specific variable for security to AIS specific structure.
+ *
+ * 03 01 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Refine the variable and parameter for security.
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Fix No PKT_INFO_T issue
+ *
+ * 02 26 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Update outgoing ProbeRequest Frame's TX data rate
+ *
+ * 02 23 2010 wh.su
+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver
+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join.
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
+ *
+ * 02 04 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 01 22 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Support protection and bandwidth switch
+ *
+ * 01 20 2010 kevin.huang
+ * [BORA00000569][WIFISYS] Phase 2 Integration Test
+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags
+ *
+ * 01 11 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add Deauth and Disassoc Handler
+ *
+ * 01 08 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ *
+ * Refine Beacon processing, add read RF channel from RX Status
+ *
+ * 01 04 2010 tehuang.liu
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * For working out the first connection Chariot-verified version
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 12 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Modify u2EstimatedExtraIELen for probe request
+ *
+ * Dec 9 2009 mtk01104
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add HT cap IE to probe request
+ *
+ * Dec 7 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix lint warning
+ *
+ *
+ * Dec 3 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Update the process of SCAN Result by adding more Phy Attributes
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the function and code for meet the new define
+ *
+ * Nov 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Rename u4RSSI to i4RSSI
+ *
+ * Nov 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Report event of scan result to host
+ *
+ * Nov 26 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix SCAN Record update
+ *
+ * Nov 24 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Revise MGMT Handler with Retain Status and Integrate with TXM
+ *
+ * Nov 23 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add (Ext)Support Rate Set IE to ProbeReq
+ *
+ * Nov 20 2009 mtk02468
+ * [BORA00000337] To check in codes for FPGA emulation
+ * Removed the use of SW_RFB->u2FrameLength
+ *
+ * Nov 20 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix uninitial aucMacAddress[] for ProbeReq
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add scanSearchBssDescByPolicy()
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Add Send Probe Request Frame
+ *
+ * Oct 30 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define REPLICATED_BEACON_TIME_THRESHOLD        (3000)
+#define REPLICATED_BEACON_FRESH_PERIOD          (10000)
+#define REPLICATED_BEACON_STRENGTH_THRESHOLD    (32)
+
+#define ROAMING_NO_SWING_RCPI_STEP              (10)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used by SCN to initialize its variables
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnInit(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_BSS_DESC_T prBSSDesc;
+	PUINT_8 pucBSSBuff;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	pucBSSBuff = &prScanInfo->aucScanBuffer[0];
+
+	DBGLOG(SCN, INFO, "->scnInit()\n");
+
+	/* 4 <1> Reset STATE and Message List */
+	prScanInfo->eCurrentState = SCAN_STATE_IDLE;
+
+	prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0;
+
+	LINK_INITIALIZE(&prScanInfo->rPendingMsgList);
+
+	/* 4 <2> Reset link list of BSS_DESC_T */
+	kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE);
+
+	LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
+	LINK_INITIALIZE(&prScanInfo->rBSSDescList);
+
+	for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) {
+
+		prBSSDesc = (P_BSS_DESC_T) pucBSSBuff;
+
+		LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry);
+
+		pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T));
+	}
+	/* Check if the memory allocation consist with this initialization function */
+	ASSERT(((ULONG) pucBSSBuff - (ULONG)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE);
+
+	/* reset freest channel information */
+	prScanInfo->fgIsSparseChannelValid = FALSE;
+
+	/* reset NLO state */
+	prScanInfo->fgNloScanning = FALSE;
+	prScanInfo->fgPscnOnnning = FALSE;
+
+	prScanInfo->prPscnParam = kalMemAlloc(sizeof(PSCN_PARAM_T), VIR_MEM_TYPE);
+	if (prScanInfo->prPscnParam)
+		kalMemZero(prScanInfo->prPscnParam, sizeof(PSCN_PARAM_T));
+
+}				/* end of scnInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used by SCN to uninitialize its variables
+*
+* @param (none)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnUninit(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	DBGLOG(SCN, INFO, "->scnUninit()\n");
+
+	/* 4 <1> Reset STATE and Message List */
+	prScanInfo->eCurrentState = SCAN_STATE_IDLE;
+
+	prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0;
+
+	/* NOTE(Kevin): Check rPendingMsgList ? */
+
+	/* 4 <2> Reset link list of BSS_DESC_T */
+	LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
+	LINK_INITIALIZE(&prScanInfo->rBSSDescList);
+
+	kalMemFree(prScanInfo->prPscnParam, VIR_MEM_TYPE, sizeof(PSCN_PARAM_T));
+
+}				/* end of scnUninit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Find the corresponding BSS Descriptor according to given BSSID
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] aucBSSID           Given BSSID.
+*
+* @return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
+{
+	return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Find the corresponding BSS Descriptor according to given BSSID
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] aucBSSID           Given BSSID.
+* @param[in] fgCheckSsid        Need to check SSID or not. (for multiple SSID with single BSSID cases)
+* @param[in] prSsid             Specified SSID
+*
+* @return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T
+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter,
+				IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_BSS_DESC_T prBssDesc;
+	P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
+
+	ASSERT(prAdapter);
+	ASSERT(aucBSSID);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	/* Search BSS Desc from current SCAN result list. */
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+		if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
+			if (fgCheckSsid == FALSE || prSsid == NULL)
+				return prBssDesc;
+
+			if (EQUAL_SSID(prBssDesc->aucSSID,
+				       prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) {
+				return prBssDesc;
+			} else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
+				prDstBssDesc = prBssDesc;
+			} else {
+				/* 20120206 frog: Equal BSSID but not SSID, SSID not hidden,
+				 * SSID must be updated. */
+				COPY_SSID(prBssDesc->aucSSID,
+					  prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen);
+				return prBssDesc;
+			}
+		}
+	}
+
+	return prDstBssDesc;
+
+}				/* end of scanSearchBssDescByBssid() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] aucSrcAddr         Given Source Address(TA).
+*
+* @return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[])
+{
+	return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] aucSrcAddr         Given Source Address(TA).
+* @param[in] fgCheckSsid        Need to check SSID or not. (for multiple SSID with single BSSID cases)
+* @param[in] prSsid             Specified SSID
+*
+* @return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T
+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter,
+			     IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_BSS_DESC_T prBssDesc;
+	P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
+
+	ASSERT(prAdapter);
+	ASSERT(aucSrcAddr);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	/* Search BSS Desc from current SCAN result list. */
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+		if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) {
+			if (fgCheckSsid == FALSE || prSsid == NULL)
+				return prBssDesc;
+
+			if (EQUAL_SSID(prBssDesc->aucSSID,
+				       prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) {
+				return prBssDesc;
+			} else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
+				prDstBssDesc = prBssDesc;
+			}
+
+		}
+	}
+
+	return prDstBssDesc;
+
+}				/* end of scanSearchBssDescByTA() */
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Find the corresponding BSS Descriptor according to given BSSID
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+* @param[in] aucBSSID           Given BSSID.
+* @param[in] fgCheckSsid        Need to check SSID or not. (for multiple SSID with single BSSID cases)
+* @param[in] prSsid             Specified SSID
+*
+* @return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_BSS_DESC_T prBssDesc;
+	P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
+	OS_SYSTIME rLatestUpdateTime = 0;
+
+	ASSERT(prAdapter);
+	ASSERT(aucBSSID);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	/* Search BSS Desc from current SCAN result list. */
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+		if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
+			if (!rLatestUpdateTime || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, rLatestUpdateTime)) {
+				prDstBssDesc = prBssDesc;
+				COPY_SYSTIME(rLatestUpdateTime, prBssDesc->rUpdateTime);
+			}
+		}
+	}
+
+	return prDstBssDesc;
+
+}				/* end of scanSearchBssDescByBssid() */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Find the corresponding BSS Descriptor according to
+*        given eBSSType, BSSID and Transmitter Address
+*
+* @param[in] prAdapter  Pointer to the Adapter structure.
+* @param[in] eBSSType   BSS Type of incoming Beacon/ProbeResp frame.
+* @param[in] aucBSSID   Given BSSID of Beacon/ProbeResp frame.
+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
+*
+* @return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T
+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter,
+			  IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[])
+{
+	return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Find the corresponding BSS Descriptor according to
+*        given eBSSType, BSSID and Transmitter Address
+*
+* @param[in] prAdapter  Pointer to the Adapter structure.
+* @param[in] eBSSType   BSS Type of incoming Beacon/ProbeResp frame.
+* @param[in] aucBSSID   Given BSSID of Beacon/ProbeResp frame.
+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
+* @param[in] prSsid     Specified SSID
+*
+* @return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T
+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter,
+				  IN ENUM_BSS_TYPE_T eBSSType,
+				  IN UINT_8 aucBSSID[],
+				  IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_BSS_DESC_T prBssDesc, prIBSSBssDesc;
+	P_LINK_T prBSSDescList;
+	P_LINK_T prFreeBSSDescList;
+
+
+	ASSERT(prAdapter);
+	ASSERT(aucSrcAddr);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	switch (eBSSType) {
+	case BSS_TYPE_P2P_DEVICE:
+		fgCheckSsid = FALSE;
+	case BSS_TYPE_INFRASTRUCTURE:
+	case BSS_TYPE_BOW_DEVICE:
+		{
+			prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
+
+			/* if (eBSSType == prBssDesc->eBSSType) */
+
+			return prBssDesc;
+		}
+
+	case BSS_TYPE_IBSS:
+		{
+			prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
+			prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid);
+
+			/* NOTE(Kevin):
+			 * Rules to maintain the SCAN Result:
+			 * For AdHoc -
+			 *    CASE I    We have TA1(BSSID1), but it change its BSSID to BSSID2
+			 *              -> Update TA1 entry's BSSID.
+			 *    CASE II   We have TA1(BSSID1), and get TA1(BSSID1) again
+			 *              -> Update TA1 entry's contain.
+			 *    CASE III  We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or
+			 *               later, TA2 merge into TA1, we get TA2(BSSID1)
+			 *              -> Remove TA2 first and then replace TA1 entry's TA with TA2,
+			 *                 Still have only one entry of BSSID.
+			 *    CASE IV   We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1.
+			 *              -> Replace TA1 entry's TA with TA2, Still have only one entry.
+			 *    CASE V    New IBSS
+			 *              -> Add this one to SCAN result.
+			 */
+			if (prBssDesc) {
+				if ((!prIBSSBssDesc) ||	/* CASE I */
+				    (prBssDesc == prIBSSBssDesc)) {	/* CASE II */
+
+					return prBssDesc;
+				}	/* CASE III */
+
+				prBSSDescList = &prScanInfo->rBSSDescList;
+				prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
+
+				/* Remove this BSS Desc from the BSS Desc list */
+				LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
+
+				/* Return this BSS Desc to the free BSS Desc list. */
+				LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
+
+				return prIBSSBssDesc;
+			}
+
+			if (prIBSSBssDesc) {	/* CASE IV */
+
+				return prIBSSBssDesc;
+			}
+			/* CASE V */
+			break;	/* Return NULL; */
+		}
+
+	default:
+		break;
+	}
+
+	return (P_BSS_DESC_T) NULL;
+
+}				/* end of scanSearchExistingBssDesc() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Delete BSS Descriptors from current list according to given Remove Policy.
+*
+* @param[in] u4RemovePolicy     Remove Policy.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_LINK_T prFreeBSSDescList;
+	P_BSS_DESC_T prBssDesc;
+
+	ASSERT(prAdapter);
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prBSSDescList = &prScanInfo->rBSSDescList;
+	prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
+
+	/* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */
+	/* prBSSDescList->u4NumElem)); */
+
+	if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) {
+		P_BSS_DESC_T prBSSDescNext;
+		OS_SYSTIME rCurrentTime;
+
+		GET_CURRENT_SYSTIME(&rCurrentTime);
+
+		/* Search BSS Desc from current SCAN result list. */
+		LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+			if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
+			    (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
+				/* Don't remove the one currently we are connected. */
+				continue;
+			}
+
+			if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
+					      SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) {
+
+				/* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x):
+				 * MAC: %pM, Current Time = %08lx, Update Time = %08lx\n", */
+				/* prBssDesc, prBssDesc->aucBSSID, rCurrentTime, prBssDesc->rUpdateTime)); */
+
+				/* Remove this BSS Desc from the BSS Desc list */
+				LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
+
+				/* Return this BSS Desc to the free BSS Desc list. */
+				LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
+			}
+		}
+	} else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) {
+		P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL;
+
+		/* Search BSS Desc from current SCAN result list. */
+		LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+			if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
+			    (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
+				/* Don't remove the one currently we are connected. */
+				continue;
+			}
+
+			if (!prBssDesc->fgIsHiddenSSID)
+				continue;
+
+			if (!prBssDescOldest) {	/* 1st element */
+				prBssDescOldest = prBssDesc;
+				continue;
+			}
+
+			if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime))
+				prBssDescOldest = prBssDesc;
+		}
+
+		if (prBssDescOldest) {
+
+			/* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x):
+			 * MAC: %pM, Update Time = %08lx\n", */
+			/* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */
+
+			/* Remove this BSS Desc from the BSS Desc list */
+			LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest);
+
+			/* Return this BSS Desc to the free BSS Desc list. */
+			LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry);
+		}
+	} else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) {
+		P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL;
+		P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL;
+		UINT_32 u4SameSSIDCount = 0;
+
+		/* Search BSS Desc from current SCAN result list. */
+		LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+			if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
+			    (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
+				/* Don't remove the one currently we are connected. */
+				continue;
+			}
+
+			if ((!prBssDesc->fgIsHiddenSSID) &&
+			    (EQUAL_SSID(prBssDesc->aucSSID,
+					prBssDesc->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) {
+
+				u4SameSSIDCount++;
+
+				if (!prBssDescWeakestSameSSID)
+					prBssDescWeakestSameSSID = prBssDesc;
+				else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI)
+					prBssDescWeakestSameSSID = prBssDesc;
+			}
+
+			if (!prBssDescWeakest) {	/* 1st element */
+				prBssDescWeakest = prBssDesc;
+				continue;
+			}
+
+			if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI)
+				prBssDescWeakest = prBssDesc;
+
+		}
+
+		if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) && (prBssDescWeakestSameSSID))
+			prBssDescWeakest = prBssDescWeakestSameSSID;
+
+		if (prBssDescWeakest) {
+
+			/* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: %pM, Update Time = %08lx\n", */
+			/* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */
+
+			/* Remove this BSS Desc from the BSS Desc list */
+			LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest);
+
+			/* Return this BSS Desc to the free BSS Desc list. */
+			LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry);
+		}
+	} else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) {
+		P_BSS_DESC_T prBSSDescNext;
+
+		LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+			if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
+			    (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
+				/* Don't remove the one currently we are connected. */
+				continue;
+			}
+
+			/* Remove this BSS Desc from the BSS Desc list */
+			LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
+
+			/* Return this BSS Desc to the free BSS Desc list. */
+			LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
+		}
+
+	}
+
+	return;
+
+}				/* end of scanRemoveBssDescsByPolicy() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Delete BSS Descriptors from current list according to given BSSID.
+*
+* @param[in] prAdapter  Pointer to the Adapter structure.
+* @param[in] aucBSSID   Given BSSID.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_LINK_T prFreeBSSDescList;
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+	P_BSS_DESC_T prBSSDescNext;
+
+	ASSERT(prAdapter);
+	ASSERT(aucBSSID);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prBSSDescList = &prScanInfo->rBSSDescList;
+	prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
+
+	/* Check if such BSS Descriptor exists in a valid list */
+	LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+		if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
+
+			/* Remove this BSS Desc from the BSS Desc list */
+			LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
+
+			/* Return this BSS Desc to the free BSS Desc list. */
+			LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
+
+			/* BSSID is not unique, so need to traverse whols link-list */
+		}
+	}
+
+}				/* end of scanRemoveBssDescByBssid() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Delete BSS Descriptors from current list according to given band configuration
+*
+* @param[in] prAdapter  Pointer to the Adapter structure.
+* @param[in] eBand      Given band
+* @param[in] eNetTypeIndex  AIS - Remove IBSS/Infrastructure BSS
+*                           BOW - Remove BOW BSS
+*                           P2P - Remove P2P BSS
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter,
+				  IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_LINK_T prFreeBSSDescList;
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+	P_BSS_DESC_T prBSSDescNext;
+	BOOLEAN fgToRemove;
+
+	ASSERT(prAdapter);
+	ASSERT(eBand <= BAND_NUM);
+	ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prBSSDescList = &prScanInfo->rBSSDescList;
+	prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
+
+	if (eBand == BAND_NULL)
+		return;		/* no need to do anything, keep all scan result */
+
+	/* Check if such BSS Descriptor exists in a valid list */
+	LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+		fgToRemove = FALSE;
+
+		if (prBssDesc->eBand == eBand) {
+			switch (eNetTypeIndex) {
+			case NETWORK_TYPE_AIS_INDEX:
+				if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)
+				    || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) {
+					fgToRemove = TRUE;
+				}
+				break;
+
+			case NETWORK_TYPE_P2P_INDEX:
+				if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE)
+					fgToRemove = TRUE;
+				break;
+
+			case NETWORK_TYPE_BOW_INDEX:
+				if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE)
+					fgToRemove = TRUE;
+				break;
+
+			default:
+				ASSERT(0);
+				break;
+			}
+		}
+
+		if (fgToRemove == TRUE) {
+			/* Remove this BSS Desc from the BSS Desc list */
+			LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
+
+			/* Return this BSS Desc to the free BSS Desc list. */
+			LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
+		}
+	}
+
+}				/* end of scanRemoveBssDescByBand() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Clear the CONNECTION FLAG of a specified BSS Descriptor.
+*
+* @param[in] aucBSSID   Given BSSID.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+
+	ASSERT(prAdapter);
+	ASSERT(aucBSSID);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	/* Search BSS Desc from current SCAN result list. */
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+		if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
+			prBssDesc->fgIsConnected = FALSE;
+			prBssDesc->fgIsConnecting = FALSE;
+
+			/* BSSID is not unique, so need to traverse whols link-list */
+		}
+	}
+
+	return;
+
+}				/* end of scanRemoveConnectionFlagOfBssDescByBssid() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Allocate new BSS_DESC_T
+*
+* @param[in] prAdapter          Pointer to the Adapter structure.
+*
+* @return   Pointer to BSS Descriptor, if has free space. NULL, if has no space.
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prFreeBSSDescList;
+	P_BSS_DESC_T prBssDesc;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
+
+	LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T);
+
+	if (prBssDesc) {
+		P_LINK_T prBSSDescList;
+
+		kalMemZero(prBssDesc, sizeof(BSS_DESC_T));
+
+#if CFG_ENABLE_WIFI_DIRECT
+		LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList));
+		prBssDesc->fgIsP2PPresent = FALSE;
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+		prBSSDescList = &prScanInfo->rBSSDescList;
+
+		/* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be
+		 * inserted to BSSDescList immediately.
+		 */
+		LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry);
+	}
+
+	return prBssDesc;
+
+}				/* end of scanAllocateBssDesc() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T
+*        with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer
+*
+* @param[in] prAdapter      Pointer to the Adapter structure.
+* @param[in] prSwRfb        Pointer to the receiving frame buffer.
+*
+* @return   Pointer to BSS Descriptor
+*           NULL if the Beacon/ProbeResp frame is invalid
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_BSS_DESC_T prBssDesc = NULL;
+	UINT_16 u2CapInfo;
+	ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE;
+
+	PUINT_8 pucIE;
+	UINT_16 u2IELength;
+	UINT_16 u2Offset = 0;
+
+	P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL;
+	P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
+	P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL;
+	P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	UINT_8 ucHwChannelNum = 0;
+	UINT_8 ucIeDsChannelNum = 0;
+	UINT_8 ucIeHtChannelNum = 0;
+	BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE;
+	PARAM_SSID_T rSsid;
+	UINT_64 u8Timestamp;
+	BOOLEAN fgIsNewBssDesc = FALSE;
+
+	UINT_32 i;
+	UINT_8 ucSSIDChar;
+
+	UINT_8 ucOuiType;
+	UINT_16 u2SubTypeVersion;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
+
+	WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo);
+	WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp);
+
+	/* decide BSS type */
+	switch (u2CapInfo & CAP_INFO_BSS_TYPE) {
+	case CAP_INFO_ESS:
+		/* It can also be Group Owner of P2P Group. */
+		eBSSType = BSS_TYPE_INFRASTRUCTURE;
+		break;
+
+	case CAP_INFO_IBSS:
+		eBSSType = BSS_TYPE_IBSS;
+		break;
+	case 0:
+		/* The P2P Device shall set the ESS bit of the Capabilities field
+		 * in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */
+		eBSSType = BSS_TYPE_P2P_DEVICE;
+		break;
+
+#if CFG_ENABLE_BT_OVER_WIFI
+		/* @TODO: add rule to identify BOW beacons */
+#endif
+
+	default:
+		 DBGLOG(SCN, ERROR, "wrong bss type %d\n", (INT_32)(u2CapInfo & CAP_INFO_BSS_TYPE));
+		return NULL;
+	}
+
+	/* 4 <1.1> Pre-parse SSID IE */
+	pucIE = prWlanBeaconFrame->aucInfoElem;
+	u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
+	    (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
+
+	if (u2IELength > CFG_IE_BUFFER_SIZE)
+		u2IELength = CFG_IE_BUFFER_SIZE;
+	kalMemZero(&rSsid, sizeof(rSsid));
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_SSID:
+			if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) {
+				ucSSIDChar = '\0';
+
+				/* D-Link DWL-900AP+ */
+				if (IE_LEN(pucIE) == 0)
+					fgIsValidSsid = FALSE;
+				/* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
+				/* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) &&
+				 * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
+				else {
+					for (i = 0; i < IE_LEN(pucIE); i++)
+						ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
+
+					if (ucSSIDChar)
+						fgIsValidSsid = TRUE;
+				}
+
+				/* Update SSID to BSS Descriptor only if SSID is not hidden. */
+				if (fgIsValidSsid == TRUE) {
+					COPY_SSID(rSsid.aucSsid,
+						  rSsid.u4SsidLen, SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength);
+				}
+			}
+			fgEscape = TRUE;
+			break;
+		default:
+			break;
+		}
+
+		if (fgEscape == TRUE)
+			break;
+	}
+	if (fgIsValidSsid)
+		DBGLOG(SCN, EVENT, "%s %pM channel %d\n", rSsid.aucSsid, prWlanBeaconFrame->aucBSSID,
+				HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr));
+	else
+		DBGLOG(SCN, EVENT, "hidden ssid, %pM channel %d\n", prWlanBeaconFrame->aucBSSID,
+				HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr));
+	/* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */
+	prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter,
+						      eBSSType,
+						      (PUINT_8) prWlanBeaconFrame->aucBSSID,
+						      (PUINT_8) prWlanBeaconFrame->aucSrcAddr,
+						      fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL);
+
+	if (prBssDesc == (P_BSS_DESC_T) NULL) {
+		fgIsNewBssDesc = TRUE;
+
+		do {
+			/* 4 <1.2.1> First trial of allocation */
+			prBssDesc = scanAllocateBssDesc(prAdapter);
+			if (prBssDesc)
+				break;
+			/* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */
+			scanRemoveBssDescsByPolicy(prAdapter,
+						   (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN));
+
+			/* 4 <1.2.3> Second tail of allocation */
+			prBssDesc = scanAllocateBssDesc(prAdapter);
+			if (prBssDesc)
+				break;
+			/* 4 <1.2.4> Remove the weakest one */
+			/* If there are more than half of BSS which has the same ssid as connection
+			 * setting, remove the weakest one from them.
+			 * Else remove the weakest one.
+			 */
+			scanRemoveBssDescsByPolicy(prAdapter,
+						   (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST));
+
+			/* 4 <1.2.5> reallocation */
+			prBssDesc = scanAllocateBssDesc(prAdapter);
+			if (prBssDesc)
+				break;
+			/* 4 <1.2.6> no space, should not happen */
+			DBGLOG(SCN, ERROR, "no bss desc available after remove policy\n");
+			return NULL;
+
+		} while (FALSE);
+
+	} else {
+		OS_SYSTIME rCurrentTime;
+
+		/* WCXRP00000091 */
+		/* if the received strength is much weaker than the original one, */
+		/* ignore it due to it might be received on the folding frequency */
+
+		GET_CURRENT_SYSTIME(&rCurrentTime);
+
+		if (prBssDesc->eBSSType != eBSSType) {
+			prBssDesc->eBSSType = eBSSType;
+		} else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum &&
+			   prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) {
+			/* for signal strength is too much weaker and previous beacon is not stale */
+			if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD &&
+				(rCurrentTime - prBssDesc->rUpdateTime) <= REPLICATED_BEACON_FRESH_PERIOD) {
+				DBGLOG(SCN, EVENT, "rssi is too much weaker and previous one is fresh\n");
+				return prBssDesc;
+			}
+			/* for received beacons too close in time domain */
+			else if (rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) {
+				DBGLOG(SCN, EVENT, "receive beacon/probe reponses too close\n");
+				return prBssDesc;
+			}
+		}
+
+		/* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */
+		if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) {
+			BOOLEAN fgIsConnected, fgIsConnecting;
+
+			/* set flag for indicating this is a new BSS-DESC */
+			fgIsNewBssDesc = TRUE;
+
+			/* backup 2 flags for APs which reset timestamp unexpectedly */
+			fgIsConnected = prBssDesc->fgIsConnected;
+			fgIsConnecting = prBssDesc->fgIsConnecting;
+			scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID);
+
+			prBssDesc = scanAllocateBssDesc(prAdapter);
+			if (!prBssDesc)
+				return NULL;
+
+			/* restore */
+			prBssDesc->fgIsConnected = fgIsConnected;
+			prBssDesc->fgIsConnecting = fgIsConnecting;
+		}
+	}
+#if 1
+
+	prBssDesc->u2RawLength = prSwRfb->u2PacketLen;
+	if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE)
+		prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE;
+	kalMemCopy(prBssDesc->aucRawBuf, prWlanBeaconFrame, prBssDesc->u2RawLength);
+#endif
+
+	/* NOTE: Keep consistency of Scan Record during JOIN process */
+	if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) {
+		DBGLOG(SCN, INFO, "we're connecting this BSS(%pM) now, don't update it\n",
+				prBssDesc->aucBSSID);
+		return prBssDesc;
+	}
+	/* 4 <2> Get information from Fixed Fields */
+	prBssDesc->eBSSType = eBSSType;	/* Update the latest BSS type information. */
+
+	COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr);
+
+	COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID);
+
+	prBssDesc->u8TimeStamp.QuadPart = u8Timestamp;
+
+	WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval);
+
+	prBssDesc->u2CapInfo = u2CapInfo;
+
+	/* 4 <2.1> Retrieve IEs for later parsing */
+	u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
+	    (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
+
+	if (u2IELength > CFG_IE_BUFFER_SIZE) {
+		u2IELength = CFG_IE_BUFFER_SIZE;
+		prBssDesc->fgIsIEOverflow = TRUE;
+	} else {
+		prBssDesc->fgIsIEOverflow = FALSE;
+	}
+	prBssDesc->u2IELength = u2IELength;
+
+	kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength);
+
+	/* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */
+	prBssDesc->fgIsERPPresent = FALSE;
+	prBssDesc->fgIsHTPresent = FALSE;
+	prBssDesc->eSco = CHNL_EXT_SCN;
+	prBssDesc->fgIEWAPI = FALSE;
+#if CFG_RSN_MIGRATION
+	prBssDesc->fgIERSN = FALSE;
+#endif
+#if CFG_PRIVACY_MIGRATION
+	prBssDesc->fgIEWPA = FALSE;
+#endif
+
+	/* 4 <3.1> Full IE parsing on SW_RFB_T */
+	pucIE = prWlanBeaconFrame->aucInfoElem;
+
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_SSID:
+			if ((!prIeSsid) &&	/* NOTE(Kevin): for Atheros IOT #1 */
+			    (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
+				BOOLEAN fgIsHiddenSSID = FALSE;
+
+				ucSSIDChar = '\0';
+
+				prIeSsid = (P_IE_SSID_T) pucIE;
+
+				/* D-Link DWL-900AP+ */
+				if (IE_LEN(pucIE) == 0)
+					fgIsHiddenSSID = TRUE;
+				/* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
+				/* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) &&
+				 * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
+				else {
+					for (i = 0; i < IE_LEN(pucIE); i++)
+						ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
+
+					if (!ucSSIDChar)
+						fgIsHiddenSSID = TRUE;
+				}
+
+				/* Update SSID to BSS Descriptor only if SSID is not hidden. */
+				if (!fgIsHiddenSSID) {
+					COPY_SSID(prBssDesc->aucSSID,
+						  prBssDesc->ucSSIDLen,
+						  SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength);
+				}
+#if 0
+				/*
+				   After we connect to a hidden SSID, prBssDesc->aucSSID[] will
+				   not be empty and prBssDesc->ucSSIDLen will not be 0,
+				   so maybe we need to empty prBssDesc->aucSSID[] and set
+				   prBssDesc->ucSSIDLen to 0 in prBssDesc to avoid that
+				   UI still displays hidden SSID AP in scan list after
+				   we disconnect the hidden SSID AP.
+				 */
+				else {
+					prBssDesc->aucSSID[0] = '\0';
+					prBssDesc->ucSSIDLen = 0;
+				}
+#endif
+
+			}
+			break;
+
+		case ELEM_ID_SUP_RATES:
+			/* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
+			 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
+			 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
+			 */
+			/* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */
+			if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM))
+				prIeSupportedRate = SUP_RATES_IE(pucIE);
+			break;
+
+		case ELEM_ID_DS_PARAM_SET:
+			if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET)
+				ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl;
+			break;
+
+		case ELEM_ID_TIM:
+			if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM)
+				prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod;
+			break;
+
+		case ELEM_ID_IBSS_PARAM_SET:
+			if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET)
+				prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow;
+			break;
+
+#if 0				/* CFG_SUPPORT_802_11D */
+		case ELEM_ID_COUNTRY_INFO:
+			prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE;
+			break;
+#endif
+
+		case ELEM_ID_ERP_INFO:
+			if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP)
+				prBssDesc->fgIsERPPresent = TRUE;
+			break;
+
+		case ELEM_ID_EXTENDED_SUP_RATES:
+			if (!prIeExtSupportedRate)
+				prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
+			break;
+
+#if CFG_RSN_MIGRATION
+		case ELEM_ID_RSN:
+			if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) {
+				prBssDesc->fgIERSN = TRUE;
+				prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap;
+				if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2)
+					rsnCheckPmkidCache(prAdapter, prBssDesc);
+			}
+			break;
+#endif
+
+		case ELEM_ID_HT_CAP:
+			prBssDesc->fgIsHTPresent = TRUE;
+			break;
+
+		case ELEM_ID_HT_OP:
+			if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2))
+				break;
+
+			if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
+				prBssDesc->eSco = (ENUM_CHNL_EXT_T)
+				    (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO);
+			}
+			ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel;
+
+			break;
+
+#if CFG_SUPPORT_WAPI
+		case ELEM_ID_WAPI:
+			if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI))
+				prBssDesc->fgIEWAPI = TRUE;
+			break;
+#endif
+
+		case ELEM_ID_VENDOR:	/* ELEM_ID_P2P, ELEM_ID_WMM */
+#if CFG_PRIVACY_MIGRATION
+			if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
+				if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && (u2SubTypeVersion == VERSION_WPA)) {
+
+					if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo))
+						prBssDesc->fgIEWPA = TRUE;
+				}
+			}
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+			if (prAdapter->fgIsP2PRegistered) {
+				if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
+					if (ucOuiType == VENDOR_OUI_TYPE_P2P)
+						prBssDesc->fgIsP2PPresent = TRUE;
+				}
+			}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+			break;
+
+			/* no default */
+		}
+	}
+
+	/* 4 <3.2> Save information from IEs - SSID */
+	/* Update Flag of Hidden SSID for used in SEARCH STATE. */
+
+	/* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent
+	 * all cases of hidden SSID.
+	 * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with
+	 * valid SSID.
+	 */
+	if (prBssDesc->ucSSIDLen == 0)
+		prBssDesc->fgIsHiddenSSID = TRUE;
+	else
+		prBssDesc->fgIsHiddenSSID = FALSE;
+
+	/* 4 <3.3> Check rate information in related IEs. */
+	if (prIeSupportedRate || prIeExtSupportedRate) {
+		rateGetRateSetFromIEs(prIeSupportedRate,
+				      prIeExtSupportedRate,
+				      &prBssDesc->u2OperationalRateSet,
+				      &prBssDesc->u2BSSBasicRateSet, &prBssDesc->fgIsUnknownBssBasicRate);
+	}
+	/* 4 <4> Update information from HIF RX Header */
+	{
+		prHifRxHdr = prSwRfb->prHifRxHdr;
+
+		ASSERT(prHifRxHdr);
+
+		/* 4 <4.1> Get TSF comparison result */
+		prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr);
+
+		/* 4 <4.2> Get Band information */
+		prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr);
+
+		/* 4 <4.2> Get channel and RCPI information */
+		ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr);
+
+		if (BAND_2G4 == prBssDesc->eBand) {
+
+			/* Update RCPI if in right channel */
+			if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) {
+
+				/* Receive Beacon/ProbeResp frame from adjacent channel. */
+				if ((ucIeDsChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI))
+					prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
+				/* trust channel information brought by IE */
+				prBssDesc->ucChannelNum = ucIeDsChannelNum;
+			} else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) {
+				/* Receive Beacon/ProbeResp frame from adjacent channel. */
+				if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI))
+					prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
+				/* trust channel information brought by IE */
+				prBssDesc->ucChannelNum = ucIeHtChannelNum;
+			} else {
+				prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
+
+				prBssDesc->ucChannelNum = ucHwChannelNum;
+			}
+		}
+		/* 5G Band */
+		else {
+			if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) {
+				/* Receive Beacon/ProbeResp frame from adjacent channel. */
+				if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI))
+					prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
+				/* trust channel information brought by IE */
+				prBssDesc->ucChannelNum = ucIeHtChannelNum;
+			} else {
+				/* Always update RCPI */
+				prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
+
+				prBssDesc->ucChannelNum = ucHwChannelNum;
+			}
+		}
+	}
+
+	/* 4 <5> PHY type setting */
+	prBssDesc->ucPhyTypeSet = 0;
+
+	if (BAND_2G4 == prBssDesc->eBand) {
+		/* check if support 11n */
+		if (prBssDesc->fgIsHTPresent)
+			prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
+
+		/* if not 11n only */
+		if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
+			/* check if support 11g */
+			if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) || prBssDesc->fgIsERPPresent)
+				prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
+
+			/* if not 11g only */
+			if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) {
+				/* check if support 11b */
+				if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS))
+					prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
+			}
+		}
+	} else {		/* (BAND_5G == prBssDesc->eBande) */
+		/* check if support 11n */
+		if (prBssDesc->fgIsHTPresent)
+			prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
+
+		/* if not 11n only */
+		if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
+			/* Support 11a definitely */
+			prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
+
+			ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS));
+		}
+	}
+
+	/* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */
+	GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
+
+	return prBssDesc;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query
+*
+* @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS   It is a valid Scan Result and been sent to the host.
+* @retval WLAN_STATUS_FAILURE   It is not a valid Scan Result.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb)
+{
+	P_SCAN_INFO_T prScanInfo;
+	UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
+	P_WLAN_BEACON_FRAME_T prWlanBeaconFrame;
+	PARAM_MAC_ADDRESS rMacAddr;
+	PARAM_SSID_T rSsid;
+	ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
+	PARAM_802_11_CONFIG_T rConfiguration;
+	ENUM_PARAM_OP_MODE_T eOpMode;
+	UINT_8 ucRateLen = 0;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	if (prBssDesc->eBand == BAND_2G4) {
+		if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM)
+		    || prBssDesc->fgIsERPPresent) {
+			eNetworkType = PARAM_NETWORK_TYPE_OFDM24;
+		} else {
+			eNetworkType = PARAM_NETWORK_TYPE_DS;
+		}
+	} else {
+		ASSERT(prBssDesc->eBand == BAND_5G);
+		eNetworkType = PARAM_NETWORK_TYPE_OFDM5;
+	}
+
+	if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
+		/* NOTE(Kevin): Not supported by WZC(TBD) */
+		return WLAN_STATUS_FAILURE;
+	}
+
+	prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
+	COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID);
+	COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
+
+	rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T);
+	rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval;
+	rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow;
+	rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum);
+	rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
+
+	rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen);
+
+	/* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0.
+	 * from OID_802_11_BSSID_LIST
+	 */
+	for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++)
+		aucRatesEx[i] = 0;
+
+	switch (prBssDesc->eBSSType) {
+	case BSS_TYPE_IBSS:
+		eOpMode = NET_TYPE_IBSS;
+		break;
+
+	case BSS_TYPE_INFRASTRUCTURE:
+	case BSS_TYPE_P2P_DEVICE:
+	case BSS_TYPE_BOW_DEVICE:
+	default:
+		eOpMode = NET_TYPE_INFRA;
+		break;
+	}
+
+	DBGLOG(SCN, TRACE, "ind %s %d\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum);
+
+#if (CFG_SUPPORT_TDLS == 1)
+	{
+		if (flgTdlsTestExtCapElm == TRUE) {
+			/* only for RALINK AP */
+			UINT8 *pucElm = (UINT8 *) (prSwRfb->pvHeader + prSwRfb->u2PacketLen);
+
+			kalMemCopy(pucElm - 9, aucTdlsTestExtCapElm, 7);
+			prSwRfb->u2PacketLen -= 2;
+/* prSwRfb->u2PacketLen += 7; */
+
+			DBGLOG(TDLS, INFO,
+			       "<tdls> %s: append ext cap element to %pM\n",
+				__func__, prBssDesc->aucBSSID);
+		}
+	}
+#endif /* CFG_SUPPORT_TDLS */
+
+	if (prAdapter->rWifiVar.rScanInfo.fgNloScanning &&
+				test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag)) {
+			UINT_8 i = 0;
+			P_BSS_DESC_T *pprPendBssDesc = &prScanInfo->rNloParam.aprPendingBssDescToInd[0];
+
+			for (; i < SCN_SSID_MATCH_MAX_NUM; i++) {
+				if (pprPendBssDesc[i])
+					continue;
+				DBGLOG(SCN, INFO,
+					"indicate bss[%pM] before wiphy resume, need to indicate again after wiphy resume\n",
+					prBssDesc->aucBSSID);
+				pprPendBssDesc[i] = prBssDesc;
+				break;
+			}
+	}
+
+	kalIndicateBssInfo(prAdapter->prGlueInfo,
+			   (PUINT_8) prSwRfb->pvHeader,
+			   prSwRfb->u2PacketLen, prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI));
+
+	nicAddScanResult(prAdapter,
+			 rMacAddr,
+			 &rSsid,
+			 prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0,
+			 RCPI_TO_dBm(prBssDesc->ucRCPI),
+			 eNetworkType,
+			 &rConfiguration,
+			 eOpMode,
+			 aucRatesEx,
+			 prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen,
+			 (PUINT_8) ((ULONG) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN));
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of scanAddScanResult() */
+
+#if 1
+
+BOOLEAN scanCheckBssIsLegal(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc)
+{
+	BOOLEAN fgAddToScanResult = FALSE;
+	ENUM_BAND_T eBand = 0;
+	UINT_8 ucChannel = 0;
+
+	ASSERT(prAdapter);
+	/* check the channel is in the legal doamin */
+	if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) {
+		/* check ucChannelNum/eBand for adjacement channel filtering */
+		if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE &&
+		    (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) {
+			fgAddToScanResult = FALSE;
+		} else {
+			fgAddToScanResult = TRUE;
+		}
+	}
+	return fgAddToScanResult;
+
+}
+
+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc)
+{
+	P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL;
+	P_LINK_T prBSSDescList = (P_LINK_T) NULL;
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+	RF_CHANNEL_INFO_T rChannelInfo;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	DBGLOG(SCN, TRACE, "scanReportBss2Cfg80211\n");
+
+	if (SpecificprBssDesc) {
+		{
+			/* check BSSID is legal channel */
+			if (!scanCheckBssIsLegal(prAdapter, SpecificprBssDesc)) {
+				DBGLOG(SCN, TRACE, "Remove specific SSID[%s %d]\n",
+						    SpecificprBssDesc->aucSSID, SpecificprBssDesc->ucChannelNum);
+				return;
+			}
+
+			DBGLOG(SCN, TRACE, "Report Specific SSID[%s]\n", SpecificprBssDesc->aucSSID);
+			if (eBSSType == BSS_TYPE_INFRASTRUCTURE) {
+
+				kalIndicateBssInfo(prAdapter->prGlueInfo,
+						   (PUINT_8) SpecificprBssDesc->aucRawBuf,
+						   SpecificprBssDesc->u2RawLength,
+						   SpecificprBssDesc->ucChannelNum,
+						   RCPI_TO_dBm(SpecificprBssDesc->ucRCPI));
+			} else {
+
+				rChannelInfo.ucChannelNum = SpecificprBssDesc->ucChannelNum;
+				rChannelInfo.eBand = SpecificprBssDesc->eBand;
+				kalP2PIndicateBssInfo(prAdapter->prGlueInfo,
+						      (PUINT_8) SpecificprBssDesc->aucRawBuf,
+						      SpecificprBssDesc->u2RawLength,
+						      &rChannelInfo, RCPI_TO_dBm(SpecificprBssDesc->ucRCPI));
+
+			}
+
+#if CFG_ENABLE_WIFI_DIRECT
+			SpecificprBssDesc->fgIsP2PReport = FALSE;
+#endif
+		}
+	} else {
+		/* Search BSS Desc from current SCAN result list. */
+		LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+			/* 4 Auto Channel Selection:Record the AP Number */
+			P_PARAM_CHN_LOAD_INFO prChnLoad;
+			UINT_8 ucIdx = 0;
+
+			if (((prBssDesc->ucChannelNum > 0) && (prBssDesc->ucChannelNum <= 48))
+			    || (prBssDesc->ucChannelNum >= 147) /*non-DFS Channel */) {
+				if (prBssDesc->ucChannelNum <= HW_CHNL_NUM_MAX_2G4) {
+					ucIdx = prBssDesc->ucChannelNum - 1;
+				} else if (prBssDesc->ucChannelNum <= 48) {
+					ucIdx = (UINT_8) (HW_CHNL_NUM_MAX_2G4 + (prBssDesc->ucChannelNum - 34) / 4);
+				} else {
+					ucIdx =
+					    (UINT_8) (HW_CHNL_NUM_MAX_2G4 + 4 + (prBssDesc->ucChannelNum - 149) / 4);
+				}
+
+				if (ucIdx < MAX_AUTO_CHAL_NUM) {
+					prChnLoad = (P_PARAM_CHN_LOAD_INFO) &
+						(prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]);
+					prChnLoad->ucChannel = prBssDesc->ucChannelNum;
+					prChnLoad->u2APNum++;
+				} else {
+					DBGLOG(SCN, WARN, "ACS: ChIdx > MAX_AUTO_CHAL_NUM\n");
+				}
+
+			}
+#endif
+			/* check BSSID is legal channel */
+			if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) {
+				DBGLOG(SCN, TRACE, "Remove SSID[%s %d]\n",
+						    prBssDesc->aucSSID, prBssDesc->ucChannelNum);
+
+				continue;
+			}
+
+			if ((prBssDesc->eBSSType == eBSSType)
+#if CFG_ENABLE_WIFI_DIRECT
+			    || ((eBSSType == BSS_TYPE_P2P_DEVICE) && (prBssDesc->fgIsP2PReport == TRUE))
+#endif
+			    ) {
+
+				DBGLOG(SCN, TRACE, "Report ALL SSID[%s %d]\n",
+						    prBssDesc->aucSSID, prBssDesc->ucChannelNum);
+
+				if (eBSSType == BSS_TYPE_INFRASTRUCTURE) {
+					if (prBssDesc->u2RawLength != 0) {
+						kalIndicateBssInfo(prAdapter->prGlueInfo,
+								   (PUINT_8) prBssDesc->aucRawBuf,
+								   prBssDesc->u2RawLength,
+								   prBssDesc->ucChannelNum,
+								   RCPI_TO_dBm(prBssDesc->ucRCPI));
+						kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE);
+						prBssDesc->u2RawLength = 0;
+
+#if CFG_ENABLE_WIFI_DIRECT
+						prBssDesc->fgIsP2PReport = FALSE;
+#endif
+					}
+				} else {
+#if CFG_ENABLE_WIFI_DIRECT
+					if (prBssDesc->fgIsP2PReport == TRUE) {
+#endif
+						rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum;
+						rChannelInfo.eBand = prBssDesc->eBand;
+
+						kalP2PIndicateBssInfo(prAdapter->prGlueInfo,
+								      (PUINT_8) prBssDesc->aucRawBuf,
+								      prBssDesc->u2RawLength,
+								      &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI));
+
+						/* do not clear it then we can pass the bss in Specific report */
+						/* kalMemZero(prBssDesc->aucRawBuf,CFG_RAW_BUFFER_SIZE); */
+
+						/*
+						   the BSS entry will not be cleared after scan done.
+						   So if we dont receive the BSS in next scan, we cannot
+						   pass it. We use u2RawLength for the purpose.
+						 */
+						/* prBssDesc->u2RawLength=0; */
+#if CFG_ENABLE_WIFI_DIRECT
+						prBssDesc->fgIsP2PReport = FALSE;
+					}
+#endif
+				}
+			}
+
+		}
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+		prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = TRUE;
+#endif
+
+	}
+
+}
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Parse the content of given Beacon or ProbeResp Frame.
+*
+* @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
+*
+* @retval WLAN_STATUS_SUCCESS           if not report this SW_RFB_T to host
+* @retval WLAN_STATUS_PENDING           if report this SW_RFB_T to host as scan result
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	P_BSS_INFO_T prAisBssInfo;
+	P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL;
+#if CFG_SLT_SUPPORT
+	P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL;
+#endif
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	/* 4 <0> Ignore invalid Beacon Frame */
+	if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
+		(TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) {
+		/* to debug beacon length too small issue */
+		UINT_32 u4MailBox0;
+
+		nicGetMailbox(prAdapter, 0, &u4MailBox0);
+		DBGLOG(SCN, WARN, "if conn sys also get less length (0x5a means yes) %x\n", (UINT_32) u4MailBox0);
+		DBGLOG(SCN, WARN, "u2PacketLen %d, u2HeaderLen %d, payloadLen %d\n",
+			prSwRfb->u2PacketLen, prSwRfb->u2HeaderLen,
+			prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen);
+		/* dumpMemory8(prSwRfb->pvHeader, prSwRfb->u2PacketLen); */
+
+#ifndef _lint
+		ASSERT(0);
+#endif /* _lint */
+		return rStatus;
+	}
+#if CFG_SLT_SUPPORT
+	prSltInfo = &prAdapter->rWifiVar.rSltInfo;
+
+	if (prSltInfo->fgIsDUT) {
+		DBGLOG(SCN, INFO, "\n\rBCN: RX\n");
+		prSltInfo->u4BeaconReceiveCnt++;
+		return WLAN_STATUS_SUCCESS;
+	} else {
+		return WLAN_STATUS_SUCCESS;
+	}
+#endif
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
+
+	/*ALPS01475157: don't show SSID on scan list for multicast MAC AP */
+	if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr)) {
+		DBGLOG(SCN, WARN, "received beacon/probe response from multicast AP\n");
+		return rStatus;
+	}
+
+	/* 4 <1> Parse and add into BSS_DESC_T */
+	prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb);
+
+	if (prBssDesc) {
+		/* 4 <1.1> Beacon Change Detection for Connected BSS */
+		if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
+		    ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
+		     || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) &&
+		    EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
+		    EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID,
+			       prAisBssInfo->ucSSIDLen)) {
+			BOOLEAN fgNeedDisconnect = FALSE;
+
+#if CFG_SUPPORT_BEACON_CHANGE_DETECTION
+			/* <1.1.2> check if supported rate differs */
+			if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet)
+				fgNeedDisconnect = TRUE;
+#endif
+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE
+			if (
+#if CFG_SUPPORT_WAPI
+			(prAdapter->rWifiVar.rConnSettings.fgWapiMode == TRUE &&
+			!wapiPerformPolicySelection(prAdapter, prBssDesc)) ||
+#endif
+			rsnCheckSecurityModeChanged(prAdapter, prAisBssInfo, prBssDesc)) {
+				DBGLOG(SCN, INFO, "Beacon security mode change detected\n");
+				fgNeedDisconnect = FALSE;
+				aisBssSecurityChanged(prAdapter);
+			}
+#endif
+
+			/* <1.1.3> beacon content change detected, disconnect immediately */
+			if (fgNeedDisconnect == TRUE)
+				aisBssBeaconTimeout(prAdapter);
+		}
+		/* 4 <1.1> Update AIS_BSS_INFO */
+		if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
+		     || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) {
+			if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+				/* *not* checking prBssDesc->fgIsConnected anymore,
+				 * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */
+				if ((!prAisBssInfo->ucDTIMPeriod) &&
+				    EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
+				    (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
+				    ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) {
+
+					prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
+
+					/* sync with firmware for beacon information */
+					nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
+				}
+			}
+#if CFG_SUPPORT_ADHOC
+			if (EQUAL_SSID(prBssDesc->aucSSID,
+				prBssDesc->ucSSIDLen,
+				prConnSettings->aucSSID,
+				prConnSettings->ucSSIDLen) &&
+			    (prBssDesc->eBSSType == BSS_TYPE_IBSS) && (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) {
+				ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc,
+							 prSwRfb->prHifRxHdr->ucRcpi);
+			}
+#endif /* CFG_SUPPORT_ADHOC */
+		}
+
+		rlmProcessBcn(prAdapter,
+			      prSwRfb,
+			      ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem,
+			      (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
+			      (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0])));
+
+		/* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */
+		if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE || prBssDesc->eBSSType == BSS_TYPE_IBSS) {
+			/* for AIS, send to host */
+			if (prConnSettings->fgIsScanReqIssued || prAdapter->rWifiVar.rScanInfo.fgNloScanning) {
+				BOOLEAN fgAddToScanResult;
+
+				fgAddToScanResult = scanCheckBssIsLegal(prAdapter, prBssDesc);
+
+				if (fgAddToScanResult == TRUE)
+					rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb);
+			}
+		}
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered)
+			scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, &rStatus, prBssDesc, prWlanBeaconFrame);
+#endif
+	}
+
+	return rStatus;
+
+}				/* end of scanProcessBeaconAndProbeResp() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or
+*        MERGE(AdHoc) according to current Connection Policy.
+*
+* \return   Pointer to BSS Descriptor, if found. NULL, if not found
+*/
+/*----------------------------------------------------------------------------*/
+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+	P_BSS_INFO_T prBssInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+	P_SCAN_INFO_T prScanInfo;
+
+	P_LINK_T prBSSDescList;
+
+	P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
+	P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL;
+	P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL;
+
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+	P_STA_RECORD_T prPrimaryStaRec;
+	P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL;
+
+	OS_SYSTIME rCurrentTime;
+
+	/* The first one reach the check point will be our candidate */
+	BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE;
+
+	BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE;
+	BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE;
+	/* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */
+
+	/* TODO(Kevin): Support Min Channel Load */
+	/* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */
+
+	BOOLEAN fgIsFixedChannel;
+	ENUM_BAND_T eBand = 0;
+	UINT_8 ucChannel = 0;
+
+	ASSERT(prAdapter);
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
+
+	prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	GET_CURRENT_SYSTIME(&rCurrentTime);
+
+	/* check for fixed channel operation */
+	if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
+#if CFG_P2P_LEGACY_COEX_REVISE
+		fgIsFixedChannel = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel);
+#else
+		fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel);
+#endif
+	} else {
+		fgIsFixedChannel = FALSE;
+	}
+
+#if DBG
+	if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID)
+		prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0';
+#endif
+
+	DBGLOG(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, %pM Band=%d, channel=%d\n",
+			   (UINT_32) prBSSDescList->u4NumElem, prConnSettings->aucSSID,
+			   (prConnSettings->aucBSSID), eBand, ucChannel);
+
+	/* 4 <1> The outer loop to search for a candidate. */
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+
+		/* TODO(Kevin): Update Minimum Channel Load Information here */
+
+		DBGLOG(SCN, TRACE, "SEARCH: [ %pM ], SSID:%s\n",
+				   prBssDesc->aucBSSID, prBssDesc->aucSSID);
+
+		/* 4 <2> Check PHY Type and attributes */
+		/* 4 <2.1> Check Unsupported BSS PHY Type */
+		if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
+			DBGLOG(SCN, TRACE, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", prBssDesc->ucPhyTypeSet);
+			continue;
+		}
+		/* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */
+		if (prBssDesc->fgIsUnknownBssBasicRate)
+			continue;
+		/* 4 <2.3> Check if fixed operation cases should be aware */
+		if (fgIsFixedChannel == TRUE && (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel))
+			continue;
+		/* 4 <2.4> Check if the channel is legal under regulatory domain */
+		if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE)
+			continue;
+		/* 4 <2.5> Check if this BSS_DESC_T is stale */
+		if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
+				      SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) {
+
+			BOOLEAN fgIsNeedToCheckTimeout = TRUE;
+
+#if CFG_SUPPORT_ROAMING
+			P_ROAMING_INFO_T prRoamingFsmInfo;
+
+			prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
+			if ((prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) ||
+			    (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) {
+				if (++prRoamingFsmInfo->RoamingEntryTimeoutSkipCount <
+				    ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX) {
+					fgIsNeedToCheckTimeout = FALSE;
+					DBGLOG(SCN, INFO, "SEARCH: Romaing skip SCN_BSS_DESC_REMOVE_TIMEOUT_SEC\n");
+				}
+			}
+#endif
+
+			if (fgIsNeedToCheckTimeout == TRUE) {
+				DBGLOG(SCN, TRACE, "Ignore stale bss %pM\n", prBssDesc->aucBSSID);
+				continue;
+			}
+		}
+		/* 4 <3> Check if reach the excessive join retry limit */
+		/* NOTE(Kevin): STA_RECORD_T is recorded by TA. */
+		prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr);
+
+		if (prStaRec) {
+			/* NOTE(Kevin):
+			 * The Status Code is the result of a Previous Connection Request,
+			 * we use this as SCORE for choosing a proper
+			 * candidate (Also used for compare see <6>)
+			 * The Reason Code is an indication of the reason why AP reject us,
+			 * we use this Code for "Reject"
+			 * a SCAN result to become our candidate(Like a blacklist).
+			 */
+#if 0				/* TODO(Kevin): */
+			if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) {
+				DBGLOG(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n",
+						   prStaRec->u2ReasonCode);
+				continue;
+			} else
+#endif
+			if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
+				/* NOTE(Kevin): greedy association - after timeout, we'll still
+				 * try to associate to the AP whose STATUS of conection attempt
+				 * was not success.
+				 * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for
+				 * time bound.
+				 */
+				if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) ||
+				    (CHECK_FOR_TIMEOUT(rCurrentTime,
+						       prStaRec->rLastJoinTime,
+						       SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) {
+
+					/* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry
+					 * JOIN_MAX_RETRY_FAILURE_COUNT times.
+					 */
+					if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT)
+						prStaRec->ucJoinFailureCount = 0;
+					DBGLOG(SCN, INFO,
+					       "SEARCH: Try to join BSS again,Status Code=%d (Curr=%u/Last Join=%u)\n",
+						prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime);
+				} else {
+					DBGLOG(SCN, INFO,
+					       "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n",
+						JOIN_MAX_RETRY_FAILURE_COUNT);
+					continue;
+				}
+
+			}
+		}
+		/* 4 <4> Check for various NETWORK conditions */
+		if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
+
+			/* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */
+			/* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */
+			if (((prConnSettings->eOPMode == NET_TYPE_INFRA) &&
+			     (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE))
+#if CFG_SUPPORT_ADHOC
+			     || ((prConnSettings->eOPMode == NET_TYPE_IBSS
+			      || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)
+			     && (prBssDesc->eBSSType != BSS_TYPE_IBSS))
+#endif
+			     ) {
+
+				DBGLOG(SCN, TRACE, "Cur OPMode %d, Ignore eBSSType = %d\n",
+						prConnSettings->eOPMode, prBssDesc->eBSSType);
+				continue;
+			}
+			/* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */
+			if ((prConnSettings->fgIsConnByBssidIssued) &&
+				(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) {
+
+				if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) {
+
+					DBGLOG(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n");
+					continue;
+				}
+			}
+#if CFG_SUPPORT_ADHOC
+			/* 4 <4.3> Check for AdHoc Mode */
+			if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
+				OS_SYSTIME rCurrentTime;
+
+				/* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */
+				/* NOTE(Kevin): Because some STA may change its BSSID frequently after it
+				 * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one.
+				 * For BSS, if the old record was matched, however it won't be able to pass
+				 * the Join Process later.
+				 */
+				GET_CURRENT_SYSTIME(&rCurrentTime);
+				if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
+						      SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) {
+					DBGLOG(SCN, LOUD,
+						"SEARCH: Skip old record of BSS Descriptor - BSSID:[%pM]\n\n",
+						prBssDesc->aucBSSID);
+					continue;
+				}
+				/* 4 <4.3.2> Check Peer's capability */
+				if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
+
+					if (prPrimaryBssDesc)
+						DBGLOG(SCN, INFO,
+							"SEARCH: BSS DESC MAC: %pM, not supported AdHoc Mode.\n",
+							prPrimaryBssDesc->aucBSSID);
+
+					continue;
+				}
+				/* 4 <4.3.3> Compare TSF */
+				if (prBssInfo->fgIsBeaconActivated &&
+				    UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) {
+
+					DBGLOG(SCN, LOUD,
+					       "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", prBssDesc->fgIsLargerTSF);
+
+					if (!prBssDesc->fgIsLargerTSF) {
+						DBGLOG(SCN, INFO,
+						       "SEARCH: Ignore BSS DESC MAC: [ %pM ], Smaller TSF\n",
+							prBssDesc->aucBSSID);
+						continue;
+					}
+				}
+			}
+#endif /* CFG_SUPPORT_ADHOC */
+
+		}
+#if 0				/* TODO(Kevin): For IBSS */
+		/* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */
+		/* NOTE(Kevin): Because some STA may change its BSSID frequently after it
+		 * create the IBSS, so we need to make sure we get the new one.
+		 * For BSS, if the old record was matched, however it won't be able to pass
+		 * the Join Process later.
+		 */
+		if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
+			OS_SYSTIME rCurrentTime;
+
+			GET_CURRENT_SYSTIME(&rCurrentTime);
+			if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
+					      SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
+				DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n",
+						     prBssDesc->aucBSSID);
+				continue;
+			}
+		}
+
+		if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) &&
+		    (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) {
+			OS_SYSTIME rCurrentTime;
+
+			GET_CURRENT_SYSTIME(&rCurrentTime);
+			if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
+					      SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
+				DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n",
+						     (prBssDesc->aucBSSID));
+				continue;
+			}
+		}
+		/* 4 <4B> Check for IBSS AdHoc Mode. */
+		/* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */
+		if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) {
+			/* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */
+			if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) {
+
+				DBGLOG(SCAN, TRACE,
+				       "Ignore BSS DESC MAC: %pM, Capability not supported for AdHoc Mode.\n",
+					prPrimaryBssDesc->aucBSSID);
+
+				continue;
+			}
+			/* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */
+			if (prAdapter->fgIsIBSSActive &&
+			    UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) {
+
+				if (!fgIsLocalTSFRead) {
+					NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf);
+
+					DBGLOG(SCAN, TRACE,
+					       "\n\nCurrent TSF : %08lx-%08lx\n\n",
+						rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart);
+				}
+
+				if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) {
+					DBGLOG(SCAN, TRACE,
+					       "Ignore BSS DESC MAC: [%pM], Current BSSID: [%pM].\n",
+						prPrimaryBssDesc->aucBSSID, prBssInfo->aucBSSID);
+
+					DBGLOG(SCAN, TRACE,
+					       "\n\nBSS's TSF : %08lx-%08lx\n\n",
+						prPrimaryBssDesc->u8TimeStamp.u.HighPart,
+						prPrimaryBssDesc->u8TimeStamp.u.LowPart);
+
+					prPrimaryBssDesc->fgIsLargerTSF = FALSE;
+					continue;
+				} else {
+					prPrimaryBssDesc->fgIsLargerTSF = TRUE;
+				}
+
+			}
+		}
+		/* 4 <5> Check the Encryption Status. */
+		if (rsnPerformPolicySelection(prPrimaryBssDesc)) {
+
+			if (prPrimaryBssDesc->ucEncLevel > 0) {
+				fgIsFindBestEncryptionLevel = TRUE;
+
+				fgIsFindFirst = FALSE;
+			}
+		} else {
+			/* Can't pass the Encryption Status Check, get next one */
+			continue;
+		}
+
+		/* For RSN Pre-authentication, update the PMKID canidate list for
+		   same SSID and encrypt status */
+		/* Update PMKID candicate list. */
+		if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
+			rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
+			if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount)
+				prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate();
+		}
+#endif
+
+		prPrimaryBssDesc = (P_BSS_DESC_T) NULL;
+
+		/* 4 <6> Check current Connection Policy. */
+		switch (prConnSettings->eConnectionPolicy) {
+		case CONNECT_BY_SSID_BEST_RSSI:
+			/* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */
+			if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) {
+				/* NOTE(Kevin): following if () statement means that
+				 * If Target is hidden, then we won't connect when user specify SSID_ANY policy.
+				 */
+				if (prConnSettings->ucSSIDLen) {
+					prPrimaryBssDesc = prBssDesc;
+					fgIsFindBestRSSI = TRUE;
+				}
+
+			} else if (EQUAL_SSID(prBssDesc->aucSSID,
+					      prBssDesc->ucSSIDLen,
+					      prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
+				prPrimaryBssDesc = prBssDesc;
+				fgIsFindBestRSSI = TRUE;
+
+				DBGLOG(SCN, TRACE, "SEARCH: fgIsFindBestRSSI=TRUE, %d, prPrimaryBssDesc=[ %pM ]\n",
+						   prBssDesc->ucRCPI, prPrimaryBssDesc->aucBSSID);
+			}
+			break;
+
+		case CONNECT_BY_SSID_ANY:
+			/* NOTE(Kevin): In this policy, we don't know the desired
+			 * SSID from user, so we should exclude the Hidden SSID from scan list.
+			 * And because we refuse to connect to Hidden SSID node at the beginning, so
+			 * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE,
+			 * then the Connection Settings must be valid without doubt.
+			 */
+			if (!prBssDesc->fgIsHiddenSSID) {
+				prPrimaryBssDesc = prBssDesc;
+				fgIsFindFirst = TRUE;
+			}
+			break;
+
+		case CONNECT_BY_BSSID:
+			if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID))
+				prPrimaryBssDesc = prBssDesc;
+			break;
+
+		default:
+			break;
+		}
+
+		/* Primary Candidate was not found */
+		if (prPrimaryBssDesc == NULL)
+			continue;
+		/* 4 <7> Check the Encryption Status. */
+		if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
+#if CFG_SUPPORT_WAPI
+			if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
+				DBGLOG(SCN, TRACE, "SEARCH: fgWapiMode == 1\n");
+
+				if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
+					fgIsFindFirst = TRUE;
+				} else {
+					/* Can't pass the Encryption Status Check, get next one */
+					DBGLOG(SCN, TRACE, "SEARCH: WAPI cannot pass the Encryption Status Check!\n");
+					continue;
+				}
+			} else
+#endif
+#if CFG_RSN_MIGRATION
+			if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
+				if (prAisSpecBssInfo->fgCounterMeasure) {
+					DBGLOG(RSN, INFO, "Skip while at counter measure period!!!\n");
+					continue;
+				}
+
+				if (prPrimaryBssDesc->ucEncLevel > 0) {
+					fgIsFindBestEncryptionLevel = TRUE;
+					fgIsFindFirst = FALSE;
+				}
+#if 0
+			/* Update PMKID candicate list. */
+			if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
+				rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
+				if (prAisSpecBssInfo->u4PmkidCandicateCount) {
+					if (rsnCheckPmkidCandicate()) {
+						DBGLOG(RSN, WARN,
+						       "Prepare a timer to indicate candidate %pM\n",
+							(prAisSpecBssInfo->arPmkidCache
+								[prAisSpecBssInfo->u4PmkidCacheCount].
+								rBssidInfo.aucBssid)));
+						cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer);
+						cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer,
+								   SEC_TO_MSEC
+								   (WAIT_TIME_IND_PMKID_CANDICATE_SEC));
+					}
+				}
+			}
+#endif
+			} else {
+				/* Can't pass the Encryption Status Check, get next one */
+				continue;
+			}
+#endif
+		} else {
+			/* Todo:: P2P and BOW Policy Selection */
+		}
+
+		prPrimaryStaRec = prStaRec;
+
+		/* 4 <8> Compare the Candidate and the Primary Scan Record. */
+		if (!prCandidateBssDesc) {
+			prCandidateBssDesc = prPrimaryBssDesc;
+			prCandidateStaRec = prPrimaryStaRec;
+
+			/* 4 <8.1> Condition - Get the first matched one. */
+			if (fgIsFindFirst)
+				break;
+		} else {
+#if 0				/* TODO(Kevin): For security(TBD) */
+	/* 4 <6B> Condition - Choose the one with best Encryption Score. */
+	if (fgIsFindBestEncryptionLevel) {
+		if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) {
+
+			prCandidateBssDesc = prPrimaryBssDesc;
+			prCandidateStaRec = prPrimaryStaRec;
+			continue;
+		}
+	}
+
+	/* If reach here, that means they have the same Encryption Score.
+	 */
+
+	/* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */
+	/* For roaming, only compare the candidates other than current associated BSSID. */
+	if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) {
+		if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) &&
+		    (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
+
+			DBGLOG(SCAN, TRACE,
+			       "So far -BSS DESC MAC: %pM has nonzero Status Code = %d\n",
+				prCandidateBssDesc->aucBSSID,
+				prCandidateStaRec->u2StatusCode);
+
+			if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) {
+				if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
+
+					/* Give opportunity to the one with smaller rLastJoinTime */
+					if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime,
+							prPrimaryStaRec->rLastJoinTime)) {
+						continue;
+					}
+					/* We've connect to CANDIDATE recently,
+					 * let us try PRIMARY now */
+					else {
+						prCandidateBssDesc = prPrimaryBssDesc;
+						prCandidateStaRec = prPrimaryStaRec;
+						continue;
+					}
+				}
+				/* PRIMARY's u2StatusCode = 0 */
+				else {
+					prCandidateBssDesc = prPrimaryBssDesc;
+					prCandidateStaRec = prPrimaryStaRec;
+					continue;
+				}
+			}
+			/* PRIMARY has no StaRec - We didn't connet to PRIMARY before */
+			else {
+				prCandidateBssDesc = prPrimaryBssDesc;
+				prCandidateStaRec = prPrimaryStaRec;
+				continue;
+			}
+		} else {
+			if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) &&
+			    (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
+				continue;
+			}
+		}
+	}
+#endif
+
+			/* 4 <6D> Condition - Visible SSID win Hidden SSID. */
+			if (prCandidateBssDesc->fgIsHiddenSSID) {
+				if (!prPrimaryBssDesc->fgIsHiddenSSID) {
+					prCandidateBssDesc = prPrimaryBssDesc;	/* The non Hidden SSID win. */
+					prCandidateStaRec = prPrimaryStaRec;
+					continue;
+				}
+			} else {
+				if (prPrimaryBssDesc->fgIsHiddenSSID)
+					continue;
+			}
+
+			/* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */
+			if (fgIsFindBestRSSI) {
+				/* TODO(Kevin): We shouldn't compare the actual value, we should
+				 * allow some acceptable tolerance of some RSSI percentage here.
+				 */
+			DBGLOG(SCN, TRACE,
+			"Candidate [%pM]: RCPI = %d, joinFailCnt=%d, Primary [%pM]: RCPI = %d, joinFailCnt=%d\n",
+					prCandidateBssDesc->aucBSSID,
+					prCandidateBssDesc->ucRCPI, prCandidateBssDesc->ucJoinFailureCount,
+					prPrimaryBssDesc->aucBSSID,
+					prPrimaryBssDesc->ucRCPI, prPrimaryBssDesc->ucJoinFailureCount);
+
+				ASSERT(!(prCandidateBssDesc->fgIsConnected && prPrimaryBssDesc->fgIsConnected));
+				if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) {
+					/* give a chance to do join if join fail before
+					 * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC seconds
+					 */
+					if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rJoinFailTime,
+							SEC_TO_SYSTIME(SCN_BSS_JOIN_FAIL_CNT_RESET_SEC))) {
+						prBssDesc->ucJoinFailureCount = SCN_BSS_JOIN_FAIL_THRESOLD -
+										SCN_BSS_JOIN_FAIL_RESET_STEP;
+						DBGLOG(SCN, INFO,
+						"decrease join fail count for Bss %pM to %u, timeout second %d\n",
+							prBssDesc->aucBSSID, prBssDesc->ucJoinFailureCount,
+							SCN_BSS_JOIN_FAIL_CNT_RESET_SEC);
+					}
+				}
+
+				/* NOTE: To prevent SWING,
+				 * we do roaming only if target AP has at least 5dBm larger than us. */
+				if (prCandidateBssDesc->fgIsConnected) {
+					if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <=
+						prPrimaryBssDesc->ucRCPI &&
+						prPrimaryBssDesc->ucJoinFailureCount < SCN_BSS_JOIN_FAIL_THRESOLD) {
+
+						prCandidateBssDesc = prPrimaryBssDesc;
+						prCandidateStaRec = prPrimaryStaRec;
+						continue;
+					}
+				} else if (prPrimaryBssDesc->fgIsConnected) {
+					if (prCandidateBssDesc->ucRCPI <
+					(prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) ||
+						(prCandidateBssDesc->ucJoinFailureCount >=
+						SCN_BSS_JOIN_FAIL_THRESOLD)) {
+						prCandidateBssDesc = prPrimaryBssDesc;
+						prCandidateStaRec = prPrimaryStaRec;
+						continue;
+					}
+				} else if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD)
+					continue;
+				else if (prCandidateBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD ||
+					prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) {
+					prCandidateBssDesc = prPrimaryBssDesc;
+					prCandidateStaRec = prPrimaryStaRec;
+					continue;
+				}
+			}
+#if 0
+			/* If reach here, that means they have the same Encryption Score, and
+			 * both RSSI value are close too.
+			 */
+			/* 4 <6F> Seek the minimum Channel Load for less interference. */
+			if (fgIsFindMinChannelLoad) {
+				/* Do nothing */
+				/* TODO(Kevin): Check which one has minimum channel load in its channel */
+			}
+#endif
+		}
+	}
+
+
+	if (prCandidateBssDesc != NULL) {
+		DBGLOG(SCN, INFO,
+		       "SEARCH: Candidate BSS: %pM\n", prCandidateBssDesc->aucBSSID);
+	}
+
+	return prCandidateBssDesc;
+
+} /* end of scanSearchBssDescByPolicy() */
+
+#if CFG_SUPPORT_AGPS_ASSIST
+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter)
+{
+	P_LINK_T prBSSDescList = &prAdapter->rWifiVar.rScanInfo.rBSSDescList;
+	P_BSS_DESC_T prBssDesc = NULL;
+	P_AGPS_AP_LIST_T prAgpsApList;
+	P_AGPS_AP_INFO_T prAgpsInfo;
+	P_SCAN_INFO_T prScanInfo = &prAdapter->rWifiVar.rScanInfo;
+	UINT_8 ucIndex = 0;
+
+	prAgpsApList = kalMemAlloc(sizeof(AGPS_AP_LIST_T), VIR_MEM_TYPE);
+	if (!prAgpsApList)
+		return;
+
+	prAgpsInfo = &prAgpsApList->arApInfo[0];
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+		if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime)
+			continue;
+		COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID);
+		prAgpsInfo->ePhyType = AGPS_PHY_G;
+		prAgpsInfo->u2Channel = prBssDesc->ucChannelNum;
+		prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI);
+		prAgpsInfo++;
+		ucIndex++;
+		if (ucIndex == 32)
+			break;
+	}
+	prAgpsApList->ucNum = ucIndex;
+	GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime);
+	/* DBGLOG(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */
+	kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, (PUINT_8) prAgpsApList, sizeof(AGPS_AP_LIST_T));
+	kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(AGPS_AP_LIST_T));
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c
new file mode 100644
index 0000000000000..fac9f94428dd9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c
@@ -0,0 +1,2136 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#1
+*/
+
+/*! \file   "scan_fsm.c"
+    \brief  This file defines the state transition function for SCAN FSM.
+
+    The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN
+    behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 .
+*/
+
+/*
+** Log: scan_fsm.c
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 14 2011 yuche.tsai
+ * [WCXRP00001095] [Volunteer Patch][Driver] Always Scan before enable Hot-Spot.
+ * Fix bug when unregister P2P network..
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 08 11 2011 cp.wu
+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
+ * sparse channel detection:
+ * driver: collect sparse channel information with scan-done event
+ *
+ * 07 18 2011 cp.wu
+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search
+ * for more than one SSID in a single scanning request
+ * free mailbox message afte parsing is completed.
+ *
+ * 07 18 2011 cp.wu
+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search
+ * for more than one SSID in a single scanning request
+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support
+ * as well as uProbeDelay in NDIS 6.x driver model
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 03 29 2011 cp.wu
+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning
+ * surpress klock warning with code path rewritten
+ *
+ * 03 18 2011 cm.chang
+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command
+ * As CR title
+ *
+ * 02 18 2011 yuche.tsai
+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame
+ * during search phase do not contain P2P wildcard SSID.
+ * Take P2P wildcard SSID into consideration.
+ *
+ * 01 27 2011 yuche.tsai
+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
+ * Fix scan channel extension issue when p2p module is not registered.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Fix Compile Error when DBG is disabled.
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * add interface for RLM to trigger OBSS-SCAN.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Fix bug for processing queued scan request.
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add a function for returning channel.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Update SCAN FSM for support P2P Device discovery scan.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Add option of channel extension while cancelling scan request.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add P2P Scan & Scan Result Parsing & Saving.
+ *
+ * 07 20 2010 cp.wu
+ *
+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8..
+ *
+ * 07 19 2010 cp.wu
+ *
+ * due to FW/DRV won't be sync. precisely, some strict assertions should be eased.
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * SCN module is now able to handle multiple concurrent scanning requests
+ *
+ * 07 16 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * bugfix for SCN migration
+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue
+ * 2) before AIS issues scan request, network(BSS) needs to be activated first
+ * 3) only invoke COPY_SSID when using specified SSID for scan
+ *
+ * 07 15 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * driver no longer generates probe request frames
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * pass band with channel number information as scan parameter
+ *
+ * 07 14 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * remove timer in DRV-SCN.
+ *
+ * 07 09 2010 cp.wu
+ *
+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
+ * 3) implment DRV-SCN module, currently only accepts single scan request,
+ * other request will be directly dropped by returning BUSY
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * take use of RLM module for parsing/generating HT IEs for 11n capability
+ *
+ * 07 02 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * when returning to SCAN_IDLE state, send a correct message to source FSM.
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * comment out RLM APIs by CFG_RLM_MIGRATION.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add scan_fsm into building.
+ *
+ * 05 14 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine the order of Stop TX Queue and Switch Channel
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Update pause/resume/flush API to new Bitmap API
+ *
+ * 05 12 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Add Power Management - Legacy PS-POLL support.
+ *
+ * 03 18 2010 kevin.huang
+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
+ * Ignore the PROBE_DELAY state if the value of Probe Delay == 0
+ *
+ * 03 10 2010 kevin.huang
+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
+ * Add Channel Manager for arbitration of JOIN and SCAN Req
+ *
+ * 02 23 2010 kevin.huang
+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
+ *
+ * 01 08 2010 kevin.huang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * Add set RX Filter to receive BCN from different BSSID during SCAN
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Nov 25 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Remove flag of CFG_TEST_MGMT_FSM
+ *
+ * Nov 20 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Change parameter of scanSendProbeReqFrames()
+ *
+ * Nov 16 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Update scnFsmSteps()
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ * Fix typo
+ *
+ * Nov 5 2009 mtk01461
+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if DBG
+/*lint -save -e64 Type mismatch */
+static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = {
+	(PUINT_8) DISP_STRING("SCAN_STATE_IDLE"),
+	(PUINT_8) DISP_STRING("SCAN_STATE_SCANNING"),
+};
+
+/*lint -restore */
+#endif /* DBG */
+
+#define CURRENT_PSCN_VERSION 1
+#define RSSI_MARGIN_DEFAULT  5
+#define MAX_PERIOD 200000
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	P_MSG_HDR_T prMsgHdr;
+
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	do {
+
+#if DBG
+		DBGLOG(SCN, STATE, "TRANSITION: [%s] -> [%s]\n",
+				    apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState]);
+#else
+		DBGLOG(SCN, STATE, "[%d] TRANSITION: [%d] -> [%d]\n",
+				    DBG_SCN_IDX, prScanInfo->eCurrentState, eNextState);
+#endif
+
+		/* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */
+		prScanInfo->eCurrentState = eNextState;
+
+		fgIsTransition = (BOOLEAN) FALSE;
+
+		switch (prScanInfo->eCurrentState) {
+		case SCAN_STATE_IDLE:
+			/* check for pending scanning requests */
+			if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) {
+				/* load next message from pending list as scan parameters */
+				LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T);
+
+				if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ
+				    || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ
+				    || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ
+				    || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) {
+					scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr);
+				} else {
+					scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr);
+				}
+
+				/* switch to next state */
+				eNextState = SCAN_STATE_SCANNING;
+				fgIsTransition = TRUE;
+
+				cnmMemFree(prAdapter, prMsgHdr);
+			}
+			break;
+
+		case SCAN_STATE_SCANNING:
+			if (prScanParam->fgIsScanV2 == FALSE)
+				scnSendScanReq(prAdapter);
+			else
+				scnSendScanReqV2(prAdapter);
+			break;
+
+		default:
+			ASSERT(0);
+			break;
+
+		}
+	} while (fgIsTransition);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        Generate CMD_ID_SCAN_REQ command
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	/*CMD_SCAN_REQ_EXT_CH rCmdScanReq;*/
+	P_CMD_SCAN_REQ_EXT_CH prCmdScanReq;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_EXT_CH), VIR_MEM_TYPE);
+	if (prCmdScanReq == NULL)
+		return;
+
+	/* send command packet for scan */
+	kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_EXT_CH));
+
+	prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum;
+	prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex;
+	prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType;
+	prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType;
+
+	if (prScanParam->ucSSIDNum == 1) {
+		COPY_SSID(prCmdScanReq->aucSSID,
+			  prCmdScanReq->ucSSIDLength,
+			  prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]);
+	}
+
+	prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel;
+
+	if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
+		/* P2P would use:
+		 * 1. Specified Listen Channel of passive scan for LISTEN state.
+		 * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL)
+		 */
+		prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum;
+
+		for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) {
+			prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand;
+
+			prCmdScanReq->arChannelList[i].ucChannelNum =
+			    (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum;
+		}
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)
+		prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval;
+#endif
+
+	if (prScanParam->u2IELen <= MAX_IE_LENGTH)
+		prCmdScanReq->u2IELen = prScanParam->u2IELen;
+	else
+		prCmdScanReq->u2IELen = MAX_IE_LENGTH;
+
+	if (prScanParam->u2IELen)
+		kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen);
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SCAN_REQ,
+			    TRUE,
+			    FALSE,
+			    FALSE,
+			    NULL,
+			    NULL,
+			    OFFSET_OF(CMD_SCAN_REQ_EXT_CH, aucIE) + prCmdScanReq->u2IELen,
+			    (PUINT_8) prCmdScanReq, NULL, 0);
+	/* sanity check for some scan parameters */
+	if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM)
+		kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType);
+	else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM)
+		kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType);
+	else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED &&
+		prCmdScanReq->ucChannelListNum != 0)
+		kalSendAeeWarning("wlan",
+			"channel list is not NULL but channel type is not specified");
+	else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM)
+		kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType);
+	else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */
+		kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType);
+	else if (prCmdScanReq->ucSSIDLength > 32)
+		kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength);
+
+	kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_EXT_CH));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        Generate CMD_ID_SCAN_REQ command
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	/*CMD_SCAN_REQ rCmdScanReq;*/
+	P_CMD_SCAN_REQ prCmdScanReq;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	if (prScanParam->ucChannelListNum > 32) {
+		scnSendScanReqExtCh(prAdapter);
+	} else {
+		prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ), VIR_MEM_TYPE);
+		if (prCmdScanReq == NULL) {
+			DBGLOG(SCN, INFO, "alloc CmdScanReq fail");
+			return;
+		}
+		/* send command packet for scan */
+		kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ));
+
+		prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum;
+		prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex;
+		prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType;
+		prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType;
+
+		if (prScanParam->ucSSIDNum == 1) {
+			COPY_SSID(prCmdScanReq->aucSSID,
+				  prCmdScanReq->ucSSIDLength,
+				  prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]);
+		}
+
+		prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel;
+
+		if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
+			/* P2P would use:
+			 * 1. Specified Listen Channel of passive scan for LISTEN state.
+			 * 2. Specified Listen Channel of Target Device of active scan for SEARCH state.
+			 * (Target != NULL)
+			 */
+			prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum;
+
+			for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) {
+				prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand;
+
+				prCmdScanReq->arChannelList[i].ucChannelNum =
+				    (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum;
+			}
+		}
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)
+			prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval;
+#endif
+#if CFG_ENABLE_FAST_SCAN
+		if (prScanParam->eNetTypeIndex == NETWORK_TYPE_AIS_INDEX)
+			prCmdScanReq->u2ChannelDwellTime = CFG_FAST_SCAN_DWELL_TIME;
+#endif
+		if (prScanParam->u2IELen <= MAX_IE_LENGTH)
+			prCmdScanReq->u2IELen = prScanParam->u2IELen;
+		else
+			prCmdScanReq->u2IELen = MAX_IE_LENGTH;
+
+		if (prScanParam->u2IELen)
+			kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen);
+
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SCAN_REQ,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL,
+				    NULL,
+				    OFFSET_OF(CMD_SCAN_REQ, aucIE) + prCmdScanReq->u2IELen,
+				    (PUINT_8) prCmdScanReq, NULL, 0);
+		/* sanity check for some scan parameters */
+		if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM)
+			kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType);
+		else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM)
+			kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType);
+		else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED &&
+			prCmdScanReq->ucChannelListNum != 0)
+			kalSendAeeWarning("wlan",
+				"channel list is not NULL but channel type is not specified");
+		else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM)
+			kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType);
+		else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */
+			kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType);
+		else if (prCmdScanReq->ucSSIDLength > 32)
+			kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength);
+
+		kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ));
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        Generate CMD_ID_SCAN_REQ_V2 command
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	/*CMD_SCAN_REQ_V2_EXT_CH rCmdScanReq;*/
+	P_CMD_SCAN_REQ_V2_EXT_CH prCmdScanReq;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2_EXT_CH), VIR_MEM_TYPE);
+	if (prCmdScanReq == NULL)
+		return;
+
+	/* send command packet for scan */
+	kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2_EXT_CH));
+
+	prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum;
+	prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex;
+	prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType;
+	prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType;
+
+	for (i = 0; i < prScanParam->ucSSIDNum; i++) {
+		COPY_SSID(prCmdScanReq->arSSID[i].aucSsid,
+			  prCmdScanReq->arSSID[i].u4SsidLen,
+			  prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]);
+	}
+
+	prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime;
+	prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel;
+
+	if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
+		/* P2P would use:
+		 * 1. Specified Listen Channel of passive scan for LISTEN state.
+		 * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL)
+		 */
+		prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum;
+
+		for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) {
+			prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand;
+
+			prCmdScanReq->arChannelList[i].ucChannelNum =
+			    (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum;
+		}
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)
+		prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval;
+#endif
+
+	if (prScanParam->u2IELen <= MAX_IE_LENGTH)
+		prCmdScanReq->u2IELen = prScanParam->u2IELen;
+	else
+		prCmdScanReq->u2IELen = MAX_IE_LENGTH;
+
+	if (prScanParam->u2IELen)
+		kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen);
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SCAN_REQ_V2,
+			    TRUE,
+			    FALSE,
+			    FALSE,
+			    NULL,
+			    NULL,
+			    OFFSET_OF(CMD_SCAN_REQ_V2_EXT_CH, aucIE) + prCmdScanReq->u2IELen,
+			    (PUINT_8) prCmdScanReq, NULL, 0);
+	/* sanity check for some scan parameters */
+	if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM)
+		kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType);
+	else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM)
+		kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType);
+	else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED &&
+		prCmdScanReq->ucChannelListNum != 0)
+		kalSendAeeWarning("wlan",
+			"channel list is not NULL but channel type is not specified");
+	else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM)
+		kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType);
+	else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */
+		kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType);
+
+	kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2_EXT_CH));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        Generate CMD_ID_SCAN_REQ_V2 command
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	/*CMD_SCAN_REQ_V2 rCmdScanReq;*/
+	P_CMD_SCAN_REQ_V2 prCmdScanReq;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	if (prScanParam->ucChannelListNum > 32) {
+		scnSendScanReqV2ExtCh(prAdapter);
+	} else {
+		prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2), VIR_MEM_TYPE);
+		if (prCmdScanReq == NULL) {
+			DBGLOG(SCN, INFO, "alloc CmdScanReq v2 fail");
+			return;
+		}
+		/* send command packet for scan */
+		kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2));
+
+		prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum;
+		prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex;
+		prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType;
+		prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType;
+
+		for (i = 0; i < prScanParam->ucSSIDNum; i++) {
+			COPY_SSID(prCmdScanReq->arSSID[i].aucSsid,
+				  prCmdScanReq->arSSID[i].u4SsidLen,
+				  prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]);
+		}
+
+		prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime;
+		prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel;
+
+		if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
+			/* P2P would use:
+			 * 1. Specified Listen Channel of passive scan for LISTEN state.
+			 * 2. Specified Listen Channel of Target Device of active scan for SEARCH state.
+			 * (Target != NULL)
+			 */
+			prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum;
+
+			for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) {
+				prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand;
+
+				prCmdScanReq->arChannelList[i].ucChannelNum =
+				    (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum;
+			}
+		}
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)
+			prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval;
+#endif
+		if (prScanParam->u2IELen <= MAX_IE_LENGTH)
+			prCmdScanReq->u2IELen = prScanParam->u2IELen;
+		else
+			prCmdScanReq->u2IELen = MAX_IE_LENGTH;
+
+		if (prScanParam->u2IELen)
+			kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen);
+
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SCAN_REQ_V2,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL,
+				    NULL,
+				    OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + prCmdScanReq->u2IELen,
+				    (PUINT_8) prCmdScanReq, NULL, 0);
+		/* sanity check for some scan parameters */
+		if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM)
+			kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType);
+		else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM)
+			kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType);
+		else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED &&
+			prCmdScanReq->ucChannelListNum != 0)
+			kalSendAeeWarning("wlan",
+				"channel list is not NULL but channel type is not specified");
+		else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM)
+			kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType);
+		else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */
+			kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType);
+
+		kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2));
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+
+	ASSERT(prMsgHdr);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) {
+		if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ
+		    || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ
+		    || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) {
+			scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr);
+		} else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2
+			   || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2
+			   || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2
+			   || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) {
+			scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr);
+		} else {
+			/* should not deliver to this function */
+			ASSERT(0);
+		}
+
+		cnmMemFree(prAdapter, prMsgHdr);
+		scnFsmSteps(prAdapter, SCAN_STATE_SCANNING);
+	} else {
+		LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
+{
+	P_MSG_SCN_SCAN_CANCEL prScanCancel;
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	CMD_SCAN_CANCEL rCmdScanCancel;
+
+	ASSERT(prMsgHdr);
+
+	prScanCancel = (P_MSG_SCN_SCAN_CANCEL) prMsgHdr;
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) {
+		if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum &&
+		    prScanCancel->ucNetTypeIndex == (UINT_8) prScanParam->eNetTypeIndex) {
+			/* send cancel message to firmware domain */
+			rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum;
+
+#if CFG_ENABLE_WIFI_DIRECT
+			if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)
+				rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt;
+			else
+				rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE;
+#endif
+
+			wlanSendSetQueryCmd(prAdapter,
+					    CMD_ID_SCAN_CANCEL,
+					    TRUE,
+					    FALSE,
+					    FALSE,
+					    NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8) &rCmdScanCancel, NULL, 0);
+
+			/* generate scan-done event for caller */
+			scnFsmGenerateScanDoneMsg(prAdapter,
+						  prScanParam->ucSeqNum,
+						  (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_CANCELLED);
+
+			/* switch to next pending scan */
+			scnFsmSteps(prAdapter, SCAN_STATE_IDLE);
+		} else {
+			scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucNetTypeIndex);
+		}
+	}
+
+	cnmMemFree(prAdapter, prMsgHdr);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief            Scan Message Parsing (Legacy)
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+	ASSERT(prScanReqMsg);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	prScanParam->eScanType = prScanReqMsg->eScanType;
+	prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex;
+	prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType;
+	if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) {
+		prScanParam->ucSSIDNum = 1;
+
+		COPY_SSID(prScanParam->aucSpecifiedSSID[0],
+			  prScanParam->ucSpecifiedSSIDLen[0], prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength);
+
+		/* reset SSID length to zero for rest array entries */
+		for (i = 1; i < SCN_SSID_MAX_NUM; i++)
+			prScanParam->ucSpecifiedSSIDLen[i] = 0;
+	} else {
+		prScanParam->ucSSIDNum = 0;
+
+		for (i = 0; i < SCN_SSID_MAX_NUM; i++)
+			prScanParam->ucSpecifiedSSIDLen[i] = 0;
+	}
+
+	prScanParam->u2ProbeDelayTime = 0;
+	prScanParam->eScanChannel = prScanReqMsg->eScanChannel;
+	if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
+		if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST)
+			prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum;
+		else
+			prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST;
+
+		kalMemCopy(prScanParam->arChnlInfoList,
+			   prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum);
+	}
+
+	if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH)
+		prScanParam->u2IELen = prScanReqMsg->u2IELen;
+	else
+		prScanParam->u2IELen = MAX_IE_LENGTH;
+
+	if (prScanParam->u2IELen)
+		kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen);
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)
+		prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime;
+#endif
+	prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum;
+
+	if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ)
+		prScanParam->fgIsObssScan = TRUE;
+	else
+		prScanParam->fgIsObssScan = FALSE;
+
+	prScanParam->fgIsScanV2 = FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief            Scan Message Parsing - V2 with multiple SSID support
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+	ASSERT(prScanReqMsg);
+	ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	prScanParam->eScanType = prScanReqMsg->eScanType;
+	prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex;
+	prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType;
+	prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum;
+
+	for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) {
+		COPY_SSID(prScanParam->aucSpecifiedSSID[i],
+			  prScanParam->ucSpecifiedSSIDLen[i],
+			  prScanReqMsg->prSsid[i].aucSsid, (UINT_8) prScanReqMsg->prSsid[i].u4SsidLen);
+	}
+
+	prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay;
+	prScanParam->eScanChannel = prScanReqMsg->eScanChannel;
+	if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
+		if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST)
+			prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum;
+		else
+			prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST;
+
+		kalMemCopy(prScanParam->arChnlInfoList,
+			   prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum);
+	}
+
+	if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH)
+		prScanParam->u2IELen = prScanReqMsg->u2IELen;
+	else
+		prScanParam->u2IELen = MAX_IE_LENGTH;
+
+	if (prScanParam->u2IELen)
+		kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen);
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)
+		prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime;
+#endif
+	prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum;
+
+	if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ)
+		prScanParam->fgIsObssScan = TRUE;
+	else
+		prScanParam->fgIsObssScan = FALSE;
+
+	prScanParam->fgIsScanV2 = TRUE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief            Remove pending scan request
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL;
+	P_LINK_ENTRY_T prRemoveLinkEntry = NULL;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	/* traverse through rPendingMsgList for removal */
+	LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr,
+				 prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), rLinkEntry, MSG_HDR_T) {
+		if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ
+		    || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ
+		    || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ
+		    || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) {
+			P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) prPendingMsgHdr;
+
+			if (ucSeqNum == prScanReqMsg->ucSeqNum && ucNetTypeIndex == prScanReqMsg->ucNetTypeIndex) {
+				prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry);
+				prRemoveMsgHdr = prPendingMsgHdr;
+			}
+		} else if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2
+			   || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2
+			   || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2
+			   || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) {
+			P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2) prPendingMsgHdr;
+
+			if (ucSeqNum == prScanReqMsgV2->ucSeqNum && ucNetTypeIndex == prScanReqMsgV2->ucNetTypeIndex) {
+				prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry);
+				prRemoveMsgHdr = prPendingMsgHdr;
+			}
+		}
+
+		if (prRemoveLinkEntry) {
+			/* generate scan-done event for caller */
+			scnFsmGenerateScanDoneMsg(prAdapter, ucSeqNum, ucNetTypeIndex, SCAN_STATUS_CANCELLED);
+
+			/* remove from pending list */
+			LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry);
+			cnmMemFree(prAdapter, prRemoveMsgHdr);
+
+			break;
+		}
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	/* buffer empty channel information */
+	if (prScanParam->eScanChannel == SCAN_CHANNEL_FULL || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) {
+		if (prScanDone->ucSparseChannelValid) {
+			prScanInfo->fgIsSparseChannelValid = TRUE;
+			prScanInfo->rSparseChannel.eBand = (ENUM_BAND_T) prScanDone->rSparseChannel.ucBand;
+			prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum;
+		} else {
+			prScanInfo->fgIsSparseChannelValid = FALSE;
+		}
+	}
+
+	if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING && prScanDone->ucSeqNum == prScanParam->ucSeqNum) {
+		/* generate scan-done event for caller */
+		scnFsmGenerateScanDoneMsg(prAdapter,
+					  prScanParam->ucSeqNum, (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_DONE);
+
+		/* switch to next pending scan */
+		scnFsmSteps(prAdapter, SCAN_STATE_IDLE);
+	} else {
+		DBGLOG(SCN, WARN, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n",
+				   prScanDone->ucSeqNum, prScanInfo->eCurrentState);
+	}
+
+}				/* end of scnEventScanDone */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter,
+			  IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_SCAN_PARAM_T prScanParam;
+	P_MSG_SCN_SCAN_DONE prScanDoneMsg;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prScanParam = &prScanInfo->rScanParam;
+
+	DBGLOG(SCN, INFO, "Rcv Scan Done, NetIdx %d, Obss %d, Status %d, Seq %d\n",
+					ucNetTypeIndex, prScanParam->fgIsObssScan, eScanStatus, ucSeqNum);
+	prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE));
+	if (!prScanDoneMsg) {
+		ASSERT(0);	/* Can't indicate SCAN FSM Complete */
+		return;
+	}
+
+	if (prScanParam->fgIsObssScan == TRUE) {
+		prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE;
+	} else {
+		switch ((ENUM_NETWORK_TYPE_INDEX_T) ucNetTypeIndex) {
+		case NETWORK_TYPE_AIS_INDEX:
+			prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE;
+			break;
+
+#if CFG_ENABLE_WIFI_DIRECT
+		case NETWORK_TYPE_P2P_INDEX:
+			prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE;
+			break;
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+		case NETWORK_TYPE_BOW_INDEX:
+			prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE;
+			break;
+#endif
+
+		default:
+			ASSERT(0);
+			break;
+		}
+	}
+
+	prScanDoneMsg->ucSeqNum = ucSeqNum;
+	prScanDoneMsg->ucNetTypeIndex = ucNetTypeIndex;
+	prScanDoneMsg->eScanStatus = eScanStatus;
+
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanDoneMsg, MSG_SEND_METHOD_BUF);
+
+}				/* end of scnFsmGenerateScanDoneMsg() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        Query for most sparse channel
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel)
+{
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	if (prScanInfo->fgIsSparseChannelValid == TRUE) {
+		if (prSparseBand)
+			*prSparseBand = prScanInfo->rSparseChannel.eBand;
+
+		if (pucSparseChannel)
+			*pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum;
+
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        Event handler for NLO done event
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_NLO_PARAM_T prNloParam;
+	P_SCAN_PARAM_T prScanParam;
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prNloParam = &prScanInfo->rNloParam;
+	prScanParam = &prNloParam->rScanParam;
+
+	if (prScanInfo->fgNloScanning == TRUE) {
+		DBGLOG(SCN, INFO, "scnEventNloDone Current State = %d\n", prScanInfo->eCurrentState);
+
+		kalSchedScanResults(prAdapter->prGlueInfo);
+
+		if (prNloParam->fgStopAfterIndication == TRUE)
+			prScanInfo->fgNloScanning = FALSE;
+
+		kalMemZero(&prNloParam->aprPendingBssDescToInd[0],
+					CFG_SCAN_SSID_MATCH_MAX_NUM * sizeof(P_BSS_DESC_T));
+	} else {
+		DBGLOG(SCN, INFO, "Unexpected NLO-DONE event\n");
+	}
+
+}
+
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief         handler for starting scheduled scan
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter,
+		       IN UINT_8 ucSsidNum,
+		       IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_NLO_PARAM_T prNloParam;
+	P_SCAN_PARAM_T prScanParam;
+	P_CMD_NLO_REQ prCmdNloReq;
+	UINT_32 i, j;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prNloParam = &prScanInfo->rNloParam;
+	prScanParam = &prNloParam->rScanParam;
+
+	if (prScanInfo->fgNloScanning) {
+		DBGLOG(SCN, INFO, "prScanInfo->fgNloScanning == TRUE  already scanning\n");
+		return TRUE;
+	}
+
+	prScanInfo->fgNloScanning = TRUE;
+
+	/* 1. load parameters */
+	prScanParam->ucSeqNum++;
+	/* prScanParam->ucBssIndex             = prAdapter->prAisBssInfo->ucBssIndex; */
+
+	prNloParam->fgStopAfterIndication = TRUE;
+	prNloParam->ucFastScanIteration = 0;
+	prNloParam->u2FastScanPeriod = u2Interval;
+	prNloParam->u2SlowScanPeriod = u2Interval;
+
+	if (prScanParam->ucSSIDNum > CFG_SCAN_SSID_MAX_NUM)
+		prScanParam->ucSSIDNum = CFG_SCAN_SSID_MAX_NUM;
+	else
+		prScanParam->ucSSIDNum = ucSsidNum;
+
+	if (prNloParam->ucMatchSSIDNum > CFG_SCAN_SSID_MATCH_MAX_NUM)
+		prNloParam->ucMatchSSIDNum = CFG_SCAN_SSID_MATCH_MAX_NUM;
+	else
+		prNloParam->ucMatchSSIDNum = ucSsidNum;
+
+	for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) {
+		if (i < CFG_SCAN_SSID_MAX_NUM) {
+			COPY_SSID(prScanParam->aucSpecifiedSSID[i],
+				  prScanParam->ucSpecifiedSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen);
+		}
+
+		COPY_SSID(prNloParam->aucMatchSSID[i],
+			  prNloParam->ucMatchSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen);
+
+		prNloParam->aucCipherAlgo[i] = 0;
+		prNloParam->au2AuthAlgo[i] = 0;
+
+		for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++)
+			prNloParam->aucChannelHint[i][j] = 0;
+	}
+
+	/* 2. prepare command for sending */
+	prCmdNloReq = (P_CMD_NLO_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_NLO_REQ) + prScanParam->u2IELen);
+
+	if (!prCmdNloReq) {
+		ASSERT(0);	/* Can't initiate NLO operation */
+		return FALSE;
+	}
+
+	/* 3. send command packet for NLO operation */
+	kalMemZero(prCmdNloReq, sizeof(CMD_NLO_REQ));
+
+	prCmdNloReq->ucSeqNum = prScanParam->ucSeqNum;
+	/* prCmdNloReq->ucBssIndex             = prScanParam->ucBssIndex; */
+
+	prCmdNloReq->ucNetworkType = prScanParam->eNetTypeIndex;
+	prCmdNloReq->ucScanType = (UINT_8) prScanParam->eScanType;
+
+	prCmdNloReq->fgStopAfterIndication = prNloParam->fgStopAfterIndication;
+	prCmdNloReq->ucFastScanIteration = prNloParam->ucFastScanIteration;
+	prCmdNloReq->u2FastScanPeriod = prNloParam->u2FastScanPeriod;
+	prCmdNloReq->u2SlowScanPeriod = prNloParam->u2SlowScanPeriod;
+	prCmdNloReq->ucEntryNum = prNloParam->ucMatchSSIDNum;
+	for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) {
+		COPY_SSID(prCmdNloReq->arNetworkList[i].aucSSID,
+			  prCmdNloReq->arNetworkList[i].ucSSIDLength,
+			  prNloParam->aucMatchSSID[i], prNloParam->ucMatchSSIDLen[i]);
+
+		prCmdNloReq->arNetworkList[i].ucCipherAlgo = prNloParam->aucCipherAlgo[i];
+		prCmdNloReq->arNetworkList[i].u2AuthAlgo = prNloParam->au2AuthAlgo[i];
+
+		for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++)
+			prCmdNloReq->arNetworkList[i].ucNumChannelHint[j] = prNloParam->aucChannelHint[i][j];
+	}
+
+	if (prScanParam->u2IELen <= MAX_IE_LENGTH)
+		prCmdNloReq->u2IELen = prScanParam->u2IELen;
+	else
+		prCmdNloReq->u2IELen = MAX_IE_LENGTH;
+
+	if (prScanParam->u2IELen)
+		kalMemCopy(prCmdNloReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdNloReq->u2IELen);
+#if !CFG_SUPPORT_GSCN
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SET_NLO_REQ,
+			    TRUE,
+			    FALSE,
+			    TRUE,
+			    nicCmdEventSetCommon,
+			    nicOidCmdTimeoutCommon,
+			    sizeof(CMD_NLO_REQ) + prCmdNloReq->u2IELen, (PUINT_8) prCmdNloReq, NULL, 0);
+
+#else
+	scnPSCNFsm(prAdapter, PSCN_RESET, prCmdNloReq, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE);
+#endif
+	cnmMemFree(prAdapter, (PVOID) prCmdNloReq);
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief         handler for stopping scheduled scan
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter)
+{
+	P_SCAN_INFO_T prScanInfo;
+	P_NLO_PARAM_T prNloParam;
+	P_SCAN_PARAM_T prScanParam;
+	CMD_NLO_CANCEL rCmdNloCancel;
+
+	ASSERT(prAdapter);
+
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prNloParam = &prScanInfo->rNloParam;
+	prScanParam = &prNloParam->rScanParam;
+
+	/* send cancel message to firmware domain */
+	rCmdNloCancel.ucSeqNum = prScanParam->ucSeqNum;
+
+#if !CFG_SUPPORT_GSCN
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SET_NLO_CANCEL,
+			    TRUE,
+			    FALSE,
+			    TRUE,
+			    nicCmdEventSetStopSchedScan,
+			    nicOidCmdTimeoutCommon, sizeof(CMD_NLO_CANCEL), (PUINT_8)(&rCmdNloCancel), NULL, 0);
+#else
+
+	scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE);
+#endif
+
+	prScanInfo->fgNloScanning = FALSE;
+
+	return TRUE;
+}
+
+#if CFG_SUPPORT_GSCN
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief         handler for Set PSCN action
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct)
+{
+	CMD_SET_PSCAN_ENABLE rCmdPscnAction;
+	P_SCAN_INFO_T prScanInfo;
+
+	DBGLOG(SCN, TRACE, "scnFsmPSCNAction Act = %d\n", ucPscanAct);
+
+	rCmdPscnAction.ucPscanAct = ucPscanAct;
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	if (ucPscanAct == DISABLE)
+		prScanInfo->fgPscnOnnning = FALSE;
+	if (ucPscanAct == ENABLE)
+		prScanInfo->fgPscnOnnning = TRUE;
+
+	wlanSendSetQueryCmd(prAdapter,
+			    CMD_ID_SET_PSCN_ENABLE,
+			    TRUE,
+			    FALSE,
+			    FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_ENABLE), (PUINT_8) &rCmdPscnAction, NULL, 0);
+
+	DBGLOG(SCN, INFO, "scnFsmPSCNAction Act = %d is Set to FW\n", ucPscanAct);
+	return TRUE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Set PSCN param
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam)
+{
+	UINT_8 i, j;
+
+	i = 0;
+	j = 0;
+
+	ASSERT(prAdapter);
+	/*prCmdPscnParam->u4BasePeriod = prCmdPscnParam->u4BasePeriod;*/
+#if 0
+	DBGLOG(SCN, TRACE,
+		"rCmdPscnParam: Period[%u],NumCache[%u],Threshold[%u],NumBkts[%u],fgGSCN[%d] fgNLO[%d] fgBatch[%d]\n",
+		prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache,
+		prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets,
+		prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, prCmdPscnParam->fgBatchScnEnable));
+
+	for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) {
+		DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i);
+		DBGLOG(SCN, TRACE,
+			"band[%u], Index[%u] NumChannels[%u], ucBktFreqMultiple[%u] Flag[%u]\n",
+			prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand,
+			prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex,
+			prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels,
+			prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple,
+			prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag));
+		for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++)
+			DBGLOG(SCN, TRACE,
+				" %d,  ", prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel);
+		DBGLOG(SCN, TRACE, "\n");
+	}
+#endif
+
+	if (1 /*prScanInfo->fgPscnOnnning == FALSE */) {
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_PSCAN_PARAM,
+				    TRUE,
+				    FALSE,
+				    FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_PARAM), (PUINT_8) prCmdPscnParam, NULL, 0);
+
+		DBGLOG(SCN, TRACE, "CMD_ID_SET_PSCAN_PARAM  is set to FW !!!!!!!!!!\n");
+		return TRUE;
+	}
+	return FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Set hotlist
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmPSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID prCmdPscnAddHotlist)
+{
+	CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist;
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	memcpy(&rCmdPscnAddHotlist.aucMacAddr, &(prCmdPscnAddHotlist->aucMacAddr), sizeof(MAC_ADDR_LEN));
+
+	/* rCmdPscnAddHotlist.aucMacAddr = prCmdPscnAddHotlist->aucMacAddr; */
+	rCmdPscnAddHotlist.ucFlags = prCmdPscnAddHotlist->ucFlags;
+
+	if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) {
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL,
+				    NULL,
+				    sizeof(CMD_SET_PSCAN_ADD_HOTLIST_BSSID), (PUINT_8) &rCmdPscnAddHotlist, NULL, 0);
+		return TRUE;
+	}
+	/* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */
+	return FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief         handler for Set CMD_ID_SET_PSCN_ADD_SW_BSSID
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId)
+{
+	CMD_SET_PSCAN_ADD_SWC_BSSID rCmdPscnAddSWCBssId;
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	memcpy(&rCmdPscnAddSWCBssId.aucMacAddr, &(prCmdPscnAddSWCBssId->aucMacAddr), sizeof(MAC_ADDR_LEN));
+
+	/* rCmdPscnAddSWCBssId.aucMacAddr = prCmdPscnAddSWCBssId->aucMacAddr; */
+	rCmdPscnAddSWCBssId.i4RssiHighThreshold = prCmdPscnAddSWCBssId->i4RssiHighThreshold;
+	rCmdPscnAddSWCBssId.i4RssiLowThreshold = prCmdPscnAddSWCBssId->i4RssiLowThreshold;
+
+	if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) {
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_PSCN_ADD_SW_BSSID,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL,
+				    NULL,
+				    sizeof(CMD_SET_PSCAN_ADD_SWC_BSSID), (PUINT_8) &rCmdPscnAddSWCBssId, NULL, 0);
+		return TRUE;
+	}
+	/* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */
+	return FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief         handler for Set CMD_ID_SET_PSCN_MAC_ADDR
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr)
+{
+	CMD_SET_PSCAN_MAC_ADDR rCmdPscnSetMacAddr;
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	/* rCmdPscnSetMacAddr.aucMacAddr = prCmdPscnSetMacAddr->aucMacAddr; */
+	memcpy(&rCmdPscnSetMacAddr.aucMacAddr, &(prCmdPscnSetMacAddr->aucMacAddr), sizeof(MAC_ADDR_LEN));
+
+	rCmdPscnSetMacAddr.ucFlags = prCmdPscnSetMacAddr->ucFlags;
+	rCmdPscnSetMacAddr.ucVersion = prCmdPscnSetMacAddr->ucVersion;
+
+	if (1 /* (prScanInfo->fgPscnOnnning == TRUE */) {
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SET_PSCN_MAC_ADDR,
+				    TRUE,
+				    FALSE,
+				    FALSE,
+				    NULL,
+				    NULL, sizeof(CMD_SET_PSCAN_MAC_ADDR), (PUINT_8) &rCmdPscnSetMacAddr, NULL, 0);
+		return TRUE;
+	}
+	/* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */
+	return FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Set GSCN param
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam)
+{
+	/*CMD_GSCN_REQ_T rCmdGscnParam;*/
+	P_CMD_GSCN_REQ_T rCmdGscnParamp;
+	P_SCAN_INFO_T prScanInfo;
+	UINT_8 ucChannelBuckIndex;
+	UINT_8 i;
+
+	ASSERT(prAdapter);
+	rCmdGscnParamp = kalMemAlloc(sizeof(CMD_GSCN_REQ_T), VIR_MEM_TYPE);
+	if (rCmdGscnParamp == NULL) {
+		DBGLOG(SCN, INFO, "alloc CmdGscnParam fail\n");
+		return TRUE;
+	}
+	kalMemZero(rCmdGscnParamp, sizeof(CMD_GSCN_REQ_T));
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	rCmdGscnParamp->u4NumBuckets = prCmdGscnParam->num_buckets;
+	rCmdGscnParamp->u4BasePeriod = prCmdGscnParam->base_period;
+	DBGLOG(SCN, INFO,
+		"u4BasePeriod[%d], u4NumBuckets[%d]\n", rCmdGscnParamp->u4BasePeriod, rCmdGscnParamp->u4NumBuckets);
+	for (ucChannelBuckIndex = 0; ucChannelBuckIndex < prCmdGscnParam->num_buckets; ucChannelBuckIndex++) {
+		DBGLOG(SCN, TRACE, "assign channels to bucket[%d]\n", ucChannelBuckIndex);
+		for (i = 0; i < prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; i++) {
+			rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel =
+			    (UINT_8) nicFreq2ChannelNum(prCmdGscnParam->buckets[ucChannelBuckIndex].
+							channels[i].channel * 1000);
+			rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive =
+			    (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].passive;
+			rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs =
+			    (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].dwellTimeMs;
+
+			DBGLOG(SCN, TRACE, "[ucChannel %d, ucPassive %d, u4DwellTimeMs %d\n",
+			       rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel,
+			       rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive,
+			       rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs);
+
+		}
+		rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].u2BucketIndex =
+		    (UINT_16) prCmdGscnParam->buckets[ucChannelBuckIndex].bucket;
+		rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].eBand =
+		    prCmdGscnParam->buckets[ucChannelBuckIndex].band;
+		rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucBucketFreqMultiple =
+		    (prCmdGscnParam->buckets[ucChannelBuckIndex].period / prCmdGscnParam->base_period);
+		rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucNumChannels =
+		    prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels;
+		rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucReportFlag =
+		    prCmdGscnParam->buckets[ucChannelBuckIndex].report_events;
+
+		/* printk("\n"); */
+	}
+
+	DBGLOG(SCN, INFO, "scnSetGSCNParam  ---> scnPSCNFsm PSCN_RESET\n");
+
+	scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, rCmdGscnParamp, NULL, FALSE, FALSE, FALSE, FALSE);
+	kalMemFree(rCmdGscnParamp, VIR_MEM_TYPE, sizeof(CMD_GSCN_REQ_T));
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Combine   PNO Scan params into PSCAN param
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID
+scnSubCombineNLOtoPSCN(IN P_ADAPTER_T prAdapter,
+		       IN P_CMD_NLO_REQ prNewCmdNloReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam)
+{
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	if (prNewCmdNloReq) {
+		prCmdPscnParam->fgNLOScnEnable = TRUE;
+		memcpy(&prCmdPscnParam->rCmdNloReq, prNewCmdNloReq, sizeof(CMD_NLO_REQ));
+	} else if (prScanInfo->prPscnParam->fgNLOScnEnable) {
+		memcpy(&prCmdPscnParam->rCmdNloReq, &prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ));
+	} else
+		prCmdPscnParam->fgNLOScnEnable = FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Combine   Batcht Scan params into PSCAN param
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID
+scnSubCombineBatchSCNtoPSCN(IN P_ADAPTER_T prAdapter,
+			    IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam)
+{
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	if (prNewCmdBatchReq) {
+		prCmdPscnParam->fgBatchScnEnable = TRUE;
+		memcpy(&prCmdPscnParam->rCmdBatchReq, prNewCmdBatchReq, sizeof(CMD_BATCH_REQ_T));
+	} else if (prScanInfo->prPscnParam->fgBatchScnEnable) {
+		memcpy(&prCmdPscnParam->rCmdBatchReq, &prScanInfo->prPscnParam->rCurrentCmdBatchReq,
+		       sizeof(CMD_BATCH_REQ_T));
+	} else
+		prCmdPscnParam->fgBatchScnEnable = FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Combine   GSCN Scan params into PSCAN param
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID
+scnSubCombineGSCNtoPSCN(IN P_ADAPTER_T prAdapter,
+			IN P_CMD_GSCN_REQ_T prNewCmdGscnReq,
+			IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam)
+{
+	P_SCAN_INFO_T prScanInfo;
+	UINT_32 ucPeriodMin = MAX_PERIOD;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prCmdPscnParam->fgGScnEnable = FALSE;
+
+	DBGLOG(SCN, TRACE, "scnSubCombineGSCNtoPSCN fgGScnParamSet %d fgGScnConfigSet %d\n",
+		prScanInfo->fgGScnParamSet, prScanInfo->fgGScnConfigSet);
+
+	if (prNewCmdGscnReq) {
+		DBGLOG(SCN, INFO, "setup prNewCmdGscnReq\n");
+		prScanInfo->fgGScnParamSet = TRUE;
+		memcpy(&prCmdPscnParam->rCmdGscnReq, prNewCmdGscnReq, sizeof(CMD_GSCN_REQ_T));
+		if (ucPeriodMin > prNewCmdGscnReq->u4BasePeriod)
+			prCmdPscnParam->u4BasePeriod = prNewCmdGscnReq->u4BasePeriod;
+	} else if (prScanInfo->fgGScnParamSet) {
+		DBGLOG(SCN, INFO, "no new prNewCmdGscnReq but there is a old one\n");
+		memcpy(&prCmdPscnParam->rCmdGscnReq, &prScanInfo->prPscnParam->rCurrentCmdGscnReq,
+		       sizeof(CMD_GSCN_REQ_T));
+		prCmdPscnParam->u4BasePeriod = prScanInfo->prPscnParam->u4BasePeriod;
+	} else
+		prScanInfo->fgGScnParamSet = FALSE;
+
+	if (prNewCmdGscnConfig) {
+		DBGLOG(SCN, INFO, "set up prNewCmdGscnConfig\n");
+		memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM));
+		prScanInfo->fgGScnConfigSet = TRUE;
+		prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = prNewCmdGscnConfig->u4BufferThreshold;
+		prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = (UINT_8) prNewCmdGscnConfig->u4NumScnToCache;
+	} else if (prScanInfo->fgGScnConfigSet) {
+		DBGLOG(SCN, INFO, "no new prNewCmdGscnConfig but there is a old one\n");
+		memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM));
+		prCmdPscnParam->rCmdGscnReq.u4BufferThreshold =
+		    prScanInfo->prPscnParam->rCurrentCmdGscnReq.u4BufferThreshold;
+		prCmdPscnParam->rCmdGscnReq.ucNumScnToCache =
+		    (UINT_8) prScanInfo->prPscnParam->rCurrentCmdGscnReq.ucNumScnToCache;
+	} else
+		prScanInfo->fgGScnConfigSet = FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Combine   GSCN Scan params into PSCAN param
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID
+scnRemoveFromPSCN(IN P_ADAPTER_T prAdapter,
+		  IN BOOLEAN fgRemoveNLOfromPSCN,
+		  IN BOOLEAN fgRemoveBatchSCNfromPSCN,
+		  IN BOOLEAN fgRemoveGSCNfromPSCN, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam)
+{
+	P_SCAN_INFO_T prScanInfo;
+	UINT_8 ucPscanAct = DISABLE;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	{
+		DBGLOG(SCN, INFO, "remove NLO or Batch or GSCN from PSCN--->NLO=%d, BSN=%d, GSN=%d\n",
+			fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN);
+
+		if (fgRemoveNLOfromPSCN) {
+			memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM));
+			prCmdPscnParam->fgNLOScnEnable = FALSE;
+			kalMemZero(&prCmdPscnParam->rCmdNloReq, sizeof(CMD_NLO_REQ));
+			kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ));
+		}
+		if (fgRemoveBatchSCNfromPSCN) {
+			memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM));
+			prCmdPscnParam->fgBatchScnEnable = FALSE;
+			kalMemZero(&prCmdPscnParam->rCmdBatchReq, sizeof(CMD_BATCH_REQ_T));
+			kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdBatchReq, sizeof(CMD_BATCH_REQ_T));
+		}
+		if (fgRemoveGSCNfromPSCN) {
+			memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM));
+			prCmdPscnParam->fgGScnEnable = FALSE;
+			prScanInfo->fgGScnParamSet = FALSE;
+			kalMemZero(&prCmdPscnParam->rCmdGscnReq, sizeof(CMD_GSCN_REQ_T));
+			kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdGscnReq, sizeof(CMD_GSCN_REQ_T));
+		}
+
+		if (!fgRemoveNLOfromPSCN && !fgRemoveBatchSCNfromPSCN && !fgRemoveGSCNfromPSCN) {
+			/* prCmdPscnParam->fgIsPeriodicallyScn = FALSE; */
+			prScanInfo->fgPscnOnnning = FALSE;
+			scnFsmPSCNSetParam(prAdapter, prCmdPscnParam);
+			scnFsmPSCNAction(prAdapter, ucPscanAct);
+		} else {
+			/* prCmdPscnParam->fgIsPeriodicallyScn = TRUE; */
+			scnFsmPSCNSetParam(prAdapter, prCmdPscnParam);
+			DBGLOG(SCN, INFO, " disable NLO or GSCN or Batch but fgIsPeriodicallyScn = TRUE <-----\n");
+		}
+	}
+
+}
+
+#if 1
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief        handler for Combine GSCN , Batch, PNO Scan params into PSCAN param
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+
+BOOLEAN
+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter,
+			 IN P_CMD_NLO_REQ prNewCmdNloReq,
+			 IN P_CMD_BATCH_REQ_T prNewCmdBatchReq,
+			 IN P_CMD_GSCN_REQ_T prNewCmdGscnReq,
+			 IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig,
+			 IN BOOLEAN fgRemoveNLOfromPSCN,
+			 IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN)
+{
+	P_SCAN_INFO_T prScanInfo;
+	/* CMD_SET_PSCAN_PARAM rCmdPscnParam; */
+	P_CMD_SET_PSCAN_PARAM prCmdPscnParam;
+	/* UINT_8 i, j = 0; */
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	prCmdPscnParam = (P_CMD_SET_PSCAN_PARAM) kalMemAlloc(sizeof(CMD_SET_PSCAN_PARAM), VIR_MEM_TYPE);
+	if (!prCmdPscnParam) {
+		DBGLOG(SCN, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n");
+		return -ENOMEM;
+	}
+	kalMemZero(prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM));
+
+	prCmdPscnParam->ucVersion = CURRENT_PSCN_VERSION;
+
+	if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) {
+		scnRemoveFromPSCN(prAdapter,
+				  fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN, prCmdPscnParam);
+	} else {
+		DBGLOG(SCN, INFO, "combine GSCN or Batch or NLO to PSCN --->\n");
+
+		scnSubCombineNLOtoPSCN(prAdapter, prNewCmdNloReq, prCmdPscnParam);
+		scnSubCombineBatchSCNtoPSCN(prAdapter, prNewCmdBatchReq, prCmdPscnParam);
+		if (prNewCmdGscnReq)
+			scnSubCombineGSCNtoPSCN(prAdapter, prNewCmdGscnReq, NULL, prCmdPscnParam);
+		if (prNewCmdGscnConfig)
+			scnSubCombineGSCNtoPSCN(prAdapter, NULL, prNewCmdGscnConfig, prCmdPscnParam);
+		/* scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); */
+
+#if 0
+		DBGLOG(SCN, TRACE, "combine GSCN or Batch or NLO to PSCN <--- rCmdPscnParam\n");
+		DBGLOG(SCN, TRACE,
+			"Period[%u], NumCache[%u],  Threshold[%u], NumBuckets[%u],GSCNEn[%d] NLOEn[%d] BatchEn[%d]\n",
+			prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache,
+			prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets,
+			prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable,
+			prCmdPscnParam->fgBatchScnEnable));
+
+		for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) {
+			DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i);
+			DBGLOG(SCN, TRACE,
+				"band[%u], ChnBkt[%u] NumChns[%u], BktFreqMltpl[%u] Flag[%u]\n",
+				prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand,
+				prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex,
+				prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels,
+				prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple,
+				prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag));
+			for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) {
+				DBGLOG(SCN, TRACE, " %d,  ",
+				       prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel);
+			}
+			DBGLOG(SCN, TRACE, "\n");
+		}
+#endif
+	}
+
+	memcpy(prScanInfo->prPscnParam, prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM));
+	kalMemFree(prCmdPscnParam, VIR_MEM_TYPE, sizeof(CMD_SET_PSCAN_PARAM));
+	return TRUE;
+}
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief         handler for Set CMD_ID_SET_PSCN_MAC_ADDR
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig)
+{
+	CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig;
+
+	ASSERT(prAdapter);
+	memcpy(&rCmdGscnScnConfig, prCmdGscnScnConfig, sizeof(CMD_GSCN_SCN_COFIG_T));
+	DBGLOG(SCN, TRACE, "rCmdGscnScnConfig: u4BufferThreshold; [%d] ucNumApPerScn [%d] ucNumScnToCache [%d]\n",
+		rCmdGscnScnConfig.u4BufferThreshold,
+		rCmdGscnScnConfig.ucNumApPerScn,
+		rCmdGscnScnConfig.u4NumScnToCache);
+
+	scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, &rCmdGscnScnConfig, FALSE, FALSE, FALSE, FALSE);
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief         handler for Set CMD_ID_SET_PSCN_MAC_ADDR
+*
+* \param[in]
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd)
+{
+	CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd;
+	P_SCAN_INFO_T prScanInfo;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultCmd, sizeof(CMD_GET_GSCAN_RESULT_T));
+	DBGLOG(SCN, INFO, "rGetGscnScnResultCmd: ucGetNum [%d]  fgFlush [%d]\n",
+		rGetGscnScnResultCmd.u4Num, rGetGscnScnResultCmd.ucFlush);
+
+	if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) {
+		wlanSendSetQueryCmd(prAdapter,
+				CMD_ID_GET_GSCN_SCN_RESULT,
+				TRUE,
+				FALSE,
+				FALSE,
+				NULL,
+				NULL, sizeof(CMD_GET_GSCAN_RESULT_T), (PUINT_8) &rGetGscnScnResultCmd, NULL, 0);
+		return TRUE;
+	}
+	/* debug msg, No PSCN, Sched SCAN GSCN ongoing ??? */
+	return FALSE;
+
+}
+
+VOID
+scnPSCNFsm(IN P_ADAPTER_T prAdapter,
+	   ENUM_PSCAN_STATE_T eNextPSCNState,
+	   IN P_CMD_NLO_REQ prCmdNloReq,
+	   IN P_CMD_BATCH_REQ_T prCmdBatchReq,
+	   IN P_CMD_GSCN_REQ_T prCmdGscnReq,
+	   IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig,
+	   IN BOOLEAN fgRemoveNLOfromPSCN,
+	   IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN)
+{
+	P_SCAN_INFO_T prScanInfo;
+	BOOLEAN fgTransitionState = FALSE;
+
+	ASSERT(prAdapter);
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+
+	do {
+		fgTransitionState = FALSE;
+
+		DBGLOG(SCN, STATE, "eCurrentPSCNState=%d, eNextPSCNState=%d\n",
+			prScanInfo->eCurrentPSCNState, eNextPSCNState);
+
+		switch (prScanInfo->eCurrentPSCNState) {
+		case PSCN_IDLE:
+			if (eNextPSCNState == PSCN_RESET) {
+				if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) {
+					DBGLOG(SCN, TRACE, "Unexpected remove NLO/BATCH/GSCN request\n");
+					eNextPSCNState = PSCN_IDLE;
+					break;
+				}
+
+				if (prCmdNloReq || prCmdBatchReq) {
+					DBGLOG(SCN, TRACE, "PSCN_IDLE->PSCN_RESET,.... scnFsmPSCNActionDISABLE\n");
+					/*TBD check PSCAN is ongoing */
+					scnFsmPSCNAction(prAdapter, DISABLE);
+					break;
+				}
+
+			} else if (eNextPSCNState == PSCN_SCANNING) {
+				if (fgEnableGSCN) {
+					if (prScanInfo->fgPscnOnnning)
+						scnFsmPSCNAction(prAdapter, DISABLE);
+					if (prScanInfo->fgGScnParamSet) {
+						DBGLOG(SCN, TRACE,
+							"PSCN_IDLE->PSCN_SCANNING,.... scnFsmPSCNActionENABLE\n");
+						prScanInfo->prPscnParam->fgGScnEnable = TRUE;
+					scnFsmPSCNSetParam(prAdapter,
+							   (P_CMD_SET_PSCAN_PARAM)prScanInfo->prPscnParam);
+						scnFsmPSCNAction(prAdapter, ENABLE);
+						eNextPSCNState = PSCN_SCANNING;
+					}
+				}
+			}
+			break;
+
+		case PSCN_RESET:
+			scnCombineParamsIntoPSCN(prAdapter,
+						 prCmdNloReq,
+						 prCmdBatchReq,
+						 prCmdGscnReq,
+						 prNewCmdGscnConfig,
+						 fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN);
+
+			if (!prScanInfo->prPscnParam->fgNLOScnEnable && !prScanInfo->prPscnParam->fgBatchScnEnable
+			    && !prScanInfo->prPscnParam->fgGScnEnable) {
+				DBGLOG(SCN, TRACE,
+				       "PSCN_RESET->PSCN_IDLE,.... fgNLOScnEnable/fgBatchScnEnable/fgGScnEnable false\n");
+				eNextPSCNState = PSCN_IDLE;
+			} else {
+				if (prScanInfo->prPscnParam->fgNLOScnEnable
+				    || prScanInfo->prPscnParam->fgBatchScnEnable) {
+					scnFsmPSCNSetParam(prAdapter, (P_CMD_SET_PSCAN_PARAM) prScanInfo->prPscnParam);
+					scnFsmPSCNAction(prAdapter, ENABLE);
+					eNextPSCNState = PSCN_SCANNING;
+					DBGLOG(SCN, TRACE,
+					       "PSCN_RESET->PSCN_SCANNING,.... fgNLOScnEnable/fgBatchScnEnable ENABLE\n");
+				}
+			}
+			break;
+
+		case PSCN_SCANNING:
+			if (eNextPSCNState == PSCN_RESET) {
+				if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) {
+					DBGLOG(SCN, TRACE,
+					       "PSCN_SCANNING->PSCN_RESET,.... fgRemoveNLOfromPSCN/fgRemoveBatchSCNfromPSCN/fgRemoveGSCNfromPSCN\n");
+					scnFsmPSCNAction(prAdapter, DISABLE);
+					break;
+				}
+
+				if (prCmdNloReq || prCmdBatchReq || prCmdGscnReq || prNewCmdGscnConfig) {
+					DBGLOG(SCN, TRACE,
+					       "PSCN_SCANNING->PSCN_RESET,.... prCmdNloReq/prCmdBatchReq/prCmdGscnReq/prNewCmdGscnConfig\n");
+					scnFsmPSCNAction(prAdapter, DISABLE);
+					break;
+				}
+
+			} else if (eNextPSCNState == PSCN_SCANNING) {
+				if (fgEnableGSCN) {
+					if (prScanInfo->prPscnParam->fgGScnEnable && (!prScanInfo->fgPscnOnnning)) {
+						DBGLOG(SCN, TRACE,
+						       "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n");
+						/* scnFsmPSCNAction(prAdapter, ENABLE); */
+						eNextPSCNState = PSCN_SCANNING;
+					} else {
+
+						DBGLOG(SCN, TRACE,
+							   "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n");
+					}
+				}
+			}
+			eNextPSCNState = PSCN_SCANNING;
+			break;
+
+		default:
+			DBGLOG(SCN, WARN, "Unexpected state\n");
+			ASSERT(0);
+			break;
+		}
+
+		DBGLOG(SCN, STATE, "eCurrentState %d , eNextPSCNState %d\n",
+		       prScanInfo->eCurrentPSCNState, eNextPSCNState);
+		if (prScanInfo->eCurrentPSCNState != eNextPSCNState)
+			fgTransitionState = TRUE;
+
+		prScanInfo->eCurrentPSCNState = eNextPSCNState;
+	} while (fgTransitionState);
+
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c
new file mode 100644
index 0000000000000..29eb8d4e7d92f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c
@@ -0,0 +1,1112 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/sec_fsm.c#1
+*/
+
+/*! \file   "sec_fsm.c"
+    \brief  This is the file implement security check state machine.
+
+    In security module, do the port control check after success join to an AP,
+    and the path to NORMAL TR, the state machine handle these state transition.
+*/
+
+/*
+** Log: sec_fsm.c
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Adjust code for DBG and CONFIG_XLOG.
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the debug module level.
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 03 29 2011 wh.su
+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error
+ * fixed the kclocwork error.
+ *
+ * 01 26 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * .
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Fix Compile Error when DBG is disabled.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 09 29 2010 wh.su
+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
+ *
+ * 09 24 2010 wh.su
+ * NULL
+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 20 2010 wh.su
+ * NULL
+ * adding the eapol callback setting.
+ *
+ * 08 19 2010 wh.su
+ * NULL
+ * adding the tx pkt call back handle for countermeasure.
+ *
+ * 07 19 2010 wh.su
+ *
+ * fixed the compilng error at debug mode.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * modify some code for concurrent network.
+ *
+ * 06 19 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * consdier the concurrent network setting.
+ *
+ * 05 28 2010 wh.su
+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
+ * fixed the ad-hoc wpa-none send non-encrypted frame issue.
+ *
+ * 05 24 2010 kevin.huang
+ * [BORA00000794][WIFISYS][New Feature]Power Management Support
+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval.
+ *
+ * 04 24 2010 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
+ *
+ * 04 13 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * fixed the Klocwork error and refine the class error message.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * move the AIS specific variable for security to AIS specific structure.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * Fixed the pre-authentication timer not correctly init issue,
+ * and modify the security related callback function prototype.
+ *
+ * 03 01 2010 wh.su
+ * [BORA00000605][WIFISYS] Phase3 Integration
+ * Refine the variable and parameter for security.
+ *
+ * 01 27 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * add and fixed some security function.
+ *
+ * 01 13 2010 wh.su
+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
+ * fixed the compiling warning
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * refine some code
+ *
+ * Dec 4 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * refine the code
+ *
+ * Dec 1 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * code refine
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the function name
+ *
+ * Nov 19 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adjust the state machine, to meet the firmware security design v1.1
+ *
+ * Nov 18 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_RSN_MIGRATION
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if DBG
+/*lint -save -e64 Type mismatch */
+static PUINT_8 apucDebugSecState[SEC_STATE_NUM] = {
+	(PUINT_8) DISP_STRING("SEC_STATE_INIT"),
+	(PUINT_8) DISP_STRING("SEC_STATE_INITIATOR_PORT_BLOCKED"),
+	(PUINT_8) DISP_STRING("SEC_STATE_RESPONDER_PORT_BLOCKED"),
+	(PUINT_8) DISP_STRING("SEC_STATE_CHECK_OK"),
+	(PUINT_8) DISP_STRING("SEC_STATE_SEND_EAPOL"),
+	(PUINT_8) DISP_STRING("SEC_STATE_SEND_DEAUTH"),
+	(PUINT_8) DISP_STRING("SEC_STATE_COUNTERMEASURE"),
+};
+
+/*lint -restore */
+#endif /* DBG */
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do initialization of Security FSM and all variables in
+*        SEC_INFO_T.
+*
+* \param[in] prSta            Pointer to the STA record
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
+
+	ASSERT(prSta);
+
+	prSecInfo = &prSta->rSecInfo;
+
+#if 1				/* MT6620 */
+	/* At MT5921, is ok, but at MT6620, firmware base ASIC, the firmware */
+	/* will lost these data, thus, driver have to keep the wep material and */
+	/* setting to firmware while awake from D3. */
+#endif
+
+	prSecInfo->eCurrentState = SEC_STATE_INIT;
+
+	prSecInfo->fg2nd1xSend = FALSE;
+	prSecInfo->fgKeyStored = FALSE;
+
+	if (IS_STA_IN_AIS(prSta)) {
+		prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+		prAisSpecBssInfo->u4RsnaLastMICFailTime = 0;
+		prAisSpecBssInfo->fgCheckEAPoLTxDone = FALSE;
+
+		cnmTimerInitTimer(prAdapter,
+				  &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer,
+				  (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEapolTxTimeout, (ULONG) prSta);
+
+		cnmTimerInitTimer(prAdapter,
+				  &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer,
+				  (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEndOfCounterMeasure, (ULONG) prSta);
+
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do uninitialization of Security FSM and all variables in
+*        SEC_INFO_T.
+*
+* \param[in] prSta            Pointer to the STA record
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID				/* whsu:Todo: */
+secFsmUnInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+
+	ASSERT(prSta);
+
+	prSecInfo = &prSta->rSecInfo;
+
+	prSecInfo->fg2nd1xSend = FALSE;
+	prSecInfo->fgKeyStored = FALSE;
+
+	/* nicPrivacyRemoveWlanTable(prSta->ucWTEntry); */
+
+	if (IS_STA_IN_AIS(prSta)) {
+		cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer);
+		cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        STANDBY to CHECK_OK.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return - none
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_INIT_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	secSetPortBlocked(prAdapter, prSta, FALSE);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        INIT to INITIATOR_PORT_BLOCKED.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return - none
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_INIT_to_INITIATOR_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        INIT to RESPONDER_PORT_BLOCKED.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return - none
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_INIT_to_RESPONDER_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        INITIATOR_PORT_BLOCKED to CHECK_OK.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return - none
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_INITIATOR_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	secSetPortBlocked(prAdapter, prSta, FALSE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        RESPONDER_PORT_BLOCKED to CHECK_OK.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return - none
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_RESPONDER_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	secSetPortBlocked(prAdapter, prSta, FALSE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        CHECK_OK to SEND_EAPOL
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_CHECK_OK_to_SEND_EAPOL(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+
+	P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo;
+
+	ASSERT(prAdapter);
+
+	ASSERT(prSta);
+
+	prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	ASSERT(prAisBssInfo);
+
+	if (!IS_STA_IN_AIS(prSta)) {
+		DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	prAisBssInfo->fgCheckEAPoLTxDone = TRUE;
+
+	/* cnmTimerStartTimer(prAdapter, */
+	/* &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer, */
+	/* SEC_TO_MSEC(EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC)); */
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        SEND_EAPOL to SEND_DEAUTH.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return - none
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_SEND_EAPOL_to_SEND_DEAUTH(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+
+	if (!IS_STA_IN_AIS(prSta)) {
+		DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	/* Compose deauth frame to AP, a call back function for tx done */
+	if (authSendDeauthFrame(prAdapter,
+				prSta,
+				(P_SW_RFB_T) NULL,
+				REASON_CODE_MIC_FAILURE,
+				(PFN_TX_DONE_HANDLER) secFsmEventDeauthTxDone) != WLAN_STATUS_SUCCESS) {
+		ASSERT(FALSE);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        SEND_DEAUTH to COUNTERMEASURE.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_SEND_DEAUTH_to_COUNTERMEASURE(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	ASSERT(prAdapter);
+	ASSERT(prSta);
+
+	if (!IS_STA_IN_AIS(prSta)) {
+		DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+	/* Start the 60 sec timer */
+	cnmTimerStartTimer(prAdapter,
+			   &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer,
+			   SEC_TO_MSEC(COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do action part while in STATE transition of
+*        SEND_DEAUTH to COUNTERMEASURE.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+static inline VOID secFsmTrans_COUNTERMEASURE_to_INIT(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+
+	/* Clear the counter measure flag */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The Core FSM engine of security module.
+*
+* \param[in] prSta            Pointer to the Sta record
+* \param[in] eNextState    Enum value of next sec STATE
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmSteps(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN ENUM_SEC_STATE_T eNextState)
+{
+	P_SEC_INFO_T prSecInfo;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	ASSERT(prSta);
+
+	prSecInfo = &prSta->rSecInfo;
+	ASSERT(prSecInfo);
+
+	DEBUGFUNC("secFsmSteps");
+	do {
+		/* Do entering Next State */
+		prSecInfo->ePreviousState = prSecInfo->eCurrentState;
+
+		/* Do entering Next State */
+#if DBG
+		DBGLOG(RSN, STATE, "\n %pM TRANSITION: [%s] -> [%s]\n\n",
+				    prSta->aucMacAddr,
+				    apucDebugSecState[prSecInfo->eCurrentState], apucDebugSecState[eNextState]);
+#else
+		DBGLOG(RSN, STATE, "\n %pM [%d] TRANSITION: [%d] -> [%d]\n\n",
+				    prSta->aucMacAddr, DBG_RSN_IDX, prSecInfo->eCurrentState, eNextState);
+#endif
+		prSecInfo->eCurrentState = eNextState;
+
+		fgIsTransition = (BOOLEAN) FALSE;
+#if 0
+		/* Do tasks of the State that we just entered */
+		switch (prSecInfo->eCurrentState) {
+		case SEC_STATE_INIT:
+			break;
+		case SEC_STATE_INITIATOR_PORT_BLOCKED:
+			break;
+		case SEC_STATE_RESPONDER_PORT_BLOCKED:
+			break;
+		case SEC_STATE_CHECK_OK:
+			break;
+		case SEC_STATE_SEND_EAPOL:
+			break;
+		case SEC_STATE_SEND_DEAUTH:
+			break;
+		case SEC_STATE_COUNTERMEASURE:
+			break;
+		default:
+			ASSERT(0);	/* Make sure we have handle all STATEs */
+			break;
+		}
+#endif
+	} while (fgIsTransition);
+
+	return;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do initialization of Security FSM and all variables in
+*        SEC_INFO_T.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+	ENUM_SEC_STATE_T eNextState;
+
+	DBGLOG(RSN, TRACE, "secFsmRunEventStart\n");
+
+	ASSERT(prSta);
+
+	if (!prSta)
+		return;
+
+	if (!IS_STA_IN_AIS(prSta))
+		return;
+
+	DBGLOG(RSN, TRACE, "secFsmRunEventStart for sta %pM network %d\n",
+			    prSta->aucMacAddr, prSta->ucNetTypeIndex);
+
+	prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo;
+
+	eNextState = prSecInfo->eCurrentState;
+
+	secSetPortBlocked(prAdapter, prSta, TRUE);
+
+	/* prSta->fgTransmitKeyExist = FALSE; */
+	/* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */
+
+#if 1				/* Since the 1x and key can set to firmware in order, always enter the check ok state */
+	SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK);
+#else
+	if (IS_STA_IN_AIS(prSta->eStaType)) {
+		if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE
+#if CFG_SUPPORT_WAPI
+		    || (prAdapter->rWifiVar.rConnSettings.fgWapiMode)
+#endif
+		    ) {
+			prSta->fgTransmitKeyExist = FALSE;
+			/* nicPrivacyInitialize(prSta->ucNetTypeIndex); */
+			SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED);
+		} else {
+			SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK);
+		}
+	}
+#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI
+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI
+	else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC)) {
+#elif CFG_ENABLE_WIFI_DIRECT
+	else if (prSta->eStaType == STA_TYPE_P2P_GC) {
+#elif CFG_ENABLE_BT_OVER_WIFI
+	else if (prSta->eStaType == STA_TYPE_BOW_CLIENT) {
+#endif
+		SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED);
+	}
+#endif
+	else
+		SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED);
+#endif
+	if (prSecInfo->eCurrentState != eNextState)
+		secFsmSteps(prAdapter, prSta, eNextState);
+
+}				/* secFsmRunEventStart */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function called by reset procedure to force the sec fsm enter
+*        idle state
+*
+* \param[in] ucNetTypeIdx  The Specific Network type index
+* \param[in] prSta         Pointer to the Sta record
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+
+	DBGLOG(RSN, TRACE, "secFsmEventAbort for sta %pM network %d\n",
+			    prSta->aucMacAddr, prSta->ucNetTypeIndex);
+
+	ASSERT(prSta);
+
+	if (!prSta)
+		return;
+
+	if (!IS_STA_IN_AIS(prSta))
+		return;
+
+	prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo;
+
+	prSta->fgTransmitKeyExist = FALSE;
+
+	secSetPortBlocked(prAdapter, prSta, TRUE);
+
+	if (prSecInfo == NULL)
+		return;
+
+	if (IS_STA_IN_AIS(prSta)) {
+
+		prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE;
+
+		if (prSecInfo->eCurrentState == SEC_STATE_SEND_EAPOL) {
+			if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone == FALSE) {
+				DBGLOG(RSN, TRACE, "EAPOL STATE not match the flag\n");
+				/* cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.
+				 * rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); */
+			}
+		}
+	}
+	prSecInfo->eCurrentState = SEC_STATE_INIT;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will indicate an Event of "2nd EAPoL Tx is sending" to Sec FSM.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+	ENUM_SEC_STATE_T eNextState;
+	/* BOOLEAN                 fgIsTransition = (BOOLEAN)FALSE; */
+
+	DEBUGFUNC("secFsmRunEvent2ndEapolTx");
+
+	ASSERT(prSta);
+
+	prSecInfo = &prSta->rSecInfo;
+	eNextState = prSecInfo->eCurrentState;
+
+#if DBG
+	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr,
+			    apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState);
+#endif
+
+	switch (prSecInfo->eCurrentState) {
+	case SEC_STATE_INITIATOR_PORT_BLOCKED:
+	case SEC_STATE_CHECK_OK:
+		prSecInfo->fg2nd1xSend = TRUE;
+		break;
+	default:
+#if DBG
+		DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at %s\n", apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+		DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState);
+#endif
+		break;
+	}
+
+	if (prSecInfo->eCurrentState != eNextState)
+		secFsmSteps(prAdapter, prSta, eNextState);
+
+	return;
+
+}				/* secFsmRunEvent2ndEapolTx */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will indicate an Event of "4th EAPoL Tx is Tx done" to Sec FSM.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+	ENUM_SEC_STATE_T eNextState;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+	P_CMD_802_11_KEY prStoredKey;
+
+	DEBUGFUNC("secFsmRunEvent4ndEapolTx");
+
+	ASSERT(prSta);
+
+	prSecInfo = &prSta->rSecInfo;
+	eNextState = prSecInfo->eCurrentState;
+
+#if DBG
+	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr,
+			    apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState);
+#endif
+
+	switch (prSecInfo->eCurrentState) {
+	case SEC_STATE_INITIATOR_PORT_BLOCKED:
+	case SEC_STATE_CHECK_OK:
+		prSecInfo->fg2nd1xSend = FALSE;
+		if (prSecInfo->fgKeyStored) {
+			prStoredKey = (P_CMD_802_11_KEY) prSecInfo->aucStoredKey;
+
+			/* prSta = rxmLookupStaRecIndexFromTA(prStoredKey->aucPeerAddr); */
+			/* if (nicPrivacySetKeyEntry(prStoredKey, prSta->ucWTEntry) == FALSE) */
+			/* DBGLOG(RSN, WARN, ("nicPrivacySetKeyEntry() fail,..\n")); */
+
+			/* key update */
+			prSecInfo->fgKeyStored = FALSE;
+			prSta->fgTransmitKeyExist = TRUE;
+		}
+		if (prSecInfo->eCurrentState == SEC_STATE_INITIATOR_PORT_BLOCKED)
+			SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK);
+		break;
+	default:
+
+#if DBG
+		DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at %s\n", apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+		DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at [%d]\n", prSecInfo->eCurrentState);
+#endif
+		break;
+	}
+
+	if (prSecInfo->eCurrentState != eNextState)
+		secFsmSteps(prAdapter, prSta, eNextState);
+
+	return;
+
+}				/* secFsmRunEvent4ndEapolTx */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will indicate an Event of "Pairwise key installed" to SEC FSM.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \retval TRUE The key can be installed to HW
+* \retval FALSE The kay conflict with the current key, abort it
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+	ENUM_SEC_STATE_T eNextState;
+	BOOLEAN fgStatus = TRUE;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	ASSERT(prSta);
+
+	prSecInfo = &prSta->rSecInfo;
+	if (prSecInfo == NULL)
+		return TRUE;	/* Not PTK */
+
+#if DBG
+	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAdd),
+			    apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState);
+#endif
+
+	eNextState = prSecInfo->eCurrentState;
+
+	switch (prSecInfo->eCurrentState) {
+	case SEC_STATE_INIT:
+		/* Legacy wep, wpa-none */
+		break;
+
+	case SEC_STATE_INITIATOR_PORT_BLOCKED:
+		if (prSecInfo->fg2nd1xSend)
+			;
+		else
+			SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK);
+		break;
+
+	case SEC_STATE_RESPONDER_PORT_BLOCKED:
+		SEC_STATE_TRANSITION(prAdapter, prSta, RESPONDER_PORT_BLOCKED, CHECK_OK);
+		break;
+
+	case SEC_STATE_CHECK_OK:
+		break;
+
+	default:
+		fgStatus = FALSE;
+		break;
+	}
+
+	if (prSecInfo->eCurrentState != eNextState)
+		secFsmSteps(prAdapter, prSta, eNextState);
+
+	return fgStatus;
+
+}				/* end of secFsmRunEventPTKInstalled() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will indicate an Event of "Counter Measure" to SEC FSM.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta)
+{
+	P_SEC_INFO_T prSecInfo;
+	ENUM_SEC_STATE_T eNextState;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	DEBUGFUNC("secFsmRunEventStartCounterMeasure");
+
+	ASSERT(prSta);
+
+	if (!IS_STA_IN_AIS(prSta)) {
+		DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	prSecInfo = &prSta->rSecInfo;
+
+	eNextState = prSecInfo->eCurrentState;
+
+#if DBG
+	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr,
+			    apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState);
+#endif
+
+	prAdapter->rWifiVar.rAisSpecificBssInfo.u4RsnaLastMICFailTime = 0;
+
+	switch (prSecInfo->eCurrentState) {
+	case SEC_STATE_CHECK_OK:
+		{
+			prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = TRUE;
+
+			/* <Todo> dls port control */
+			SEC_STATE_TRANSITION(prAdapter, prSta, CHECK_OK, SEND_EAPOL);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	/* Call arbFsmSteps() when we are going to change ARB STATE */
+	if (prSecInfo->eCurrentState != eNextState)
+		secFsmSteps(prAdapter, prSta, eNextState);
+
+	return;
+
+}				/* secFsmRunEventStartCounterMeasure */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will indicate an Event of "802.1x EAPoL Tx Done" to Sec FSM.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_SEC_INFO_T prSecInfo;
+	ENUM_SEC_STATE_T eNextState;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+	P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo;
+
+	DEBUGFUNC("secFsmRunEventEapolTxDone");
+
+	ASSERT(prStaRec);
+
+	if (rTxDoneStatus != TX_RESULT_SUCCESS) {
+		DBGLOG(RSN, INFO, "Error EAPoL fram fail to send!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	if (!IS_STA_IN_AIS(prStaRec)) {
+		DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
+
+	ASSERT(prAisBssInfo);
+
+	prSecInfo = &prStaRec->rSecInfo;
+	eNextState = prSecInfo->eCurrentState;
+
+#if DBG
+	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr,
+			    apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState);
+#endif
+
+	switch (prSecInfo->eCurrentState) {
+	case SEC_STATE_SEND_EAPOL:
+		if (prAisBssInfo->fgCheckEAPoLTxDone == FALSE)
+			ASSERT(0);
+
+		prAisBssInfo->fgCheckEAPoLTxDone = FALSE;
+		/* cnmTimerStopTimer(prAdapter, &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer); */
+
+		SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_EAPOL, SEND_DEAUTH);
+		break;
+	default:
+		break;
+	}
+
+	if (prSecInfo->eCurrentState != eNextState)
+		secFsmSteps(prAdapter, prStaRec, eNextState);
+
+	return;
+
+}				/* secFsmRunEventEapolTxDone */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will indicate an Event of "Deauth frame Tx Done" to Sec FSM.
+*
+* \param[in] pMsduInfo            Pointer to the Msdu Info
+* \param[in] rStatus              The Tx done status
+*
+* \return -
+*
+* \note after receive deauth frame, callback function call this
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_STA_RECORD_T prStaRec;
+	P_SEC_INFO_T prSecInfo;
+	ENUM_SEC_STATE_T eNextState;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	DEBUGFUNC("secFsmRunEventDeauthTxDone");
+
+	ASSERT(prMsduInfo);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	ASSERT(prStaRec);
+
+	if (!prStaRec)
+		return;
+
+	if (!IS_STA_IN_AIS(prStaRec)) {
+		DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	prSecInfo = (P_SEC_INFO_T) &prStaRec->rSecInfo;
+
+#if DBG
+	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr,
+			    apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState);
+#endif
+
+	switch (prSecInfo->eCurrentState) {
+	case SEC_STATE_SEND_DEAUTH:
+
+		DBGLOG(RSN, TRACE, "Set timer %d\n", COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC);
+
+		SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_DEAUTH, COUNTERMEASURE);
+
+		break;
+
+	default:
+		ASSERT(0);
+		break;
+	}
+
+}				/* secFsmRunEventDeauthTxDone */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will check the eapol error frame fail to send issue.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm)
+{
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("secFsmRunEventEapolTxTimeout");
+
+	prStaRec = (P_STA_RECORD_T) ulParm;
+
+	ASSERT(prStaRec);
+
+	/* Todo:: How to handle the Eapol Error fail to send case? */
+	ASSERT(0);
+
+	return;
+
+}				/* secFsmEventEapolTxTimeout */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will stop the counterMeasure duration.
+*
+* \param[in] prSta            Pointer to the Sta record
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, ULONG ulParm)
+{
+	P_STA_RECORD_T prSta;
+	P_SEC_INFO_T prSecInfo;
+	ENUM_SEC_STATE_T eNextState;
+	BOOLEAN fgIsTransition = (BOOLEAN) FALSE;
+
+	DEBUGFUNC("secFsmRunEventEndOfCounterMeasure");
+
+	prSta = (P_STA_RECORD_T) ulParm;
+
+	ASSERT(prSta);
+
+	if (!IS_STA_IN_AIS(prSta)) {
+		DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	prSecInfo = &prSta->rSecInfo;
+	eNextState = prSecInfo->eCurrentState;
+
+#if DBG
+	DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr,
+			    apucDebugSecState[prSecInfo->eCurrentState]);
+#else
+	DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState);
+#endif
+
+	switch (prSecInfo->eCurrentState) {
+	case SEC_STATE_SEND_DEAUTH:
+		{
+			prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = FALSE;
+
+			SEC_STATE_TRANSITION(prAdapter, prSta, COUNTERMEASURE, INIT);
+		}
+		break;
+
+	default:
+		ASSERT(0);
+	}
+
+	/* Call arbFsmSteps() when we are going to change ARB STATE */
+	if (prSecInfo->eCurrentState != eNextState)
+		secFsmSteps(prAdapter, prSta, eNextState);
+
+}				/* end of secFsmRunEventEndOfCounterMeasure */
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c
new file mode 100644
index 0000000000000..ab3fcc028375b
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c
@@ -0,0 +1,1342 @@
+/*
+** Id: stats.c#1
+*/
+
+/*! \file stats.c
+    \brief This file includes statistics support.
+*/
+
+/*
+** Log: stats.c
+ *
+ * 07 17 2014 samp.lin
+ * NULL
+ * Initial version.
+ */
+
+/*******************************************************************************
+ *						C O M P I L E R	 F L A G S
+ ********************************************************************************
+ */
+
+/*******************************************************************************
+ *						E X T E R N A L	R E F E R E N C E S
+ ********************************************************************************
+ */
+#include "precomp.h"
+
+enum EVENT_TYPE {
+	EVENT_RX,
+	EVENT_TX,
+	EVENT_TX_DONE
+};
+/*******************************************************************************
+*						C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*						F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen);
+
+static WLAN_STATUS
+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+/*******************************************************************************
+*						P U B L I C   D A T A
+********************************************************************************
+*/
+UINT_64 u8DrvOwnStart, u8DrvOwnEnd;
+UINT32 u4DrvOwnMax = 0;
+#define CFG_USER_LOAD 0
+static UINT_16 su2TxDoneCfg = CFG_DHCP | CFG_ICMP | CFG_EAPOL;
+/*******************************************************************************
+*						P R I V A T E  F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display all environment log.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer, from u4EventSubId
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	P_ADAPTER_T prAdapter;
+	STA_RECORD_T *prStaRec;
+	UINT32 u4NumOfInfo, u4InfoId;
+	UINT32 u4RxErrBitmap;
+	STATS_INFO_ENV_T *prInfo;
+	UINT32 u4Total, u4RateId;
+
+/*
+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok.
+[wlan] statsEventHandle: (INIT INFO) <stats> statsEventHandle: Rcv a event
+[wlan] statsEventHandle: (INIT INFO) <stats> statsEventHandle: Rcv a event: 0
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> Display stats for [00:0c:43:31:35:97]:
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0)
+	TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI,
+		bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack)
+	RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS)
+	BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number)
+	OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK)
+	ERR (1st: total number of tx err, 2nd ~ 7st: total number of
+		WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT,
+		WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3)
+	TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0)
+	RX (1st: latest RCPI, 2nd: chan num)
+	BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number)
+	OK (number of rx packets without error, number of rx packets to OS)
+	ERR (number of rx packets with error)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
+	CCK MODE (1 2 5.5 11M)
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
+	OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M)
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0)
+	MIXED MODE (number of rx packets with MCS0 ~ MCS15)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntH2M us (29 29 32) (0 0 0) (0 0 0)
+	delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> AirTime us (608 864 4480) (0 0 0) (0 0 0)
+	delay from MAC start TX to MAC TX done
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0)
+	delay from HIF to MAC TX done (min, avg, max_system time for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0)
+	delay from driver to MAC TX done (min, avg, max for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0)
+	delay from MAC to HIF (min, avg, max for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0)
+	delay from HIF to Driver OS (min, avg, max for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayCntD2H unit:10ms (10 0 0 0)
+	delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayCnt unit:1ms (6 3 0 1)
+	delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1)
+	delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> OTHER (61877) (0) (38) (0) (0) (0ms)
+	Channel idle time, scan count, channel change count, empty tx quota count,
+	power save change count from active to PS, maximum delay from PS to active
+*/
+
+	/* init */
+	prAdapter = prGlueInfo->prAdapter;
+	/*prInfo = &rStatsInfoEnv;*/
+	prInfo = kalMemAlloc(sizeof(STATS_INFO_ENV_T), VIR_MEM_TYPE);
+	if (prInfo == NULL) {
+		DBGLOG(RX, INFO, "prInfo alloc fail");
+		return;
+	}
+
+	kalMemZero(prInfo, sizeof(STATS_INFO_ENV_T));
+
+	if (u4InBufLen > sizeof(STATS_INFO_ENV_T))
+		u4InBufLen = sizeof(STATS_INFO_ENV_T);
+
+	/* parse */
+	u4NumOfInfo = *(UINT32 *) prInBuf;
+	u4RxErrBitmap = *(UINT32 *) (prInBuf + 4);
+
+	/* print */
+	for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) {
+		/*
+		   use u4InBufLen, not sizeof(rStatsInfoEnv)
+		   because the firmware version maybe not equal to driver version
+		 */
+		kalMemCopy(prInfo, prInBuf + 8, u4InBufLen);
+
+		prStaRec = cnmGetStaRecByIndex(prAdapter, prInfo->ucStaRecIdx);
+		if (prStaRec == NULL)
+			continue;
+
+		DBGLOG(RX, INFO, "<stats> Display stats for [%pM]: %uB\n",
+				    prStaRec->aucMacAddr, (UINT32) sizeof(STATS_INFO_ENV_T));
+
+		if (prStaRec->ucStatsGenDisplayCnt++ > 10) {
+			/* display general statistics information every 10 * (5 or 10s) */
+			DBGLOG(RX, INFO, "<stats> TBA(0x%x %u) RBA(0x%x %u)\n",
+					    prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize,
+					    prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize);
+			prStaRec->ucStatsGenDisplayCnt = 0;
+		}
+
+		if (prInfo->u4TxDataCntErr == 0) {
+			DBGLOG(RX, INFO, "<stats> TOS(%u) OK(%u %u)\n",
+					    (UINT32) prGlueInfo->rNetDevStats.tx_packets,
+					    prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK);
+		} else {
+			DBGLOG(RX, INFO, "<stats> TOS(%u) OK(%u %u) ERR(%u)\n",
+					    (UINT32) prGlueInfo->rNetDevStats.tx_packets,
+					    prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, prInfo->u4TxDataCntErr);
+			DBGLOG(RX, INFO, "<stats> ERR type(%u %u %u %u %u %u)\n",
+					    prInfo->u4TxDataCntErrType[0], prInfo->u4TxDataCntErrType[1],
+					    prInfo->u4TxDataCntErrType[2], prInfo->u4TxDataCntErrType[3],
+					    prInfo->u4TxDataCntErrType[4], prInfo->u4TxDataCntErrType[5]);
+		}
+
+		for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++)
+			u4Total += prInfo->u4TxRateCntNonHT[u4RateId];
+		if (u4Total > 0) {
+			DBGLOG(RX, INFO, "<stats> non-HT TRATE (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n",
+					    prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1],
+					    prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3],
+					    prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5],
+					    prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7],
+					    prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9],
+					    prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11],
+					    prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13],
+					    prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15]);
+		}
+		if (prInfo->u4TxRateCntNonHT[0] > 0) {
+			DBGLOG(RX, INFO, "<stats> HT TRATE (1M %u) (%u %u %u %u %u %u %u %u)\n",
+					    prInfo->u4TxRateCntNonHT[0],
+					    prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1],
+					    prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3],
+					    prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5],
+					    prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]);
+		} else {
+			DBGLOG(RX, INFO, "<stats> HT TRATE (%u %u %u %u %u %u %u %u)\n",
+					    prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1],
+					    prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3],
+					    prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5],
+					    prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]);
+		}
+
+		if ((prStaRec->u4RxReorderFallAheadCnt != 0) ||
+		    (prStaRec->u4RxReorderFallBehindCnt != 0) || (prStaRec->u4RxReorderHoleCnt != 0)) {
+			DBGLOG(RX, INFO, "<stats> TREORDER (%u %u %u)\n",
+					    prStaRec->u4RxReorderFallAheadCnt,
+					    prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt);
+		}
+
+		if (prInfo->u4RxDataCntErr == 0) {
+			DBGLOG(RX, INFO, "<stats> ROK(%u %u)\n",
+					    prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt);
+		} else {
+			DBGLOG(RX, INFO, "<stats> ROK(%u %u) ERR(%u)\n",
+					    prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt,
+					    prInfo->u4RxDataCntErr);
+		}
+
+		for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++)
+			u4Total += prInfo->u4RxRateCnt[0][u4RateId] + prInfo->u4RxRateRetryCnt[0][u4RateId];
+		if (u4Total > 0) {
+			for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++)
+				u4Total += prInfo->u4RxRateRetryCnt[0][u4RateId];
+			if (u4Total > 0) {
+				DBGLOG(RX, INFO,
+					"<stats> RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n"
+					 "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n",
+						    prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0],
+						    prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1],
+						    prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2],
+						    prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3],
+						    prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4],
+						    prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5],
+						    prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6],
+						    prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7],
+						    prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8],
+						    prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9],
+						    prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10],
+						    prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11],
+						    prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12],
+						    prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13],
+						    prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14],
+						    prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15]);
+			} else {
+				DBGLOG(RX, INFO, "<stats> RCCK (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n",
+						    prInfo->u4RxRateCnt[0][0],
+						    prInfo->u4RxRateCnt[0][1],
+						    prInfo->u4RxRateCnt[0][2],
+						    prInfo->u4RxRateCnt[0][3],
+						    prInfo->u4RxRateCnt[0][4],
+						    prInfo->u4RxRateCnt[0][5],
+						    prInfo->u4RxRateCnt[0][6],
+						    prInfo->u4RxRateCnt[0][7],
+						    prInfo->u4RxRateCnt[0][8],
+						    prInfo->u4RxRateCnt[0][9],
+						    prInfo->u4RxRateCnt[0][10],
+						    prInfo->u4RxRateCnt[0][11],
+						    prInfo->u4RxRateCnt[0][12],
+						    prInfo->u4RxRateCnt[0][13],
+						    prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateCnt[0][15]);
+			}
+		} else {
+			if ((prInfo->u4RxRateCnt[0][0] + prInfo->u4RxRateRetryCnt[0][0]) > 0) {
+				DBGLOG(RX, INFO, "<stats> RCCK (%u %u)\n",
+						    prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0]);
+			}
+		}
+
+		for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++)
+			u4Total += prInfo->u4RxRateCnt[1][u4RateId] + prInfo->u4RxRateRetryCnt[1][u4RateId];
+		if (u4Total > 0) {
+			for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++)
+				u4Total += prInfo->u4RxRateRetryCnt[1][u4RateId];
+			if (u4Total > 0) {
+				DBGLOG(RX, INFO,
+					"<stats> ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n"
+					 "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n",
+						    prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0],
+						    prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1],
+						    prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2],
+						    prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3],
+						    prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4],
+						    prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5],
+						    prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6],
+						    prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7],
+						    prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8],
+						    prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9],
+						    prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10],
+						    prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11],
+						    prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12],
+						    prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13],
+						    prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14],
+						    prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15]);
+			} else {
+				DBGLOG(RX, INFO, "<stats> ROFDM (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n",
+						    prInfo->u4RxRateCnt[1][0],
+						    prInfo->u4RxRateCnt[1][1],
+						    prInfo->u4RxRateCnt[1][2],
+						    prInfo->u4RxRateCnt[1][3],
+						    prInfo->u4RxRateCnt[1][4],
+						    prInfo->u4RxRateCnt[1][5],
+						    prInfo->u4RxRateCnt[1][6],
+						    prInfo->u4RxRateCnt[1][7],
+						    prInfo->u4RxRateCnt[1][8],
+						    prInfo->u4RxRateCnt[1][9],
+						    prInfo->u4RxRateCnt[1][10],
+						    prInfo->u4RxRateCnt[1][11],
+						    prInfo->u4RxRateCnt[1][12],
+						    prInfo->u4RxRateCnt[1][13],
+						    prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateCnt[1][15]);
+			}
+		}
+
+		for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++)
+			u4Total += prInfo->u4RxRateCnt[2][u4RateId] + prInfo->u4RxRateRetryCnt[2][u4RateId];
+		if (u4Total > 0) {
+			for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++)
+				u4Total += prInfo->u4RxRateRetryCnt[2][u4RateId];
+			if (u4Total > 0) {
+				DBGLOG(RX, INFO, "<stats> RHT\n"
+						    "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n",
+						    prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0],
+						    prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1],
+						    prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2],
+						    prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3],
+						    prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4],
+						    prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5],
+						    prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6],
+						    prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7]);
+			} else {
+				DBGLOG(RX, INFO, "<stats> RHT (%u %u %u %u %u %u %u %u)\n",
+						    prInfo->u4RxRateCnt[2][0],
+						    prInfo->u4RxRateCnt[2][1],
+						    prInfo->u4RxRateCnt[2][2],
+						    prInfo->u4RxRateCnt[2][3],
+						    prInfo->u4RxRateCnt[2][4],
+						    prInfo->u4RxRateCnt[2][5],
+						    prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateCnt[2][7]);
+			}
+		}
+
+		/* RX drop counts */
+		for (u4RateId = 0, u4Total = 0; u4RateId < 20; u4RateId++)
+			u4Total += prInfo->u4NumOfRxDrop[u4RateId];
+		if (u4Total > 0) {
+			DBGLOG(RX, INFO, "<stats> RX Drop Count: (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n"
+					    " (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n",
+					    prInfo->u4NumOfRxDrop[0], prInfo->u4NumOfRxDrop[1],
+					    prInfo->u4NumOfRxDrop[2], prInfo->u4NumOfRxDrop[3],
+					    prInfo->u4NumOfRxDrop[4], prInfo->u4NumOfRxDrop[5],
+					    prInfo->u4NumOfRxDrop[6], prInfo->u4NumOfRxDrop[7],
+					    prInfo->u4NumOfRxDrop[8], prInfo->u4NumOfRxDrop[9],
+					    prInfo->u4NumOfRxDrop[10], prInfo->u4NumOfRxDrop[11],
+					    prInfo->u4NumOfRxDrop[12], prInfo->u4NumOfRxDrop[13],
+					    prInfo->u4NumOfRxDrop[14], prInfo->u4NumOfRxDrop[15],
+					    prInfo->u4NumOfRxDrop[16], prInfo->u4NumOfRxDrop[17],
+					    prInfo->u4NumOfRxDrop[18], prInfo->u4NumOfRxDrop[19]);
+		}
+
+		/* delay from HIF RX to HIF RX Done */
+		if (((prInfo->u4StayIntMinHR2HRD[1] + prInfo->u4StayIntAvgHR2HRD[1] +
+		      prInfo->u4StayIntMaxHR2HRD[1]) > 0) ||
+		    ((prInfo->u4StayIntMinHR2HRD[2] + prInfo->u4StayIntAvgHR2HRD[2] +
+		      prInfo->u4StayIntMaxHR2HRD[2]) > 0)) {
+			DBGLOG(RX, INFO, "<stats> StayIntR_HR2HRD us (%u %u %u) (%u %u %u) (%u %u %u)\n",
+					    prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0],
+					    prInfo->u4StayIntMaxHR2HRD[0],
+					    prInfo->u4StayIntMinHR2HRD[1], prInfo->u4StayIntAvgHR2HRD[1],
+					    prInfo->u4StayIntMaxHR2HRD[1],
+					    prInfo->u4StayIntMinHR2HRD[2], prInfo->u4StayIntAvgHR2HRD[2],
+					    prInfo->u4StayIntMaxHR2HRD[2]);
+		} else {
+			DBGLOG(RX, INFO, "<stats> StayIntR_HR2HRD us (%u %u %u)\n",
+					    prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0],
+					    prInfo->u4StayIntMaxHR2HRD[0]);
+		}
+
+		/* others */
+		DBGLOG(RX, INFO, "<stats> OTHER (%u) (%u) (%u) (%x)\n",
+				    prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime,
+				    prInfo->u4NumOfChanChange, prInfo->u4CurrChnlInfo);
+#if CFG_SUPPORT_THERMO_THROTTLING
+		prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000;
+#endif
+		/* reset */
+		kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx));
+		kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx));
+		kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx));
+		prStaRec->u4StatsRxPassToOsCnt = 0;
+		prStaRec->u4RxReorderFallAheadCnt = 0;
+		prStaRec->u4RxReorderFallBehindCnt = 0;
+		prStaRec->u4RxReorderHoleCnt = 0;
+	}
+
+	STATS_DRIVER_OWN_RESET();
+	kalMemFree(prInfo, VIR_MEM_TYPE, sizeof(STATS_INFO_ENV_T));
+}
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display all environment log.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer, from u4EventSubId
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	P_ADAPTER_T prAdapter;
+	STA_RECORD_T *prStaRec;
+	UINT32 u4NumOfInfo, u4InfoId;
+	UINT32 u4RxErrBitmap;
+	STATS_INFO_ENV_T rStatsInfoEnv, *prInfo;
+
+/*
+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok.
+[wlan] statsEventHandle: (INIT INFO) <stats> statsEventHandle: Rcv a event
+[wlan] statsEventHandle: (INIT INFO) <stats> statsEventHandle: Rcv a event: 0
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> Display stats for [00:0c:43:31:35:97]:
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0)
+	TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI,
+		bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack)
+	RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS)
+	BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number)
+	OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK)
+	ERR (1st: total number of tx err, 2nd ~ 7st: total number of
+		WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT,
+		WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3)
+	TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0)
+	RX (1st: latest RCPI, 2nd: chan num)
+	BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number)
+	OK (number of rx packets without error, number of rx packets to OS)
+	ERR (number of rx packets with error)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
+	CCK MODE (1 2 5.5 11M)
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
+	OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M)
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0)
+	MIXED MODE (number of rx packets with MCS0 ~ MCS15)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntH2M us (29 29 32) (0 0 0) (0 0 0)
+	delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> AirTime us (608 864 4480) (0 0 0) (0 0 0)
+	delay from MAC start TX to MAC TX done
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0)
+	delay from HIF to MAC TX done (min, avg, max_system time for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0)
+	delay from driver to MAC TX done (min, avg, max for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0)
+	delay from MAC to HIF (min, avg, max for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0)
+	delay from HIF to Driver OS (min, avg, max for 500B)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayCntD2H unit:10ms (10 0 0 0)
+	delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayCnt unit:1ms (6 3 0 1)
+	delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1)
+	delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others)
+
+[wlan] statsInfoEnvDisplay: (INIT INFO) <stats> OTHER (61877) (0) (38) (0) (0) (0ms)
+	Channel idle time, scan count, channel change count, empty tx quota count,
+	power save change count from active to PS, maximum delay from PS to active
+*/
+
+	/* init */
+	prAdapter = prGlueInfo->prAdapter;
+	prInfo = &rStatsInfoEnv;
+	kalMemZero(&rStatsInfoEnv, sizeof(rStatsInfoEnv));
+
+	if (u4InBufLen > sizeof(rStatsInfoEnv))
+		u4InBufLen = sizeof(rStatsInfoEnv);
+
+	/* parse */
+	u4NumOfInfo = *(UINT32 *) prInBuf;
+	u4RxErrBitmap = *(UINT32 *) (prInBuf + 4);
+
+	/* print */
+	for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) {
+		/*
+		   use u4InBufLen, not sizeof(rStatsInfoEnv)
+		   because the firmware version maybe not equal to driver version
+		 */
+		kalMemCopy(&rStatsInfoEnv, prInBuf + 8, u4InBufLen);
+
+		prStaRec = cnmGetStaRecByIndex(prAdapter, rStatsInfoEnv.ucStaRecIdx);
+		if (prStaRec == NULL)
+			continue;
+
+		DBGLOG(RX, INFO, "<stats> Display stats V%d.%d for [%pM]: %uB %ums\n",
+				    prInfo->ucFwVer[0], prInfo->ucFwVer[1],
+				    (prStaRec->aucMacAddr), (UINT32) sizeof(STATS_INFO_ENV_T),
+				    prInfo->u4ReportSysTime);
+		DBGLOG(RX, INFO, "<stats>TPAM(0x%x)RTS(%u %u)BA(0x%x %u)OS(%u)OK(%u %u)ERR(%u %u %u %u %u %u %u)\n",
+				    prInfo->ucTxParam,
+				    prInfo->fgTxIsRtsUsed, prInfo->fgTxIsRtsEverUsed,
+				    prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize,
+				    (UINT32) prGlueInfo->rNetDevStats.tx_packets,
+				    prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK,
+				    prInfo->u4TxDataCntErr, prInfo->u4TxDataCntErrType[0],
+				    prInfo->u4TxDataCntErrType[1], prInfo->u4TxDataCntErrType[2],
+				    prInfo->u4TxDataCntErrType[3], prInfo->u4TxDataCntErrType[4],
+				    prInfo->u4TxDataCntErrType[5]));
+
+		DBGLOG(RX, INFO, "TRATE(%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n",
+				    prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1],
+				    prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3],
+				    prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5],
+				    prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7],
+				    prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9],
+				    prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11],
+				    prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13],
+				    prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15],
+				    prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1],
+				    prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3],
+				    prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5],
+				    prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]));
+
+		DBGLOG(RX, INFO, "<stats> TREORDER (%u %u %u)\n",
+				    prStaRec->u4RxReorderFallAheadCnt,
+				    prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt);
+
+		DBGLOG(RX, INFO, "<stats> RX(%u %u %u) BA(0x%x %u) OK(%u %u) ERR(%u)\n",
+				    prInfo->ucRcvRcpi, prInfo->ucHwChanNum, prInfo->fgRxIsShortGI,
+				    prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize,
+				    prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, prInfo->u4RxDataCntErr);
+
+		DBGLOG(RX, INFO, "<stats> RX Free MAC DESC(%u %u %u %u %u %u) Free HIF DESC(%u %u %u %u %u %u)\n",
+				    prInfo->u4RxMacFreeDescCnt[0], prInfo->u4RxMacFreeDescCnt[1],
+				    prInfo->u4RxMacFreeDescCnt[2], prInfo->u4RxMacFreeDescCnt[3],
+				    prInfo->u4RxMacFreeDescCnt[4], prInfo->u4RxMacFreeDescCnt[5],
+				    prInfo->u4RxHifFreeDescCnt[0], prInfo->u4RxHifFreeDescCnt[1],
+				    prInfo->u4RxHifFreeDescCnt[2], prInfo->u4RxHifFreeDescCnt[3],
+				    prInfo->u4RxHifFreeDescCnt[4], prInfo->u4RxHifFreeDescCnt[5]));
+
+		DBGLOG(RX, INFO, "<stats> RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n"
+				    "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n",
+				    prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0],
+				    prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1],
+				    prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2],
+				    prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3],
+				    prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4],
+				    prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5],
+				    prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6],
+				    prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7],
+				    prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8],
+				    prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9],
+				    prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10],
+				    prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11],
+				    prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12],
+				    prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13],
+				    prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14],
+				    prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15]));
+		DBGLOG(RX, INFO, "<stats> ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n"
+				    "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n",
+				    prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0],
+				    prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1],
+				    prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2],
+				    prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3],
+				    prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4],
+				    prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5],
+				    prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6],
+				    prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7],
+				    prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8],
+				    prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9],
+				    prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10],
+				    prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11],
+				    prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12],
+				    prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13],
+				    prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14],
+				    prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15]));
+		DBGLOG(RX, INFO, "<stats> RHT (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n"
+				    "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n",
+				    prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0],
+				    prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1],
+				    prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2],
+				    prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3],
+				    prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4],
+				    prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5],
+				    prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6],
+				    prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7],
+				    prInfo->u4RxRateCnt[2][8], prInfo->u4RxRateRetryCnt[2][8],
+				    prInfo->u4RxRateCnt[2][9], prInfo->u4RxRateRetryCnt[2][9],
+				    prInfo->u4RxRateCnt[2][10], prInfo->u4RxRateRetryCnt[2][10],
+				    prInfo->u4RxRateCnt[2][11], prInfo->u4RxRateRetryCnt[2][11],
+				    prInfo->u4RxRateCnt[2][12], prInfo->u4RxRateRetryCnt[2][12],
+				    prInfo->u4RxRateCnt[2][13], prInfo->u4RxRateRetryCnt[2][13],
+				    prInfo->u4RxRateCnt[2][14], prInfo->u4RxRateRetryCnt[2][14],
+				    prInfo->u4RxRateCnt[2][15], prInfo->u4RxRateRetryCnt[2][15]));
+
+		/* delay from HIF to MAC */
+		DBGLOG(RX, INFO, "<stats> StayIntH2M us (%u %u %u) (%u %u %u) (%u %u %u)\n",
+				    prInfo->u4StayIntMinH2M[0], prInfo->u4StayIntAvgH2M[0],
+				    prInfo->u4StayIntMaxH2M[0],
+				    prInfo->u4StayIntMinH2M[1], prInfo->u4StayIntAvgH2M[1],
+				    prInfo->u4StayIntMaxH2M[1],
+				    prInfo->u4StayIntMinH2M[2], prInfo->u4StayIntAvgH2M[2],
+				    prInfo->u4StayIntMaxH2M[2]));
+		/* delay from MAC to TXDONE */
+		DBGLOG(RX, INFO, "<stats> AirTime us (%u %u %u) (%u %u %u) (%u %u %u)\n",
+				    prInfo->u4AirDelayMin[0] << 5, prInfo->u4AirDelayAvg[0] << 5,
+				    prInfo->u4AirDelayMax[0] << 5,
+				    prInfo->u4AirDelayMin[1] << 5, prInfo->u4AirDelayAvg[1] << 5,
+				    prInfo->u4AirDelayMax[1] << 5,
+				    prInfo->u4TxDataCntAll, (prInfo->u4AirDelayAvg[2] << 5) / (prInfo->u4TxDataCntAll),
+				    (prInfo->u4AirDelayAvg[2] << 5) / 400000));
+		prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000;
+		/* delay from HIF to TXDONE */
+		DBGLOG(RX, INFO, "<stats> StayInt us (%u %u %u_%u) (%u %u %u_%u) (%u %u %u_%u)\n",
+				    prInfo->u4StayIntMin[0], prInfo->u4StayIntAvg[0],
+				    prInfo->u4StayIntMax[0], prInfo->u4StayIntMaxSysTime[0],
+				    prInfo->u4StayIntMin[1], prInfo->u4StayIntAvg[1],
+				    prInfo->u4StayIntMax[1], prInfo->u4StayIntMaxSysTime[1],
+				    prInfo->u4StayIntMin[2], prInfo->u4StayIntAvg[2],
+				    prInfo->u4StayIntMax[2], prInfo->u4StayIntMaxSysTime[2]));
+		/* delay from Driver to TXDONE */
+		DBGLOG(RX, INFO, "<stats> StayIntD2T us (%u %u %u) (%u %u %u) (%u %u %u)\n",
+				    prInfo->u4StayIntMinD2T[0], prInfo->u4StayIntAvgD2T[0],
+				    prInfo->u4StayIntMaxD2T[0],
+				    prInfo->u4StayIntMinD2T[1], prInfo->u4StayIntAvgD2T[1],
+				    prInfo->u4StayIntMaxD2T[1],
+				    prInfo->u4StayIntMinD2T[2], prInfo->u4StayIntAvgD2T[2],
+				    prInfo->u4StayIntMaxD2T[2]));
+
+		/* delay from RXDONE to HIF */
+		DBGLOG(RX, INFO, "<stats> StayIntR_M2H us (%u %u %u) (%u %u %u) (%u %u %u)\n",
+				    prInfo->u4StayIntMinRx[0], prInfo->u4StayIntAvgRx[0],
+				    prInfo->u4StayIntMaxRx[0],
+				    prInfo->u4StayIntMinRx[1], prInfo->u4StayIntAvgRx[1],
+				    prInfo->u4StayIntMaxRx[1],
+				    prInfo->u4StayIntMinRx[2], prInfo->u4StayIntAvgRx[2], prInfo->u4StayIntMaxRx[2]));
+		/* delay from HIF to OS */
+		DBGLOG(RX, INFO, "<stats> StayIntR_H2D us (%u %u %u) (%u %u %u) (%u %u %u)\n",
+				    prStaRec->u4StayIntMinRx[0], prStaRec->u4StayIntAvgRx[0],
+				    prStaRec->u4StayIntMaxRx[0],
+				    prStaRec->u4StayIntMinRx[1], prStaRec->u4StayIntAvgRx[1],
+				    prStaRec->u4StayIntMaxRx[1],
+				    prStaRec->u4StayIntMinRx[2], prStaRec->u4StayIntAvgRx[2],
+				    prStaRec->u4StayIntMaxRx[2]));
+
+		/* count based on delay from OS to HIF */
+		DBGLOG(RX, INFO, "<stats> StayCntD2H unit:%dms (%d %d %d %d)\n",
+				    STATS_STAY_INT_D2H_CONST,
+				    prInfo->u4StayIntD2HByConst[0], prInfo->u4StayIntD2HByConst[1],
+				    prInfo->u4StayIntD2HByConst[2], prInfo->u4StayIntD2HByConst[3]);
+
+		/* count based on different delay from HIF to TX DONE */
+		DBGLOG(RX, INFO, "<stats> StayCnt unit:%dms (%d %d %d %d)\n",
+				    STATS_STAY_INT_CONST,
+				    prInfo->u4StayIntByConst[0], prInfo->u4StayIntByConst[1],
+				    prInfo->u4StayIntByConst[2], prInfo->u4StayIntByConst[3]);
+		DBGLOG(RX, INFO, "<stats> StayCnt (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~:%d)\n",
+				    0, prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntCnt[0],
+				    prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntCnt[1],
+				    prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntMaxPast * 3 / 4,
+				    prInfo->u4StayIntCnt[2], prInfo->u4StayIntMaxPast * 3 / 4, prInfo->u4StayIntMaxPast,
+				    prInfo->u4StayIntCnt[3], prInfo->u4StayIntMaxPast, prInfo->u4StayIntCnt[4]));
+
+		/* channel idle time */
+		DBGLOG(RX, INFO, "<stats> Idle Time (slot): (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n",
+				    prInfo->au4ChanIdleCnt[0], prInfo->au4ChanIdleCnt[1],
+				    prInfo->au4ChanIdleCnt[2], prInfo->au4ChanIdleCnt[3],
+				    prInfo->au4ChanIdleCnt[4], prInfo->au4ChanIdleCnt[5],
+				    prInfo->au4ChanIdleCnt[6], prInfo->au4ChanIdleCnt[7],
+				    prInfo->au4ChanIdleCnt[8], prInfo->au4ChanIdleCnt[9]));
+
+		/* BT coex */
+		DBGLOG(RX, INFO, "<stats> BT coex (0x%x)\n", prInfo->u4BtContUseTime);
+
+		/* others */
+		DBGLOG(RX, INFO, "<stats> OTHER (%u) (%u) (%u) (%u) (%u) (%ums) (%uus)\n",
+				    prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime,
+				    prInfo->u4NumOfChanChange, prStaRec->u4NumOfNoTxQuota,
+				    prInfo->ucNumOfPsChange, prInfo->u4PsIntMax, u4DrvOwnMax / 1000);
+
+		/* reset */
+		kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx));
+		kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx));
+		kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx));
+		prStaRec->u4StatsRxPassToOsCnt = 0;
+		prStaRec->u4RxReorderFallAheadCnt = 0;
+		prStaRec->u4RxReorderFallBehindCnt = 0;
+		prStaRec->u4RxReorderHoleCnt = 0;
+	}
+
+	STATS_DRIVER_OWN_RESET();
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to request firmware to feedback statistics.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static WLAN_STATUS
+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	STATS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* sanity check */
+	if (fgIsUnderSuspend == true)
+		return WLAN_STATUS_SUCCESS;	/* do not request stats after early suspend */
+
+	/* init command buffer */
+	prCmdContent = (STATS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = STATS_CORE_CMD_ENV_REQUEST;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_STATS,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(STATS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(RX, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return WLAN_STATUS_RESOURCES;
+	}
+
+	DBGLOG(RX, INFO, "%s cmd ok.\n", __func__);
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+*						P U B L I C  F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to handle any statistics event.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	UINT32 u4EventId;
+
+	/* sanity check */
+/* DBGLOG(RX, INFO, */
+/* ("<stats> %s: Rcv a event\n", __FUNCTION__)); */
+
+	if ((prGlueInfo == NULL) || (prInBuf == NULL))
+		return;		/* shall not be here */
+
+	/* handle */
+	u4EventId = *(UINT32 *) prInBuf;
+	u4InBufLen -= 4;
+
+/* DBGLOG(RX, INFO, */
+/* ("<stats> %s: Rcv a event: %d\n", __FUNCTION__, u4EventId)); */
+
+	switch (u4EventId) {
+	case STATS_HOST_EVENT_ENV_REPORT:
+		statsInfoEnvDisplay(prGlueInfo, prInBuf + 4, u4InBufLen);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to detect if we can request firmware to feedback statistics.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] ucStaRecIndex	The station index
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex)
+{
+	STA_RECORD_T *prStaRec;
+	OS_SYSTIME rCurTime;
+	STATS_CMD_CORE_T rCmd;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex);
+	if (prStaRec == NULL)
+		return;
+
+	prStaRec->u4StatsEnvTxCnt++;
+	GET_CURRENT_SYSTIME(&rCurTime);
+
+	if (prStaRec->rStatsEnvTxPeriodLastTime == 0) {
+		prStaRec->rStatsEnvTxLastTime = rCurTime;
+		prStaRec->rStatsEnvTxPeriodLastTime = rCurTime;
+		return;
+	}
+
+	if (prStaRec->u4StatsEnvTxCnt > STATS_ENV_TX_CNT_REPORT_TRIGGER) {
+		if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxLastTime,
+				      SEC_TO_SYSTIME(STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC))) {
+			rCmd.ucStaRecIdx = ucStaRecIndex;
+			statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL);
+
+			prStaRec->rStatsEnvTxLastTime = rCurTime;
+			prStaRec->rStatsEnvTxPeriodLastTime = rCurTime;
+			prStaRec->u4StatsEnvTxCnt = 0;
+			return;
+		}
+	}
+
+	if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxPeriodLastTime, SEC_TO_SYSTIME(STATS_ENV_TIMEOUT_SEC))) {
+		rCmd.ucStaRecIdx = ucStaRecIndex;
+		statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL);
+
+		prStaRec->rStatsEnvTxPeriodLastTime = rCurTime;
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to handle rx done.
+*
+* \param[in] prStaRec		Pointer to the STA_RECORD_T structure
+* \param[in] prSwRfb		Pointer to the received packet
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb)
+{
+	UINT32 u4LenId;
+	UINT32 u4CurTime, u4DifTime;
+
+	/* sanity check */
+	if (prStaRec == NULL)
+		return;
+
+	/* stats: rx done count */
+	prStaRec->u4StatsRxPassToOsCnt++;
+
+	/* get length partition ID */
+	u4LenId = 0;
+	if (prSwRfb->u2PacketLen < STATS_STAY_INT_BYTE_THRESHOLD) {
+		u4LenId = 0;
+	} else {
+		if ((STATS_STAY_INT_BYTE_THRESHOLD <= prSwRfb->u2PacketLen) &&
+		    (prSwRfb->u2PacketLen < (STATS_STAY_INT_BYTE_THRESHOLD << 1))) {
+			u4LenId = 1;
+		} else
+			u4LenId = 2;
+	}
+
+	/* stats: rx delay */
+	u4CurTime = kalGetTimeTick();
+
+	if ((u4CurTime > prSwRfb->rRxTime) && (prSwRfb->rRxTime != 0)) {
+		u4DifTime = u4CurTime - prSwRfb->rRxTime;
+
+		if (prStaRec->u4StayIntMinRx[u4LenId] == 0)	/* impossible */
+			prStaRec->u4StayIntMinRx[u4LenId] = 0xffffffff;
+
+		if (u4DifTime > prStaRec->u4StayIntMaxRx[u4LenId])
+			prStaRec->u4StayIntMaxRx[u4LenId] = u4DifTime;
+		else if (u4DifTime < prStaRec->u4StayIntMinRx[u4LenId])
+			prStaRec->u4StayIntMinRx[u4LenId] = u4DifTime;
+
+		prStaRec->u4StayIntAvgRx[u4LenId] += u4DifTime;
+		if (prStaRec->u4StayIntAvgRx[u4LenId] != u4DifTime)
+			prStaRec->u4StayIntAvgRx[u4LenId] >>= 1;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to handle rx done.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+UINT_64 StatsEnvTimeGet(VOID)
+{
+	/* TODO: use better API to get time to save time, jiffies unit is 10ms, too large */
+
+/* struct timeval tv; */
+
+/* do_gettimeofday(&tv); */
+/* return tv.tv_usec + tv.tv_sec * (UINT_64)1000000; */
+
+	UINT_64 u8Clk;
+/* UINT32 *pClk = &u8Clk; */
+
+	u8Clk = sched_clock();	/* unit: naro seconds */
+/* printk("<stats> sched_clock() = %x %x %u\n", pClk[0], pClk[1], sizeof(jiffies)); */
+
+	return (UINT_64) u8Clk;	/* sched_clock *//* jiffies size = 4B */
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to handle rx done.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader)
+{
+	UINT_64 u8SysTime, u8SysTimeIn;
+	UINT32 u4TimeDiff;
+
+	u8SysTime = StatsEnvTimeGet();
+	u8SysTimeIn = GLUE_GET_PKT_XTIME(prMsduInfo->prPacket);
+
+/* printk("<stats> hif: 0x%x %u %u %u\n", */
+/* prMsduInfo->prPacket, StatsEnvTimeGet(), u8SysTime, GLUE_GET_PKT_XTIME(prMsduInfo->prPacket)); */
+
+	if ((u8SysTimeIn > 0) && (u8SysTime > u8SysTimeIn)) {
+		u8SysTime = u8SysTime - u8SysTimeIn;
+		u4TimeDiff = (UINT32) u8SysTime;
+		u4TimeDiff = u4TimeDiff / 1000;	/* ns to us */
+
+		/* pass the delay between OS to us and we to HIF */
+		if (u4TimeDiff > 0xFFFF)
+			*(UINT16 *) prHwTxHeader->aucReserved = (UINT16) 0xFFFF;	/* 65535 us */
+		else
+			*(UINT16 *) prHwTxHeader->aucReserved = (UINT16) u4TimeDiff;
+
+/* printk("<stats> u4TimeDiff: %u\n", u4TimeDiff); */
+	} else {
+		prHwTxHeader->aucReserved[0] = 0;
+		prHwTxHeader->aucReserved[1] = 0;
+	}
+}
+
+static VOID statsParsePktInfo(PUINT_8 pucPkt, UINT_8 status, UINT_8 eventType, P_MSDU_INFO_T prMsduInfo)
+{
+	/* get ethernet protocol */
+	UINT_16 u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]);
+	PUINT_8 pucEthBody = &pucPkt[ETH_HLEN];
+
+	switch (u2EtherType) {
+	case ETH_P_ARP:
+	{
+		UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7];
+		if (eventType == EVENT_TX)
+			prMsduInfo->fgIsBasicRate = TRUE;
+
+		if ((su2TxDoneCfg & CFG_ARP) == 0)
+			break;
+
+		switch (eventType) {
+		case EVENT_RX:
+			if (u2OpCode == ARP_PRO_REQ)
+				DBGLOG(RX, INFO, "<RX> Arp Req From IP: %d.%d.%d.%d\n",
+					pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]);
+			else if (u2OpCode == ARP_PRO_RSP)
+				DBGLOG(RX, INFO, "<RX> Arp Rsp from IP: %d.%d.%d.%d\n",
+					pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]);
+			break;
+		case EVENT_TX:
+			if (u2OpCode == ARP_PRO_REQ)
+				DBGLOG(TX, INFO, "<TX> Arp Req to IP: %d.%d.%d.%d\n",
+					pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]);
+			else if (u2OpCode == ARP_PRO_RSP)
+				DBGLOG(TX, INFO, "<TX> Arp Rsp to IP: %d.%d.%d.%d\n",
+					pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]);
+			prMsduInfo->fgNeedTxDoneStatus = TRUE;
+			break;
+		case EVENT_TX_DONE:
+			if (u2OpCode == ARP_PRO_REQ)
+				DBGLOG(TX, INFO, "<TX status:%d> Arp Req to IP: %d.%d.%d.%d\n", status,
+					pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]);
+			else if (u2OpCode == ARP_PRO_RSP)
+				DBGLOG(TX, INFO, "<TX status:%d> Arp Rsp to IP: %d.%d.%d.%d\n", status,
+					pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]);
+			break;
+		}
+		break;
+	}
+	case ETH_P_IP:
+	{
+		UINT_8 ucIpProto = pucEthBody[9]; /* IP header without options */
+		UINT_8 ucIpVersion = (pucEthBody[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
+		UINT_16 u2IpId = pucEthBody[4]<<8 | pucEthBody[5];
+
+		if (ucIpVersion != IPVERSION)
+			break;
+
+		switch (ucIpProto) {
+		case IP_PRO_ICMP:
+		{
+			/* the number of ICMP packets is seldom so we print log here */
+			UINT_8 ucIcmpType;
+			UINT_16 u2IcmpId, u2IcmpSeq;
+			PUINT_8 pucIcmp = &pucEthBody[20];
+
+			ucIcmpType = pucIcmp[0];
+			/* don't log network unreachable packet */
+			if (((su2TxDoneCfg & CFG_ICMP) == 0) || ucIcmpType == 3)
+				break;
+			u2IcmpId = *(UINT_16 *) &pucIcmp[4];
+			u2IcmpSeq = *(UINT_16 *) &pucIcmp[6];
+			switch (eventType) {
+			case EVENT_RX:
+				DBGLOG(RX, INFO, "<RX> ICMP: Type %d, Id BE 0x%04x, Seq BE 0x%04x\n",
+							ucIcmpType, u2IcmpId, u2IcmpSeq);
+				break;
+			case EVENT_TX:
+				DBGLOG(TX, INFO, "<TX> ICMP: Type %d, Id 0x04%x, Seq BE 0x%04x\n",
+								ucIcmpType, u2IcmpId, u2IcmpSeq);
+				prMsduInfo->fgNeedTxDoneStatus = TRUE;
+				break;
+			case EVENT_TX_DONE:
+				DBGLOG(TX, INFO, "<TX status:%d> Type %d, Id 0x%04x, Seq 0x%04x\n",
+						status, ucIcmpType, u2IcmpId, u2IcmpSeq);
+				break;
+			}
+			break;
+		}
+		case IP_PRO_UDP:
+		{
+			/* the number of DHCP packets is seldom so we print log here */
+			PUINT_8 pucUdp = &pucEthBody[20];
+			PUINT_8 pucUdpPayload = &pucUdp[8];
+			UINT_16 u2UdpDstPort;
+			UINT_16 u2UdpSrcPort;
+
+			u2UdpDstPort = (pucUdp[2] << 8) | pucUdp[3];
+			u2UdpSrcPort = (pucUdp[0] << 8) | pucUdp[1];
+			/* dhcp */
+			if ((u2UdpDstPort == UDP_PORT_DHCPS) || (u2UdpDstPort == UDP_PORT_DHCPC)) {
+				UINT_32 u4TransID = pucUdpPayload[4]<<24 | pucUdpPayload[5]<<16 |
+						pucUdpPayload[6]<<8  | pucUdpPayload[7];
+
+				switch (eventType) {
+				case EVENT_RX:
+					DBGLOG(RX, INFO, "<RX> DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n",
+									u2IpId, pucUdpPayload[0], u4TransID);
+					break;
+				case EVENT_TX:
+					DBGLOG(TX, INFO, "<TX> DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n",
+									u2IpId, pucUdpPayload[0], u4TransID);
+					prMsduInfo->fgNeedTxDoneStatus = TRUE;
+					prMsduInfo->fgIsBasicRate = TRUE;
+					break;
+				case EVENT_TX_DONE:
+					DBGLOG(TX, INFO,
+						"<TX status:%d> DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n",
+							status, u2IpId, pucUdpPayload[0], u4TransID);
+					break;
+				}
+			} else if (u2UdpDstPort == UDP_PORT_DNS) { /* tx dns */
+				UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1];
+				if (eventType == EVENT_TX)
+					prMsduInfo->fgIsBasicRate = TRUE;
+
+				if ((su2TxDoneCfg & CFG_DNS) == 0)
+					break;
+				if (eventType == EVENT_TX) {
+					DBGLOG(TX, INFO, "<TX> DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId);
+					prMsduInfo->fgNeedTxDoneStatus = TRUE;
+				} else if (eventType == EVENT_TX_DONE)
+					DBGLOG(TX, INFO, "<TX status:%d> DNS: IPID 0x%02x, TransID 0x%04x\n",
+							status, u2IpId, u2TransId);
+			} else if (u2UdpSrcPort == UDP_PORT_DNS && eventType == EVENT_RX) { /* rx dns */
+				UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1];
+
+				if ((su2TxDoneCfg & CFG_DNS) == 0)
+					break;
+				DBGLOG(RX, INFO, "<RX> DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId);
+			} else if ((su2TxDoneCfg & CFG_UDP) != 0) {
+				switch (eventType) {
+				case EVENT_RX:
+					DBGLOG(RX, INFO, "<RX> UDP: IPID 0x%04x\n", u2IpId);
+					break;
+				case EVENT_TX:
+					DBGLOG(TX, INFO, "<TX> UDP: IPID 0x%04x\n", u2IpId);
+					prMsduInfo->fgNeedTxDoneStatus = TRUE;
+					break;
+				case EVENT_TX_DONE:
+					DBGLOG(TX, INFO, "<TX status:%d> UDP: IPID 0x%04x\n", status, u2IpId);
+					break;
+				}
+			}
+			break;
+		}
+		case IP_PRO_TCP:
+			if ((su2TxDoneCfg & CFG_TCP) == 0)
+				break;
+
+			switch (eventType) {
+			case EVENT_RX:
+				DBGLOG(RX, INFO, "<RX> TCP: IPID 0x%04x\n", u2IpId);
+				break;
+			case EVENT_TX:
+				DBGLOG(TX, INFO, "<TX> TCP: IPID 0x%04x\n", u2IpId);
+				prMsduInfo->fgNeedTxDoneStatus = TRUE;
+				break;
+			case EVENT_TX_DONE:
+				DBGLOG(TX, INFO, "<TX status:%d> TCP: IPID 0x%04x\n", status, u2IpId);
+				break;
+			}
+			break;
+		}
+		break;
+	}
+	case ETH_P_PRE_1X:
+		DBGLOG(RX, INFO, "pre-1x\n");
+	case ETH_P_1X:
+	{
+		PUINT_8 pucEapol = pucEthBody;
+		UINT_8 ucEapolType = pucEapol[1];
+
+		switch (ucEapolType) {
+		case 0: /* eap packet */
+			switch (eventType) {
+			case EVENT_RX:
+				DBGLOG(RX, INFO, "<RX> EAP Packet: code %d, id %d, type %d\n",
+						pucEapol[4], pucEapol[5], pucEapol[7]);
+				break;
+			case EVENT_TX:
+				DBGLOG(TX, INFO, "<TX> EAP Packet: code %d, id %d, type %d\n",
+						pucEapol[4], pucEapol[5], pucEapol[7]);
+				break;
+			case EVENT_TX_DONE:
+				DBGLOG(TX, INFO, "<TX status: %d> EAP Packet: code %d, id %d, type %d\n",
+						status, pucEapol[4], pucEapol[5], pucEapol[7]);
+				break;
+			}
+			break;
+		case 1: /* eapol start */
+			switch (eventType) {
+			case EVENT_RX:
+				DBGLOG(RX, INFO, "<RX> EAPOL: start\n");
+				break;
+			case EVENT_TX:
+				DBGLOG(TX, INFO, "<RX> EAPOL: start\n");
+				break;
+			case EVENT_TX_DONE:
+				DBGLOG(TX, INFO, "<TX status: %d> EAPOL: start\n", status);
+				break;
+			}
+			break;
+		case 3: /* key */
+		{
+			UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6];
+
+			switch (eventType) {
+			case EVENT_RX:
+				DBGLOG(RX, INFO,
+					"<RX> EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n",
+					u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20],
+					pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]);
+				break;
+			case EVENT_TX:
+				DBGLOG(TX, INFO,
+					"<TX> EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n",
+					u2KeyInfo,
+					pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20],
+					pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]);
+				break;
+			case EVENT_TX_DONE:
+				DBGLOG(TX, INFO,
+					"<TX status: %d> EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n",
+					status, u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19],
+					pucEapol[20], pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]);
+				break;
+			}
+
+			break;
+		}
+		}
+		break;
+	}
+	case ETH_WPI_1X:
+	{
+		UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/
+		UINT_16 u2Length = *(PUINT_16)&pucEthBody[6];
+		UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8];
+
+		switch (eventType) {
+		case EVENT_RX:
+			DBGLOG(RX, INFO, "<RX> WAPI: subType %d, Len %d, Seq %d\n",
+					ucSubType, u2Length, u2Seq);
+			break;
+		case EVENT_TX:
+			DBGLOG(TX, INFO, "<TX> WAPI: subType %d, Len %d, Seq %d\n",
+					ucSubType, u2Length, u2Seq);
+			break;
+		case EVENT_TX_DONE:
+			DBGLOG(TX, INFO, "<TX status: %d> WAPI: subType %d, Len %d, Seq %d\n",
+					status, ucSubType, u2Length, u2Seq);
+			break;
+		}
+		break;
+	}
+	}
+}
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display rx packet information.
+*
+* \param[in] pPkt			Pointer to the packet
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt)
+{
+	statsParsePktInfo(pPkt, 0, EVENT_RX, NULL);
+#if 0				/* carefully! too many ARP */
+	if (pucIpHdr[0] == 0x00) {	/* ARP */
+		UINT_8 *pucDstIp = (UINT_8 *) pucIpHdr;
+
+		if (pucDstIp[7] == ARP_PRO_REQ) {
+			DBGLOG(RX, TRACE, "<rx> OS rx a arp req from %d.%d.%d.%d\n",
+					     pucDstIp[14], pucDstIp[15], pucDstIp[16], pucDstIp[17]);
+		} else if (pucDstIp[7] == ARP_PRO_RSP) {
+			DBGLOG(RX, TRACE, "<rx> OS rx a arp rsp from %d.%d.%d.%d\n",
+					     pucDstIp[24], pucDstIp[25], pucDstIp[26], pucDstIp[27]);
+		}
+	}
+#endif
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display tx packet information.
+*
+* \param[in] pPkt			Pointer to the packet
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo)
+{
+	UINT_16 u2EtherTypeLen;
+
+	u2EtherTypeLen = (pPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pPkt[ETH_TYPE_LEN_OFFSET + 1]);
+	statsParsePktInfo(pPkt, 0, EVENT_TX, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to handle display tx packet tx done information.
+*
+* \param[in] pPkt			Pointer to the packet
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf)
+{
+	EVENT_TX_DONE_STATUS_T *prTxDone;
+
+	prTxDone = (EVENT_TX_DONE_STATUS_T *) pucEvtBuf;
+	/*
+	 * Why 65 Bytes:
+	 * 8B + wlanheader(40B) + hif_tx_header(16B) + 6B + 6B(LLC) - 12B
+	 */
+	statsParsePktInfo(&prTxDone->aucPktBuf[64], prTxDone->ucStatus, EVENT_TX_DONE, NULL);
+}
+
+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet)
+{
+	if (fgSet)
+		su2TxDoneCfg |= u2Cfg;
+	else
+		su2TxDoneCfg &= ~u2Cfg;
+}
+
+UINT_16 StatsGetCfgTxDone(VOID)
+{
+	return su2TxDoneCfg;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c
new file mode 100644
index 0000000000000..67eccbda9fa8f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c
@@ -0,0 +1,1170 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/swcr.c#1
+*/
+
+/*! \file   "swcr.c"
+    \brief
+
+*/
+
+/*
+** Log: swcr.c
+ *
+ * 06 04 2012 tsaiyuan.hsu
+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1"
+ * resolve build waring for "WNM_UNIT_TEST not defined".
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ * 11 22 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * keep debug counter setting after wake up.
+ *
+ * 11 15 2011 cm.chang
+ * NULL
+ * Fix compiling warning
+ *
+ * 11 11 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * fix debug counters of rx in driver.
+ *
+ * 11 11 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters of bb and ar for xlog.
+ *
+ * 11 10 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Modify the QM xlog level and remove LOG_FUNC.
+ *
+ * 11 08 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters, eCurPsProf, for PS.
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 11 03 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG
+ *
+ * 08 31 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * remove obsolete code.
+ *
+ * 08 15 2011 tsaiyuan.hsu
+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
+ * add swcr in driver reg, 0x9fxx0000, to disable roaming .
+ *
+ * 05 11 2011 eddie.chen
+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
+ * Fix dest type when GO packet copying.
+ *
+ * 05 09 2011 eddie.chen
+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
+ * Check free number before copying broadcast packet.
+ *
+ * 04 14 2011 eddie.chen
+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
+ * Check the SW RFB free. Fix the compile warning..
+ *
+ * 04 12 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix the sta index in processing security frame
+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
+ * Add debug message.
+ *
+ * 03 28 2011 eddie.chen
+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
+ * Fix Klockwork warning.
+ *
+ * 03 15 2011 eddie.chen
+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter
+ * Add sw debug counter for QM.
+ *
+ * 01 11 2011 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * Add swcr for test.
+ *
+*
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_SUPPORT_SWCR
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wformat"
+#endif
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+#if 0
+SWCR_MOD_MAP_ENTRY_T g_arSwCrAllMaps[] = {
+	{SWCR_MAP_NUM(g_arRlmArSwCrMap), g_arRlmArSwCrMap},	/* 0x00nn */
+	{0, NULL}
+};
+#endif
+
+UINT_32 g_au4SwCr[SWCR_CR_NUM];	/*: 0: command other: data */
+
+/* JB mDNS Filter*/
+UINT_32 g_u4mDNSRXFilter = 0;	/* [31] 0: stop 1: start, [3] IPv6 [2] IPv4 */
+
+static TIMER_T g_rSwcrDebugTimer;
+static BOOLEAN g_fgSwcrDebugTimer = FALSE;
+static UINT_32 g_u4SwcrDebugCheckTimeout;
+static ENUM_SWCR_DBG_TYPE_T g_ucSwcrDebugCheckType;
+static UINT_32 g_u4SwcrDebugFrameDumpType;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#define TEST_PS 1
+
+static const PFN_CMD_RW_T g_arSwCtrlCmd[] = {
+	swCtrlCmdCategory0,
+	swCtrlCmdCategory1
+#if TEST_PS
+	    , testPsCmdCategory0, testPsCmdCategory1
+#endif
+#if CFG_SUPPORT_802_11V
+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1)
+	    , testWNMCmdCategory0
+#endif
+#endif
+};
+
+const PFN_SWCR_RW_T g_arSwCrModHandle[] = {
+	swCtrlSwCr,
+	NULL
+};
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+enum {
+	SWCTRL_MAGIC,
+	SWCTRL_DEBUG,
+	SWCTRL_WIFI_VAR,
+	SWCTRL_ENABLE_INT,
+	SWCTRL_DISABLE_INT,
+	SWCTRL_TXM_INFO,
+	SWCTRL_RXM_INFO,
+	SWCTRL_DUMP_BSS,
+	SWCTRL_QM_INFO,
+	SWCTRL_DUMP_ALL_QUEUE_LEN,
+	SWCTRL_DUMP_MEM,
+	SWCTRL_TX_CTRL_INFO,
+	SWCTRL_DUMP_QUEUE,
+	SWCTRL_DUMP_QM_DBG_CNT,
+	SWCTRL_QM_DBG_CNT,
+	SWCTRL_RX_PKTS_DUMP,
+	SWCTRL_RX_MDNS_FILTER,
+	SWCTRL_CATA0_INDEX_NUM
+};
+
+enum {
+	SWCTRL_STA_INFO,
+	SWCTRL_DUMP_STA,
+	SWCTRL_STA_QUE_INFO,
+	SWCTRL_CATA1_INDEX_NUM
+};
+
+/* JB mDNS Filter*/
+#define RX_MDNS_FILTER_START (1<<31)
+#define RX_MDNS_FILTER_IPV4  (1<<2)
+#define RX_MDNS_FILTER_IPV6  (1<<3)
+typedef enum _ENUM_SWCR_RX_MDNS_FILTER_CMD_T {
+	SWCR_RX_MDNS_FILTER_CMD_STOP = 0,
+	SWCR_RX_MDNS_FILTER_CMD_START,
+	SWCR_RX_MDNS_FILTER_CMD_ADD,
+	SWCR_RX_MDNS_FILTER_CMD_REMOVE,
+	SWCR_RX_MDNS_FILTER_NUM
+} ENUM_SWCR_RX_MDNS_FILTER_CMD_T;
+
+#if TEST_PS
+enum {
+	TEST_PS_MAGIC,
+	TEST_PS_SETUP_BSS,
+	TEST_PS_ENABLE_BEACON,
+	TEST_PS_TRIGGER_BMC,
+	TEST_PS_SEND_NULL,
+	TEST_PS_BUFFER_BMC,
+	TEST_PS_UPDATE_BEACON,
+	TEST_PS_CATA0_INDEX_NUM
+};
+
+enum {
+	TEST_PS_STA_PS,
+	TEST_PS_STA_ENTER_PS,
+	TEST_PS_STA_EXIT_PS,
+	TEST_PS_STA_TRIGGER_PSPOLL,
+	TEST_PS_STA_TRIGGER_FRAME,
+	TEST_PS_CATA1_INDEX_NUM
+};
+#endif
+
+#if CFG_SUPPORT_802_11V
+#if WNM_UNIT_TEST
+enum {
+	TEST_WNM_TIMING_MEAS,
+	TEST_WNM_CATA0_INDEX_NUM
+};
+#endif
+#endif
+
+#define _SWCTRL_MAGIC 0x66201642
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+void dumpQueue(P_ADAPTER_T prAdapter)
+{
+
+	P_TX_CTRL_T prTxCtrl;
+	P_QUE_MGT_T prQM;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 i;
+	UINT_32 j;
+
+	DEBUGFUNC("dumpQueue");
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	prQM = &prAdapter->rQM;
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	for (i = TC0_INDEX; i <= TC5_INDEX; i++) {
+		DBGLOG(SW4, INFO, "TC %u\n", i);
+		DBGLOG(SW4, INFO, "Max %u Free %u\n",
+				   prTxCtrl->rTc.aucMaxNumOfBuffer[i], prTxCtrl->rTc.aucFreeBufferCount[i]);
+
+		DBGLOG(SW4, INFO, "Average %u minReserved %u CurrentTcResource %u GuaranteedTcResource %u\n",
+				   QM_GET_TX_QUEUE_LEN(prAdapter, i),
+				   prQM->au4MinReservedTcResource[i],
+				   prQM->au4CurrentTcResource[i], prQM->au4GuaranteedTcResource[i]);
+
+	}
+
+	for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) {
+		DBGLOG(SW4, INFO,
+		       "TC %u HeadStaIdx %u ForwardCount %u\n", i, prQM->au4HeadStaRecIndex[i],
+			prQM->au4ForwardCount[i]);
+	}
+
+	DBGLOG(SW4, INFO, "BMC or unknown TxQueue Len %u\n", prQM->arTxQueue[0].u4NumElem);
+	DBGLOG(SW4, INFO, "Pending %d\n", prGlueInfo->i4TxPendingFrameNum);
+	DBGLOG(SW4, INFO, "Pending Security %d\n", prGlueInfo->i4TxPendingSecurityFrameNum);
+#if defined(LINUX)
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < CFG_MAX_TXQ_NUM; j++) {
+			DBGLOG(SW4, INFO,
+			       "Pending Q[%u][%u] %d\n", i, j, prGlueInfo->ai4TxPendingFrameNumPerQueue[i][j]);
+		}
+	}
+#endif
+
+	DBGLOG(SW4, INFO, " rFreeSwRfbList %u\n", prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem);
+	DBGLOG(SW4, INFO, " rReceivedRfbList %u\n", prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem);
+	DBGLOG(SW4, INFO, " rIndicatedRfbList %u\n", prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem);
+	DBGLOG(SW4, INFO, " ucNumIndPacket %u\n", prAdapter->rRxCtrl.ucNumIndPacket);
+	DBGLOG(SW4, INFO, " ucNumRetainedPacket %u\n", prAdapter->rRxCtrl.ucNumRetainedPacket);
+
+}
+
+void dumpSTA(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec)
+{
+	UINT_8 ucWTEntry;
+	UINT_32 i;
+	P_BSS_INFO_T prBssInfo;
+
+	DEBUGFUNC("dumpSTA");
+
+	ASSERT(prStaRec);
+	ucWTEntry = prStaRec->ucWTEntry;
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
+	ASSERT(prBssInfo);
+
+	DBGLOG(SW4, INFO, "Mac address: %pM Rcpi %u" "\n", prStaRec->aucMacAddr, prStaRec->ucRCPI);
+
+	DBGLOG(SW4, INFO, "Idx %u Wtbl %u Used %u State %u Bss Phy 0x%x Sta DesiredPhy 0x%x\n",
+			   prStaRec->ucIndex, ucWTEntry,
+			   prStaRec->fgIsInUse, prStaRec->ucStaState,
+			   prBssInfo->ucPhyTypeSet, prStaRec->ucDesiredPhyTypeSet);
+
+	DBGLOG(SW4, INFO, "Sta Operation 0x%x  DesiredNontHtRateSet  0x%x Mcs 0x%x u2HtCapInfo 0x%x\n",
+			   prStaRec->u2OperationalRateSet, prStaRec->u2DesiredNonHTRateSet, prStaRec->ucMcsSet,
+			   prStaRec->u2HtCapInfo);
+
+	for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++)
+		DBGLOG(SW4, INFO, "TC %u Queue Len %u\n", i, prStaRec->arTxQueue[i].u4NumElem);
+
+	DBGLOG(SW4, INFO, "BmpDeliveryAC %x\n", prStaRec->ucBmpDeliveryAC);
+	DBGLOG(SW4, INFO, "BmpTriggerAC  %x\n", prStaRec->ucBmpTriggerAC);
+	DBGLOG(SW4, INFO, "UapsdSpSupproted  %u\n", prStaRec->fgIsUapsdSupported);
+	DBGLOG(SW4, INFO, "IsQoS  %u\n", prStaRec->fgIsQoS);
+	DBGLOG(SW4, INFO, "AssocId %u\n", prStaRec->u2AssocId);
+
+	DBGLOG(SW4, INFO, "fgIsInPS %u\n", prStaRec->fgIsInPS);
+	DBGLOG(SW4, INFO, "ucFreeQuota %u\n", prStaRec->ucFreeQuota);
+	DBGLOG(SW4, INFO, "ucFreeQuotaForDelivery %u\n", prStaRec->ucFreeQuotaForDelivery);
+	DBGLOG(SW4, INFO, "ucFreeQuotaForNonDelivery %u\n", prStaRec->ucFreeQuotaForNonDelivery);
+
+#if 0
+	DBGLOG(SW4, INFO, "IsQmmSup  %u\n", prStaRec->fgIsWmmSupported);
+	DBGLOG(SW4, INFO, "IsUapsdSup  %u\n", prStaRec->fgIsUapsdSupported);
+	DBGLOG(SW4, INFO, "AvailabaleDeliverPkts  %u\n", prStaRec->ucAvailableDeliverPkts);
+	DBGLOG(SW4, INFO, "BmpDeliverPktsAC  %u\n", prStaRec->u4BmpDeliverPktsAC);
+	DBGLOG(SW4, INFO, "BmpBufferAC  %u\n", prStaRec->u4BmpBufferAC);
+	DBGLOG(SW4, INFO, "BmpNonDeliverPktsAC  %u\n", prStaRec->u4BmpNonDeliverPktsAC);
+#endif
+
+	for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) {
+		if (prStaRec->aprRxReorderParamRefTbl[i]) {
+			DBGLOG(SW4, INFO,
+			       "RxReorder fgIsValid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->fgIsValid);
+			DBGLOG(SW4, INFO, "RxReorder Tid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->ucTid);
+			DBGLOG(SW4, INFO,
+			       "RxReorder rReOrderQue Len: %u\n",
+				prStaRec->aprRxReorderParamRefTbl[i]->rReOrderQue.u4NumElem);
+			DBGLOG(SW4, INFO,
+			       "RxReorder WinStart: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinStart);
+			DBGLOG(SW4, INFO, "RxReorder WinEnd: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinEnd);
+			DBGLOG(SW4, INFO, "RxReorder WinSize: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinSize);
+		}
+	}
+
+}
+
+VOID dumpBss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
+{
+
+	DBGLOG(SW4, INFO, "SSID %s\n", prBssInfo->aucSSID);
+	DBGLOG(SW4, INFO, "OWN %pM\n", prBssInfo->aucOwnMacAddr);
+	DBGLOG(SW4, INFO, "BSSID %pM\n", prBssInfo->aucBSSID);
+	DBGLOG(SW4, INFO, "ucNetTypeIndex %u\n", prBssInfo->ucNetTypeIndex);
+	DBGLOG(SW4, INFO, "eConnectionState %u\n", prBssInfo->eConnectionState);
+	DBGLOG(SW4, INFO, "eCurrentOPMode %u\n", prBssInfo->eCurrentOPMode);
+	DBGLOG(SW4, INFO, "fgIsQBSS %u\n", prBssInfo->fgIsQBSS);
+	DBGLOG(SW4, INFO, "fgIsShortPreambleAllowed %u\n", prBssInfo->fgIsShortPreambleAllowed);
+	DBGLOG(SW4, INFO, "fgUseShortPreamble %u\n", prBssInfo->fgUseShortPreamble);
+	DBGLOG(SW4, INFO, "fgUseShortSlotTime %u\n", prBssInfo->fgUseShortSlotTime);
+	DBGLOG(SW4, INFO, "ucNonHTBasicPhyType %x\n", prBssInfo->ucNonHTBasicPhyType);
+	DBGLOG(SW4, INFO, "u2OperationalRateSet %x\n", prBssInfo->u2OperationalRateSet);
+	DBGLOG(SW4, INFO, "u2BSSBasicRateSet %x\n", prBssInfo->u2BSSBasicRateSet);
+	DBGLOG(SW4, INFO, "ucPhyTypeSet %x\n", prBssInfo->ucPhyTypeSet);
+	DBGLOG(SW4, INFO, "rStaRecOfClientList %d\n", prBssInfo->rStaRecOfClientList.u4NumElem);
+	DBGLOG(SW4, INFO, "u2CapInfo %x\n", prBssInfo->u2CapInfo);
+	DBGLOG(SW4, INFO, "u2ATIMWindow %x\n", prBssInfo->u2ATIMWindow);
+	DBGLOG(SW4, INFO, "u2AssocId %x\n", prBssInfo->u2AssocId);
+	DBGLOG(SW4, INFO, "ucDTIMPeriod %x\n", prBssInfo->ucDTIMPeriod);
+	DBGLOG(SW4, INFO, "ucDTIMCount %x\n", prBssInfo->ucDTIMCount);
+	DBGLOG(SW4, INFO, "fgIsNetAbsent %x\n", prBssInfo->fgIsNetAbsent);
+	DBGLOG(SW4, INFO, "eBand %d\n", prBssInfo->eBand);
+	DBGLOG(SW4, INFO, "ucPrimaryChannel %d\n", prBssInfo->ucPrimaryChannel);
+	DBGLOG(SW4, INFO, "ucHtOpInfo1 %d\n", prBssInfo->ucHtOpInfo1);
+	DBGLOG(SW4, INFO, "ucHtOpInfo2 %d\n", prBssInfo->u2HtOpInfo2);
+	DBGLOG(SW4, INFO, "ucHtOpInfo3 %d\n", prBssInfo->u2HtOpInfo3);
+	DBGLOG(SW4, INFO, "fgErpProtectMode %d\n", prBssInfo->fgErpProtectMode);
+	DBGLOG(SW4, INFO, "eHtProtectMode %d\n", prBssInfo->eHtProtectMode);
+	DBGLOG(SW4, INFO, "eGfOperationMode %d\n", prBssInfo->eGfOperationMode);
+	DBGLOG(SW4, INFO, "eRifsOperationMode %d\n", prBssInfo->eRifsOperationMode);
+	DBGLOG(SW4, INFO, "fgObssErpProtectMode %d\n", prBssInfo->fgObssErpProtectMode);
+	DBGLOG(SW4, INFO, "eObssHtProtectMode %d\n", prBssInfo->eObssHtProtectMode);
+	DBGLOG(SW4, INFO, "eObssGfProtectMode %d\n", prBssInfo->eObssGfOperationMode);
+	DBGLOG(SW4, INFO, "fgObssRifsOperationMode %d\n", prBssInfo->fgObssRifsOperationMode);
+	DBGLOG(SW4, INFO, "fgAssoc40mBwAllowed %d\n", prBssInfo->fgAssoc40mBwAllowed);
+	DBGLOG(SW4, INFO, "fg40mBwAllowed %d\n", prBssInfo->fg40mBwAllowed);
+	DBGLOG(SW4, INFO, "eBssSCO %d\n", prBssInfo->eBssSCO);
+
+}
+
+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1)
+{
+	UINT_8 ucIndex, ucRead;
+	UINT_32 i;
+
+	DEBUGFUNC("swCtrlCmdCategory0");
+
+	SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex);
+
+	i = 0;
+
+	if (ucIndex >= SWCTRL_CATA0_INDEX_NUM)
+		return;
+
+	if (ucRead == SWCR_WRITE) {
+		switch (ucIndex) {
+		case SWCTRL_DEBUG:
+#if DBG
+			aucDebugModule[ucOpt0] = (UINT_8) g_au4SwCr[1];
+#endif
+			break;
+		case SWCTRL_WIFI_VAR:
+			break;
+
+#if QM_DEBUG_COUNTER
+		case SWCTRL_DUMP_QM_DBG_CNT:
+			for (i = 0; i < QM_DBG_CNT_NUM; i++)
+				prAdapter->rQM.au4QmDebugCounters[i] = 0;
+			break;
+		case SWCTRL_QM_DBG_CNT:
+			prAdapter->rQM.au4QmDebugCounters[ucOpt0] = g_au4SwCr[1];
+
+			break;
+#endif
+#if CFG_RX_PKTS_DUMP
+		case SWCTRL_RX_PKTS_DUMP:
+			/* DBGLOG(SW4, INFO,("SWCTRL_RX_PKTS_DUMP: mask %x\n", g_au4SwCr[1])); */
+			prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = g_au4SwCr[1];
+			break;
+#endif
+		case SWCTRL_RX_MDNS_FILTER:
+			{
+				UINT_32 u4rxfilter;
+				BOOLEAN fgUpdate = FALSE;
+				WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+				if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_STOP) {
+					g_u4mDNSRXFilter &= ~(RX_MDNS_FILTER_START);
+
+					u4rxfilter = prAdapter->u4OsPacketFilter;
+					fgUpdate = TRUE;
+				} else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_START) {
+					g_u4mDNSRXFilter |= (RX_MDNS_FILTER_START);
+
+					u4rxfilter = prAdapter->u4OsPacketFilter;
+					if ((g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV4) ||
+					    (g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV6)) {
+						u4rxfilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
+					}
+					fgUpdate = TRUE;
+				} else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_ADD) {
+					if (ucOpt1 < 31)
+						g_u4mDNSRXFilter |= (1 << ucOpt1);
+				} else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_REMOVE) {
+					if (ucOpt1 < 31)
+						g_u4mDNSRXFilter &= ~(1 << ucOpt1);
+				}
+
+				if (fgUpdate == TRUE) {
+					rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+								      CMD_ID_SET_RX_FILTER,	/* ucCID */
+								      TRUE,	/* fgSetQuery */
+								      FALSE,	/* fgNeedResp */
+								      FALSE,	/* fgIsOid */
+								      NULL,	/* pfCmdDoneHandler */
+								      NULL,	/* pfCmdTimeoutHandler */
+								      sizeof(UINT_32),	/* u4SetQueryInfoLen */
+								      (PUINT_8)&u4rxfilter,	/* pucInfoBuffer */
+								      NULL,	/* pvSetQueryBuffer */
+								      0	/* un4SetQueryBufferLen */
+					    );
+				}
+/* DBGLOG(SW4, INFO,("SWCTRL_RX_MDNS_FILTER: g_u4mDNSRXFilter %x ucOpt0 %x ucOpt1 %x fgUpdate %x u4rxfilter %x, */
+/* rStatus %x\n", g_u4mDNSRXFilter, ucOpt0, ucOpt1, fgUpdate, u4rxfilter, rStatus)); */
+			}
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (ucIndex) {
+		case SWCTRL_DEBUG:
+#if DBG
+			g_au4SwCr[1] = aucDebugModule[ucOpt0];
+#endif
+			break;
+		case SWCTRL_MAGIC:
+			g_au4SwCr[1] = _SWCTRL_MAGIC;
+			/* DBGLOG(SW4, INFO, "BUILD TIME: %s %s\n", __DATE__, __TIME__); */
+			break;
+		case SWCTRL_QM_INFO:
+			{
+				P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+				switch (ucOpt0) {
+				case 0:
+					g_au4SwCr[1] = (QM_GET_TX_QUEUE_LEN(prAdapter, ucOpt1));
+					g_au4SwCr[2] = prQM->au4MinReservedTcResource[ucOpt1];
+					g_au4SwCr[3] = prQM->au4CurrentTcResource[ucOpt1];
+					g_au4SwCr[4] = prQM->au4GuaranteedTcResource[ucOpt1];
+					break;
+
+				case 1:
+					g_au4SwCr[1] = prQM->au4ForwardCount[ucOpt1];
+					g_au4SwCr[2] = prQM->au4HeadStaRecIndex[ucOpt1];
+					break;
+
+				case 2:
+					g_au4SwCr[1] = prQM->arTxQueue[ucOpt1].u4NumElem;	/* only one */
+
+					break;
+				}
+
+			}
+			break;
+		case SWCTRL_TX_CTRL_INFO:
+			{
+				P_TX_CTRL_T prTxCtrl;
+
+				prTxCtrl = &prAdapter->rTxCtrl;
+				switch (ucOpt0) {
+				case 0:
+					g_au4SwCr[1] = prAdapter->rTxCtrl.rTc.aucFreeBufferCount[ucOpt1];
+					g_au4SwCr[2] = prAdapter->rTxCtrl.rTc.aucMaxNumOfBuffer[ucOpt1];
+					break;
+				}
+
+			}
+			break;
+		case SWCTRL_DUMP_QUEUE:
+			dumpQueue(prAdapter);
+
+			break;
+#if QM_DEBUG_COUNTER
+		case SWCTRL_DUMP_QM_DBG_CNT:
+			for (i = 0; i < QM_DBG_CNT_NUM; i++)
+				DBGLOG(SW4, INFO, "QM:DBG %u %u\n", i, prAdapter->rQM.au4QmDebugCounters[i]);
+			break;
+
+		case SWCTRL_QM_DBG_CNT:
+			g_au4SwCr[1] = prAdapter->rQM.au4QmDebugCounters[ucOpt0];
+			break;
+#endif
+		case SWCTRL_DUMP_BSS:
+			{
+				dumpBss(prAdapter, &(prAdapter->rWifiVar.arBssInfo[ucOpt0]));
+			}
+			break;
+
+		default:
+			break;
+		}
+
+	}
+}
+
+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1)
+{
+	UINT_8 ucIndex, ucRead;
+	UINT_8 ucWTEntry;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("swCtrlCmdCategory1");
+
+	SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex);
+
+	if (ucOpt0 >= CFG_STA_REC_NUM)
+		return;
+
+	/* prStaRec = cnmGetStaRecByIndex (prAdapter, ucOpt0); */
+	prStaRec = &prAdapter->arStaRec[ucOpt0];
+	ucWTEntry = prStaRec->ucWTEntry;
+	if (ucRead == SWCR_WRITE) {
+		/* Do nothing */
+	} else {
+		/* Read */
+		switch (ucIndex) {
+		case SWCTRL_STA_QUE_INFO:
+			{
+				g_au4SwCr[1] = prStaRec->arTxQueue[ucOpt1].u4NumElem;
+			}
+			break;
+		case SWCTRL_STA_INFO:
+			switch (ucOpt1) {
+			case 0:
+				g_au4SwCr[1] = prStaRec->fgIsInPS;
+				break;
+			}
+
+			break;
+
+		case SWCTRL_DUMP_STA:
+			{
+				dumpSTA(prAdapter, prStaRec);
+			}
+			break;
+
+		default:
+
+			break;
+		}
+	}
+
+}
+
+#if TEST_PS
+
+VOID
+testPsSendQoSNullFrame(IN P_ADAPTER_T prAdapter,
+		       IN P_STA_RECORD_T prStaRec,
+		       IN UINT_8 ucUP,
+		       IN UINT_8 ucNetTypeIndex,
+		       IN BOOLEAN fgBMC,
+		       IN BOOLEAN fgIsBurstEnd, IN BOOLEAN ucPacketType, IN BOOLEAN ucPsSessionID, IN BOOLEAN fgSetEOSP)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	UINT_16 u2EstimatedFrameLen;
+	P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame;
+
+	DEBUGFUNC("testPsSendQoSNullFrame");
+	DBGLOG(SW4, LOUD, "\n");
+
+	/* 4 <1> Allocate a PKT_INFO_T for Null Frame */
+	/* Init with MGMT Header Length */
+	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN;
+
+	/* Allocate a MSDU_INFO_T */
+	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
+	if (prMsduInfo == NULL) {
+		DBGLOG(SW4, WARN, "No PKT_INFO_T for sending Null Frame.\n");
+		return;
+	}
+	/* 4 <2> Compose Null frame in MSDU_INfO_T. */
+	bssComposeQoSNullFrame(prAdapter,
+			       (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
+			       prStaRec, ucUP, fgSetEOSP);
+
+	prMsduInfo->eSrc = TX_PACKET_MGMT;
+	/* prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; */
+	prMsduInfo->ucPacketType = ucPacketType;
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = NULL;
+	prMsduInfo->fgIsBasicRate = TRUE;
+	prMsduInfo->fgIsBurstEnd = fgIsBurstEnd;
+	prMsduInfo->ucUserPriority = ucUP;
+	prMsduInfo->ucPsSessionID = ucPsSessionID /* 0~7 Test 7 means NOACK */;
+
+	prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) (((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD));
+
+	if (fgBMC)
+		prQoSNullFrame->aucAddr1[0] = 0xfd;
+	else
+		prQoSNullFrame->aucAddr1[5] = 0xdd;
+
+	/* 4 <4> Inform TXM  to send this Null frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+}
+
+VOID testPsSetupBss(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetworkTypeIndex)
+{
+	P_BSS_INFO_T prBssInfo;
+	UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR;
+
+	DEBUGFUNC("testPsSetupBss()");
+	DBGLOG(SW4, INFO, "index %d\n", ucNetworkTypeIndex);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetworkTypeIndex]);
+
+	/* 4 <1.2> Initiate PWR STATE */
+	/* SET_NET_PWR_STATE_IDLE(prAdapter, ucNetworkTypeIndex); */
+
+	/* 4 <2> Initiate BSS_INFO_T - common part */
+	BSS_INFO_INIT(prAdapter, ucNetworkTypeIndex);
+
+	prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED;
+	prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
+	prBssInfo->eCurrentOPMode = OP_MODE_ACCESS_POINT;
+	prBssInfo->fgIsNetActive = TRUE;
+	prBssInfo->ucNetTypeIndex = (ucNetworkTypeIndex);
+	prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED;
+
+	prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG;	/* Depend on eBand */
+	prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG;	/* Depend on eCurrentOPMode and ucPhyTypeSet */
+	prBssInfo->u2BSSBasicRateSet = RATE_SET_ERP;
+	prBssInfo->u2OperationalRateSet = RATE_SET_OFDM;
+	prBssInfo->fgErpProtectMode = FALSE;
+	prBssInfo->fgIsQBSS = TRUE;
+
+	/* 4 <1.5> Setup MIB for current BSS */
+	prBssInfo->u2BeaconInterval = 100;
+	prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT;
+	prBssInfo->u2ATIMWindow = 0;
+
+	prBssInfo->ucBeaconTimeoutCount = 0;
+
+	bssInitForAP(prAdapter, prBssInfo, TRUE);
+
+	COPY_MAC_ADDR(prBssInfo->aucBSSID, _aucZeroMacAddr);
+	LINK_INITIALIZE(&prBssInfo->rStaRecOfClientList);
+	prBssInfo->fgIsBeaconActivated = TRUE;
+	prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG;
+
+	COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress);
+
+	/* 4 <3> Initiate BSS_INFO_T - private part */
+	/* TODO */
+	prBssInfo->eBand = BAND_2G4;
+	prBssInfo->ucPrimaryChannel = 1;
+	prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL;
+
+	/* prBssInfo->fgErpProtectMode =  eErpProectMode; */
+	/* prBssInfo->eHtProtectMode = eHtProtectMode; */
+	/* prBssInfo->eGfOperationMode = eGfOperationMode; */
+
+	/* 4 <4> Allocate MSDU_INFO_T for Beacon */
+	prBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH);
+
+	if (prBssInfo->prBeacon) {
+		prBssInfo->prBeacon->eSrc = TX_PACKET_MGMT;
+		prBssInfo->prBeacon->ucNetworkType = ucNetworkTypeIndex;
+	} else {
+		DBGLOG(SW4, INFO, "prBeacon allocation fail\n");
+	}
+
+#if 0
+	prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL;
+	prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL;
+	prBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2;
+#else
+	prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp;
+	prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp;
+	prBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen;
+#endif
+
+#if 0
+	for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {
+
+		prBssInfo->arACQueParms[eAci].fgIsACMSet = FALSE;
+		prBssInfo->arACQueParms[eAci].u2Aifsn = (UINT_16) eAci;
+		prBssInfo->arACQueParms[eAci].u2CWmin = 7;
+		prBssInfo->arACQueParms[eAci].u2CWmax = 31;
+		prBssInfo->arACQueParms[eAci].u2TxopLimit = eAci + 1;
+		DBGLOG(SW4, INFO, "MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n",
+				   eAci, prBssInfo->arACQueParms[eAci].fgIsACMSet,
+				   prBssInfo->arACQueParms[eAci].u2Aifsn,
+				   prBssInfo->arACQueParms[eAci].u2CWmin,
+				   prBssInfo->arACQueParms[eAci].u2CWmax, prBssInfo->arACQueParms[eAci].u2TxopLimit));
+
+	}
+#endif
+
+	DBGLOG(SW4, INFO, "[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x",
+			   prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC,
+			   prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, prBssInfo->rPmProfSetupInfo.ucUapsdSp);
+
+}
+
+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1)
+{
+	UINT_8 ucIndex, ucRead;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("testPsCmdCategory0");
+	SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex);
+
+	DBGLOG(SW4, LOUD, "Read %u Index %u\n", ucRead, ucIndex);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, 0);
+
+	if (ucIndex >= TEST_PS_CATA0_INDEX_NUM)
+		return;
+
+	if (ucRead == SWCR_WRITE) {
+		switch (ucIndex) {
+		case TEST_PS_SETUP_BSS:
+			testPsSetupBss(prAdapter, ucOpt0);
+			break;
+
+		case TEST_PS_ENABLE_BEACON:
+			break;
+
+		case TEST_PS_TRIGGER_BMC:
+			/* txmForwardQueuedBmcPkts (ucOpt0); */
+			break;
+		case TEST_PS_SEND_NULL:
+			{
+
+				testPsSendQoSNullFrame(prAdapter, prStaRec, (UINT_8) (g_au4SwCr[1] & 0xFF),	/* UP */
+						       ucOpt0, (BOOLEAN) ((g_au4SwCr[1] >> 8) & 0xFF),	/* BMC */
+						       (BOOLEAN) ((g_au4SwCr[1] >> 16) & 0xFF),	/* BurstEnd */
+						       (BOOLEAN) ((g_au4SwCr[1] >> 24) & 0xFF),	/* Packet type */
+						       (UINT_8) ((g_au4SwCr[2]) & 0xFF), /* PS sesson ID 7: NOACK */
+						       FALSE	/* EOSP */
+				    );
+			}
+			break;
+		case TEST_PS_BUFFER_BMC:
+			/* g_aprBssInfo[ucOpt0]->fgApToBufferBMC = (g_au4SwCr[1] & 0xFF); */
+			break;
+		case TEST_PS_UPDATE_BEACON:
+			bssUpdateBeaconContent(prAdapter, ucOpt0 /*networktype */);
+			break;
+
+		default:
+			break;
+		}
+	} else {
+		switch (ucIndex) {
+
+		case TEST_PS_MAGIC:
+			g_au4SwCr[1] = 0x88660011;
+			break;
+
+		}
+	}
+}
+
+#endif /* TEST_PS */
+
+#if TEST_PS
+
+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1)
+{
+	UINT_8 ucIndex, ucRead;
+	UINT_8 ucWTEntry;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("testPsCmdCategory1");
+
+	SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex);
+
+	if (ucOpt0 >= CFG_STA_REC_NUM)
+		return;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, ucOpt0);
+	if (!prStaRec)
+		return;
+	ucWTEntry = prStaRec->ucWTEntry;
+	if (ucRead == SWCR_WRITE) {
+
+		switch (ucIndex) {
+		case TEST_PS_STA_PS:
+			prStaRec->fgIsInPS = (BOOLEAN) (g_au4SwCr[1] & 0x1);
+			prStaRec->fgIsQoS = (BOOLEAN) (g_au4SwCr[1] >> 8 & 0xFF);
+			prStaRec->fgIsUapsdSupported = (BOOLEAN) (g_au4SwCr[1] >> 16 & 0xFF);
+			prStaRec->ucBmpDeliveryAC = (BOOLEAN) (g_au4SwCr[1] >> 24 & 0xFF);
+			break;
+
+		}
+
+	} else {
+		/* Read */
+		switch (ucIndex) {
+		default:
+			break;
+		}
+	}
+
+}
+
+#endif /* TEST_PS */
+
+#if CFG_SUPPORT_802_11V
+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1)
+VOID testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1)
+{
+	UINT_8 ucIndex, ucRead;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("testWNMCmdCategory0");
+	SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex);
+
+	DBGLOG(SW4, INFO, "Read %u Index %u\n", ucRead, ucIndex);
+
+	if (ucIndex >= TEST_WNM_CATA0_INDEX_NUM)
+		return;
+
+	if (ucRead == SWCR_WRITE) {
+		switch (ucIndex) {
+		case TEST_WNM_TIMING_MEAS:
+			wnmTimingMeasUnitTest1(prAdapter, ucOpt0);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+#endif /* TEST_WNM */
+#endif /* CFG_SUPPORT_802_11V */
+
+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data)
+{
+	/* According other register STAIDX */
+	UINT_8 ucOffset;
+
+	ucOffset = (u2Addr >> 2) & 0x3F;
+
+	if (ucOffset >= SWCR_CR_NUM)
+		return;
+
+	if (ucRead == SWCR_WRITE) {
+		g_au4SwCr[ucOffset] = *pu4Data;
+		if (ucOffset == 0x0) {
+			/* Commmand   [31:24]: Category */
+			/* Commmand   [23:23]: 1(W) 0(R) */
+			/* Commmand   [22:16]: Index */
+			/* Commmand   [15:08]: Option0  */
+			/* Commmand   [07:00]: Option1   */
+			UINT_8 ucCate;
+			UINT_32 u4Cmd;
+
+			u4Cmd = g_au4SwCr[0];
+			ucCate = (UINT_8) (u4Cmd >> 24);
+			if (ucCate < sizeof(g_arSwCtrlCmd) / sizeof(g_arSwCtrlCmd[0])) {
+				if (g_arSwCtrlCmd[ucCate] != NULL) {
+					g_arSwCtrlCmd[ucCate] (prAdapter, ucCate, (UINT_8) (u4Cmd >> 16 & 0xFF),
+							       (UINT_8) ((u4Cmd >> 8) & 0xFF), (UINT_8) (u4Cmd & 0xFF));
+				}
+			}
+		}
+	} else {
+		*pu4Data = g_au4SwCr[ucOffset];
+	}
+}
+
+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data)
+{
+	UINT_8 ucMod;
+
+	ucMod = u2Addr >> 8;
+	/* Address [15:8] MOD ID */
+	/* Address [7:0] OFFSET */
+
+	DEBUGFUNC("swCrReadWriteCmd");
+	DBGLOG(SW4, TRACE, "%u addr 0x%x data 0x%x\n", ucRead, u2Addr, *pu4Data);
+
+	if (ucMod < (sizeof(g_arSwCrModHandle) / sizeof(g_arSwCrModHandle[0]))) {
+
+		if (g_arSwCrModHandle[ucMod] != NULL)
+			g_arSwCrModHandle[ucMod] (prAdapter, ucRead, u2Addr, pu4Data);
+	}			/* ucMod */
+}
+
+/* Debug Support */
+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType)
+{
+	g_u4SwcrDebugFrameDumpType = u4DumpType;
+	prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = u4DumpType;
+}
+
+VOID swCrDebugInit(P_ADAPTER_T prAdapter)
+{
+	/* frame dump */
+	if (g_u4SwcrDebugFrameDumpType)
+		swCrFrameCheckEnable(prAdapter, g_u4SwcrDebugFrameDumpType);
+	/* debug counter */
+	g_fgSwcrDebugTimer = FALSE;
+
+	cnmTimerInitTimer(prAdapter, &g_rSwcrDebugTimer, (PFN_MGMT_TIMEOUT_FUNC) swCrDebugCheckTimeout, (ULONG) NULL);
+
+	if (g_u4SwcrDebugCheckTimeout)
+		swCrDebugCheckEnable(prAdapter, TRUE, g_ucSwcrDebugCheckType, g_u4SwcrDebugCheckTimeout);
+}
+
+VOID swCrDebugUninit(P_ADAPTER_T prAdapter)
+{
+	cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer);
+
+	g_fgSwcrDebugTimer = FALSE;
+}
+
+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout)
+{
+	if (fgIsEnable) {
+		g_ucSwcrDebugCheckType = ucType;
+		g_u4SwcrDebugCheckTimeout = u4Timeout;
+		if (g_fgSwcrDebugTimer == FALSE)
+			swCrDebugCheckTimeout(prAdapter, 0);
+	} else {
+		cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer);
+		g_u4SwcrDebugCheckTimeout = 0;
+	}
+
+	g_fgSwcrDebugTimer = fgIsEnable;
+}
+
+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_TX_CTRL_T prTxCtrl;
+
+	ASSERT(prAdapter);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	prRxCtrl = &prAdapter->rRxCtrl;
+
+	/* dump counters */
+	if (prCmdSwCtrl) {
+		if (prCmdSwCtrl->u4Data == SWCR_DBG_TYPE_ALL) {
+
+			/* TX Counter from fw */
+			DBGLOG(SW4, INFO, "TX0\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x %08x %08x\n",
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_BCN_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_FAILED_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_RETRY_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_MGNT_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_ERROR_CNT]);
+#if 1
+			/* TX Counter from drv */
+			DBGLOG(SW4, INFO, "TX1\n"
+					   "%08x %08x %08x %08x\n",
+					   (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_BSS_DROP),
+					   (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_STA_DROP),
+					   (UINT_32) TX_GET_CNT(prTxCtrl, TX_FORWARD_OVERFLOW_DROP),
+					   (UINT_32) TX_GET_CNT(prTxCtrl, TX_AP_BORADCAST_DROP));
+#endif
+
+			/* RX Counter */
+			DBGLOG(SW4, INFO, "RX0\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x %08x %08x\n",
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DUP_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FCSERR_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FIFOFULL_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_PFDROP_CNT]);
+
+			DBGLOG(SW4, INFO, "RX1\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x %08x %08x\n",
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT),
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT),
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT),
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT),
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT),
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT),
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT),
+					   (UINT_32) RX_GET_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT));
+
+			DBGLOG(SW4, INFO, "PWR\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x %08x %08x\n",
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PS_POLL_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_IND_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE0],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE1],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF0],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF1]);
+
+			DBGLOG(SW4, INFO, "ARM\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x\n",
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RATE],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_BWGI],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ENABLE],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ROAM_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_INT_CNT]);
+
+			DBGLOG(SW4, INFO, "BB\n"
+					   "%08x %08x %08x %08x\n"
+					   "%08x %08x %08x %08x\n",
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_MDRDY_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_FCSERR_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_PD_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_PD_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SFDERR_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SIGERR_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT],
+					   prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT]);
+
+		}
+	}
+	/* start the next check */
+	if (g_u4SwcrDebugCheckTimeout)
+		cnmTimerStartTimer(prAdapter, &g_rSwcrDebugTimer, g_u4SwcrDebugCheckTimeout * MSEC_PER_SEC);
+}
+
+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	CMD_SW_DBG_CTRL_T rCmdSwCtrl;
+	WLAN_STATUS rStatus;
+
+	rCmdSwCtrl.u4Id = (0xb000 << 16) + g_ucSwcrDebugCheckType;
+	rCmdSwCtrl.u4Data = 0;
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_SW_DBG_CTRL,	/* ucCID */
+				      FALSE,	/* fgSetQuery */
+				      TRUE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      swCrDebugQuery,	/* pfCmdDoneHandler */
+				      swCrDebugQueryTimeout,	/* pfCmdTimeoutHandler */
+				      sizeof(CMD_SW_DBG_CTRL_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8)&rCmdSwCtrl,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	ASSERT(rStatus == WLAN_STATUS_PENDING);
+
+}
+
+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	ASSERT(prAdapter);
+
+	swCrDebugCheck(prAdapter, (P_CMD_SW_DBG_CTRL_T) (pucEventBuf));
+}
+
+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	ASSERT(prAdapter);
+
+	swCrDebugCheck(prAdapter, NULL);
+}
+
+#endif /* CFG_SUPPORT_SWCR */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c
new file mode 100644
index 0000000000000..96293c57e2b03
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c
@@ -0,0 +1,5199 @@
+/*
+** Id: tdls.c#1
+*/
+
+/*! \file tdls.c
+    \brief This file includes IEEE802.11z TDLS support.
+*/
+
+/*
+** Log: tdls.c
+ *
+ * 11 13 2013 vend_samp.lin
+ * NULL
+ * Initial version.
+ */
+
+/*******************************************************************************
+ *						C O M P I L E R	 F L A G S
+ ********************************************************************************
+ */
+
+/*******************************************************************************
+ *						E X T E R N A L	R E F E R E N C E S
+ ********************************************************************************
+ */
+#include "precomp.h"
+
+#if (CFG_SUPPORT_TDLS == 1)
+#include "gl_wext.h"
+#include "tdls.h"
+#include "gl_cfg80211.h"
+#include <uapi/linux/nl80211.h>
+/*******************************************************************************
+*						C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*						F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb);
+
+#if TDLS_CFG_CMD_TEST
+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static TDLS_STATUS
+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd);
+
+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param);
+
+static TDLS_STATUS
+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+
+static TDLS_STATUS
+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static VOID
+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo,
+		      BOOLEAN fgIsTearDown,
+		      UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers);
+
+static VOID
+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo,
+			    UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo);
+
+static TDLS_STATUS
+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static TDLS_STATUS
+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen);
+
+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen);
+
+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen);
+
+#endif /* TDLS_CFG_CMD_TEST */
+
+/*******************************************************************************
+*						P R I V A T E   D A T A
+********************************************************************************
+*/
+static BOOLEAN fgIsPtiTimeoutSkip = FALSE;
+
+/*******************************************************************************
+*						P R I V A T E  F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to indicate packets to upper layer.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prSkb			A pointer to the received packet
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb)
+{
+	struct net_device *prNetDev;
+
+	/* init */
+	prNetDev = prGlueInfo->prDevHandler;
+	prGlueInfo->rNetDevStats.rx_bytes += prSkb->len;
+	prGlueInfo->rNetDevStats.rx_packets++;
+
+	/* pass to upper layer */
+	//prNetDev->last_rx = jiffies;
+	prSkb->protocol = eth_type_trans(prSkb, prNetDev);
+	prSkb->dev = prNetDev;
+
+	if (!in_interrupt())
+		netif_rx_ni(prSkb);	/* only in non-interrupt context */
+	else
+		netif_rx(prSkb);
+}
+
+#if TDLS_CFG_CMD_TEST
+
+#define LR_TDLS_FME_FIELD_FILL(__Len) \
+do { \
+	pPkt += __Len; \
+	u4PktLen += __Len; \
+} while (0)
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to add a TDLS peer.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_2_[Responder MAC]
+
+		iwpriv wlan0 set_str_cmd 0_2_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd;
+	struct wireless_dev *prWdev;
+
+	/* reset */
+	kalMemZero(&rCmd, sizeof(rCmd));
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr);
+
+	/* init */
+	rCmd.rPeerInfo.supported_rates = NULL;
+	rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa;
+	rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */
+	rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER);
+
+	/* send command to wifi task to handle */
+	prWdev = prGlueInfo->prDevHandler->ieee80211_ptr;
+	mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to simulate to set the TDLS Prohibited bit.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_16_[Enable/Disable]_[Set/Clear]
+
+		iwpriv wlan0 set_str_cmd 0_16_1_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	TDLS_CMD_CORE_T rCmd;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+	rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable);
+
+	/* command to do this */
+	flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable;
+
+	aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP;
+	aucTdlsTestExtCapElm[1] = 5;
+	aucTdlsTestExtCapElm[2] = 0;
+	aucTdlsTestExtCapElm[3] = 0;
+	aucTdlsTestExtCapElm[4] = 0;
+	aucTdlsTestExtCapElm[5] = 0;
+	aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 7);	/* bit39 */
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a channel switch request from the peer.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_5_[TDLS Peer MAC]_[Chan]_[RegulatoryClass]_
+			[SecondaryChannelOffset]_[SwitchTime]_[SwitchTimeout]
+
+		iwpriv wlan0 set_str_cmd 0_1_5_00:11:22:33:44:01_1_255_0_15000_30000
+
+		RegulatoryClass: TODO (reference to Annex I of 802.11n spec.)
+		Secondary Channel Offset:	0 (SCN - no secondary channel)
+								1 (SCA - secondary channel above)
+								2 (SCB - secondary channel below)
+		SwitchTime: units of microseconds
+
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+
+	rCmd.Content.rCmdChStReqRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChStReqRcv.u4RegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChStReqRcv.u4SecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChStReqRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s:[%pM]u4Chan=%u u4RegClass=%u u4SecChanOff=%u u4SwitchTime=%u u4SwitchTimeout=%u\n",
+			    __func__, rCmd.aucPeerMac,
+			    (UINT32) rCmd.Content.rCmdChStReqRcv.u4Chan,
+			    (UINT32) rCmd.Content.rCmdChStReqRcv.u4RegClass,
+			    (UINT32) rCmd.Content.rCmdChStReqRcv.u4SecChanOff,
+			    (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTime,
+			    (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestChStReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a channel switch response from the peer.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_6_[TDLS Peer MAC]_[Chan]_
+			[SwitchTime]_[SwitchTimeout]_[StatusCode]
+
+		iwpriv wlan0 set_str_cmd 0_1_6_00:11:22:33:44:01_11_15000_30000_0
+
+		RegulatoryClass: TODO (reference to Annex I of 802.11n spec.)
+		Secondary Channel Offset:	0 (SCN - no secondary channel)
+								1 (SCA - secondary channel above)
+								2 (SCB - secondary channel below)
+		SwitchTime: units of microseconds
+
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+
+	rCmd.Content.rCmdChStRspRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChStRspRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChStRspRcv.u4StatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: [ %pM ] u4Chan=%u u4SwitchTime=%u u4SwitchTimeout=%u u4StatusCode=%u\n",
+			    __func__, rCmd.aucPeerMac,
+			    (UINT32) rCmd.Content.rCmdChStRspRcv.u4Chan,
+			    (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTime,
+			    (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout,
+			    (UINT32) rCmd.Content.rCmdChStRspRcv.u4StatusCode);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestChStRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to inform firmware to skip channel switch timeout function.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]
+
+		iwpriv wlan0 set_str_cmd 0_11_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+	rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo,
+			   TdlsTestChSwTimeoutSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a data frame to the peer periodically.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TIMER_T rTdlsTimerTestDataSend;
+static UINT_8 aucTdlsTestDataSPeerMac[6];
+static UINT_16 u2TdlsTestDataSInterval;
+
+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	ADAPTER_T *prAdapter;
+	BOOLEAN fgIsEnabled;
+
+	/* init */
+	prAdapter = prGlueInfo->prAdapter;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucTdlsTestDataSPeerMac);
+	u2TdlsTestDataSInterval = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	fgIsEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend);
+
+	if (fgIsEnabled == FALSE) {
+		/* stop test timer */
+		return;
+	}
+
+	/* re-init test timer */
+	cnmTimerInitTimer(prAdapter,
+			  &rTdlsTimerTestDataSend, (PFN_MGMT_TIMEOUT_FUNC) TdlsTimerTestDataContSend, (ULONG) NULL);
+
+	cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a data frame from the peer.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_0_x80_[TDLS Peer MAC]_[PM]_[UP]_[EOSP]_[IsNull]
+
+		iwpriv wlan0 set_str_cmd 0_1_x80_00:11:22:33:44:01_0_0_0_0
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+	rCmd.Content.rCmdDatRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdDatRcv.u4UP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdDatRcv.u4EOSP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdDatRcv.u4IsNull = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_cmd> %s: [%pM] PM(%u) UP(%u) EOSP(%u) NULL(%u)\n",
+		__func__, rCmd.aucPeerMac,
+		(UINT32) rCmd.Content.rCmdDatRcv.u4PM,
+		(UINT32) rCmd.Content.rCmdDatRcv.u4UP,
+		(UINT32) rCmd.Content.rCmdDatRcv.u4EOSP, (UINT32) rCmd.Content.rCmdDatRcv.u4IsNull);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestDataRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a data frame to the peer.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_4_[Responder MAC]_[tx status]
+
+		iwpriv wlan0 set_str_cmd 0_4_00:11:22:33:44:01_0
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	P_ADAPTER_T prAdapter;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *prPkt;
+	UINT_8 MAC[6];
+	UINT_8 ucTxStatus;
+
+	/* init */
+	prAdapter = prGlueInfo->prAdapter;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, MAC);
+	ucTxStatus = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	/* allocate a data frame */
+	prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt);
+	if (prMsduInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s allocate pkt fail!\n", __func__);
+		return;
+	}
+
+	/* init dev */
+	prMsduInfo->dev = prGlueInfo->prDevHandler;
+	if (prMsduInfo->dev == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s prMsduInfo->dev == NULL!\n", __func__);
+		kalPacketFree(prGlueInfo, prMsduInfo);
+		return;
+	}
+
+	/* init packet */
+	prMsduInfo->len = 1000;
+	kalMemZero(prMsduInfo->data, 100);	/* for QoS field */
+	kalMemCopy(prMsduInfo->data, MAC, 6);
+	kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6);
+	*(UINT_16 *) (prMsduInfo->data + 12) = 0x0800;
+
+	/* simulate OS to send the packet */
+	wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to simulate to set the TDLS Prohibited bit.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_16_[mili seconds]
+
+		iwpriv wlan0 set_str_cmd 0_19_1000
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	UINT32 u4Delay;
+
+	u4Delay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	DBGLOG(TDLS, INFO, "%s: Delay = %d\n", __func__, u4Delay);
+
+	kalMdelay(u4Delay);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a test discovery request frame command.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_10_[DialogToken]_[Peer MAC]_[BSSID]
+
+		iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01
+		iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01_00:22:33:44:11:22
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	ADAPTER_T *prAdapter;
+	P_BSS_INFO_T prBssInfo;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *pPkt;
+	UINT_32 u4PktLen, u4IeLen;
+	UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6];
+
+	/* parse arguments */
+	ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac);
+
+	kalMemZero(aucZeroMac, sizeof(aucZeroMac));
+	kalMemZero(aucBSSID, sizeof(aucBSSID));
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID);
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_fme> %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac);
+
+	/* allocate/init packet */
+	prAdapter = prGlueInfo->prAdapter;
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	u4PktLen = 0;
+
+	prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
+	if (prMsduInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
+		return;
+	}
+
+	prMsduInfo->dev = prGlueInfo->prDevHandler;
+	if (prMsduInfo->dev == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
+		kalPacketFree(prGlueInfo, prMsduInfo);
+		return;
+	}
+
+	/* make up frame content */
+	/* 1. 802.3 header */
+	kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	*(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 2. payload type */
+	*pPkt = TDLS_FRM_PAYLOAD_TYPE;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (1) Category */
+	*pPkt = TDLS_FRM_CATEGORY;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (2) Action */
+	*pPkt = TDLS_FRM_ACTION_DISCOVERY_REQ;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (3) Dialog token */
+	*pPkt = ucDialogToken;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (16) Link identifier element */
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
+
+	if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0)
+		kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
+	else
+		kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6);
+
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6);
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 4. Update packet length */
+	prMsduInfo->len = u4PktLen;
+	dumpMemory8(prMsduInfo->data, u4PktLen);
+
+	/* pass to OS */
+	TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to inform firmware to skip keep alive function.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_10_[Enable/Disable]
+
+		iwpriv wlan0 set_str_cmd 0_10_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+	rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo,
+			   TdlsTestKeepAliveSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to simulate to set the TDLS Prohibited bit.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]_[Set/Clear]
+
+		iwpriv wlan0 set_str_cmd 0_13_1_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	TDLS_CMD_CORE_T rCmd;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+	rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable);
+
+	/* command to do this */
+	flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable;
+
+	aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP;
+	aucTdlsTestExtCapElm[1] = 5;
+	aucTdlsTestExtCapElm[2] = 0;
+	aucTdlsTestExtCapElm[3] = 0;
+	aucTdlsTestExtCapElm[4] = 0;
+	aucTdlsTestExtCapElm[5] = 0;
+	aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 6);	/* bit38 */
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a PTI request from the AP.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_4_[TDLS Peer MAC]_[Dialog Token]
+
+		iwpriv wlan0 set_str_cmd 0_1_4_00:11:22:33:44:01_0
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+
+	rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: [ %pM ] u4DialogToken = %u\n",
+			    __func__, rCmd.aucPeerMac, (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestPtiReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a PTI response from the peer.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_9_[TDLS Peer MAC]_[Dialog Token]_[PM]
+
+		iwpriv wlan0 set_str_cmd 0_1_9_00:11:22:33:44:01_0_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+
+	rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdPtiRspRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: [%pM] u4DialogToken = %u %u\n",
+			    __func__, rCmd.aucPeerMac,
+			    (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken,
+			    (UINT32) rCmd.Content.rCmdPtiRspRcv.u4PM);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestPtiRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to inform firmware to simulate PTI tx done fail case.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_21_[Enable/Disable]
+
+		iwpriv wlan0 set_str_cmd 0_21_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+	rCmd.Content.rCmdPtiTxFail.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdPtiTxFail.fgIsEnable);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestPtiTxFail, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a test frame.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+/* PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; */
+/* TDLS_STATUS u4Status; */
+	UINT_32 u4Subcmd;
+/* UINT_32 u4BufLen; */
+
+	/* parse sub-command */
+	u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	DBGLOG(TDLS, INFO, "<tdls_cmd> test rv frame sub command = %u\n", (UINT32) u4Subcmd);
+
+	/* parse command arguments */
+	switch (u4Subcmd) {
+	case TDLS_FRM_ACTION_SETUP_REQ:
+		/* simulate to receive a setup request frame */
+		TdlsCmdTestSetupReqRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_SETUP_RSP:
+		/* simulate to receive a setup response frame */
+		TdlsCmdTestSetupRspRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_CONFIRM:
+		/* simulate to receive a setup confirm frame */
+		TdlsCmdTestSetupConfirmRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_TEARDOWN:
+		/* simulate to receive a tear down frame */
+		TdlsCmdTestTearDownRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_PTI:
+		/* simulate to receive a PTI request frame */
+		TdlsCmdTestPtiReqRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_PTI_RSP:
+		/* simulate to receive a PTI response frame */
+		TdlsCmdTestPtiRspRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_DATA_TEST_DATA:
+		/* simulate to receive a DATA frame */
+		TdlsCmdTestDataRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_CHAN_SWITCH_REQ:
+		/* simulate to receive a channel switch request frame */
+		TdlsCmdTestChSwReqRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_CHAN_SWITCH_RSP:
+		/* simulate to receive a channel switch response frame */
+		TdlsCmdTestChSwRspRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	case TDLS_FRM_ACTION_DISCOVERY_REQ:
+		/* simulate to receive a discovery request frame */
+		TdlsCmdTestDiscoveryReqRecv(prGlueInfo, prInBuf, u4InBufLen);
+		break;
+
+	default:
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> wrong test rv frame sub command\n");
+		return;
+	}
+
+/* if (u4Status != TDLS_STATUS_SUCCESS) */
+	{
+/* DBGLOG(TDLS, ERROR, ("<tdls_cmd> command parse fail\n")); */
+/* return; */
+	}
+
+	/* send command to wifi task to handle */
+#if 0
+	kalIoctl(prGlueInfo,
+		 TdlsTestFrameSend,
+		 (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a test setup confirm frame command.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_2_[DialogToken]_[StatusCode]_[Peer MAC]
+
+		iwpriv wlan0 set_str_cmd 0_1_2_1_0_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	ADAPTER_T *prAdapter;
+	P_BSS_INFO_T prBssInfo;
+	PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *pPkt;
+	UINT_32 u4PktLen, u4IeLen;
+	UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6];
+
+	/* parse arguments */
+	ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac);
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_fme> %s: DialogToken=%d StatusCode=%d from %pM\n",
+		__func__, ucDialogToken, ucStatusCode, aucPeerMac);
+
+	/* allocate/init packet */
+	prAdapter = prGlueInfo->prAdapter;
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
+	u4PktLen = 0;
+
+	prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
+	if (prMsduInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
+		return;
+	}
+
+	prMsduInfo->dev = prGlueInfo->prDevHandler;
+	if (prMsduInfo->dev == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
+		kalPacketFree(prGlueInfo, prMsduInfo);
+		return;
+	}
+
+	/* make up frame content */
+	/* 1. 802.3 header */
+	kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	*(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 2. payload type */
+	*pPkt = TDLS_FRM_PAYLOAD_TYPE;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (1) Category */
+	*pPkt = TDLS_FRM_CATEGORY;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (2) Action */
+	*pPkt = TDLS_FRM_ACTION_CONFIRM;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (3) Status Code */
+	*pPkt = ucStatusCode;
+	*(pPkt + 1) = 0x00;
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 3. Frame Formation - (4) Dialog token */
+	*pPkt = ucDialogToken;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (17) WMM Information element */
+	if (prAdapter->rWifiVar.fgSupportQoS) {
+		u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE);
+		LR_TDLS_FME_FIELD_FILL(u4IeLen);
+	}
+
+	/* 3. Frame Formation - (16) Link identifier element */
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER;
+
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6);
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 4. Update packet length */
+	prMsduInfo->len = u4PktLen;
+	dumpMemory8(prMsduInfo->data, u4PktLen);
+
+	/* pass to OS */
+	TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a test setup request frame command.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_0_[DialogToken]_[Peer MAC]_[BSSID]
+
+		iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01
+		iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01_00:22:33:44:11:22
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	ADAPTER_T *prAdapter;
+	P_BSS_INFO_T prBssInfo;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *pPkt;
+	UINT_32 u4PktLen, u4IeLen;
+	UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6];
+	UINT_16 u2CapInfo;
+
+	/* parse arguments */
+	ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac);
+
+	kalMemZero(aucZeroMac, sizeof(aucZeroMac));
+	kalMemZero(aucBSSID, sizeof(aucBSSID));
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID);
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_fme> %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac);
+
+	/* allocate/init packet */
+	prAdapter = prGlueInfo->prAdapter;
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	u4PktLen = 0;
+
+	prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
+	if (prMsduInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
+		return;
+	}
+
+	prMsduInfo->dev = prGlueInfo->prDevHandler;
+	if (prMsduInfo->dev == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
+		kalPacketFree(prGlueInfo, prMsduInfo);
+		return;
+	}
+
+	/* make up frame content */
+	/* 1. 802.3 header */
+	kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	*(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 2. payload type */
+	*pPkt = TDLS_FRM_PAYLOAD_TYPE;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (1) Category */
+	*pPkt = TDLS_FRM_CATEGORY;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (2) Action */
+	*pPkt = TDLS_FRM_ACTION_SETUP_REQ;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (3) Dialog token */
+	*pPkt = ucDialogToken;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (4) Capability */
+	u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL);
+	WLAN_SET_FIELD_16(pPkt, u2CapInfo);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 4. Append general IEs */
+	u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 3. Frame Formation - (10) Extended capabilities element */
+	EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
+	EXT_CAP_IE(pPkt)->ucLength = 5;
+
+	EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00;	/* bit0 ~ bit7 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00;	/* bit8 ~ bit15 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00;	/* bit16 ~ bit23 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00;	/* bit24 ~ bit31 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00;	/* bit32 ~ bit39 */
+
+	/* TDLS_EX_CAP_PEER_UAPSD */
+	EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
+	/* TDLS_EX_CAP_CHAN_SWITCH */
+	EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
+	/* TDLS_EX_CAP_TDLS */
+	EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 3. Frame Formation - (16) Link identifier element */
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
+
+	if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0)
+		kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
+	else
+		kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6);
+
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6);
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 4. Update packet length */
+	prMsduInfo->len = u4PktLen;
+	dumpMemory8(prMsduInfo->data, u4PktLen);
+
+	/* pass to OS */
+	TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a test setup response frame command.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_1_[DialogToken]_[StatusCode]_[Peer MAC]
+
+		iwpriv wlan0 set_str_cmd 0_1_1_1_0_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	ADAPTER_T *prAdapter;
+	P_BSS_INFO_T prBssInfo;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *pPkt;
+	UINT_32 u4PktLen, u4IeLen;
+	UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6];
+	UINT_16 u2CapInfo;
+
+	/* parse arguments */
+	ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac);
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_fme> %s: DialogToken=%d StatusCode=%d from %pM\n",
+		__func__, ucDialogToken, ucStatusCode, aucPeerMac);
+
+	/* allocate/init packet */
+	prAdapter = prGlueInfo->prAdapter;
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	u4PktLen = 0;
+
+	prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
+	if (prMsduInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
+		return;
+	}
+
+	prMsduInfo->dev = prGlueInfo->prDevHandler;
+	if (prMsduInfo->dev == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
+		kalPacketFree(prGlueInfo, prMsduInfo);
+		return;
+	}
+
+	/* make up frame content */
+	/* 1. 802.3 header */
+	kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	*(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 2. payload type */
+	*pPkt = TDLS_FRM_PAYLOAD_TYPE;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (1) Category */
+	*pPkt = TDLS_FRM_CATEGORY;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (2) Action */
+	*pPkt = TDLS_FRM_ACTION_SETUP_RSP;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (3) Status Code */
+	*pPkt = ucStatusCode;
+	*(pPkt + 1) = 0x00;
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 3. Frame Formation - (4) Dialog token */
+	*pPkt = ucDialogToken;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (5) Capability */
+	u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL);
+	WLAN_SET_FIELD_16(pPkt, u2CapInfo);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 4. Append general IEs */
+	u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 3. Frame Formation - (10) Extended capabilities element */
+	EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
+	EXT_CAP_IE(pPkt)->ucLength = 5;
+
+	EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00;	/* bit0 ~ bit7 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00;	/* bit8 ~ bit15 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00;	/* bit16 ~ bit23 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00;	/* bit24 ~ bit31 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00;	/* bit32 ~ bit39 */
+
+	/* TDLS_EX_CAP_PEER_UAPSD */
+	EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
+	/* TDLS_EX_CAP_CHAN_SWITCH */
+	EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
+	/* TDLS_EX_CAP_TDLS */
+	EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 3. Frame Formation - (16) Link identifier element */
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER;
+
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6);
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 4. Update packet length */
+	prMsduInfo->len = u4PktLen;
+	dumpMemory8(prMsduInfo->data, u4PktLen);
+
+	/* pass to OS */
+	TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to inform firmware to skip channel switch timeout function.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_14_[Enable/Disable]
+
+		iwpriv wlan0 set_str_cmd 0_14_0
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+	rCmd.Content.rCmdScanSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdScanSkip.fgIsEnable);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestScanSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a test tear down frame command.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_1_3_[IsInitiator]_[ReasonCode]_[Peer MAC]_[Where]
+
+		Where 0 (From driver) or 1 (From FW)
+
+		iwpriv wlan0 set_str_cmd 0_1_3_1_26_00:11:22:33:44:01_0
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	ADAPTER_T *prAdapter;
+	P_BSS_INFO_T prBssInfo;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *pPkt;
+	UINT_32 u4PktLen, u4IeLen;
+	BOOLEAN fgIsInitiator;
+	UINT_8 ucReasonCode, aucPeerMac[6];
+	BOOLEAN fgIsFromWhich;
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	fgIsInitiator = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	ucReasonCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac);
+	fgIsFromWhich = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_fme> %s: ReasonCode=%d from %pM %d\n",
+		__func__, ucReasonCode, aucPeerMac, fgIsFromWhich);
+
+	if (fgIsFromWhich == 0) {
+		/* allocate/init packet */
+		prAdapter = prGlueInfo->prAdapter;
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+		u4PktLen = 0;
+
+		prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
+		if (prMsduInfo == NULL) {
+			DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
+			return;
+		}
+
+		prMsduInfo->dev = prGlueInfo->prDevHandler;
+		if (prMsduInfo->dev == NULL) {
+			DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
+			kalPacketFree(prGlueInfo, prMsduInfo);
+			return;
+		}
+
+		/* make up frame content */
+		/* 1. 802.3 header */
+		kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
+		LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+		kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN);
+		LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+		*(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
+		LR_TDLS_FME_FIELD_FILL(2);
+
+		/* 2. payload type */
+		*pPkt = TDLS_FRM_PAYLOAD_TYPE;
+		LR_TDLS_FME_FIELD_FILL(1);
+
+		/* 3. Frame Formation - (1) Category */
+		*pPkt = TDLS_FRM_CATEGORY;
+		LR_TDLS_FME_FIELD_FILL(1);
+
+		/* 3. Frame Formation - (2) Action */
+		*pPkt = TDLS_FRM_ACTION_TEARDOWN;
+		LR_TDLS_FME_FIELD_FILL(1);
+
+		/* 3. Frame Formation - (3) Reason Code */
+		*pPkt = ucReasonCode;
+		*(pPkt + 1) = 0x00;
+		LR_TDLS_FME_FIELD_FILL(2);
+
+		/* 3. Frame Formation - (16) Link identifier element */
+		TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
+		TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER;
+
+		kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
+		if (fgIsInitiator == 1) {
+			kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6);
+			kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6);
+		} else {
+			kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
+			kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6);
+		}
+
+		u4IeLen = IE_SIZE(pPkt);
+		LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+		/* 4. Update packet length */
+		prMsduInfo->len = u4PktLen;
+		dumpMemory8(prMsduInfo->data, u4PktLen);
+
+		/* pass to OS */
+		TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo);
+	} else {
+		kalMemZero(&rCmd, sizeof(rCmd));
+		kalMemCopy(rCmd.aucPeerMac, aucPeerMac, 6);
+		rCmd.Content.rCmdTearDownRcv.u4ReasonCode = (UINT32) ucReasonCode;
+
+		/* command to do this */
+		rStatus = kalIoctl(prGlueInfo,
+				   TdlsTestTearDownRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		if (rStatus != WLAN_STATUS_SUCCESS) {
+			DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+			return;
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to inform firmware to skip tx fail case.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_7_[Enable/Disable]
+
+		iwpriv wlan0 set_str_cmd 0_7_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+	rCmd.Content.rCmdTxFailSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdTxFailSkip.fgIsEnable);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestTxFailSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a test frame command to wifi task.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC]
+
+		iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_12_2_[FrameType]_[DialogToken]_[Peer MAC]
+
+		iwpriv wlan0 set_str_cmd 0_12_2_0_1_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd;
+	UINT32 u4Subcmd;
+	UINT_32 u4BufLen;
+
+	/* parse sub-command */
+	u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	DBGLOG(TDLS, INFO, "<tdls_cmd> test tx tdls frame sub command = %u\n", u4Subcmd);
+
+	/* parse command arguments */
+	rCmd.ucFmeType = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen);
+
+	switch (u4Subcmd) {
+	case TDLS_FRM_ACTION_SETUP_REQ:
+	case TDLS_FRM_ACTION_SETUP_RSP:
+	case TDLS_FRM_ACTION_CONFIRM:
+		rCmd.ucToken = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen);
+		CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr);
+
+		DBGLOG(TDLS, INFO, "<tdls_cmd> setup FmeType=%d Token=%d to [%pM]\n",
+				   rCmd.ucFmeType, rCmd.ucToken, rCmd.arRspAddr);
+		break;
+
+	default:
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> wrong test tx frame sub command\n");
+		return;
+	}
+
+	/* send command to wifi task to handle */
+	kalIoctl(prGlueInfo,
+		 TdlsTestTdlsFrameSend,
+		 (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a test frame command to wifi task.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_
+		[SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_
+		[SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_
+		[Timeout]_[Peer MAC]
+
+		iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd;
+	TDLS_STATUS u4Status;
+	UINT_32 u4Subcmd;
+	UINT_32 u4BufLen;
+
+	/* parse sub-command */
+	u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	DBGLOG(TDLS, INFO, "<tdls_cmd> test tx frame sub command = %u\n", (UINT32) u4Subcmd);
+
+	/* parse command arguments */
+	switch (u4Subcmd) {
+	case TDLS_FRM_ACTION_SETUP_REQ:
+		u4Status = TdlsCmdTestTxFmeSetupReqBufTranslate(prInBuf, u4InBufLen, &rCmd);
+		break;
+
+	default:
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> wrong test tx frame sub command\n");
+		return;
+	}
+
+	if (u4Status != TDLS_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> command parse fail\n");
+		return;
+	}
+
+	/* send command to wifi task to handle */
+	kalIoctl(prGlueInfo,
+		 TdlsTestFrameSend,
+		 (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Parse the TDLS test frame command, setup request
+*
+* @param CmdBuf		Pointer to the buffer.
+* @param BufLen		Record buffer length.
+* @param CmdTspec	Pointer to the structure.
+*
+* @retval WLAN_STATUS_SUCCESS: Translate OK.
+* @retval WLAN_STATUS_FAILURE: Translate fail.
+* @usage iwpriv wlan0 set_str_cmd [tdls]_[command]
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_
+		[SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_
+		[SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_
+		[Timeout]_[Peer MAC]
+
+		iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd)
+{
+/* dumpMemory8(ANDROID_LOG_INFO, pCmdBuf, u4BufLen); */
+
+	prCmd->ucFmeType = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->ucToken = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->u2Cap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->ucExCap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupRate[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupRate[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupRate[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupRate[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupChan[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupChan[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupChan[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->arSupChan[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	prCmd->u4Timeout = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen);
+	CmdStringMacParse(pCmdBuf, &pCmdBuf, &u4BufLen, prCmd->arRspAddr);
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> command content =\n");
+	DBGLOG(TDLS, INFO, "\tPeer MAC = %pM\n", (prCmd->arRspAddr));
+	DBGLOG(TDLS, INFO, "\tToken = %u, Cap = 0x%x, ExCap = 0x%x, Timeout = %us FrameType = %u\n",
+			    (UINT32) prCmd->ucToken, prCmd->u2Cap, prCmd->ucExCap,
+			    (UINT32) prCmd->u4Timeout, (UINT32) prCmd->ucFmeType);
+	DBGLOG(TDLS, INFO, "\tSupRate = 0x%x %x %x %x\n",
+			    prCmd->arSupRate[0], prCmd->arSupRate[1], prCmd->arSupRate[2], prCmd->arSupRate[3]);
+	DBGLOG(TDLS, INFO, "\tSupChan = %d %d %d %d\n",
+			    prCmd->arSupChan[0], prCmd->arSupChan[1], prCmd->arSupChan[2], prCmd->arSupChan[3]);
+
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to update a TDLS peer.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_3_[Responder MAC]
+
+		iwpriv wlan0 set_str_cmd 0_3_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd;
+	struct wireless_dev *prWdev;
+
+	/* reset */
+	kalMemZero(&rCmd, sizeof(rCmd));
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr);
+
+	/* init */
+	rCmd.rPeerInfo.supported_rates = rCmd.arSupRate;
+	rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa;
+	rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */
+	rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER);
+	rCmd.rPeerInfo.uapsd_queues = 0xf;	/* all AC */
+	rCmd.rPeerInfo.max_sp = 0;	/* delivery all packets */
+
+	/* send command to wifi task to handle */
+	prWdev = prGlueInfo->prDevHandler->ieee80211_ptr;
+	mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo);
+
+	/* update */
+	TdlsexCfg80211TdlsOper(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, NL80211_TDLS_ENABLE_LINK);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a Null frame from the peer.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_5_[Responder MAC]_[PM bit]
+
+		iwpriv wlan0 set_str_cmd 0_5_00:11:22:33:44:01_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+	rCmd.Content.rCmdNullRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: [%pM] u4PM = %u\n",
+			    __func__, (rCmd.aucPeerMac), (UINT32) rCmd.Content.rCmdNullRcv.u4PM);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsTestNullRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a data frame to the peer periodically.
+*
+* \param[in] prAdapter		Pointer to the Adapter structure
+* \param[in] u4Param		no use
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_15_[Responder MAC]_[Interval: ms]_[Enable/Disable]
+
+		iwpriv wlan0 set_str_cmd 0_15_00:11:22:33:44:01_5000_1
+*/
+/*----------------------------------------------------------------------------*/
+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param)
+{
+	GLUE_INFO_T *prGlueInfo;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *prPkt;
+
+	/* init */
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	/* allocate a data frame */
+	prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt);
+	if (prMsduInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s allocate pkt fail!\n", __func__);
+		return;
+	}
+
+	/* init dev */
+	prMsduInfo->dev = prGlueInfo->prDevHandler;
+	if (prMsduInfo->dev == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s prMsduInfo->dev == NULL!\n", __func__);
+		kalPacketFree(prGlueInfo, prMsduInfo);
+		return;
+	}
+
+	/* init packet */
+	prMsduInfo->len = 1000;
+	kalMemCopy(prMsduInfo->data, aucTdlsTestDataSPeerMac, 6);
+	kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6);
+	*(UINT_16 *) (prMsduInfo->data + 12) = 0x0800;
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s try to send a data frame to %pM\n",
+			    __func__, aucTdlsTestDataSPeerMac);
+
+	/* simulate OS to send the packet */
+	wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
+
+	/* restart test timer */
+	cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a Channel Switch Request frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_REQ;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a Channel Switch Response frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_RSP;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to send a test frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	GLUE_INFO_T *prGlueInfo;
+	PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd;
+	P_BSS_INFO_T prBssInfo;
+	struct sk_buff *prMsduInfo;
+	UINT_8 *pPkt;
+	UINT_32 u4PktLen, u4IeLen;
+
+	/* sanity check */
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	DBGLOG(TDLS, INFO, "<tdls_fme> %s\n", __func__);
+
+	if (u4SetBufferLen == 0)
+		return TDLS_STATUS_INVALID_LENGTH;
+
+	/* allocate/init packet */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+	prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer;
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	*pu4SetInfoLen = u4SetBufferLen;
+	u4PktLen = 0;
+
+	prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
+	if (prMsduInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	prMsduInfo->dev = prGlueInfo->prDevHandler;
+	if (prMsduInfo->dev == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
+		kalPacketFree(prGlueInfo, prMsduInfo);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	/* make up frame content */
+	/* 1. 802.3 header */
+	kalMemCopy(pPkt, prCmd->arRspAddr, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
+	LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+	*(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 2. payload type */
+	*pPkt = TDLS_FRM_PAYLOAD_TYPE;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (1) Category */
+	*pPkt = TDLS_FRM_CATEGORY;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (2) Action */
+	*pPkt = prCmd->ucFmeType;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (3) Dialog token */
+	*pPkt = prCmd->ucToken;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - (4) Capability */
+	WLAN_SET_FIELD_16(pPkt, prCmd->u2Cap);
+	LR_TDLS_FME_FIELD_FILL(2);
+
+	/* 4. Append general IEs */
+	u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 3. Frame Formation - (10) Extended capabilities element */
+	EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
+	EXT_CAP_IE(pPkt)->ucLength = 5;
+
+	EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00;	/* bit0 ~ bit7 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00;	/* bit8 ~ bit15 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00;	/* bit16 ~ bit23 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00;	/* bit24 ~ bit31 */
+	EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00;	/* bit32 ~ bit39 */
+
+	if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD)
+		EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
+	if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH)
+		EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
+	if (prCmd->ucExCap & TDLS_EX_CAP_TDLS)
+		EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
+	TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
+	TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
+
+	TIMEOUT_INTERVAL_IE(pPkt)->ucType = IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME;
+	TIMEOUT_INTERVAL_IE(pPkt)->u4Value = htonl(prCmd->u4Timeout);
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 3. Frame Formation - (16) Link identifier element */
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER;
+
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prCmd->arRspAddr, 6);
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 4. Update packet length */
+	prMsduInfo->len = u4PktLen;
+	dumpMemory8(prMsduInfo->data, u4PktLen);
+
+	/* 5. send the data frame */
+	wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a NULL frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_NULL_RCV;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a PTI frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_REQ;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a PTI response frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_RSP;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a Tear Down frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TEAR_DOWN;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to receive a data frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_DATA_RCV;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to skip PTI tx fail status.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_TX_FAIL;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to send a TDLS action frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC]
+
+		iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	GLUE_INFO_T *prGlueInfo;
+	PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd;
+	struct wireless_dev *prWdev;
+
+	/* sanity check */
+	ASSERT(prAdapter);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	DBGLOG(TDLS, INFO, "<tdls_fme> %s\n", __func__);
+
+	if (u4SetBufferLen == 0)
+		return TDLS_STATUS_INVALID_LENGTH;
+
+	/* allocate/init packet */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+	prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer;
+	prWdev = (struct wireless_dev *)prGlueInfo->prDevHandler->ieee80211_ptr;
+
+	TdlsexCfg80211TdlsMgmt(prWdev->wiphy, NULL,
+			prCmd->arRspAddr, prCmd->ucFmeType, 1,
+			0, 0, /* open/none */
+			FALSE, NULL, 0);
+
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to skip tx fail status. So always success in tx done in firmware.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TX_FAIL_SKIP;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to skip to do keep alive function in firmware.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to skip channel switch timeout.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to skip scan request.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_TEST_SCAN_SKIP;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+#endif /* TDLS_CFG_CMD_TEST */
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to configure channel switch parameters.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_CHSW_CONF;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to update channel switch parameters.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_9_[TDLS Peer MAC]_
+			[NetworkTypeIndex]_[1 (Enable) or (0) Disable]_[1 (Start) or 0 (Stop)]_
+			[RegClass]_[Chan]_[SecChanOff]_[1 (Reqular) or (0) One Shot]
+
+		RegulatoryClass: TODO (reference to Annex I of 802.11n spec.)
+		Secondary Channel Offset:	0 (SCN - no secondary channel)
+								1 (SCA - secondary channel above)
+								2 (SCB - secondary channel below)
+		SwitchTime: units of microseconds
+
+		iwpriv wlan0 set_str_cmd 0_9_00:11:22:33:44:01_0_1_0_0_1_0_0
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+
+	rCmd.Content.rCmdChSwConf.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChSwConf.fgIsChSwStarted = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChSwConf.ucRegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChSwConf.ucTargetChan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChSwConf.ucSecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdChSwConf.fgIsChSwRegular = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: %pM ucNetTypeIndex=%d, fgIsChSwEnabled=%d, fgIsChSwStarted=%d",
+		__func__, (rCmd.aucPeerMac),
+		rCmd.Content.rCmdChSwConf.ucNetTypeIndex,
+		rCmd.Content.rCmdChSwConf.fgIsChSwEnabled,
+		rCmd.Content.rCmdChSwConf.fgIsChSwStarted);
+	DBGLOG(TDLS, INFO, " RegClass=%d, TargetChan=%d, SecChanOff=%d, Regular=%d\n",
+		rCmd.Content.rCmdChSwConf.ucRegClass,
+		rCmd.Content.rCmdChSwConf.ucTargetChan,
+		rCmd.Content.rCmdChSwConf.ucSecChanOff, rCmd.Content.rCmdChSwConf.fgIsChSwRegular);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsChSwConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display TDLS related information.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_18_[Peer MAC]_[Network Interface ID]_[IsClear]
+
+		Network Interface ID: reference to ENUM_NETWORK_TYPE_INDEX_T
+
+		typedef enum _ENUM_NETWORK_TYPE_INDEX_T {
+			NETWORK_TYPE_AIS_INDEX = 0,
+			NETWORK_TYPE_P2P_INDEX,
+			NETWORK_TYPE_BOW_INDEX,
+			NETWORK_TYPE_INDEX_NUM
+		} ENUM_NETWORK_TYPE_INDEX_T;
+
+		iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(&rCmd, sizeof(rCmd));
+
+	CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac);
+	rCmd.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdInfoDisplay.fgIsToClearAllHistory = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: Command PeerMac=%pM in BSS%u\n",
+			    __func__, (rCmd.aucPeerMac), rCmd.ucNetTypeIndex);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display key related information.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_20
+
+		iwpriv wlan0 set_str_cmd 0_20
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(&rCmd, sizeof(rCmd));
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s\n", __func__);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsKeyInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to update MIB parameters.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_6_[TdlsEn]_[UapsdEn]_[PsmEn]_[PtiWin]_[CWCap]_
+			[AckMisRetry]_[RspTimeout]_[CWPbDelay]_[DRWin]_[LowestAcInt]
+
+		iwpriv wlan0 set_str_cmd 0_6_1_1_0_1_1_3_5_1000_2_1
+
+		reference to TDLS_CMD_CORE_MIB_PARAM_UPDATE_T
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* reset */
+	kalMemZero(&rCmd, sizeof(rCmd));
+
+	/* parse arguments */
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented =
+	    CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated =
+	    CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow =
+	    CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated =
+	    CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit =
+	    CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow =
+	    CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval =
+	    CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> MIB param = %d %d %d %d %d %d %d %d %d %d\n",
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow,
+			    rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsMibParamUpdate, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to update setup parameters.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_17_[20/40 Support]
+
+		iwpriv wlan0 set_str_cmd 0_17_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+
+	rCmd.Content.rCmdSetupConf.fgIs2040Supported = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+
+	DBGLOG(TDLS, INFO, "%s: rCmdSetupConf=%d\n", __func__, rCmd.Content.rCmdSetupConf.fgIs2040Supported);
+
+	/* command to do this */
+	prGlueInfo->rTdlsLink.fgIs2040Sup = rCmd.Content.rCmdSetupConf.fgIs2040Supported;
+
+	rStatus = kalIoctl(prGlueInfo, TdlsSetupConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to update UAPSD parameters.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure
+* \param[in] prInBuf A pointer to the command string buffer
+* \param[in] u4InBufLen The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*		EX: iwpriv wlan0 set_str_cmd 0_8_[SP timeout skip]_[PTI timeout skip]
+
+		iwpriv wlan0 set_str_cmd 0_8_1_1
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	WLAN_STATUS rStatus;
+	TDLS_CMD_CORE_T rCmd;
+	UINT_32 u4BufLen;
+
+	/* parse arguments */
+	kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac));
+
+	/* UAPSD Service Period */
+	rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	/* PTI Service Period */
+	fgIsPtiTimeoutSkip = rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip;
+
+	DBGLOG(TDLS, INFO, "%s: fgIsSpTimeoutSkip=%d, fgIsPtiTimeoutSkip=%d\n",
+			    __func__, rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip, fgIsPtiTimeoutSkip);
+
+	/* command to do this */
+	rStatus = kalIoctl(prGlueInfo, TdlsUapsdConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus);
+		return;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display TDLS all information.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*	iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	GLUE_INFO_T *prGlueInfo;
+	TDLS_CMD_CORE_T *prCmdContent;
+	STA_RECORD_T *prStaRec;
+	TDLS_INFO_LINK_T *prLink;
+	UINT32 u4StartIdx;
+	UINT32 u4PeerNum;
+	BOOLEAN fgIsListAll;
+	UINT8 ucMacZero[6];
+	UINT32 u4HisIdx;
+	UINT8 ucNetTypeIndex;
+
+	/* init */
+	prGlueInfo = prAdapter->prGlueInfo;
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	u4StartIdx = 0;
+	u4PeerNum = 1;
+	fgIsListAll = TRUE;
+	kalMemZero(ucMacZero, sizeof(ucMacZero));
+	ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+
+	/* display common information */
+	DBGLOG(TDLS, TRACE, "TDLS common:\n");
+	DBGLOG(TDLS, TRACE, "\t\trFreeSwRfbList=%u\n", (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem);
+	DBGLOG(TDLS, TRACE, "\t\tjiffies=%u %ums (HZ=%d)\n", (UINT32) jiffies, (UINT32) kalGetTimeTick(), HZ);
+
+	/* display disconnection history information */
+	DBGLOG(TDLS, TRACE, "TDLS link history: %d\n", prGlueInfo->rTdlsLink.u4LinkIdx);
+
+	for (u4HisIdx = prGlueInfo->rTdlsLink.u4LinkIdx + 1; u4HisIdx < TDLS_LINK_HISTORY_MAX; u4HisIdx++) {
+		prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx];
+
+		if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0)
+			continue;	/* skip all zero */
+
+		DBGLOG(TDLS, TRACE,
+			"\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n",
+			u4HisIdx, prLink->aucPeerMac,
+			prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start),
+			prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end),
+			prLink->ucReasonCode,
+			prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP));
+
+		if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) {
+			DBGLOG(TDLS, TRACE,
+			       "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n",
+				prLink->ucHtBa[0], prLink->ucHtBa[1],
+				prLink->ucHtBa[2], prLink->ucHtBa[3],
+				prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]);
+		}
+	}
+	for (u4HisIdx = 0; u4HisIdx <= prGlueInfo->rTdlsLink.u4LinkIdx; u4HisIdx++) {
+		prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx];
+
+		if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0)
+			continue;	/* skip all zero, use continue, not break */
+
+		DBGLOG(TDLS, TRACE,
+		       "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n",
+			u4HisIdx, (prLink->aucPeerMac),
+			prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start),
+			prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end),
+			prLink->ucReasonCode,
+			prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP));
+
+		if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) {
+			DBGLOG(TDLS, TRACE,
+			       "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n",
+				prLink->ucHtBa[0], prLink->ucHtBa[1],
+				prLink->ucHtBa[2], prLink->ucHtBa[3],
+				prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]);
+		}
+	}
+	DBGLOG(TDLS, TRACE, "\n");
+
+	/* display link information */
+	if (prCmdContent != NULL) {
+		if (kalMemCmp(prCmdContent->aucPeerMac, ucMacZero, 6) != 0) {
+			prStaRec = cnmGetStaRecByAddress(prAdapter,
+							 prCmdContent->ucNetTypeIndex, prCmdContent->aucPeerMac);
+			if (prStaRec == NULL)
+				fgIsListAll = TRUE;
+		}
+
+		ucNetTypeIndex = prCmdContent->ucNetTypeIndex;
+	}
+
+	while (1) {
+		if (fgIsListAll == TRUE) {
+			/* list all TDLS peers */
+			prStaRec = cnmStaTheTypeGet(prAdapter, ucNetTypeIndex, STA_TYPE_TDLS_PEER, &u4StartIdx);
+			if (prStaRec == NULL)
+				break;
+		}
+
+		DBGLOG(TDLS, TRACE, "-------- TDLS %d: 0x %pM\n", u4PeerNum, (prStaRec->aucMacAddr));
+		DBGLOG(TDLS, TRACE, "\t\t\t State %d, PM %d, Cap 0x%x\n",
+				     prStaRec->ucStaState, prStaRec->fgIsInPS, prStaRec->u2CapInfo);
+		DBGLOG(TDLS, TRACE, "\t\t\t SetupDisable %d, ChSwDisable %d\n",
+				     prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited);
+
+		if (fgIsListAll == FALSE)
+			break;	/* only list one */
+	}
+
+	/* check if we need to clear all histories */
+	if ((prCmdContent != NULL) && (prCmdContent->Content.rCmdInfoDisplay.fgIsToClearAllHistory == TRUE)) {
+		kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink));
+		prGlueInfo->rTdlsLink.u4LinkIdx = TDLS_LINK_HISTORY_MAX - 1;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to display key information.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_KEY_INFO;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to record a disconnection event.
+*
+* \param[in] prGlueInfo			Pointer to the GLUE_INFO_T structure
+* \param[in] fgIsTearDown		TRUE: the link is torn down
+* \param[in] pucPeerMac		Pointer to the MAC of the TDLS peer
+* \param[in] fgIsFromUs		TRUE: tear down is from us
+* \param[in] u2ReasonCode		Disconnection reason (TDLS_REASON_CODE)
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+static VOID
+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo,
+		      BOOLEAN fgIsTearDown,
+		      UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers)
+{
+	TDLS_INFO_LINK_T *prLink;
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_evt> %s: record history for %pM %d %d %d %d\n",
+		__func__, pucPeerMac, prGlueInfo->rTdlsLink.u4LinkIdx,
+		fgIsTearDown, fgIsFromUs, u2ReasonCode);
+
+	/* check duplicate one */
+	if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) {
+		DBGLOG(TDLS, ERROR, "<tdls_evt> %s: u4LinkIdx >= TDLS_LINK_HISTORY_MAX\n", __func__);
+
+		/* reset to 0 */
+		prGlueInfo->rTdlsLink.u4LinkIdx = 0;
+	}
+
+	prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx];
+
+	if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) == 0) {
+		if ((prLink->ucReasonCode == u2ReasonCode) && (prLink->fgIsFromUs == fgIsFromUs)) {
+			/* same Peer MAC, Reason Code, Trigger source */
+			if (fgIsTearDown == TRUE) {
+				if (prLink->jiffies_end != 0) {
+					/* already torn down */
+					prLink->ucDupCount++;
+					return;
+				}
+			} else {
+				/* already built */
+				prLink->ucDupCount++;
+				return;
+			}
+		}
+	}
+
+	/* search old entry */
+	if (fgIsTearDown == TRUE) {
+		/* TODO: need to search all entries to find it if we support multiple TDLS link design */
+		if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) {
+			/* error! can not find the link entry */
+			DBGLOG(TDLS, INFO, "<tdls_evt> %s: cannot find the same entry!!!\n", __func__);
+			return;
+		}
+
+		prLink->jiffies_end = jiffies;
+		prLink->ucReasonCode = (UINT8) u2ReasonCode;
+		prLink->fgIsFromUs = fgIsFromUs;
+	} else {
+		/* record new one */
+		prGlueInfo->rTdlsLink.u4LinkIdx++;
+		if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX)
+			prGlueInfo->rTdlsLink.u4LinkIdx = 0;
+
+		prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx];
+
+		prLink->jiffies_start = jiffies;
+		prLink->jiffies_end = 0;
+		kalMemCopy(&prLink->aucPeerMac, pucPeerMac, 6);
+		prLink->ucReasonCode = 0;
+		prLink->fgIsFromUs = (UINT8) fgIsFromUs;
+		prLink->ucDupCount = 0;
+
+		if (prOthers != NULL) {
+			/* record other parameters */
+			TDLS_LINK_HIS_OTHERS_T *prHisOthers;
+
+			prHisOthers = (TDLS_LINK_HIS_OTHERS_T *) prOthers;
+			if (prHisOthers->fgIsHt == TRUE)
+				prLink->ucHtCap |= TDLS_INFO_LINK_HT_CAP_SUP;
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to update a disconnection event.
+*
+* \param[in] prGlueInfo			Pointer to the GLUE_INFO_T structure
+* \param[in] pucPeerMac		Pointer to the MAC of the TDLS peer
+* \param[in] eFmeStatus		TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME
+* \param[in] pInfo				other information
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+static VOID
+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo,
+			    UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo)
+{
+	TDLS_INFO_LINK_T *prLink;
+	UINT32 u4LinkIdx;
+	UINT32 u4Tid;
+
+	/* sanity check */
+	if ((eFmeStatus < TDLS_HOST_EVENT_SF_BA) || (eFmeStatus > TDLS_HOST_EVENT_SF_BA_RSP_DECLINE)) {
+		/* do not care these frames */
+		return;
+	}
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_evt> %s: update history for %pM %d %d\n",
+		__func__, (pucPeerMac), prGlueInfo->rTdlsLink.u4LinkIdx, eFmeStatus);
+
+	/* init */
+	u4LinkIdx = prGlueInfo->rTdlsLink.u4LinkIdx;
+	prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4LinkIdx];
+
+	/* TODO: need to search all entries to find it if we support multiple TDLS link design */
+	if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) {
+		/* error! can not find the link entry */
+		DBGLOG(TDLS, INFO, "<tdls_evt> %s: cannot find the same entry!!!\n", __func__);
+		return;
+	}
+
+	/* update */
+	u4Tid = *(UINT32 *) pInfo;
+	switch (eFmeStatus) {
+	case TDLS_HOST_EVENT_SF_BA:
+		prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP;
+		break;
+
+	case TDLS_HOST_EVENT_SF_BA_OK:
+		prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_OK;
+		break;
+
+	case TDLS_HOST_EVENT_SF_BA_DECLINE:
+		prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_DECLINE;
+		break;
+
+	case TDLS_HOST_EVENT_SF_BA_PEER:
+		prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_PEER;
+		break;
+
+	case TDLS_HOST_EVENT_SF_BA_RSP_OK:
+		prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_OK;
+		break;
+
+	case TDLS_HOST_EVENT_SF_BA_RSP_DECLINE:
+		prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_DECLINE;
+		break;
+	}
+
+	/* display TDLS link history */
+	TdlsInfoDisplay(prGlueInfo->prAdapter, NULL, 0, NULL);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to configure TDLS MIB parameters.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_MIB_UPDATE;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to configure TDLS SETUP parameters.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_SETUP_CONF;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to configure UAPSD parameters.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*
+*/
+/*----------------------------------------------------------------------------*/
+static TDLS_STATUS
+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	TDLS_CMD_CORE_T *prCmdContent;
+	WLAN_STATUS rStatus;
+
+	/* init command buffer */
+	prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer;
+	prCmdContent->u4Command = TDLS_CORE_CMD_UAPSD_CONF;
+
+	/* send the command */
+	rStatus = wlanSendSetQueryCmd(prAdapter,	/* prAdapter */
+				      CMD_ID_TDLS_CORE,	/* ucCID */
+				      TRUE,	/* fgSetQuery */
+				      FALSE,	/* fgNeedResp */
+				      FALSE,	/* fgIsOid */
+				      NULL, NULL,	/* pfCmdTimeoutHandler */
+				      sizeof(TDLS_CMD_CORE_T),	/* u4SetQueryInfoLen */
+				      (PUINT_8) prCmdContent,	/* pucInfoBuffer */
+				      NULL,	/* pvSetQueryBuffer */
+				      0	/* u4SetQueryBufferLen */
+	    );
+
+	if (rStatus != WLAN_STATUS_PENDING) {
+		DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__);
+		return TDLS_STATUS_RESOURCES;
+	}
+
+	DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__);
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to update frame status.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer, from u4EventSubId
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsEventFmeStatus(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus;
+	STA_RECORD_T *prStaRec;
+	UINT32 u4Tid;
+
+	/* init */
+	u4Tid = *(UINT32 *) prInBuf;
+	prInBuf += 4;		/* skip u4EventSubId */
+
+	/* sanity check */
+	prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf);
+	if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec)))
+		return;
+	prInBuf++;
+
+	/* update status */
+	eFmeStatus = *prInBuf;
+	TdlsLinkHistoryRecordUpdate(prGlueInfo, prStaRec->aucMacAddr, eFmeStatus, &u4Tid);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to collect TDLS statistics from firmware.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer, from u4EventSubId
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	STA_RECORD_T *prStaRec;
+	STAT_CNT_INFO_FW_T *prStat;
+	UINT32 u4RateId;
+
+	/* init */
+	prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf);
+	if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec)))
+		return;
+
+	prInBuf += 4;		/* skip prStaRec->ucIndex */
+
+	/* update statistics */
+	kalMemCopy(&prStaRec->rTdlsStatistics.rFw, prInBuf, sizeof(prStaRec->rTdlsStatistics.rFw));
+
+	/* display statistics */
+	prStat = &prStaRec->rTdlsStatistics.rFw;
+
+	DBGLOG(TDLS, TRACE, "<tdls_evt> peer [%pM] statistics:\n", (prStaRec->aucMacAddr));
+	DBGLOG(TDLS, TRACE, "\t\tT%d %d %d (P%d %d) (%dus) - E%d 0x%x - R%d (P%d)\n",
+			     prStat->u4NumOfTx, prStat->u4NumOfTxOK, prStat->u4NumOfTxRetry,
+			     prStat->u4NumOfPtiRspTxOk, prStat->u4NumOfPtiRspTxErr,
+			     prStat->u4TxDoneAirTimeMax,
+			     prStat->u4NumOfTxErr, prStat->u4TxErrBitmap, prStat->u4NumOfRx, prStat->u4NumOfPtiRspRx);
+
+	DBGLOG(TDLS, TRACE, "\t\t");
+
+	for (u4RateId = prStat->u4TxRateOkHisId; u4RateId < STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM; u4RateId++)
+		DBGLOG(TDLS, TRACE,
+			"%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]);
+	for (u4RateId = 0; u4RateId < prStat->u4TxRateOkHisId; u4RateId++)
+		DBGLOG(TDLS, TRACE,
+			"%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]);
+
+	DBGLOG(TDLS, TRACE, "\n\n");
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to do tear down.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer, from u4EventSubId
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	STA_RECORD_T *prStaRec;
+	UINT16 u2ReasonCode;
+	UINT32 u4TearDownSubId;
+	UINT8 *pMac, aucZeroMac[6];
+
+	/* init */
+	u4TearDownSubId = *(UINT32 *) prInBuf;
+	kalMemZero(aucZeroMac, sizeof(aucZeroMac));
+	pMac = aucZeroMac;
+
+	prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4));
+	if (prStaRec != NULL)
+		pMac = prStaRec->aucMacAddr;
+
+	/* handle */
+	if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) {
+		DBGLOG(TDLS, WARN, "<tdls_evt> %s: peer [%pM] Reason=PTI timeout\n",
+				    __func__, pMac);
+	} else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) {
+		DBGLOG(TDLS, WARN, "<tdls_evt> %s: peer [%pM] Reason=AGE timeout\n",
+				    __func__, pMac);
+	} else {
+		DBGLOG(TDLS, WARN, "<tdls_evt> %s: peer [%pM] Reason=%d\n",
+				    __func__, pMac, u4TearDownSubId);
+	}
+
+	/* sanity check */
+	if (prStaRec == NULL)
+		return;
+
+	if (fgIsPtiTimeoutSkip == TRUE) {
+		/* skip PTI timeout event */
+		if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) {
+			DBGLOG(TDLS, WARN, "<tdls_evt> %s: skip PTI timeout\n", __func__);
+			return;
+		}
+	}
+
+	/* record history */
+	if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT)
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT;
+	else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT)
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT;
+	else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_FAIL)
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL;
+	else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL)
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL;
+	else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX)
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX;
+	else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_NON_STATE3)
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3;
+	else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN)
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN;
+	else {
+		/* shall not be here */
+		u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN;
+	}
+
+	TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, TRUE, u2ReasonCode, NULL);
+
+	/* correct correct reason code for PTI or AGE timeout to supplicant */
+	if ((u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT) ||
+	    (u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT)) {
+		u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE;
+	}
+
+	/* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
+	cfg80211_tdls_oper_request(prGlueInfo->prDevHandler,
+				   prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN, u2ReasonCode, GFP_ATOMIC);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to do tx down.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer, from u4EventSubId
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+static void TdlsEventTxDone(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	/* UINT32 u4FmeIdx; */
+	UINT8 *pucFmeHdr;
+	UINT8 ucErrStatus;
+
+	ucErrStatus = *(UINT32 *) prInBuf;
+
+	pucFmeHdr = prInBuf + 4;	/* skip ucErrStatus */
+
+	if (ucErrStatus == 0)
+		DBGLOG(TDLS, TRACE, "<tdls_evt> %s: OK to tx a TDLS action:", __func__);
+	else
+		DBGLOG(TDLS, TRACE, "<tdls_evt> %s: fail to tx a TDLS action (err=0x%x):", __func__, ucErrStatus);
+	#if 0
+	/* dump TX packet content from wlan header */
+	for (u4FmeIdx = 0; u4FmeIdx < (u4InBufLen - 4); u4FmeIdx++) {
+		if ((u4FmeIdx % 16) == 0)
+			DBGLOG(TDLS, TRACE, "\n");
+
+		DBGLOG(TDLS, TRACE, "%02x ", *pucFmeHdr++);
+	}
+	DBGLOG(TDLS, TRACE, "\n\n");
+	#endif
+}
+
+/*******************************************************************************
+*						P U B L I C  F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to parse TDLS Extended Capabilities element.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE)
+{
+	UINT_8 *pucIeExtCap;
+
+	/* sanity check */
+	if ((prStaRec == NULL) || (pucIE == NULL))
+		return;
+
+	if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP)
+		return;
+
+	/*
+	   from bit0 ~
+
+	   bit 38: TDLS Prohibited
+	   The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The
+	   field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is
+	   allowed.
+	 */
+	if (IE_LEN(pucIE) < 5)
+		return;		/* we need 39/8 = 5 bytes */
+
+	/* init */
+	prStaRec->fgTdlsIsProhibited = FALSE;
+	prStaRec->fgTdlsIsChSwProhibited = FALSE;
+
+	/* parse */
+	pucIeExtCap = pucIE + 2;
+	pucIeExtCap += 4;	/* shift to the byte we care about */
+
+	if ((*pucIeExtCap) & BIT(38 - 32))
+		prStaRec->fgTdlsIsProhibited = TRUE;
+	if ((*pucIeExtCap) & BIT(39 - 32))
+		prStaRec->fgTdlsIsChSwProhibited = TRUE;
+
+	DBGLOG(TDLS, TRACE,
+	       "<tdls> %s: AP [%pM] tdls prohibit bit=%d %d\n",
+		__func__,
+		prStaRec->aucMacAddr, prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to transmit a TDLS data frame from nl80211.
+*
+* \param[in] pvAdapter		Pointer to the Adapter structure.
+* \param[in]
+* \param[in]
+* \param[in] buf			includes RSN IE + FT IE + Lifetimeout IE
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+int
+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev,
+		       const u8 *peer, u8 action_code, u8 dialog_token,
+		       u16 status_code, u32 peer_capability,
+		       bool initiator, const u8 *buf, size_t len)
+{
+	ADAPTER_T *prAdapter;
+	GLUE_INFO_T *prGlueInfo;
+	BSS_INFO_T *prAisBssInfo;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	TDLS_MGMT_TX_INFO *prMgmtTxInfo;
+
+	/*
+	   Have correct behavior for STAUT receiving TDLS Setup Request after sending TDLS
+	   Set Request and before receiving TDLS Setup Response:
+	   -- Source Address of received Request is higher than own MAC address
+	   -- Source Address of received Request is lower than own MAC address
+
+	   ==> STA with larger MAC address will send the response frame.
+
+	   Supplicant will do this in wpa_tdls_process_tpk_m1().
+	 */
+
+	/* sanity check */
+	if ((wiphy == NULL) || (peer == NULL)) {
+		DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: wrong 0x%p 0x%p!\n", __func__, wiphy, peer);
+		return -EINVAL;
+	}
+
+	DBGLOG(TDLS, INFO, "<tdls_cfg> %s: [%pM] %d %d %d 0x%p %u\n",
+			    __func__, peer, action_code, dialog_token, status_code, buf, (UINT32) len);
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy);
+	if (prGlueInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo);
+		return -EINVAL;
+	}
+
+	prAdapter = prGlueInfo->prAdapter;
+	if (prAdapter->fgTdlsIsSup == FALSE) {
+		DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: firmware TDLS is not supported!\n", __func__);
+		return -EBUSY;
+	}
+
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	if (prAisBssInfo->fgTdlsIsProhibited == TRUE) {
+		/* do not send anything if TDLS is prohibited in the BSS */
+		return 0;
+	}
+
+	prMgmtTxInfo = kalMemAlloc(sizeof(TDLS_MGMT_TX_INFO), VIR_MEM_TYPE);
+	if (prMgmtTxInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: allocate fail!\n", __func__);
+		return -ENOMEM;
+	}
+
+	kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO));
+
+	if (peer != NULL)
+		kalMemCopy(prMgmtTxInfo->aucPeer, peer, 6);
+	prMgmtTxInfo->ucActionCode = action_code;
+	prMgmtTxInfo->ucDialogToken = dialog_token;
+	prMgmtTxInfo->u2StatusCode = status_code;
+
+	if (buf != NULL) {
+		if (len > sizeof(prMgmtTxInfo->aucSecBuf)) {
+			kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO));
+			return -EINVAL;
+		}
+		prMgmtTxInfo->u4SecBufLen = len;
+		kalMemCopy(prMgmtTxInfo->aucSecBuf, buf, len);
+	}
+
+	/* send the TDLS action data frame */
+	rStatus = kalIoctl(prGlueInfo,
+			   TdlsexMgmtCtrl,
+			   prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	/*
+	   clear all content to avoid any bug if we dont yet execute TdlsexMgmtCtrl()
+	   then kalIoctl finishes
+	 */
+	kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO));
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus);
+		kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO));
+		return -EINVAL;
+	}
+
+	kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO));
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to enable or disable TDLS link from upper layer.
+*
+* \param[in] pvAdapter		Pointer to the Adapter structure.
+* \param[in]
+* \param[in]
+* \param[in] buf			includes RSN IE + FT IE + Lifetimeout IE
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev,
+				const u8 *peer, enum nl80211_tdls_operation oper)
+{
+	ADAPTER_T *prAdapter;
+	GLUE_INFO_T *prGlueInfo;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	TDLS_CMD_LINK_T rCmdLink;
+
+	/* sanity check */
+	if (peer == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: peer == NULL!\n", __func__);
+		return -EINVAL;
+	}
+
+	DBGLOG(TDLS, INFO, "<tdls_cfg> %s: [%pM] %d %d\n",
+			    __func__, peer, oper, (wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS));
+
+	if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
+		return -ENOTSUPP;
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy);
+	if (prGlueInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo);
+		return -EINVAL;
+	}
+	prAdapter = prGlueInfo->prAdapter;
+	kalMemCopy(rCmdLink.aucPeerMac, peer, sizeof(rCmdLink.aucPeerMac));
+	rCmdLink.fgIsEnabled = FALSE;
+
+	/*
+	   enum nl80211_tdls_operation {
+	   NL80211_TDLS_DISCOVERY_REQ,
+	   NL80211_TDLS_SETUP,
+	   NL80211_TDLS_TEARDOWN,
+	   NL80211_TDLS_ENABLE_LINK,
+	   NL80211_TDLS_DISABLE_LINK,
+	   };
+	 */
+
+	switch (oper) {
+	case NL80211_TDLS_ENABLE_LINK:
+		rCmdLink.fgIsEnabled = TRUE;
+		break;
+
+	case NL80211_TDLS_DISABLE_LINK:
+		rCmdLink.fgIsEnabled = FALSE;
+		break;
+
+	case NL80211_TDLS_TEARDOWN:
+	case NL80211_TDLS_SETUP:
+	case NL80211_TDLS_DISCOVERY_REQ:
+		/* we do not support setup/teardown/discovery from driver */
+		return -ENOTSUPP;
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	/* enable or disable TDLS link */
+	rStatus = kalIoctl(prGlueInfo,
+			   TdlsexLinkCtrl, &rCmdLink, sizeof(TDLS_CMD_LINK_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a command to TDLS module.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
+{
+	UINT_32 u4Subcmd;
+	static void (*TdlsCmdTestFunc)(P_GLUE_INFO_T, UINT_8 *, UINT_32);
+
+	/* parse TDLS sub-command */
+	u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen);
+	DBGLOG(TDLS, INFO, "<tdls_cmd> sub command = %u\n", (UINT32) u4Subcmd);
+	TdlsCmdTestFunc = NULL;
+
+	/* handle different sub-command */
+	switch (u4Subcmd) {
+#if TDLS_CFG_CMD_TEST		/* only for unit test */
+	case TDLS_CMD_TEST_TX_FRAME:
+		/* simulate to send a TDLS frame */
+		/* TdlsCmdTestTxFrame(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestTxFrame;
+		break;
+
+	case TDLS_CMD_TEST_TX_TDLS_FRAME:
+		/* simulate to send a TDLS frame from supplicant */
+		/* TdlsCmdTestTxTdlsFrame(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestTxTdlsFrame;
+		break;
+
+	case TDLS_CMD_TEST_RCV_FRAME:
+		/* simulate to receive a TDLS frame */
+		/* TdlsCmdTestRvFrame(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestRvFrame;
+		break;
+
+	case TDLS_CMD_TEST_PEER_ADD:
+		/* simulate to add a TDLS peer */
+		/* TdlsCmdTestAddPeer(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestAddPeer;
+		break;
+
+	case TDLS_CMD_TEST_PEER_UPDATE:
+		/* simulate to update a TDLS peer */
+		/* TdlsCmdTestUpdatePeer(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestUpdatePeer;
+		break;
+
+	case TDLS_CMD_TEST_DATA_FRAME:
+		/* simulate to send a data frame to the peer */
+		/* TdlsCmdTestDataSend(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestDataSend;
+		break;
+
+	case TDLS_CMD_TEST_RCV_NULL:
+		/* simulate to receive a QoS null frame from the peer */
+		/* TdlsCmdTestNullRecv(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestNullRecv;
+		break;
+
+	case TDLS_CMD_TEST_SKIP_TX_FAIL:
+		/* command firmware to skip tx fail case */
+		/* TdlsCmdTestTxFailSkip(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestTxFailSkip;
+		break;
+
+	case TDLS_CMD_TEST_SKIP_KEEP_ALIVE:
+		/* command firmware to skip keep alive function */
+		/* TdlsCmdTestKeepAliveSkip(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestKeepAliveSkip;
+		break;
+
+	case TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT:
+		/* command firmware to skip channel switch timeout function */
+		/* TdlsCmdTestChSwTimeoutSkip(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestChSwTimeoutSkip;
+		break;
+
+	case TDLS_CMD_TEST_PROHIBIT_SET_IN_AP:
+		/* simulate to set Prohibited Bit in AP */
+		/* TdlsCmdTestProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestProhibitedBitSet;
+		break;
+
+	case TDLS_CMD_TEST_SCAN_DISABLE:
+		/* command to disable scan request to do channel switch */
+		/* TdlsCmdTestScanCtrl(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestScanCtrl;
+		break;
+
+	case TDLS_CMD_TEST_DATA_FRAME_CONT:
+		/* simulate to send a data frame to the peer periodically */
+		/* TdlsCmdTestDataContSend(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestDataContSend;
+		break;
+
+	case TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP:
+		/* simulate to set channel switch Prohibited Bit in AP */
+		/* TdlsCmdTestChSwProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestChSwProhibitedBitSet;
+		break;
+
+	case TDLS_CMD_TEST_DELAY:
+		/* delay a where */
+		/* TdlsCmdTestDelay(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestDelay;
+		break;
+
+	case TDLS_CMD_TEST_PTI_TX_FAIL:
+		/* simulate the tx done fail for PTI */
+		/* TdlsCmdTestPtiTxDoneFail(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdTestPtiTxDoneFail;
+		break;
+#endif /* TDLS_CFG_CMD_TEST */
+
+	case TDLS_CMD_MIB_UPDATE:
+		/* update MIB parameters */
+		/* TdlsCmdMibParamUpdate(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdMibParamUpdate;
+		break;
+
+	case TDLS_CMD_UAPSD_CONF:
+		/* config UAPSD parameters */
+		/* TdlsCmdUapsdConf(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdUapsdConf;
+		break;
+
+	case TDLS_CMD_CH_SW_CONF:
+		/* enable or disable or start or stop channel switch function */
+		/* TdlsCmdChSwConf(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdChSwConf;
+		break;
+
+	case TDLS_CMD_SETUP_CONF:
+		/* config setup parameters */
+		/* TdlsCmdSetupConf(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdSetupConf;
+		break;
+
+	case TDLS_CMD_INFO:
+		/* display all TDLS information */
+		/* TdlsCmdInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdInfoDisplay;
+		break;
+
+	case TDLS_CMD_KEY_INFO:
+		/* display key information */
+		/* TdlsCmdKeyInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */
+		TdlsCmdTestFunc = TdlsCmdKeyInfoDisplay;
+		break;
+
+	default:
+		break;
+	}
+
+	if (TdlsCmdTestFunc != NULL)
+		TdlsCmdTestFunc(prGlueInfo, prInBuf, u4InBufLen);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to record a disconnection event.
+*
+* \param[in] prGlueInfo			Pointer to the GLUE_INFO_T structure
+* \param[in] fgIsTearDown		TRUE: tear down
+* \param[in] pucPeerMac		Pointer to the MAC of the TDLS peer
+* \param[in] fgIsFromUs		TRUE: tear down is from us
+* \param[in] u2ReasonCode		Disconnection reason (TDLS_REASON_CODE)
+*
+* \retval none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo,
+			BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode)
+{
+	/* sanity check */
+	if ((prGlueInfo == NULL) || (pucPeerMac == NULL))
+		return;
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_evt> %s: Rcv a inform from %pM %d %d\n",
+		__func__, pucPeerMac, fgIsFromUs, u2ReasonCode);
+
+	/* record */
+	TdlsLinkHistoryRecord(prGlueInfo, fgIsTearDown, pucPeerMac, fgIsFromUs, u2ReasonCode, NULL);
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to send a command to TDLS module.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen)
+{
+	UINT32 u4EventId;
+
+	/* sanity check */
+	if ((prGlueInfo == NULL) || (prInBuf == NULL))
+		return;		/* shall not be here */
+
+	/* handle */
+	u4EventId = *(UINT32 *) prInBuf;
+	u4InBufLen -= 4;
+
+	DBGLOG(TDLS, INFO, "<tdls> %s: Rcv a event: %d\n", __func__, u4EventId);
+
+	switch (u4EventId) {
+	case TDLS_HOST_EVENT_TEAR_DOWN:
+		TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen);
+		break;
+
+	case TDLS_HOST_EVENT_TX_DONE:
+		TdlsEventTxDone(prGlueInfo, prInBuf + 4, u4InBufLen);
+		break;
+
+	case TDLS_HOST_EVENT_FME_STATUS:
+		TdlsEventFmeStatus(prGlueInfo, prInBuf + 4, u4InBufLen);
+		break;
+
+	case TDLS_HOST_EVENT_STATISTICS:
+		TdlsEventStatistics(prGlueInfo, prInBuf + 4, u4InBufLen);
+		break;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to initialize variables in TDLS.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+*
+* @return	TDLS_STATUS_SUCCESS: do not set key and key infor. is queued
+			TDLS_STATUS_FAILURE: set key
+*/
+/*----------------------------------------------------------------------------*/
+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey)
+{
+	STA_RECORD_T *prStaRec;
+
+	/* sanity check */
+	if ((prAdapter == NULL) || (prNewKey == NULL))
+		return TDLS_STATUS_FAILURE;
+
+	/*
+	   supplicant will set key before updating station & enabling the link so we need to
+	   backup the key information and set key when link is enabled
+	 */
+	prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prNewKey->arBSSID);
+	if ((prStaRec != NULL) && IS_TDLS_STA(prStaRec)) {
+		DBGLOG(TDLS, TRACE, "<tdls> %s: [%pM] queue key (len=%d) until link is enabled\n",
+				     __func__, prNewKey->arBSSID, (UINT32) prNewKey->u4KeyLength);
+
+		if (prStaRec->ucStaState == STA_STATE_3) {
+			DBGLOG(TDLS, TRACE, "<tdls> %s: [%pM] tear down the link due to STA_STATE_3\n",
+					     __func__, prNewKey->arBSSID);
+
+			/* re-key */
+			TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE,
+					      prStaRec->aucMacAddr, TRUE,
+					      TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL);
+
+			/* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
+			cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler,
+						   prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN,
+						   TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC);
+			return TDLS_STATUS_SUCCESS;
+		}
+
+		/* backup the key */
+		kalMemCopy(&prStaRec->rTdlsKeyTemp, prNewKey, sizeof(prStaRec->rTdlsKeyTemp));
+		return TDLS_STATUS_SUCCESS;
+	}
+
+	return TDLS_STATUS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to initialize variables in TDLS.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID TdlsexInit(ADAPTER_T *prAdapter)
+{
+	GLUE_INFO_T *prGlueInfo;
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+
+	/* reset */
+	kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink));
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to get any peer is in power save.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+*
+* \retval TRUE (at least one peer is in power save)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter)
+{
+	STA_RECORD_T *prStaRec;
+	UINT32 u4StaId, u4StartIdx;
+
+	for (u4StaId = 0, u4StartIdx = 0; u4StaId < CFG_STA_REC_NUM; u4StaId++) {
+		/* list all TDLS peers */
+		prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx);
+		if (prStaRec == NULL)
+			break;
+
+		if (prStaRec->fgIsInPS == TRUE) {
+			DBGLOG(TDLS, TRACE, "<tx> yes, at least one peer is in ps\n");
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to enable or disable a TDLS link.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*/
+/*----------------------------------------------------------------------------*/
+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	GLUE_INFO_T *prGlueInfo;
+	TDLS_CMD_LINK_T *prCmd;
+	BSS_INFO_T *prBssInfo;
+	STA_RECORD_T *prStaRec;
+	TDLS_LINK_HIS_OTHERS_T rHisOthers;
+
+	/* sanity check */
+	if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: sanity fail!\n", __func__);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+	*pu4SetInfoLen = sizeof(TDLS_CMD_LINK_T);
+	prCmd = (TDLS_CMD_LINK_T *) pvSetBuffer;
+
+	/* search old entry */
+	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac);
+	if (prStaRec == NULL) {
+		DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: cannot find the peer! %pM\n",
+				     __func__, prCmd->aucPeerMac);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	if (prCmd->fgIsEnabled == TRUE) {
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
+		DBGLOG(TDLS, TRACE, "<tdls_cfg> %s: NL80211_TDLS_ENABLE_LINK\n", __func__);
+
+		/* update key information after cnmStaRecChangeState(STA_STATE_3) */
+		prStaRec->fgTdlsInSecurityMode = FALSE;
+
+		if (prStaRec->rTdlsKeyTemp.u4Length > 0) {
+			UINT_32 u4BufLen;	/* no use */
+
+			DBGLOG(TDLS, INFO, "<tdls_cfg> %s: key len=%d\n",
+					    __func__, (UINT32) prStaRec->rTdlsKeyTemp.u4Length);
+
+			/*
+			   reminder the function that we are CIPHER_SUITE_CCMP,
+			   do not change cipher type to CIPHER_SUITE_WEP128
+			 */
+			_wlanoidSetAddKey(prAdapter, &prStaRec->rTdlsKeyTemp,
+					  prStaRec->rTdlsKeyTemp.u4Length, FALSE, CIPHER_SUITE_CCMP, &u4BufLen);
+
+			/* clear the temp key */
+			prStaRec->fgTdlsInSecurityMode = TRUE;
+			kalMemZero(&prStaRec->rTdlsKeyTemp, sizeof(prStaRec->rTdlsKeyTemp));
+		}
+
+		/* check if we need to disable channel switch function */
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+		if (prBssInfo->fgTdlsIsChSwProhibited == TRUE) {
+			TDLS_CMD_CORE_T rCmd;
+
+			kalMemZero(&rCmd, sizeof(TDLS_CMD_CORE_T));
+			rCmd.Content.rCmdChSwConf.ucNetTypeIndex = prStaRec->ucNetTypeIndex;
+			rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = FALSE;
+			kalMemCopy(rCmd.aucPeerMac, prStaRec->aucMacAddr, 6);
+			TdlsChSwConf(prAdapter, &rCmd, 0, 0);
+
+			DBGLOG(TDLS, INFO, "<tdls_cfg> %s: disable channel switch\n", __func__);
+		}
+
+		TDLS_LINK_INCREASE(prGlueInfo);
+
+		/* record link */
+		if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N)
+			rHisOthers.fgIsHt = TRUE;
+		else
+			rHisOthers.fgIsHt = FALSE;
+
+		TdlsLinkHistoryRecord(prAdapter->prGlueInfo, FALSE,
+				      prStaRec->aucMacAddr, !prStaRec->flgTdlsIsInitiator, 0, &rHisOthers);
+	} else {
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+		cnmStaRecFree(prAdapter, prStaRec, TRUE);	/* release to other TDLS peers */
+		DBGLOG(TDLS, TRACE, "<tdls_cfg> %s: NL80211_TDLS_DISABLE_LINK\n", __func__);
+
+		TDLS_LINK_DECREASE(prGlueInfo);
+/* while(1); //sample debug */
+	}
+
+	/* work-around link count */
+	if ((TDLS_LINK_COUNT(prGlueInfo) < 0) || (TDLS_LINK_COUNT(prGlueInfo) > 1)) {
+		/* ERROR case: work-around to recount by searching all station records */
+		UINT32 u4Idx;
+
+		TDLS_LINK_COUNT_RESET(prGlueInfo);
+
+		for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) {
+			prStaRec = &prAdapter->arStaRec[u4Idx];
+
+			if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec))
+				TDLS_LINK_INCREASE(prGlueInfo);
+		}
+
+		if (TDLS_LINK_COUNT(prGlueInfo) > 1) {
+			/* number of links is still > 1 */
+			DBGLOG(TDLS, INFO, "<tdls_cfg> %s: cTdlsLinkCnt %d > 1?\n",
+					    __func__, TDLS_LINK_COUNT(prGlueInfo));
+
+			TDLS_LINK_COUNT_RESET(prGlueInfo);
+
+			/* free all TDLS links */
+			for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) {
+				prStaRec = &prAdapter->arStaRec[u4Idx];
+
+				if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec))
+					cnmStaRecFree(prAdapter, prStaRec, TRUE);
+			}
+
+			/* maybe inform supplicant ? */
+		}
+	}
+
+	/* display TDLS link history */
+	TdlsInfoDisplay(prAdapter, NULL, 0, NULL);
+
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to send a TDLS action data frame.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*/
+/*----------------------------------------------------------------------------*/
+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	GLUE_INFO_T *prGlueInfo;
+	TDLS_MGMT_TX_INFO *prMgmtTxInfo;
+	STA_RECORD_T *prStaRec;
+
+	/* sanity check */
+	if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: sanity fail!\n", __func__);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+	*pu4SetInfoLen = sizeof(TDLS_MGMT_TX_INFO);
+	prMgmtTxInfo = (TDLS_MGMT_TX_INFO *) pvSetBuffer;
+
+	switch (prMgmtTxInfo->ucActionCode) {
+	case TDLS_FRM_ACTION_DISCOVERY_RESPONSE:
+		prStaRec = NULL;
+		break;
+
+	case TDLS_FRM_ACTION_SETUP_REQ:
+		prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer);
+		if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3)) {
+			/* rekey? we reject re-setup link currently */
+			/* TODO: Still can setup link during rekey */
+
+			/*
+			   return success to avoid supplicant clear TDLS entry;
+			   Or we cannot send out any TDLS tear down frame to the peer
+			 */
+			DBGLOG(TDLS, TRACE, "<tdls_cmd> %s: skip new setup on the exist link!\n", __func__);
+			return TDLS_STATUS_SUCCESS;
+		}
+
+		prStaRec = NULL;
+		break;
+
+	case TDLS_FRM_ACTION_SETUP_RSP:
+	case TDLS_FRM_ACTION_CONFIRM:
+	case TDLS_FRM_ACTION_TEARDOWN:
+		prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer);
+#if 0				/* in some cases, the prStaRec is still NULL */
+		/*
+		   EX: if a peer sends us a TDLS setup request with wrong BSSID,
+		   supplicant will not call TdlsexPeerAdd() to create prStaRec and
+		   supplicant will send a TDLS setup response with status code 7.
+
+		   So in the case, prStaRec will be NULL.
+		 */
+		if (prStaRec == NULL) {
+			DBGLOG(TDLS, ERROR, "<tdls_cfg> %s: cannot find the peer!\n", __func__);
+			return -EINVAL;
+		}
+#endif
+		break;
+
+		/*
+		   TODO: Discovery response frame
+		   Note that the TDLS Discovery Response frame is not a TDLS frame but a 11
+		   Public Action frame.
+		   In WiFi TDLS Tech Minutes June 8 2010.doc,
+		   a public action frame (i.e. it is no longer an encapsulated data frame)
+		 */
+
+	default:
+		DBGLOG(TDLS, ERROR,
+		       "<tdls_cfg> %s: wrong action_code %d!\n", __func__, prMgmtTxInfo->ucActionCode);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	/* send the TDLS data frame */
+	if (prStaRec != NULL) {
+		DBGLOG(TDLS, INFO, "<tdls_cfg> %s: [%pM] ps=%d status=%d\n",
+				    __func__, prStaRec->aucMacAddr,
+				    prStaRec->fgIsInPS, prMgmtTxInfo->u2StatusCode);
+
+		if (prMgmtTxInfo->ucActionCode == TDLS_FRM_ACTION_TEARDOWN) {
+			/* record disconnect history */
+			TdlsLinkHistoryRecord(prGlueInfo, TRUE, prMgmtTxInfo->aucPeer,
+					      TRUE, prMgmtTxInfo->u2StatusCode, NULL);
+		}
+	}
+
+	return TdlsDataFrameSend(prAdapter,
+				 prStaRec,
+				 prMgmtTxInfo->aucPeer,
+				 prMgmtTxInfo->ucActionCode,
+				 prMgmtTxInfo->ucDialogToken,
+				 prMgmtTxInfo->u2StatusCode,
+				 (UINT_8 *) prMgmtTxInfo->aucSecBuf, prMgmtTxInfo->u4SecBufLen);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to add a peer record.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*/
+/*----------------------------------------------------------------------------*/
+TDLS_STATUS TdlsexPeerAdd(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	GLUE_INFO_T *prGlueInfo;
+	TDLS_CMD_PEER_ADD_T *prCmd;
+	BSS_INFO_T *prAisBssInfo;
+	STA_RECORD_T *prStaRec;
+	UINT_8 ucNonHTPhyTypeSet;
+	UINT32 u4StartIdx;
+	OS_SYSTIME rCurTime;
+
+	/* sanity check */
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s\n", __func__);
+
+	if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: sanity fail!\n", __func__);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+	*pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T);
+	prCmd = (TDLS_CMD_PEER_ADD_T *) pvSetBuffer;
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	u4StartIdx = 0;
+
+	/* search old entry */
+	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac);
+
+	/* check if any TDLS link exists because we only support one TDLS link currently */
+	if (prStaRec == NULL) {
+		/* the MAC is new peer */
+		prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx);
+
+		if (prStaRec != NULL) {
+			/* a building TDLS link exists */
+			DBGLOG(TDLS, ERROR,
+			       "<tdls_cmd> %s: one TDLS link setup [%pM] is going...\n",
+				__func__, prStaRec->aucMacAddr);
+
+			if (prStaRec->ucStaState != STA_STATE_3) {
+				/* check timeout */
+				GET_CURRENT_SYSTIME(&rCurTime);
+
+				if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsSetupStartTime,
+						      SEC_TO_SYSTIME(TDLS_SETUP_TIMEOUT_SEC))) {
+					/* free the StaRec */
+					cnmStaRecFree(prAdapter, prStaRec, TRUE);
+
+					DBGLOG(TDLS, ERROR,
+					       "<tdls_cmd> %s: free going TDLS link setup [%pM]\n",
+						__func__, (prStaRec->aucMacAddr));
+
+					/* handle new setup */
+					prStaRec = NULL;
+				} else
+					return TDLS_STATUS_FAILURE;
+			} else {
+				/* the TDLS is built and works fine, reject new one */
+				return TDLS_STATUS_FAILURE;
+			}
+		}
+	} else {
+		if (prStaRec->ucStaState == STA_STATE_3) {
+			/* the peer exists, maybe TPK lifetime expired, supplicant wants to renew key */
+			TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE,
+					      prStaRec->aucMacAddr, TRUE,
+					      TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL);
+
+			/* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
+			cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler,
+						   prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN,
+						   TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC);
+
+			DBGLOG(TDLS, TRACE,
+			       "<tdls_cmd> %s: re-setup link for [%pM] maybe re-key?\n",
+				__func__, (prStaRec->aucMacAddr));
+			return TDLS_STATUS_FAILURE;
+		}
+	}
+
+	/*
+	   create new entry if not exist
+
+	   1. we are initiator
+	   (1) send TDLS setup request
+	   wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
+	   create a station record with STA_STATE_1.
+	   (2) got TDLS setup response and send TDLS setup confirm
+	   wpa_tdls_enable_link()
+	   update a station record with STA_STATE_3.
+
+	   2. we are responder
+	   (1) got TDLS setup request
+	   wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
+	   create a station record with STA_STATE_1.
+	   (2) send TDLS setup response
+	   (3) got TDLS setup confirm
+	   wpa_tdls_enable_link()
+	   update a station record with STA_STATE_3.
+	 */
+	if (prStaRec == NULL) {
+		prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX);
+
+		if (prStaRec == NULL) {
+			/* shall not be here */
+			DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: alloc prStaRec fail!\n", __func__);
+			return TDLS_STATUS_RESOURCES;
+		}
+
+		/* init the prStaRec */
+		/* prStaRec will be zero first in cnmStaRecAlloc() */
+		COPY_MAC_ADDR(prStaRec->aucMacAddr, prCmd->aucPeerMac);
+
+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); */
+	} else {
+#if 0
+		if ((prStaRec->ucStaState > STA_STATE_1) && (IS_TDLS_STA(prStaRec))) {
+			/*
+			   test plan: The STAUT should locally tear down existing TDLS direct link and
+			   respond with Set up Response frame.
+			 */
+			cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+		}
+#endif
+	}
+
+	/* reference to bssCreateStaRecFromBssDesc() and use our best capability */
+	/* reference to assocBuildReAssocReqFrameCommonIEs() to fill elements */
+
+	/* prStaRec->u2CapInfo */
+	/* TODO: Need to parse elements from setup request frame */
+	prStaRec->u2OperationalRateSet = prAisBssInfo->u2OperationalRateSet;
+	prStaRec->u2BSSBasicRateSet = prAisBssInfo->u2BSSBasicRateSet;
+	prStaRec->u2DesiredNonHTRateSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet;
+	prStaRec->ucPhyTypeSet = prAisBssInfo->ucPhyTypeSet;
+	prStaRec->eStaType = STA_TYPE_TDLS_PEER;
+
+	prStaRec->ucDesiredPhyTypeSet =	/*prStaRec->ucPhyTypeSet & */
+	    prAdapter->rWifiVar.ucAvailablePhyTypeSet;
+	ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG;
+
+	/* check for Target BSS's non HT Phy Types */
+	if (ucNonHTPhyTypeSet) {
+		if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) {
+			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX;
+		} else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) {
+			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX;
+		} else {	/* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */
+
+			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX;
+		}
+
+		prStaRec->fgHasBasicPhyType = TRUE;
+	} else {
+		/* use mandatory for 11N only BSS */
+/* ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); */
+
+		prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX;
+		prStaRec->fgHasBasicPhyType = FALSE;
+	}
+
+	/* update non HT Desired Rate Set */
+	{
+		P_CONNECTION_SETTINGS_T prConnSettings;
+
+		prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+		prStaRec->u2DesiredNonHTRateSet =
+		    (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet);
+	}
+
+#if 0		/* TdlsexPeerAdd() will be called before we receive setup rsp in TdlsexRxFrameHandle() */
+	/* check if the add is from the same peer in the 1st unhandled setup request frame */
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: [%pM] [%pM]\n",
+			    __func__, prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac);
+
+	if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) {
+		/* copy the HT capability from its setup request */
+		kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T));
+
+		prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N;
+		prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX);
+
+		/* reset backup */
+		kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap));
+		kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac));
+
+		DBGLOG(TDLS, INFO, "<tdls_cmd> %s: peer is a HT device\n", __func__);
+	}
+#endif
+
+	/* update WMM: must support due to UAPSD in TDLS link */
+	prStaRec->fgIsWmmSupported = TRUE;
+	prStaRec->fgIsUapsdSupported = TRUE;
+
+	/* update station record to firmware */
+	cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+
+	/* update time */
+	GET_CURRENT_SYSTIME(&prStaRec->rTdlsSetupStartTime);
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: create a peer [%pM]\n",
+			    __func__, (prStaRec->aucMacAddr));
+
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to update a peer record.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+* \param[in] pvSetBuffer		A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen		The length of the set buffer
+* \param[out] pu4SetInfoLen	If the call is successful, returns the number of
+*	bytes read from the set buffer. If the call failed due to invalid length of
+*	the set buffer, returns the amount of storage needed.
+*
+* \retval TDLS_STATUS_xx
+*/
+/*----------------------------------------------------------------------------*/
+TDLS_STATUS TdlsexPeerUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen)
+{
+	GLUE_INFO_T *prGlueInfo;
+	TDLS_CMD_PEER_UPDATE_T *prCmd;
+	BSS_INFO_T *prAisBssInfo;
+	STA_RECORD_T *prStaRec;
+	IE_HT_CAP_T *prHtCap;
+
+	/* sanity check */
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s\n", __func__);
+
+	if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: sanity fail!\n", __func__);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+	*pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T);
+	prCmd = (TDLS_CMD_PEER_UPDATE_T *) pvSetBuffer;
+	prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+	/* search old entry */
+	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac);
+
+	/*
+	   create new entry if not exist
+
+	   1. we are initiator
+	   (1) send TDLS setup request
+	   wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
+	   create a station record with STA_STATE_1.
+	   (2) got TDLS setup response and send TDLS setup confirm
+	   wpa_tdls_enable_link()
+	   update a station record with STA_STATE_3.
+
+	   2. we are responder
+	   (1) got TDLS setup request
+	   wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
+	   create a station record with STA_STATE_1.
+	   (2) send TDLS setup response
+	   (3) got TDLS setup confirm
+	   wpa_tdls_enable_link()
+	   update a station record with STA_STATE_3.
+	 */
+	if ((prStaRec == NULL) || (prStaRec->fgIsInUse == 0)) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: cannot find the peer!\n", __func__);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: update a peer [%pM] %d -> %d, 0x%x\n",
+			    __func__, (prStaRec->aucMacAddr),
+			    prStaRec->ucStaState, STA_STATE_3, prStaRec->eStaType);
+
+	if (!IS_TDLS_STA(prStaRec)) {
+		DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: peer is not TDLS one!\n", __func__);
+		return TDLS_STATUS_FAILURE;
+	}
+
+	/* check if the add is from the same peer in the 1st unhandled setup request frame */
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: [%pM] [%pM]\n",
+			    __func__, (prGlueInfo->aucTdlsHtPeerMac), (prCmd->aucPeerMac));
+
+	if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) {
+		/* copy the HT capability from its setup request */
+		kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T));
+
+		prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N;
+		prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX);
+
+		/* reset backup */
+		kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap));
+		kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac));
+
+		DBGLOG(TDLS, INFO, "<tdls_cmd> %s: peer is a HT device\n", __func__);
+	}
+
+	/* update the record join time. */
+	GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);
+
+	/* update Station Record - Status/Reason Code */
+	prStaRec->u2StatusCode = prCmd->u2StatusCode;
+
+	/* prStaRec->ucStaState shall be STA_STATE_1 */
+
+	prStaRec->u2CapInfo = prCmd->u2Capability;
+/*	prStaRec->u2OperationalRateSet */
+	prStaRec->u2AssocId = 0;	/* no use */
+	prStaRec->u2ListenInterval = 0;	/* unknown */
+/*	prStaRec->ucDesiredPhyTypeSet */
+/*	prStaRec->u2DesiredNonHTRateSet */
+/*	prStaRec->u2BSSBasicRateSet */
+/*	prStaRec->ucMcsSet */
+/*	prStaRec->fgSupMcs32 */
+/*	prStaRec->u2HtCapInfo */
+	prStaRec->fgIsQoS = TRUE;
+	prStaRec->fgIsUapsdSupported = (prCmd->UapsdBitmap == 0) ? FALSE : TRUE;
+/*	prStaRec->ucAmpduParam */
+/*	prStaRec->u2HtExtendedCap */
+	prStaRec->u4TxBeamformingCap = 0;	/* no use */
+	prStaRec->ucAselCap = 0;	/* no use */
+	prStaRec->ucRCPI = 0;
+	prStaRec->ucBmpTriggerAC = prCmd->UapsdBitmap;
+	prStaRec->ucBmpDeliveryAC = prCmd->UapsdBitmap;
+	prStaRec->ucUapsdSp = prCmd->UapsdMaxSp;
+
+	/* update HT */
+#if (TDLS_CFG_HT_SUP == 1)
+	if (prCmd->fgIsSupHt == FALSE) {
+		/* no HT IE is from supplicant so we use the backup */
+		prHtCap = (IE_HT_CAP_T *) &prStaRec->rTdlsHtCap;
+
+		DBGLOG(TDLS, INFO, "<tdls_cmd> %s: [%pM] update ht ie 0x%x\n",
+				    __func__, (prStaRec->aucMacAddr), prHtCap->ucId);
+
+		if (prHtCap->ucId == ELEM_ID_HT_CAP) {
+			prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
+			prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE;
+
+			prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
+			prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
+			prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
+			prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
+			prStaRec->ucAselCap = prHtCap->ucAselCap;
+			prStaRec->ucDesiredPhyTypeSet |= PHY_TYPE_SET_802_11N;
+		}
+	} else {
+		/* TODO: use the HT IE from supplicant */
+	}
+#endif /* TDLS_CFG_HT_SUP */
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: UAPSD 0x%x %d MCS=0x%x\n",
+			    __func__, prCmd->UapsdBitmap, prCmd->UapsdMaxSp, prStaRec->ucMcsSet);
+
+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: update a peer [%pM]\n",
+			    __func__, (prStaRec->aucMacAddr));
+
+	return TDLS_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to check if we need to drop a TDLS action frame.
+*
+* \param[in] *pPkt		Pointer to the struct sk_buff->data.
+* \param[in]
+* \param[in]
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt)
+{
+	ADAPTER_T *prAdapter;
+	UINT8 ucActionId;
+
+	/* sanity check */
+	if ((pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d))
+		return FALSE;	/* not TDLS data frame htons(0x890d) */
+
+#if 0				/* supplicant handles this check */
+	if (prStaRec == NULL)
+		return FALSE;	/* shall not be here */
+
+	DBGLOG(TDLS, INFO,
+	       "<tdls_fme> %s: Rcv a TDLS action frame (id=%d) %d %d\n",
+		__func__, *(pPkt + 13 + 4), prStaRec->fgTdlsIsProhibited, fgIsPtiTimeoutSkip);
+
+	/* check if TDLS Prohibited bit is set in AP's beacon */
+	if (prStaRec->fgTdlsIsProhibited == TRUE)
+		return TRUE;
+#endif
+
+	ucActionId = *(pPkt + 12 + 2 + 2);	/* skip dst, src MAC, type, payload type, category */
+
+	if (fgIsPtiTimeoutSkip == TRUE) {
+		/* also skip any tear down frame from the peer */
+		if (ucActionId == TDLS_FRM_ACTION_TEARDOWN)
+			return TRUE;
+	}
+
+	prAdapter = prGlueInfo->prAdapter;
+	DBGLOG(TDLS, INFO,
+	       "<tdls_fme> %s: Rcv a TDLS action frame %d (%u)\n",
+		__func__, ucActionId, (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem);
+
+	if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) {
+		DBGLOG(TDLS, WARN, "<tdls_fme> %s: Rcv a TDLS tear down frame %d, will DISABLE link\n",
+				__func__, *(pPkt + 13 + 4));	/* reason code */
+
+		/* record disconnect history */
+		TdlsLinkHistoryRecord(prGlueInfo, TRUE, pPkt + 6, FALSE, *(pPkt + 13 + 4), NULL);
+
+		/* inform tear down to supplicant only in OPEN/NONE mode */
+		/*
+		   we need to tear down the link manually; or supplicant will display
+		   "No FTIE in TDLS Teardown" and it will not tear down the link
+		 */
+		cfg80211_tdls_oper_request(prGlueInfo->prDevHandler,
+					   pPkt + 6, TDLS_FRM_ACTION_TEARDOWN, *(pPkt + 13 + 4), GFP_ATOMIC);
+	}
+#if 0				/* pass all to supplicant except same thing is handled in supplicant */
+	if (((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI) ||
+	    ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_REQ) ||
+	    ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_RSP) ||
+	    ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI_RSP)) {
+		return TRUE;
+	}
+#endif
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to parse some IEs in the setup frame from the peer.
+*
+* \param[in] prGlueInfo			Pointer to the Adapter structure
+* \param[in] pPkt				Pointer to the ethernet packet
+*
+* \retval None
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen)
+{
+	ADAPTER_T *prAdapter;
+	STA_RECORD_T *prStaRec;
+	UINT8 ucActionId;
+	UINT8 *pucPeerMac, ucElmId, ucElmLen;
+	INT16 s2FmeLen;
+
+	/* sanity check */
+	if ((prGlueInfo == NULL) || (pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d))
+		return;
+
+	ucActionId = *(pPkt + 12 + 2 + 2);	/* skip dst, src MAC, type, payload type, category */
+
+	if ((ucActionId != TDLS_FRM_ACTION_SETUP_REQ) && (ucActionId != TDLS_FRM_ACTION_SETUP_RSP))
+		return;
+
+	/* init */
+	prAdapter = prGlueInfo->prAdapter;
+	pucPeerMac = pPkt + 6;
+	s2FmeLen = (INT16) u2PktLen;
+
+	DBGLOG(TDLS, TRACE,
+	       "<tdls_fme> %s: get a setup frame %d from %pM\n",
+		__func__, ucActionId, (pucPeerMac));
+
+	if (ucActionId == TDLS_FRM_ACTION_SETUP_REQ)
+		pPkt += 12 + 2 + 2 + 1 + 1 + 2;	/* skip action, dialog token, capability */
+	else
+		pPkt += 12 + 2 + 2 + 1 + 2 + 1 + 2;	/* skip action, status code, dialog token, capability */
+
+	/* check station record */
+	prStaRec = cnmGetStaRecByAddress(prGlueInfo->prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, pucPeerMac);
+
+	if (prStaRec == NULL) {
+		prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX);
+
+		if (prStaRec == NULL) {
+			/* TODO: only one TDLS entry, need to free old one if timeout */
+			DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: alloc prStaRec fail!\n", __func__);
+			return;
+		}
+
+		/* init the prStaRec */
+		/* prStaRec will be zero first in cnmStaRecAlloc() */
+		COPY_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMac);
+
+		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
+	}
+
+	/* backup HT IE to station record */
+	/* TODO: Maybe our TDLS only supports non-11n */
+	while (s2FmeLen > 0) {
+		ucElmId = *pPkt++;
+		ucElmLen = *pPkt++;
+
+		switch (ucElmId) {
+		case ELEM_ID_HT_CAP:	/* 0x2d */
+			/* backup the HT IE of 1st unhandled setup request frame */
+			if (prGlueInfo->rTdlsHtCap.ucId == 0x00) {
+				kalMemCopy(prGlueInfo->aucTdlsHtPeerMac, pucPeerMac, 6);
+				kalMemCopy(&prGlueInfo->rTdlsHtCap, pPkt - 2, ucElmLen + 2);
+
+				/*
+				   cannot backup in prStaRec; or
+
+				   1. we build a TDLS link
+				   2. peer re-sends setup req
+				   3. we backup HT cap element
+				   4. supplicant disables the link
+				   5. we clear the prStaRec
+				 */
+
+				DBGLOG(TDLS, TRACE,
+				       "<tdls_fme> %s: %pM: find a HT IE\n",
+					__func__, (pucPeerMac));
+			}
+			return;
+
+		case ELEM_ID_EXTENDED_CAP:
+			/* TODO: backup the extended capability IE */
+			break;
+		}
+
+		pPkt += ucElmLen;
+		s2FmeLen -= (2 + ucElmLen);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*! \brief  This routine is called to get the TDLS station record.
+*
+* \param[in] prGlueInfo		Pointer to the Adapter structure
+* \param[in] prInBuf		A pointer to the command string buffer
+* \param[in] u4InBufLen	The length of the buffer
+* \param[out] None
+*
+* \retval	TDLS_STATUS_SUCCESS: this is TDLS packet
+*		TDLS_STATUS_FAILURE: this is not TDLS packet
+*/
+/*----------------------------------------------------------------------------*/
+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo)
+{
+	BSS_INFO_T *prBssInfo;
+	STA_RECORD_T *prStaRec;
+	TDLS_STATUS Status;
+
+	/* sanity check */
+	if ((prAdapter == NULL) || (prMsduInfo == NULL))
+		return TDLS_STATUS_FAILURE;
+
+	if (prAdapter->prGlueInfo == NULL)
+		return TDLS_STATUS_FAILURE;
+	if (TDLS_IS_NO_LINK_GOING(prAdapter->prGlueInfo))
+		return TDLS_STATUS_FAILURE;
+
+	/* init */
+	prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND;
+	Status = TDLS_STATUS_SUCCESS;
+
+	/* get record by ether dest */
+	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMsduInfo->aucEthDestAddr);
+
+	/*
+	   TDLS Setup Request frames, TDLS Setup Response frames and TDLS Setup Confirm
+	   frames shall be transmitted through the AP and shall not be transmitted to a group
+	   address.
+
+	   1. In first time, prStaRec == NULL or prStaRec->ucStaState != STA_STATE_3,
+	   we will send them to AP;
+	   2. When link is still on, if you command to send TDLS setup from supplicant,
+	   supplicant will DISABLE LINK first, prStaRec will be NULL then send TDLS
+	   setup frame to the peer.
+	 */
+
+	do {
+		if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3) && (IS_TDLS_STA(prStaRec))) {
+			/*
+			   TDLS Test Case 5.3 Tear Down
+			   Automatically sends TDLS Teardown frame to STA 2 via AP
+
+			   11.21.5 TDLS Direct Link Teardown
+			   The TDLS Teardown frame shall be sent over the direct path and the reason
+			   code shall be set to "TDLS 40 direct link teardown for unspecified reason",
+			   except when the TDLS peer STA is unreachable via the TDLS direct link,
+			   in which case, the TDLS Teardown frame shall be sent through the AP and
+			   the reason code shall be set to "TDLS direct link teardown due to TDLS peer
+			   STA unreachable via the TDLS direct link".
+			 */
+			/* if (prStaRec->fgIsInPS == TRUE) */
+			/*
+			   check if the packet is tear down:
+			   we do not want to use PTI to indicate the tear down and
+			   we want to send the tear down to AP then AP help us to send it
+			 */
+			struct sk_buff *prSkb;
+			UINT8 *pEth;
+			UINT_16 u2EtherTypeLen;
+
+			prSkb = (struct sk_buff *)prMsduInfo->prPacket;
+			if (prSkb != NULL) {
+				UINT8 ucActionCode, ucReasonCode;
+
+				/* init */
+				pEth = prSkb->data;
+				u2EtherTypeLen = (pEth[ETH_TYPE_LEN_OFFSET] << 8) |
+				    (pEth[ETH_TYPE_LEN_OFFSET + 1]);
+				ucActionCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 3];
+				ucReasonCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] |
+				    (pEth[ETH_TYPE_LEN_OFFSET + 1 + 5] << 8);
+
+				/* TDLS_REASON_CODE_UNREACHABLE: keep alive fail or PTI timeout */
+				if ((u2EtherTypeLen == TDLS_FRM_PROT_TYPE) &&
+					(ucActionCode == TDLS_FRM_ACTION_TEARDOWN) &&
+					(ucReasonCode == TDLS_REASON_CODE_UNREACHABLE)) {
+					/*
+					   when we cannot reach the peer,
+					   we need AP's help to send the tear down frame
+					 */
+					prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+					prStaRec = prBssInfo->prStaRecOfAP;
+					if (prStaRec == NULL) {
+						Status = TDLS_STATUS_FAILURE;
+						break;
+					}
+#if 0
+					/* change status code */
+					pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] = TDLS_REASON_CODE_UNREACHABLE;
+#endif
+				}
+			}
+			prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+		}
+	} while (FALSE);
+
+	DBGLOG(TDLS, INFO, "<tdls> %s: (Status=%x) [%pM] ucStaRecIndex = %d!\n",
+			    __func__, (INT32) Status, (prMsduInfo->aucEthDestAddr),
+			    prMsduInfo->ucStaRecIndex);
+	return Status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to check if we suffer timeout for TX quota empty case.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota)
+{
+	OS_SYSTIME rCurTime;
+
+	/* sanity check */
+	if (!IS_TDLS_STA(prStaRec))
+		return;
+
+	if (FreeQuota != 0) {
+		/* reset timeout */
+		prStaRec->rTdlsTxQuotaEmptyTime = 0;
+		return;
+	}
+
+	/* work-around: check if the no free quota case is too long */
+	GET_CURRENT_SYSTIME(&rCurTime);
+
+	if (prStaRec->rTdlsTxQuotaEmptyTime == 0) {
+		prStaRec->rTdlsTxQuotaEmptyTime = rCurTime;
+	} else {
+		if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsTxQuotaEmptyTime,
+				      SEC_TO_SYSTIME(TDLS_TX_QUOTA_EMPTY_TIMEOUT))) {
+			/* tear down the link */
+			DBGLOG(TDLS, WARN,
+			       "<tdls> %s: [%pM] TX quota empty timeout!\n",
+				__func__, (prStaRec->aucMacAddr));
+
+			/* record disconnect history */
+			TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr,
+					      TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY, NULL);
+
+			/* inform tear down to supplicant only in OPEN/NONE mode */
+			/*
+			   we need to tear down the link manually; or supplicant will display
+			   "No FTIE in TDLS Teardown" and it will not tear down the link
+			 */
+			cfg80211_tdls_oper_request(prGlueInfo->prDevHandler,
+						   prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN,
+						   TDLS_REASON_CODE_UNREACHABLE, GFP_ATOMIC);
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to un-initialize variables in TDLS.
+*
+* \param[in] prAdapter			Pointer to the Adapter structure
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID TdlsexUninit(ADAPTER_T *prAdapter)
+{
+#if TDLS_CFG_CMD_TEST
+	cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend);
+#endif /* TDLS_CFG_CMD_TEST */
+}
+
+#endif /* CFG_SUPPORT_TDLS */
+
+/* End of tdls.c */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c
new file mode 100644
index 0000000000000..5450cbb651837
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c
@@ -0,0 +1,741 @@
+/*
+** Id: tdls_com.c#1
+*/
+
+/*! \file tdls_com.c
+    \brief This file includes IEEE802.11z TDLS main support.
+*/
+
+/*
+** Log: tdls_com.c
+ *
+ * 11 13 2013 vend_samp.lin
+ * NULL
+ * Initial version.
+ */
+
+/*******************************************************************************
+ *						C O M P I L E R	 F L A G S
+ ********************************************************************************
+ */
+
+/*******************************************************************************
+ *						E X T E R N A L	R E F E R E N C E S
+ ********************************************************************************
+ */
+
+#include "precomp.h"
+
+#if (CFG_SUPPORT_TDLS == 1)
+#include "tdls.h"
+
+ /*******************************************************************************
+ *						 C O N S T A N T S
+ ********************************************************************************
+ */
+
+ /*******************************************************************************
+ *						 F U N C T I O N   D E C L A R A T I O N S
+ ********************************************************************************
+ */
+
+ /*******************************************************************************
+ *						 P R I V A T E	 D A T A
+ ********************************************************************************
+ */
+
+ /*******************************************************************************
+ *						 P R I V A T E	F U N C T I O N S
+ ********************************************************************************
+ */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to append general IEs.
+*
+* \param[in] pvAdapter		Pointer to the Adapter structure.
+* \param[in] prStaRec		Pointer to the STA_RECORD_T structure.
+* \param[in] u2StatusCode	Status code.
+* \param[in] pPkt			Pointer to the frame body
+*
+* \retval append length
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt)
+{
+	GLUE_INFO_T *prGlueInfo;
+	BSS_INFO_T *prBssInfo;
+	PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
+	UINT_32 u4NonHTPhyType;
+	UINT_16 u2SupportedRateSet;
+	UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 };
+	UINT_8 ucAllSupportedRatesLen;
+	UINT_8 ucSupRatesLen;
+	UINT_8 ucExtSupRatesLen;
+	UINT_32 u4PktLen, u4IeLen;
+	BOOLEAN fg40mAllowed;
+
+	/* reference to assocBuildReAssocReqFrameCommonIEs() */
+
+	/* init */
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
+	u4PktLen = 0;
+
+	/* 3. Frame Formation - (5) Supported Rates element */
+	/* use all sup rate we can support */
+	if (prStaRec != NULL)
+		u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
+	else
+		u4NonHTPhyType = PHY_TYPE_ERP_INDEX;	/* default */
+
+	u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
+
+	if (prStaRec != NULL) {
+		u2SupportedRateSet &= prStaRec->u2OperationalRateSet;
+
+		if (u2SupportedRateSet == 0)
+			u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
+	}
+
+	rateGetDataRatesFromRateSet(u2SupportedRateSet,
+				    prBssInfo->u2BSSBasicRateSet, aucAllSupportedRates, &ucAllSupportedRatesLen);
+
+	ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ?
+			 ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen);
+
+	ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen;
+
+	if (ucSupRatesLen) {
+		SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES;
+		SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen;
+		kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen);
+
+		u4IeLen = IE_SIZE(pPkt);
+		pPkt += u4IeLen;
+		u4PktLen += u4IeLen;
+	}
+
+	/* 3. Frame Formation - (7) Extended sup rates element */
+	if (ucExtSupRatesLen) {
+
+		EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
+		EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen;
+
+		kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates,
+			   &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen);
+
+		u4IeLen = IE_SIZE(pPkt);
+		pPkt += u4IeLen;
+		u4PktLen += u4IeLen;
+	}
+
+	/* 3. Frame Formation - (8) Supported channels element */
+	/*
+	   The Supported channels element is included in Request frame and also in Response
+	   frame if Status Code 0 (successful).
+	 */
+	if (u2StatusCode == 0) {
+		SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS;
+		SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2;
+		SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1;
+		SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 11;
+
+#if CFG_SUPPORT_DFS
+		if (prAdapter->fgEnable5GBand == TRUE) {
+			/* 5G support */
+			SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165;
+			SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 4;
+		}
+#endif /* CFG_SUPPORT_DFS */
+
+		u4IeLen = IE_SIZE(pPkt);
+		pPkt += u4IeLen;
+		u4PktLen += u4IeLen;
+	}
+
+	/* 3. Frame Formation - (14) HT capabilities element */
+
+	/* no need to check AP capability */
+/* if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && */
+
+	/*
+	   after we set ucPhyTypeSet to PHY_TYPE_SET_802_11N in TdlsexRxFrameHandle(),
+	   supplicant will disable link if exists and we will clear prStaRec.
+
+	   finally, prStaRec->ucPhyTypeSet will also be 0
+
+	   so we have a fix in TdlsexPeerAdd().
+	 */
+	if (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
+		/* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */
+#if 0				/* always support */
+		if (prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode == CONFIG_BW_20M)
+			fg40mAllowed = FALSE;
+		else
+#endif
+			fg40mAllowed = TRUE;
+
+		u4IeLen = rlmFillHtCapIEByParams(fg40mAllowed,
+						 prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled,
+						 prAdapter->rWifiVar.u8SupportRxSgi20,
+						 prAdapter->rWifiVar.u8SupportRxSgi40,
+						 prAdapter->rWifiVar.u8SupportRxGf,
+						 prAdapter->rWifiVar.u8SupportRxSTBC, prBssInfo->eCurrentOPMode, pPkt);
+
+		pPkt += u4IeLen;
+		u4PktLen += u4IeLen;
+	}
+
+	/* 3. Frame Formation - (17) WMM Information element */
+
+	/* always support */
+/* if (prAdapter->rWifiVar.fgSupportQoS) */
+
+	{
+		/* force to support all UAPSD in TDLS link */
+		u4IeLen = mqmGenerateWmmInfoIEByParam(TRUE /*prAdapter->rWifiVar.fgSupportUAPSD */ ,
+						      0xf /*prPmProfSetupInfo->ucBmpDeliveryAC */ ,
+						      0xf /*prPmProfSetupInfo->ucBmpTriggerAC */ ,
+						      WMM_MAX_SP_LENGTH_ALL /*prPmProfSetupInfo->ucUapsdSp */ ,
+						      pPkt);
+
+		pPkt += u4IeLen;
+		u4PktLen += u4IeLen;
+	}
+
+	return u4PktLen;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to transmit a TDLS data frame (setup req/rsp/confirm and tear down).
+*
+* \param[in] pvAdapter		Pointer to the Adapter structure.
+* \param[in] prStaRec		Pointer to the STA_RECORD_T structure.
+* \param[in] pPeerMac		Pointer to the MAC of the TDLS peer
+* \param[in] ucActionCode	TDLS Action
+* \param[in] ucDialogToken	Dialog token
+* \param[in] u2StatusCode	Status code
+* \param[in] pAppendIe		Others IEs (here are security IEs from supplicant)
+* \param[in] AppendIeLen	IE length of others IEs
+*
+* \retval TDLS_STATUS_xx
+*/
+/*----------------------------------------------------------------------------*/
+TDLS_STATUS
+TdlsDataFrameSend(ADAPTER_T *prAdapter,
+		  STA_RECORD_T *prStaRec,
+		  UINT_8 *pPeerMac,
+		  UINT_8 ucActionCode,
+		  UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
+{
+#define LR_TDLS_FME_FIELD_FILL(__Len) \
+do { \
+	pPkt += __Len; \
+	u4PktLen += __Len; \
+} while (0)
+
+	GLUE_INFO_T *prGlueInfo;
+	BSS_INFO_T *prBssInfo;
+	PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
+	struct sk_buff *prMsduInfo;
+	MSDU_INFO_T *prMsduInfoMgmt;
+	UINT8 *pPkt, *pucInitiator, *pucResponder;
+	UINT32 u4PktLen, u4IeLen;
+	UINT16 u2CapInfo;
+/* UINT8 *pPktTemp; */
+
+	prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
+
+	DBGLOG(TDLS, INFO, "<tdls_fme> %s: 2040=%d\n", __func__, prGlueInfo->rTdlsLink.fgIs2040Sup);
+
+	/* sanity check */
+	if (prStaRec != NULL) {
+		if (prStaRec->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) {
+			DBGLOG(TDLS, ERROR,
+			       "<tdls_cmd> %s: net index %d fail\n", __func__, prStaRec->ucNetTypeIndex);
+			return TDLS_STATUS_FAILURE;
+		}
+
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+	} else {
+		/* prStaRec maybe NULL in setup request */
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	}
+
+	/* allocate/init packet */
+	prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
+	u4PktLen = 0;
+	prMsduInfo = NULL;
+	prMsduInfoMgmt = NULL;
+
+	/* make up frame content */
+	if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) {
+		/*
+		   The STAUT will not respond to a TDLS Discovery Request Frame with different BSSID.
+		   Supplicant will check this in wpa_tdls_process_discovery_request().
+		 */
+
+		/* TODO: reduce 1600 to correct size */
+		prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
+		if (prMsduInfo == NULL) {
+			DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
+			return TDLS_STATUS_RESOURCES;
+		}
+
+		prMsduInfo->dev = prGlueInfo->prDevHandler;
+		if (prMsduInfo->dev == NULL) {
+			DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
+			kalPacketFree(prGlueInfo, prMsduInfo);
+			return TDLS_STATUS_FAILURE;
+		}
+
+		/* 1. 802.3 header */
+/* pPktTemp = pPkt; */
+		kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
+		LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+		kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
+		LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
+		*(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
+		LR_TDLS_FME_FIELD_FILL(2);
+
+		/* 2. payload type */
+		*pPkt = TDLS_FRM_PAYLOAD_TYPE;
+		LR_TDLS_FME_FIELD_FILL(1);
+
+		/* 3. Frame Formation - (1) Category */
+		*pPkt = TDLS_FRM_CATEGORY;
+		LR_TDLS_FME_FIELD_FILL(1);
+	} else {
+		/* discovery response */
+		WLAN_MAC_HEADER_T *prHdr;
+
+		prMsduInfoMgmt = (MSDU_INFO_T *)
+		    cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
+		if (prMsduInfoMgmt == NULL) {
+			DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate mgmt pkt fail\n", __func__);
+			return TDLS_STATUS_RESOURCES;
+		}
+
+		pPkt = (UINT8 *) prMsduInfoMgmt->prPacket;
+		prHdr = (WLAN_MAC_HEADER_T *) pPkt;
+
+		/* 1. 802.11 header */
+		prHdr->u2FrameCtrl = MAC_FRAME_ACTION;
+		prHdr->u2DurationID = 0;
+		kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
+		kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
+		kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN);
+		prHdr->u2SeqCtrl = 0;
+		LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T));
+
+		/* Frame Formation - (1) Category */
+		*pPkt = CATEGORY_PUBLIC_ACTION;
+		LR_TDLS_FME_FIELD_FILL(1);
+	}
+
+	/* 3. Frame Formation - (2) Action */
+	*pPkt = ucActionCode;
+	LR_TDLS_FME_FIELD_FILL(1);
+
+	/* 3. Frame Formation - Status Code */
+	switch (ucActionCode) {
+	case TDLS_FRM_ACTION_SETUP_RSP:
+	case TDLS_FRM_ACTION_CONFIRM:
+	case TDLS_FRM_ACTION_TEARDOWN:
+		WLAN_SET_FIELD_16(pPkt, u2StatusCode);
+		LR_TDLS_FME_FIELD_FILL(2);
+		break;
+	}
+
+	/* 3. Frame Formation - (3) Dialog token */
+	if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
+		*pPkt = ucDialogToken;
+		LR_TDLS_FME_FIELD_FILL(1);
+	}
+
+	/* Fill elements */
+	if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
+		/*
+		   Capability
+
+		   Support Rates
+		   Extended Support Rates
+		   Supported Channels
+		   HT Capabilities
+		   WMM Information Element
+
+		   Extended Capabilities
+		   Link Identifier
+
+		   RSNIE
+		   FTIE
+		   Timeout Interval
+		 */
+		if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) {
+			/* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */
+			u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
+			WLAN_SET_FIELD_16(pPkt, u2CapInfo);
+			LR_TDLS_FME_FIELD_FILL(2);
+
+			/* 4. Append general IEs */
+			/*
+			   TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode
+			   must be CONFIG_BW_20_40M.
+
+			   TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if
+			   Tdls 20/40 is enabled.
+			 */
+			u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, u2StatusCode, pPkt);
+			LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+			/* 5. Frame Formation - Extended capabilities element */
+			EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
+			EXT_CAP_IE(pPkt)->ucLength = 5;
+
+			EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00;	/* bit0 ~ bit7 */
+			EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00;	/* bit8 ~ bit15 */
+			EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00;	/* bit16 ~ bit23 */
+			EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00;	/* bit24 ~ bit31 */
+			EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00;	/* bit32 ~ bit39 */
+
+			/* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */
+			EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
+			/* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */
+			EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
+			/* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */
+			EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
+
+			u4IeLen = IE_SIZE(pPkt);
+			LR_TDLS_FME_FIELD_FILL(u4IeLen);
+		} else {
+			/* 5. Frame Formation - WMM Parameter element */
+			if (prAdapter->rWifiVar.fgSupportQoS) {
+				u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter,
+								   prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE);
+
+				LR_TDLS_FME_FIELD_FILL(u4IeLen);
+			}
+		}
+	}
+
+	/* 6. Frame Formation - 20/40 BSS Coexistence */
+	/*
+	   Follow WiFi test plan, add 20/40 element to request/response/confirm.
+	 */
+/* if (prGlueInfo->rTdlsLink.fgIs2040Sup == TRUE) */ /* force to enable */
+	if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
+		/*
+		   bit0 = 1: The Information Request field is used to indicate that a
+		   transmitting STA is requesting the recipient to transmit a 20/40 BSS
+		   Coexistence Management frame with the transmitting STA as the
+		   recipient.
+
+		   bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
+		   that receives this information or reports of this information from
+		   operating a 20/40 MHz BSS.
+
+		   bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
+		   a receiving AP from operating its BSS as a 20/40 MHz BSS.
+		 */
+		BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
+		BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
+		BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
+		LR_TDLS_FME_FIELD_FILL(3);
+	}
+
+	/* 6. Frame Formation - HT Operation element */
+/* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */
+/* LR_TDLS_FME_FIELD_FILL(u4IeLen); */
+
+	/* 7. Frame Formation - Link identifier element */
+	/* Note1: Link ID sequence must be correct; Or the calculated MIC will be error */
+	/*
+	   Note2: When we receive a setup request with link ID, Marvell will send setup response
+	   to the peer in link ID, not the SA in the WLAN header.
+	 */
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
+	TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER;
+
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
+
+	switch (ucActionCode) {
+	case TDLS_FRM_ACTION_SETUP_REQ:
+	case TDLS_FRM_ACTION_CONFIRM:
+	default:
+		/* we are initiator */
+		pucInitiator = prBssInfo->aucOwnMacAddr;
+		pucResponder = pPeerMac;
+
+		if (prStaRec != NULL)
+			prStaRec->flgTdlsIsInitiator = TRUE;
+		break;
+
+	case TDLS_FRM_ACTION_SETUP_RSP:
+	case TDLS_FRM_ACTION_DISCOVERY_RESPONSE:
+		/* peer is initiator */
+		pucInitiator = pPeerMac;
+		pucResponder = prBssInfo->aucOwnMacAddr;
+
+		if (prStaRec != NULL)
+			prStaRec->flgTdlsIsInitiator = FALSE;
+		break;
+
+	case TDLS_FRM_ACTION_TEARDOWN:
+		if (prStaRec != NULL) {
+			if (prStaRec->flgTdlsIsInitiator == TRUE) {
+				/* we are initiator */
+				pucInitiator = prBssInfo->aucOwnMacAddr;
+				pucResponder = pPeerMac;
+			} else {
+				/* peer is initiator */
+				pucInitiator = pPeerMac;
+				pucResponder = prBssInfo->aucOwnMacAddr;
+			}
+		} else {
+			/* peer is initiator */
+			pucInitiator = pPeerMac;
+			pucResponder = prBssInfo->aucOwnMacAddr;
+		}
+		break;
+	}
+
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6);
+	kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6);
+
+	u4IeLen = IE_SIZE(pPkt);
+	LR_TDLS_FME_FIELD_FILL(u4IeLen);
+
+	/* 8. Append security IEs */
+	/*
+	   11.21.5 TDLS Direct Link Teardown
+	   If the STA has security enabled on the link 37 with the AP, then the FTIE shall be
+	   included in the TDLS Teardown frame.
+
+	   For ralink station, it can accept our tear down without FTIE but marvell station.
+	 */
+/* if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) */
+	if (pAppendIe != NULL) {
+		if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) ||
+		    ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) &&
+		     (prStaRec != NULL) && (prStaRec->fgTdlsInSecurityMode == TRUE))) {
+			kalMemCopy(pPkt, pAppendIe, AppendIeLen);
+			LR_TDLS_FME_FIELD_FILL(AppendIeLen);
+		}
+	}
+
+	/* 7. Append Supported Operating Classes IE */
+	if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
+		/* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
+		u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
+		LR_TDLS_FME_FIELD_FILL(u4IeLen);
+	}
+
+	/* 11. send the data or management frame */
+	if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) {
+#if 0
+		/*
+		   Note1: remember to modify our MAC & AP MAC & peer MAC in LINK ID
+		   Note2: dialog token in rsp & confirm must be same as sender.
+		 */
+
+#if 1
+		/* example for Ralink's and Broadcom's TDLS setup request frame in open/none */
+		if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) {
+#if 0
+			/* mediatek */
+			char buffer[] = { 0x31, 0x04,
+				0x01, 0x08, 0x02, 0x04, 0x0b, 0x16, 0xc, 0x12, 0x18, 0x24,
+				0x32, 0x04, 0x30, 0x48, 0x60, 0x6c,
+				0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01,
+				0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00,
+				0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f,
+				0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20,
+				0x48, 0x01, 0x01,
+				0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33,
+				0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
+				0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
+				0x1b, 0x1c, 0x1e, 0x20, 0x21,
+				0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e
+			};
+#endif
+
+#if 1
+			/* ralink *//* from capability */
+			char buffer[] = { 0x21, 0x04,
+				0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c,
+				0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00,
+				0x32, 0x04, 0x0c, 0x18, 0x30, 0x60,
+				0x24, 0x06, 0x01, 0x0b, 0x24, 0x08, 0x95, 0x04,
+				0x7f, 0x05, 0x01, 0x00, 0x00, 0x50, 0x20,
+				0x3b, 0x10, 0x20, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19,
+				0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21,
+				0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+				0x00, 0x00, 0x00, 0x00,
+				0x48, 0x01, 0x01,
+				0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
+				0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
+				0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f
+			};
+#endif
+#if 0
+			/* 6630 */
+			char buffer[] = { 0x01, 0x01,
+				0x01, 0x04, 0x02, 0x04, 0x0b, 0x16,
+				0x24, 0x02, 0x01, 0x0d,
+				0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0xff,
+				0x2d, 0x1a, 0x61, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00,
+				0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00,
+				0x48, 0x01, 0x01,
+				0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
+				0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21,
+				0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e,
+				0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
+				0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
+				0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x01, 0x00, 0x00,
+				0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60,
+				0x00, 0x00, 0x00,
+				0xbf, 0x0c, 0x30, 0x01, 0x80, 0x03, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff,
+				0x00, 0x00
+			};
+#endif
+
+			pPktTemp += 18;
+			memcpy(pPktTemp, buffer, sizeof(buffer));
+			u4PktLen = 18 + sizeof(buffer);
+		}
+#endif
+
+#if 1
+		if (ucActionCode == TDLS_FRM_ACTION_CONFIRM) {
+			/* Note: dialog token must be same as request */
+#if 1
+			/* ralink */
+			char buffer[] = { 0x00,
+				0x01, 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00,
+				0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
+				0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
+				0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x00, 0x03,
+				0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00,
+				0x62, 0x32, 0x2f, 0x00
+			};
+#endif
+
+#if 0
+			/* 6630 */
+			char buffer[] = { 0x00,
+				0x01,
+				0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00,
+				0x48, 0x01, 0x01,
+				0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
+				0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21,
+				0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e,
+				0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
+				0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
+				0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00,
+				0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x3f, 0x00, 0x00,
+				0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60,
+				0x00, 0x00, 0x00
+			};
+#endif
+
+#if 0
+			/* A/D die */
+			char buffer[] = { 0x00,
+				0x01,
+				0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x6b, 0x00, 0x00,
+				0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60,
+				0x00, 0x00, 0x00 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33,
+				0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
+				0x38, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b,
+				0x1c, 0x1e, 0x20, 0x21,
+				0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e
+			};
+#endif
+
+			pPktTemp += 18;
+			memcpy(pPktTemp, buffer, sizeof(buffer));
+			u4PktLen = 18 + sizeof(buffer);
+		}
+#endif
+
+#else
+
+#if 0
+		/* for test in open/none */
+		if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) {
+			char buffer[] = { 0x01, 0x04,
+				0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c,
+				0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00,
+				0x32, 0x04, 0x30, 0x48, 0x60, 0x6c,
+				0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01,
+				0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00,
+				0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f,
+				0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20,
+				0x48, 0x01, 0x01,
+				0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
+				0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
+				0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
+				0x1b, 0x1c, 0x1e, 0x20, 0x21
+			};
+
+			pPktTemp += 18;
+			memcpy(pPktTemp, buffer, sizeof(buffer));
+			u4PktLen = 18 + sizeof(buffer);
+		}
+#endif
+#endif /* 0 */
+
+		/* 9. Update packet length */
+		prMsduInfo->len = u4PktLen;
+		dumpMemory8(prMsduInfo->data, u4PktLen);
+
+		wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
+	} else {
+		/*
+		   A TDLS capable STA that receives a TDLS Discovery Request frame is required to
+		   send the response "to the requesting STA, via the direct path."
+		   However, prior to establishment of the direct link, the responding STA may not
+		   know the rate capabilities of the requesting STA. In this case, the responding
+		   STA shall send the TDLS Discovery Response frame using a rate from the
+		   BSSBasicRateSet of the BSS to which the STA is currently associated.
+		 */
+		prMsduInfoMgmt->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
+		prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
+		prMsduInfoMgmt->ucNetworkType = prBssInfo->ucNetTypeIndex;
+		prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+		prMsduInfoMgmt->fgIs802_1x = FALSE;
+		prMsduInfoMgmt->fgIs802_11 = TRUE;
+		prMsduInfoMgmt->u2FrameLength = u4PktLen;
+		prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+		prMsduInfoMgmt->pfTxDoneHandler = NULL;
+		prMsduInfoMgmt->fgIsBasicRate = TRUE;	/* use basic rate */
+
+		/* Send them to HW queue */
+		nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt);
+	}
+
+	return TDLS_STATUS_SUCCESS;
+}
+
+#endif /* CFG_SUPPORT_TDLS */
+
+ /* End of tdls_com.c */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c
new file mode 100644
index 0000000000000..af66ef95d17cf
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c
@@ -0,0 +1,491 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1
+*/
+
+/*! \file   "wapi.c"
+    \brief  This file including the WAPI related function.
+
+    This file provided the macros and functions library support the wapi ie parsing,
+    cipher and AKM check to help the AP seleced deciding.
+*/
+
+/*
+** Log: wapi.c
+**
+** 10 24 2012 wh.su
+** [ALPS00376392] [klocwork 9.1]  in  wapi.c, line 344
+** Use MAX_NUM_SUPPORTED_WAPI_AKM_SUITESfor avoid Klocwork warning.
+**
+** 10 24 2012 wh.su
+** [ALPS00376391] [klocwork 9.1]  in  wapi.c, line 311
+** Use the MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES for avoid Klccwork waring.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the debug module level.
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
+ * fixed the network type
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 07 20 2010 wh.su
+ *
+ * .
+ *
+ * 04 06 2010 wh.su
+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
+ * fixed the firmware return the broadcast frame at wrong tc.
+ *
+ * 03 03 2010 wh.su
+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
+ * move the AIS specific variable for security to AIS specific structure.
+ *
+ * 12 18 2009 cm.chang
+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time
+ * .
+ *
+ * Dec 8 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the function to check and update the default wapi tx
+ *
+ * Dec 7 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ * adding the generate wapi ie function, and replace the tabe by space
+ *
+ * Nov 23 2009 mtk01088
+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+#if CFG_SUPPORT_WAPI
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to generate WPA IE for
+*        associate request frame.
+*
+* \param[in]  prCurrentBss     The Selected BSS description
+*
+* \retval The append WPA IE length
+*
+* \note
+*      Called by: AIS module, Associate request
+*/
+/*----------------------------------------------------------------------------*/
+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	PUINT_8 pucBuffer;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
+		return;
+
+	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + prMsduInfo->u2FrameLength);
+
+	/* ASSOC INFO IE ID: 68 :0x44 */
+	if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) {
+		kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs,
+			   prAdapter->prGlueInfo->u2WapiAssocInfoIESz);
+		prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz;
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to parse WAPI IE.
+*
+* \param[in]  prInfoElem Pointer to the RSN IE
+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the
+**                  WAPI information from the given WAPI IE
+*
+* \retval TRUE - Succeeded
+* \retval FALSE - Failed
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo)
+{
+	UINT_32 i;
+	INT_32 u4RemainWapiIeLen;
+	UINT_16 u2Version;
+	UINT_16 u2Cap = 0;
+	UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI;
+	UINT_16 u2PairSuiteCount = 0;
+	UINT_16 u2AuthSuiteCount = 0;
+	PUCHAR pucPairSuite = NULL;
+	PUCHAR pucAuthSuite = NULL;
+	PUCHAR cp;
+
+	DEBUGFUNC("wapiParseWapiIE");
+
+	ASSERT(prInfoElem);
+	ASSERT(prWapiInfo);
+
+	/* Verify the length of the WAPI IE. */
+	if (prInfoElem->ucLength < 6) {
+		DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", prInfoElem->ucLength);
+		return FALSE;
+	}
+
+	/* Check WAPI version: currently, we only support version 1. */
+	WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
+	if (u2Version != 1) {
+		DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", u2Version);
+		return FALSE;
+	}
+
+	cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount;
+	u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2;
+
+	do {
+		if (u4RemainWapiIeLen == 0)
+			break;
+
+		/*
+		   AuthCount    : 2
+		   AuthSuite    : 4 * authSuiteCount
+		   PairwiseCount: 2
+		   PairwiseSuite: 4 * pairSuiteCount
+		   GroupSuite   : 4
+		   Cap          : 2 */
+
+		/* Parse the Authentication and Key Management Cipher Suite Count
+		   field. */
+		if (u4RemainWapiIeLen < 2) {
+			DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
+		cp += 2;
+		u4RemainWapiIeLen -= 2;
+
+		/* Parse the Authentication and Key Management Cipher Suite List
+		   field. */
+		i = (UINT_32) u2AuthSuiteCount * 4;
+		if (u4RemainWapiIeLen < (INT_32) i) {
+			DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		pucAuthSuite = cp;
+
+		cp += i;
+		u4RemainWapiIeLen -= (INT_32) i;
+
+		if (u4RemainWapiIeLen == 0)
+			break;
+
+		/* Parse the Pairwise Key Cipher Suite Count field. */
+		if (u4RemainWapiIeLen < 2) {
+			DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
+		cp += 2;
+		u4RemainWapiIeLen -= 2;
+
+		/* Parse the Pairwise Key Cipher Suite List field. */
+		i = (UINT_32) u2PairSuiteCount * 4;
+		if (u4RemainWapiIeLen < (INT_32) i) {
+			DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		pucPairSuite = cp;
+
+		cp += i;
+		u4RemainWapiIeLen -= (INT_32) i;
+
+		/* Parse the Group Key Cipher Suite field. */
+		if (u4RemainWapiIeLen < 4) {
+			DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_32(cp, &u4GroupSuite);
+		cp += 4;
+		u4RemainWapiIeLen -= 4;
+
+		/* Parse the WAPI u2Capabilities field. */
+		if (u4RemainWapiIeLen < 2) {
+			DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n",
+					    prInfoElem->ucLength);
+			return FALSE;
+		}
+
+		WLAN_GET_FIELD_16(cp, &u2Cap);
+		u4RemainWapiIeLen -= 2;
+
+		/* Todo:: BKID support */
+	} while (FALSE);
+
+	/* Save the WAPI information for the BSS. */
+
+	prWapiInfo->ucElemId = ELEM_ID_WAPI;
+
+	prWapiInfo->u2Version = u2Version;
+
+	prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite;
+
+	DBGLOG(SEC, LOUD, "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
+			   u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
+			   (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
+			   (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF));
+
+	if (pucPairSuite) {
+		/* The information about the pairwise key cipher suites is present. */
+		if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES)
+			u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES;
+
+		prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
+
+		for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
+			WLAN_GET_FIELD_32(pucPairSuite, &prWapiInfo->au4PairwiseKeyCipherSuite[i]);
+			pucPairSuite += 4;
+
+			DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
+					   (UINT_8) i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
+					   (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
+					   (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
+					   (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF));
+		}
+	} else {
+		/* The information about the pairwise key cipher suites is not present.
+		   Use the default chipher suite for WAPI: WPI. */
+		prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1;
+		prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI;
+
+		DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
+				   (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
+				   (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
+				   (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
+				   (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF));
+	}
+
+	if (pucAuthSuite) {
+		/* The information about the authentication and key management suites
+		   is present. */
+		if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES)
+			u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES;
+
+		prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
+
+		for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
+			WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]);
+			pucAuthSuite += 4;
+
+			DBGLOG(SEC, LOUD, "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
+					   (UINT_8) i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
+					   (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
+					   (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
+					   (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF));
+		}
+	} else {
+		/* The information about the authentication and key management suites
+		   is not present. Use the default AKM suite for WAPI. */
+		prWapiInfo->u4AuthKeyMgtSuiteCount = 1;
+		prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X;
+
+		DBGLOG(SEC, LOUD, "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n",
+				   (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
+				   (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
+				   (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
+				   (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF));
+	}
+
+	prWapiInfo->u2WapiCap = u2Cap;
+	DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap);
+
+	return TRUE;
+}				/* wapiParseWapiIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to perform WAPI policy selection for a given BSS.
+*
+* \param[in]  prAdapter Pointer to the adapter object data area.
+* \param[in]  prBss Pointer to the BSS description
+*
+* \retval TRUE - The WAPI policy selection for the given BSS is
+*                successful. The selected pairwise and group cipher suites
+*                are returned in the BSS description.
+* \retval FALSE - The WAPI policy selection for the given BSS is failed.
+*                 The driver shall not attempt to join the given BSS.
+*
+* \note The Encrypt status matched score will save to bss for final ap select.
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss)
+{
+	UINT_32 i;
+	UINT_32 u4PairwiseCipher = 0;
+	UINT_32 u4GroupCipher = 0;
+	UINT_32 u4AkmSuite = 0;
+	P_WAPI_INFO_T prBssWapiInfo;
+	P_WLAN_INFO_T prWlanInfo;
+
+	DEBUGFUNC("wapiPerformPolicySelection");
+
+	ASSERT(prBss);
+
+	/* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */
+	prWlanInfo = &prAdapter->rWlanInfo;
+
+	if (prBss->fgIEWAPI) {
+		prBssWapiInfo = &prBss->rIEWAPI;
+	} else {
+		if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) {
+			DBGLOG(SEC, TRACE, "-- No Protected BSS\n");
+			return TRUE;
+		}
+		DBGLOG(SEC, TRACE, "WAPI Information Element does not exist.\n");
+		return FALSE;
+	}
+
+	/* Select pairwise/group ciphers */
+	for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) {
+		if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] ==
+		    prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) {
+			u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i];
+		}
+	}
+	if (prBssWapiInfo->u4GroupKeyCipherSuite == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher)
+		u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite;
+
+	/* Exception handler */
+	/* If we cannot find proper pairwise and group cipher suites to join the
+	   BSS, do not check the supported AKM suites. */
+	if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
+		DBGLOG(SEC, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n",
+				    u4PairwiseCipher, u4GroupCipher);
+		return FALSE;
+	}
+
+	/* Select AKM */
+	/* If the driver cannot support any authentication suites advertised in
+	   the given BSS, we fail to perform RSNA policy selection. */
+	/* Attempt to find any overlapping supported AKM suite. */
+	for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) {
+		if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) {
+			u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i];
+			break;
+		}
+	}
+
+	if (u4AkmSuite == 0) {
+		DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n");
+		return FALSE;
+	}
+
+	DBGLOG(SEC, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
+			    (UINT_8) (u4PairwiseCipher & 0x000000FF),
+			    (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
+			    (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
+			    (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
+			    (UINT_8) (u4GroupCipher & 0x000000FF),
+			    (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
+			    (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
+			    (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF));
+
+	DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n",
+			    (UINT_8) (u4AkmSuite & 0x000000FF),
+			    (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
+			    (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF));
+
+	return TRUE;
+}				/* wapiPerformPolicySelection */
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 .
+*
+* \param[in]  prStaRec Pointer to the Sta record
+* \param[out] ucWlanIdx The Rx status->wlanidx field
+*
+* \retval TRUE - Succeeded
+* \retval FALSE - Failed
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wapiUpdateTxKeyIdx(IN P_STA_RECORD_T prStaRec, IN UINT_8 ucWlanIdx)
+{
+	UINT_8 ucKeyId;
+
+	if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) {
+
+		ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4);
+
+		if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) {
+			DBGLOG(RSN, STATE,
+			       "Change wapi key index from %d->%d\n",
+				g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId);
+			g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId;
+
+			prStaRec->ucWTEntry =
+			    (ucKeyId ==
+			     WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1;
+		}
+	}
+}
+#endif
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c
new file mode 100644
index 0000000000000..f54d229411485
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c
@@ -0,0 +1,301 @@
+/*
+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1
+*/
+
+/*! \file   "wnm.c"
+    \brief  This file includes the 802.11v default vale and functions.
+*/
+
+/*
+** Log: wnm.c
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ *
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#if CFG_SUPPORT_802_11V
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define WNM_MAX_TOD_ERROR  0
+#define WNM_MAX_TOA_ERROR  0
+#define MICRO_TO_10NANO(x) ((x)*100)
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+static UINT_8 ucTimingMeasToken;
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to process the 802.11v wnm category action frame.
+*
+*
+* \note
+*      Called by: Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_WLAN_ACTION_FRAME prRxFrame;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader;
+
+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
+	if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) {
+		wnmTimingMeasRequest(prAdapter, prSwRfb);
+		return;
+	}
+#endif
+
+	DBGLOG(WNM, TRACE, "Unsupport WNM action frame: %d\n", prRxFrame->ucAction);
+}
+
+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to report timing measurement data.
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA)
+{
+	P_STA_RECORD_T prStaRec;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex);
+
+	if ((!prStaRec) || (!prStaRec->fgIsInUse))
+		return;
+
+	DBGLOG(WNM, TRACE, "wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA);
+
+	if (!prStaRec->rWNMTimingMsmt.ucTrigger)
+		return;
+
+	prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD);
+	prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will handle TxDone(TimingMeasurement) Event.
+*
+* @param[in] prAdapter      Pointer to the Adapter structure.
+* @param[in] prMsduInfo     Pointer to the MSDU_INFO_T.
+* @param[in] rTxDoneStatus  Return TX status of the Timing Measurement frame.
+*
+* @retval WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter,
+			     IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
+{
+	P_STA_RECORD_T prStaRec;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	DBGLOG(WNM, LOUD, "EVENT-TX DONE: Current Time = %u\n", kalGetTimeTick());
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if ((!prStaRec) || (!prStaRec->fgIsInUse))
+		return WLAN_STATUS_SUCCESS;	/* For the case of replying ERROR STATUS CODE */
+
+	DBGLOG(WNM, TRACE, "wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x",
+			    prStaRec->rWNMTimingMsmt.ucDialogToken,
+			    prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken,
+			    prStaRec->rWNMTimingMsmt.u4ToD, prStaRec->rWNMTimingMsmt.u4ToA);
+
+	prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
+	prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
+
+	wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of wnmRunEventTimgingMeasTxDone() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will compose the Timing Measurement frame.
+*
+* @param[in] prAdapter              Pointer to the Adapter structure.
+* @param[in] prStaRec               Pointer to the STA_RECORD_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
+{
+	P_MSDU_INFO_T prMsduInfo;
+	P_BSS_INFO_T prBssInfo;
+	P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame;
+	UINT_16 u2PayloadLen;
+
+	prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
+	ASSERT(prBssInfo);
+
+	prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
+
+	if (!prMsduInfo)
+		return;
+
+	prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME)
+	    ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+	prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
+
+	COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr);
+	COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
+	COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
+
+	prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION;
+	prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT;
+
+	/* 3 Compose the frame body's frame. */
+	prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
+	prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken;
+	prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD;
+	prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA;
+	prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR;
+	prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR;
+
+	u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN;
+
+	/* 4 Update information of MSDU_INFO_T */
+	prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;	/* Management frame */
+	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
+	prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
+	prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
+	prMsduInfo->fgIs802_1x = FALSE;
+	prMsduInfo->fgIs802_11 = TRUE;
+	prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
+	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
+	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
+	prMsduInfo->fgIsBasicRate = FALSE;
+
+	DBGLOG(WNM, TRACE, "wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n",
+			    prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken,
+			    prTxFrame->u4ToD, prTxFrame->u4ToA);
+
+	/* 4 Enqueue the frame to send this action frame. */
+	nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+	return;
+
+}				/* end of wnmComposeTimingMeasFrame() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to process the 802.11v timing measurement request.
+*
+*
+* \note
+*      Handle Rx mgmt request
+*/
+/*----------------------------------------------------------------------------*/
+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL;
+	P_STA_RECORD_T prStaRec;
+
+	prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME) prSwRfb->pvHeader;
+	if (!prRxFrame)
+		return;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	if ((!prStaRec) || (!prStaRec->fgIsInUse))
+		return;
+
+	DBGLOG(WNM, TRACE, "IEEE 802.11: Received Timing Measuremen Request from %pM\n"
+			    prStaRec->aucMacAdd);
+
+	/* reset timing msmt */
+	prStaRec->rWNMTimingMsmt.fgInitiator = TRUE;
+	prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger;
+	if (!prRxFrame->ucTrigger)
+		return;
+
+	prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
+	prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0;
+
+	wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone);
+}
+
+#if WNM_UNIT_TEST
+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex)
+{
+	P_STA_RECORD_T prStaRec;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex);
+	if ((!prStaRec) || (!prStaRec->fgIsInUse))
+		return;
+
+	DBGLOG(WNM, INFO, "IEEE 802.11v: Test Timing Measuremen Request from %pM\n",
+			prStaRec->aucMacAddr);
+
+	prStaRec->rWNMTimingMsmt.fgInitiator = TRUE;
+	prStaRec->rWNMTimingMsmt.ucTrigger = 1;
+
+	prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
+	prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0;
+
+	wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone);
+}
+#endif
+
+#endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */
+
+#endif /* CFG_SUPPORT_802_11V */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c
new file mode 100644
index 0000000000000..6f1bb6fd771ec
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c
@@ -0,0 +1,254 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/cmd_buf.c#1
+*/
+
+/*! \file   "cmd_buf.c"
+    \brief  This file contain the management function of internal Command Buffer
+	    for CMD_INFO_T.
+
+	We'll convert the OID into Command Packet and then send to FW. Thus we need
+    to copy the OID information to Command Buffer for following reasons.
+    1. The data structure of OID information may not equal to the data structure of
+       Command, we cannot use the OID buffer directly.
+    2. If the Command was not generated by driver we also need a place to store the
+       information.
+    3. Because the CMD is NOT FIFO when doing memory allocation (CMD will be generated
+       from OID or interrupt handler), thus we'll use the Block style of Memory Allocation
+       here.
+*/
+
+/*
+** Log: cmd_buf.c
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 02 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. clear prPendingCmdInfo properly
+ *  * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-13 21:59:08 GMT mtk01084
+**  remove un-neceasary spaces
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-05-20 12:24:26 GMT mtk01461
+**  Increase CMD Buffer - HIF_RX_HW_APPENDED_LEN when doing CMD_INFO_T allocation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 09:41:08 GMT mtk01461
+**  Add init of Driver Domain MCR flag and fix lint MTK WARN
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-17 19:51:45 GMT mtk01461
+**  allocation function of CMD_INFO_T
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+static BOOLEAN fgCmdDumpIsDone = FALSE;
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to initial the MGMT memory pool for CMD Packet.
+*
+* @param prAdapter  Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter)
+{
+	P_CMD_INFO_T prCmdInfo;
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	QUEUE_INITIALIZE(&prAdapter->rFreeCmdList);
+
+	for (i = 0; i < CFG_TX_MAX_CMD_PKT_NUM; i++) {
+		prCmdInfo = &prAdapter->arHifCmdDesc[i];
+		QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry);
+	}
+	fgCmdDumpIsDone = FALSE;
+}				/* end of cmdBufInitialize() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief dump CMD queue and print to trace, for debug use only
+* @param[in] prQueue	Pointer to the command Queue to be dumped
+* @param[in] quename	Name of the queue
+*/
+/*----------------------------------------------------------------------------*/
+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName)
+{
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_HEAD(prQueue);
+
+	DBGLOG(NIC, INFO, "Dump CMD info for %s, Elem number:%u\n", queName, prQueue->u4NumElem);
+	while (prCmdInfo) {
+		P_CMD_INFO_T prCmdInfo1, prCmdInfo2, prCmdInfo3;
+
+		prCmdInfo1 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo);
+		if (!prCmdInfo1) {
+			DBGLOG(NIC, INFO, "CID:%d SEQ:%d\n", prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum);
+			break;
+		}
+		prCmdInfo2 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo1);
+		if (!prCmdInfo2) {
+			DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID,
+				prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum);
+			break;
+		}
+		prCmdInfo3 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo2);
+		if (!prCmdInfo3) {
+			DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID,
+				prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum,
+				prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum);
+			break;
+		}
+		DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n",
+				prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID,
+				prCmdInfo1->ucCmdSeqNum, prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum,
+				prCmdInfo3->ucCID, prCmdInfo3->ucCmdSeqNum);
+		prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo3);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Allocate CMD_INFO_T from a free list and MGMT memory pool.
+*
+* @param[in] prAdapter      Pointer to the Adapter structure.
+* @param[in] u4Length       Length of the frame buffer to allocate.
+*
+* @retval NULL      Pointer to the valid CMD Packet handler
+* @retval !NULL     Fail to allocat CMD Packet
+*/
+/*----------------------------------------------------------------------------*/
+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length)
+{
+	P_CMD_INFO_T prCmdInfo;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("cmdBufAllocateCmdInfo");
+
+	ASSERT(prAdapter);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+	QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+
+	if (prCmdInfo) {
+		/* Setup initial value in CMD_INFO_T */
+		/* Start address of allocated memory */
+		prCmdInfo->pucInfoBuffer = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length);
+
+		if (prCmdInfo->pucInfoBuffer == NULL) {
+			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+			QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry);
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+
+			prCmdInfo = NULL;
+
+			DBGLOG(NIC, ERROR, "Allocate prCmdInfo->pucInfoBuffer fail!\n");
+		} else {
+			prCmdInfo->u2InfoBufLen = 0;
+			prCmdInfo->fgIsOid = FALSE;
+			prCmdInfo->fgDriverDomainMCR = FALSE;
+		}
+		fgCmdDumpIsDone = FALSE;
+	} else if (!fgCmdDumpIsDone) {
+		P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+		P_QUE_T prCmdQue = &prGlueInfo->rCmdQueue;
+		P_QUE_T prPendingCmdQue = &prAdapter->rPendingCmdQueue;
+		P_TX_TCQ_STATUS_T prTc = &prAdapter->rTxCtrl.rTc;
+
+		fgCmdDumpIsDone = TRUE;
+		cmdBufDumpCmdQueue(prCmdQue, "waiting Tx CMD queue");
+		cmdBufDumpCmdQueue(prPendingCmdQue, "waiting response CMD queue");
+		DBGLOG(NIC, INFO, "Tc4 number:%d\n", prTc->aucFreeBufferCount[TC4_INDEX]);
+		if (prTc->aucFreeBufferCount[TC4_INDEX] != 0)
+			glDoChipReset();
+	}
+
+	return prCmdInfo;
+
+}				/* end of cmdBufAllocateCmdInfo() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to free the CMD Packet to the MGMT memory pool.
+*
+* @param prAdapter  Pointer to the Adapter structure.
+* @param prCmdInfo  CMD Packet handler
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("cmdBufFreeCmdInfo");
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	if (prCmdInfo) {
+		if (prCmdInfo->pucInfoBuffer) {
+			cnmMemFree(prAdapter, prCmdInfo->pucInfoBuffer);
+			prCmdInfo->pucInfoBuffer = NULL;
+		}
+
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+		QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+	}
+
+	return;
+
+}				/* end of cmdBufFreeCmdPacket() */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c
new file mode 100644
index 0000000000000..dfaaedd118bfb
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c
@@ -0,0 +1,4062 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#2
+*/
+
+/*! \file   nic.c
+    \brief  Functions that provide operation in NIC's (Network Interface Card) point of view.
+
+    This file includes functions which unite multiple hal(Hardware) operations
+    and also take the responsibility of Software Resource Management in order
+    to keep the synchronization with Hardware Manipulation.
+*/
+
+/*
+** Log: nic.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 05 02 2012 terry.wu
+ * NULL
+ * Set the default value of AP StaRec index to "STA_REC_INDEX_NOT_FOUND" in update firmware bss command.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 11 28 2011 cp.wu
+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when
+ * returining to ROM code
+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware
+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not
+ *
+ * 11 22 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * keep debug counter setting after wake up.
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Update RSSI for P2P.
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 11 04 2011 cp.wu
+ * [WCXRP00001079] [MT5931][Driver] Release pending MMPDU only when BSS is being deactivated
+ * pre-check for NULL before calling MMPDU free function
+ *
+ * 11 03 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG
+ *
+ * 11 01 2011 chinglan.wang
+ * NULL
+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP.
+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to
+ * the AP..
+ *
+ * 10 11 2011 terry.wu
+ * NULL
+ * Rewrite Assert Dump Function for Portability.
+ *
+ * 09 20 2011 cm.chang
+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
+ * New CMD definition about RLM parameters
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * reuse firmware download logic of MT6620 for MT6628.
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ *
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ * 08 03 2011 terry.wu
+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
+ * Reply Probe Rsp in FW for Hotspot Mode.
+ *
+ * 08 02 2011 yuche.tsai
+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device
+ * issue.
+ * Fix GO send deauth frame issue.
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 07 11 2011 wh.su
+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for
+ * customer not enable WAPI
+ * For make sure wapi initial value is set.
+ *
+ * 06 27 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky
+ * AP which use space character as hidden SSID
+ * 1. correct logic
+ * 2. replace only BSS-DESC which doesn't have a valid SSID.
+ *
+ * 06 27 2011 cp.wu
+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky
+ * AP which use space character as hidden SSID
+ * allow to have a single BSSID with multiple SSID to be presented in scanning result
+ *
+ * 05 12 2011 puff.wen
+ * NULL
+ * FW Assert information dump to driver
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 15 2011 cp.wu
+ * [WCXRP00000651] [MT6620 Wi-Fi][Driver] Refine RSSI buffering mechanism
+ * ROLLBACK due to the special design is to workaround incorrect initial RCPI value coming from firmware domain.
+ *
+ * 04 14 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 14 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
+ * RESET_START and RESET_END events
+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
+ * 2. add dummy function for both Win32 and Linux part.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for
+ * dedicated network type
+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected
+ *
+ * 04 12 2011 wh.su
+ * NULL
+ * enable the p2p check the cipher to set the bssInfo auth mode.
+ *
+ * 04 12 2011 wh.su
+ * NULL
+ * prepare the code for sync the auth mode and encryption status for P2P and BOW.
+ *
+ * 04 11 2011 yuche.tsai
+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue.
+ * Fix kernel panic issue when MMPDU of P2P is pending in driver.
+ *
+ * 04 10 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * Fix compiler issue.
+ *
+ * 04 08 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * separate settings of P2P and AIS
+ *
+ * 04 08 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix for sigma
+ *
+ * 04 07 2011 cp.wu
+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside
+ * wlanAdapterStart
+ * .
+ *
+ * 04 07 2011 cp.wu
+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside
+ * wlanAdapterStart
+ * implementation of internal error handling of nicAllocateAdapterMemory.
+ *
+ * 03 31 2011 chinglan.wang
+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not.
+ * .
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability improvement
+ *
+ * 03 17 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * use pre-allocated buffer for storing enhanced interrupt response as well
+ *
+ * 03 16 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * 1. pre-allocate physical continuous buffer while module is being loaded
+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
+ *
+ * The windows part remained the same as before, but added similar APIs to hide the difference.
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
+ * memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 10 2011 cm.chang
+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after
+ * connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
+ *
+ * 02 08 2011 terry.wu
+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log
+ * Use kalPrint to print firmware assert info.
+ *
+ * 02 01 2011 terry.wu
+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log
+ * .
+ *
+ * 02 01 2011 cm.chang
+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
+ * .
+ *
+ * 01 31 2011 terry.wu
+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log
+ * Print firmware ASSERT info at Android kernel log, driver side
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * Allocate system RAM if fixed message or mgmt buffer is not available
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 19 2011 cp.wu
+ * [WCXRP00000372] [MT6620 Wi-Fi][Driver] Check bus access failure inside nicProcessIST()
+ * check bus error and/or card removal when retrieving interrupt status from HAL
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
+ * physically continuous memory demands
+ * 1) correct typo in scan.c
+ * 2) TX descriptors, RX descriptos and management buffer should use virtually continuous buffer instead of
+ * physically contineous one
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
+ * physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 12 30 2010 cp.wu
+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
+ * host driver not to set FW-own when there is still pending interrupts
+ *
+ * 12 17 2010 cp.wu
+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged
+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
+ * 1. BSSINFO include RLM parameter
+ * 2. free all sta records when network is disconnected
+ *
+ * 12 02 2010 eddie.chen
+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry
+ * Add more control value but dont use it now.
+ *
+ * 11 30 2010 eddie.chen
+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry
+ * Add auto rate check window in registry
+ *
+ * 11 10 2010 eddie.chen
+ * [WCXRP00000156] [MT6620][FW] Change Auto rate window to 64 and add throughput swcr
+ * Use autorate parameter 1 as phy rate mask.
+ *
+ * 11 08 2010 cp.wu
+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time
+ *
+ * 10 26 2010 eddie.chen
+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB
+ * Add auto rate parameter in registry.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to
+ * BSOD when entering RF test with AIS associated
+ * 1. remove redundant variables in STA_REC structure
+ * 2. add STA-REC uninitialization routine for clearing pending events
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A
+ * reset ptrs when IEs are going to be dropped
+ *
+ * 10 12 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * add HT (802.11n) fixed rate support.
+ *
+ * 10 08 2010 cp.wu
+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
+ * adding fixed rate support for distance test. (from registry setting)
+ *
+ * 10 07 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * add firmware download for MT5931.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by
+ * ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test
+ * with AIS associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 06 2010 cp.wu
+ * NULL
+ * Androi/Linux: return current operating channel information
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * HIFSYS Clock Source Workaround
+ *
+ * 08 26 2010 yuche.tsai
+ * NULL
+ * Fix someones coding error while enable WIFI_DIRECT.
+ *
+ * 08 25 2010 george.huang
+ * NULL
+ * update OID/ registry control path for PM related settings
+ *
+ * 08 24 2010 cm.chang
+ * NULL
+ * Support RLM initail channel of Ad-hoc, P2P and BOW
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Update BOW for the 1st time.
+ *
+ * 08 23 2010 chinghwa.yu
+ * NULL
+ * Update for BOW.
+ *
+ * 08 20 2010 yuche.tsai
+ * NULL
+ * Add state change indication.
+ *
+ * 08 16 2010 yuche.tsai
+ * NULL
+ * Add support for P2P BSS update info.
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * [removing debugging] not to dump beacon content.
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
+ *
+ * 08 11 2010 cp.wu
+ * NULL
+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting)
+ * 2) extending scanning result to 64 instead of 48
+ *
+ * 08 04 2010 yarco.yang
+ * NULL
+ * Add TX_AMPDU and ADDBA_REJECT command
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * Centralize mgmt/system service procedures into independent calls.
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo
+ * 2) change nicMediaStateChange() API prototype
+ *
+ * 07 28 2010 cp.wu
+ * NULL
+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15.
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 23 2010 cp.wu
+ *
+ * FIX: structure of CMD_SET_BSS_INFO has been changed but no follow-ups are done.
+ *
+ * 07 22 2010 george.huang
+ *
+ * .
+ *
+ * 07 22 2010 george.huang
+ *
+ * Update fgIsQoS information in BSS INFO by CMD
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Add Ad-Hoc support to AIS-FSM
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * update prStaRecOfAP with BSS-INFO.
+ *
+ * 07 06 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Update arguments for nicUpdateBeaconIETemplate()
+ *
+ * 07 06 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * STA-REC is maintained by CNM only.
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) ignore RSN checking when RSN is not turned on.
+ * 2) set STA-REC deactivation callback as NULL
+ * 3) add variable initialization API based on PHY configuration
+ *
+ * 07 01 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Support sync command of STA_REC
+ *
+ * 06 30 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * sync. with CMD/EVENT document ver0.07.
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE.
+ *
+ * 06 29 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) sync to. CMD/EVENT document v0.03
+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
+ * 3) send command packet to indicate FW-PM after
+ *     a) 1st beacon is received after AIS has connected to an AP
+ *     b) IBSS-ALONE has been created
+ *     c) IBSS-MERGE has occurred
+ *
+ * 06 25 2010 george.huang
+ * [WPD00001556]Basic power managemenet function
+ * Create beacon update path, with expose bssUpdateBeaconContent()
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * fill fgIsUapsdConnection when indicating BSS-CREATE with AIS-STA mode.
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implement TX_DONE callback path.
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * remove duplicate variable for migration.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * TX descriptors are now allocated once for reducing allocation overhead
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 04 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) surpress compiler warning
+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add channel frequency <-> number conversion
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver
+ * correct nicProcessIST_impl() for interrupt status brought up by RX enhanced response
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ *  *  *  *  *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
+ *
+ * 03 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * always process TX interrupt first then RX interrupt.
+ *
+ * 02 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE
+ *
+ * 02 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add checksum offloading support.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-16 18:03:43 GMT mtk02752
+**  handling enhanced response which fields are fetched at different moments
+**  \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-15 17:00:29 GMT mtk02752
+**  if RX enhanced response is used, D2H interrupt status should be coming from buffered result as well
+**  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-15 12:01:55 GMT mtk02752
+**  if TX_DONE bit is not set but WTSR0/WTSR1 is non-zero, then set TX_DONE
+**	bit due to time latency of interrupt status enhanced response
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:52:52 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-24 20:51:01 GMT mtk02752
+**  integrate with SD1 by invoking qmHandleMailboxRxMessage()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-16 17:32:33 GMT mtk02752
+**  prepare code for invoking rxHandleMailboxRxMessage()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:08 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-09 22:56:41 GMT mtk01084
+**  modify HW access routines
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:20 GMT mtk01084
+**  prevent warning
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:54:57 GMT mtk01084
+**  init HIF
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:30 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:12 GMT mtk01084
+**  update for new HW design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-09-09 17:26:15 GMT mtk01084
+**  modify for CFG_TEST_WITH_MT5921
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-19 10:55:22 GMT mtk01461
+**  Unmask the unused HISR
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-18 15:59:13 GMT mtk01084
+**  remove debug purpose code
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 14:05:02 GMT mtk01084
+**  update for WIFI ownback part on initial
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-04 21:32:57 GMT mtk01084
+**  add temporarily code to set driver own on adapter initialization
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:35:41 GMT mtk01461
+**  Add init of TX aggregation and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-24 21:12:10 GMT mtk01104
+**  Add function nicRestoreSpiDefMode()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:43:31 GMT mtk01461
+**  Revise for MTK coding style - nicInitializeAdapter()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:52:47 GMT mtk01461
+**  Update allocate Adapter Memory for MGMT Memory pool
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:57:08 GMT mtk01461
+**  Refine the order of release memory from pucRxCoalescingBufCached
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-19 18:32:57 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:00:14 GMT mtk01426
+**  Add CFG_SDIO_RX_ENHANCE support
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:27 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:25:59 GMT mtk01426
+**  Init for develop
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+const UINT_8 aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] = {
+	PHY_TYPE_SET_802_11ABG,	/* PHY_CONFIG_802_11ABG */
+	PHY_TYPE_SET_802_11BG,	/* PHY_CONFIG_802_11BG */
+	PHY_TYPE_SET_802_11G,	/* PHY_CONFIG_802_11G */
+	PHY_TYPE_SET_802_11A,	/* PHY_CONFIG_802_11A */
+	PHY_TYPE_SET_802_11B,	/* PHY_CONFIG_802_11B */
+	PHY_TYPE_SET_802_11ABGN,	/* PHY_CONFIG_802_11ABGN */
+	PHY_TYPE_SET_802_11BGN,	/* PHY_CONFIG_802_11BGN */
+	PHY_TYPE_SET_802_11AN,	/* PHY_CONFIG_802_11AN */
+	PHY_TYPE_SET_802_11GN	/* PHY_CONFIG_802_11GN */
+};
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+#define REQ_GATING_ENABLE_H2D_INT   BIT(31)
+#define REQ_GATING_DISABLE_H2D_INT  BIT(30)
+#define ACK_GATING_ENABLE_D2H_INT   BIT(31)
+#define ACK_GATING_DISABLE_D2H_INT  BIT(30)
+
+#define GATING_CONTROL_POLL_LIMIT   64
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+static INT_EVENT_MAP_T arIntEventMapTable[] = {
+	{WHISR_ABNORMAL_INT, INT_EVENT_ABNORMAL},
+	{WHISR_D2H_SW_INT, INT_EVENT_SW_INT},
+	{WHISR_TX_DONE_INT, INT_EVENT_TX},
+	{(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX}
+};
+
+static const UINT_8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T));
+
+static IST_EVENT_FUNCTION apfnEventFuncTable[] = {
+	nicProcessAbnormalInterrupt,	/*!< INT_EVENT_ABNORMAL */
+	nicProcessSoftwareInterrupt,	/*!< INT_EVENT_SW_INT   */
+	nicProcessTxInterrupt,	/*!< INT_EVENT_TX       */
+	nicProcessRxInterrupt,	/*!< INT_EVENT_RX       */
+};
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory()
+ * and also enhance the readability.
+ */
+#define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \
+	{ \
+	    DBGLOG(NIC, INFO, "Allocating %u bytes for %s.\n", u4Size, pucComment); \
+	    pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType); \
+	    if (pucMem == (PUINT_8)NULL) { \
+		DBGLOG(NIC, ERROR, "Could not allocate %u bytes for %s.\n", u4Size, pucComment); \
+		break; \
+	    } \
+	    ASSERT(((ULONG)pucMem % 4) == 0); \
+	    DBGLOG(NIC, TRACE, "Virtual Address = %p for %s.\n", pucMem, pucComment); \
+	}
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter)
+{
+	dumpMemory32((PUINT_32)prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T));
+}
+
+VOID HifRegDump(P_ADAPTER_T prAdapter)
+{
+	UINT_32 i;
+	UINT_32 RegVal = 0;
+
+	for (i = 0; i <= 0x58; i += 4) {
+		if ((i != MCR_WTDR0) && (i != MCR_WTDR1) && (i != MCR_WRDR0) &&
+			(i != MCR_WRDR1) && (i != MCR_WSDIOCSR) && (i != MCR_WRPLR)) {
+			HAL_MCR_RD(prAdapter, i, &RegVal);
+			DBGLOG(NIC, WARN, "HIF Reg 0x%x = 0x%x\n", i, RegVal);
+		}
+	}
+	DBGLOG(NIC, WARN, "\n\n");
+}
+
+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter)
+{
+	return prAdapter->fgIsFwOwn;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This routine is responsible for the allocation of the data structures
+*        inside the Adapter structure, include:
+*        1. SW_RFB_Ts
+*        2. Common coalescing buffer for TX PATH.
+*
+* @param prAdapter Pointer of Adapter Data Structure
+*
+* @retval WLAN_STATUS_SUCCESS - Has enough memory.
+* @retval WLAN_STATUS_RESOURCES - Memory is not enough.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter)
+{
+	WLAN_STATUS status = WLAN_STATUS_RESOURCES;
+	P_RX_CTRL_T prRxCtrl;
+	P_TX_CTRL_T prTxCtrl;
+
+	DEBUGFUNC("nicAllocateAdapterMemory");
+
+	ASSERT(prAdapter);
+	prRxCtrl = &prAdapter->rRxCtrl;
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	do {
+		/* 4 <0> Reset all Memory Handler */
+#if CFG_DBG_MGT_BUF
+		prAdapter->u4MemFreeDynamicCount = 0;
+		prAdapter->u4MemAllocDynamicCount = 0;
+#endif
+		prAdapter->pucMgtBufCached = (PUINT_8) NULL;
+		prRxCtrl->pucRxCached = (PUINT_8) NULL;
+		prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL;
+
+		/* 4 <1> Memory for Management Memory Pool and CMD_INFO_T */
+		/* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */
+		prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE;
+
+		LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached,
+					  prAdapter->u4MgtBufCachedSize, VIR_MEM_TYPE, "COMMON MGMT MEMORY POOL");
+
+		/* 4 <2> Memory for RX Descriptor */
+		/* Initialize the number of rx buffers we will have in our queue. */
+		/* <TODO> We may setup ucRxPacketDescriptors by GLUE Layer, and using
+		 * this variable directly.
+		 */
+		/* Allocate memory for the SW receive structures. */
+		prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * ALIGN_4(sizeof(SW_RFB_T));
+
+		LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize, VIR_MEM_TYPE, "SW_RFB_T");
+
+		/* 4 <3> Memory for TX DEscriptor */
+		prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * ALIGN_4(sizeof(MSDU_INFO_T));
+
+		LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, prTxCtrl->u4TxCachedSize, VIR_MEM_TYPE, "MSDU_INFO_T");
+
+		/* 4 <4> Memory for Common Coalescing Buffer */
+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG
+		prAdapter->pucCoalescingBufCached = (PUINT_8) NULL;
+
+		/* Allocate memory for the common coalescing buffer. */
+		prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ?
+		    CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE;
+
+		prAdapter->pucCoalescingBufCached = kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize);
+
+		if (prAdapter->pucCoalescingBufCached == NULL) {
+			DBGLOG(NIC, ERROR,
+			       "Could not allocate %u bytes for coalescing buffer.\n",
+				prAdapter->u4CoalescingBufCachedSize);
+			break;
+		}
+#endif /* CFG_COALESCING_BUFFER_SIZE */
+
+		/* 4 <5> Memory for enhanced interrupt response */
+		prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T)
+		    kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T));
+
+		if (prAdapter->prSDIOCtrl == NULL) {
+			DBGLOG(NIC, ERROR,
+			       "Could not allocate %zu bytes for interrupt response.\n",
+				sizeof(ENHANCE_MODE_DATA_STRUCT_T));
+			break;
+		}
+
+		status = WLAN_STATUS_SUCCESS;
+
+	} while (FALSE);
+
+	if (status != WLAN_STATUS_SUCCESS)
+		nicReleaseAdapterMemory(prAdapter);
+
+	return status;
+
+}				/* end of nicAllocateAdapterMemory() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This routine is responsible for releasing the allocated memory by
+*        nicAllocatedAdapterMemory().
+*
+* @param prAdapter Pointer of Adapter Data Structure
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter)
+{
+	P_TX_CTRL_T prTxCtrl;
+	P_RX_CTRL_T prRxCtrl;
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+	prRxCtrl = &prAdapter->rRxCtrl;
+
+	/* 4 <5> Memory for enhanced interrupt response */
+	if (prAdapter->prSDIOCtrl) {
+		kalReleaseIOBuffer((PVOID) prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T));
+		prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL;
+	}
+	/* 4 <4> Memory for Common Coalescing Buffer */
+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG
+	if (prAdapter->pucCoalescingBufCached) {
+		kalReleaseIOBuffer((PVOID) prAdapter->pucCoalescingBufCached, prAdapter->u4CoalescingBufCachedSize);
+		prAdapter->pucCoalescingBufCached = (PUINT_8) NULL;
+	}
+#endif /* CFG_COALESCING_BUFFER_SIZE */
+
+	/* 4 <3> Memory for TX Descriptor */
+	if (prTxCtrl->pucTxCached) {
+		kalMemFree((PVOID) prTxCtrl->pucTxCached, VIR_MEM_TYPE, prTxCtrl->u4TxCachedSize);
+		prTxCtrl->pucTxCached = (PUINT_8) NULL;
+	}
+	/* 4 <2> Memory for RX Descriptor */
+	if (prRxCtrl->pucRxCached) {
+		kalMemFree((PVOID) prRxCtrl->pucRxCached, VIR_MEM_TYPE, prRxCtrl->u4RxCachedSize);
+		prRxCtrl->pucRxCached = (PUINT_8) NULL;
+	}
+	/* 4 <1> Memory for Management Memory Pool */
+	if (prAdapter->pucMgtBufCached) {
+		kalMemFree((PVOID) prAdapter->pucMgtBufCached, VIR_MEM_TYPE, prAdapter->u4MgtBufCachedSize);
+		prAdapter->pucMgtBufCached = (PUINT_8) NULL;
+	}
+#if CFG_DBG_MGT_BUF
+	/* Check if all allocated memories are free */
+	ASSERT(prAdapter->u4MemFreeDynamicCount == prAdapter->u4MemAllocDynamicCount);
+#endif
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief disable global interrupt
+*
+* @param prAdapter pointer to the Adapter handler
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
+
+	prAdapter->fgIsIntEnable = FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief enable global interrupt
+*
+* @param prAdapter pointer to the Adapter handler
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter)
+{
+	BOOLEAN fgIsIntEnableCache;
+
+	ASSERT(prAdapter);
+	fgIsIntEnableCache = prAdapter->fgIsIntEnable;
+
+	prAdapter->fgIsIntEnable = TRUE;	/* NOTE(Kevin): It must be placed before MCR GINT write. */
+
+	/* If need enable INT and also set LPOwn at the same time. */
+	if (prAdapter->fgIsIntEnableWithLPOwnSet) {
+		prAdapter->fgIsIntEnableWithLPOwnSet = FALSE;	/* NOTE(Kevin): It's better to place it
+								 * before MCR GINT write.
+								 */
+		/* If INT was enabled, only set LPOwn */
+		if (fgIsIntEnableCache) {
+			HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
+			prAdapter->fgIsFwOwn = TRUE;
+		}
+		/* If INT was not enabled, enable it and also set LPOwn now */
+		else {
+			HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET | WHLPCR_INT_EN_SET);
+			prAdapter->fgIsFwOwn = TRUE;
+		}
+	}
+	/* If INT was not enabled, enable it now */
+	else if (!fgIsIntEnableCache)
+		HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+}				/* end of nicEnableInterrupt() */
+
+#if CFG_SDIO_INTR_ENHANCE
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief For SDIO enhance mode, set the max rx len and tx status
+*
+* @param prAdapter      a pointer to adapter private data structure.
+*
+* @return  - none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 u4Value = 0;
+
+	ASSERT(prAdapter);
+
+	/* 4 <1> Check STATUS Buffer is DW alignment. */
+	ASSERT(IS_ALIGN_4((ULONG)&prAdapter->prSDIOCtrl->u4WHISR));
+
+	/* 4 <2> Setup STATUS count. */
+	{
+		HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);
+
+		/* 4 <2.1> Setup the number of maximum RX length to be report */
+		u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM);
+		u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM));
+
+		/* 4 <2.2> Setup RX enhancement mode */
+#if CFG_SDIO_RX_ENHANCE
+		u4Value |= WHCR_RX_ENHANCE_MODE_EN;
+#else
+		u4Value &= ~WHCR_RX_ENHANCE_MODE_EN;
+#endif /* CFG_SDIO_RX_AGG */
+
+		HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value);
+	}
+
+	return;
+
+}				/* end of nicSDIOInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Read interrupt status from hardware
+*
+* @param prAdapter pointer to the Adapter handler
+* @param the interrupts
+*
+* @return N/A
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus)
+{
+	P_SDIO_CTRL_T prSDIOCtrl;
+
+	DEBUGFUNC("nicSDIOReadIntStatus");
+
+	ASSERT(prAdapter);
+	ASSERT(pu4IntStatus);
+
+	/*
+	   prSDIOCtrl is from IO buffer.
+	   prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T)
+	   kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T));
+	 */
+	prSDIOCtrl = prAdapter->prSDIOCtrl;
+	ASSERT(prSDIOCtrl);
+
+	HAL_PORT_RD(prAdapter,
+		    MCR_WHISR,
+		    sizeof(ENHANCE_MODE_DATA_STRUCT_T), (PUINT_8) prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T));
+
+	if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+		*pu4IntStatus = 0;
+		return;
+	}
+
+	/* workaround */
+	if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 &&
+	    (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) {
+		prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT;
+	}
+
+	if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 &&
+	    HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE &&
+	    (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) {
+		prSDIOCtrl->u4WHISR |= BIT(31);
+	}
+
+	*pu4IntStatus = prSDIOCtrl->u4WHISR;
+
+}				/* end of nicSDIOReadIntStatus() */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief The function used to read interrupt status and then invoking
+*        dispatching procedure for the appropriate functions
+*        corresponding to specific interrupt bits
+*
+* @param prAdapter pointer to the Adapter handler
+*
+* @retval WLAN_STATUS_SUCCESS
+* @retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter)
+{
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+	UINT_32 u4IntStatus = 0;
+	UINT_32 i;
+
+	DEBUGFUNC("nicProcessIST");
+	/* DBGLOG(NIC, LOUD, ("\n")); */
+
+	ASSERT(prAdapter);
+
+	if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+		DBGLOG(REQ, WARN, "Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+				   prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	if (prAdapter->fgIsClockGatingEnabled == TRUE)
+		nicDisableClockGating(prAdapter);
+#endif
+
+	for (i = 0; i < CFG_IST_LOOP_COUNT; i++) {	/* CFG_IST_LOOP_COUNT = 1 */
+
+#if CFG_SDIO_INTR_ENHANCE
+		nicSDIOReadIntStatus(prAdapter, &u4IntStatus);
+#else
+		HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus);
+#endif /* CFG_SDIO_INTR_ENHANCE */
+
+/* DBGLOG(NIC, TRACE, ("u4IntStatus: 0x%x\n", u4IntStatus)); */
+
+		if (u4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) {
+			DBGLOG(INTR, WARN, "Un-handled HISR %#x, HISR = %#x (HIER:0x%x)\n",
+					    (UINT_32) (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus,
+					    (UINT_32) WHIER_DEFAULT);
+			u4IntStatus &= WHIER_DEFAULT;
+		}
+
+		nicProcessIST_impl(prAdapter, u4IntStatus);
+
+		if (u4IntStatus == 0) {
+			if (i == 0)
+				u4Status = WLAN_STATUS_NOT_INDICATING;
+			break;
+		}
+	}
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	if (prAdapter->fgIsClockGatingEnabled == FALSE)
+		nicEnableClockGating(prAdapter);
+#endif
+
+	return u4Status;
+}				/* end of nicProcessIST() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief The function used to dispatch the appropriate functions for specific
+*        interrupt bits
+*
+* @param prAdapter   pointer to the Adapter handler
+*        u4IntStatus interrupt status bits
+*
+* @retval WLAN_STATUS_SUCCESS
+* @retval WLAN_STATUS_ADAPTER_NOT_READY
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus)
+{
+	UINT_32 u4IntCount = 0;
+	P_INT_EVENT_MAP_T prIntEventMap = NULL;
+
+	ASSERT(prAdapter);
+
+	prAdapter->u4IntStatus = u4IntStatus;
+
+	/* Process each of the interrupt status consequently */
+	prIntEventMap = &arIntEventMapTable[0];
+	for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) {
+		if (prIntEventMap->u4Int & prAdapter->u4IntStatus) {
+			if (prIntEventMap->u4Event == INT_EVENT_RX && prAdapter->fgIsEnterD3ReqIssued == TRUE) {
+				/* ignore */
+			} else if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) {
+				apfnEventFuncTable[prIntEventMap->u4Event] (prAdapter);
+			} else {
+				DBGLOG(INTR, WARN,
+				       "Empty INTR handler! ISAR bit#: %u, event:%u, func: %p\n",
+					prIntEventMap->u4Int, prIntEventMap->u4Event,
+					apfnEventFuncTable[prIntEventMap->u4Event]);
+
+				ASSERT(0);	/* to trap any NULL interrupt handler */
+			}
+			prAdapter->u4IntStatus &= ~prIntEventMap->u4Int;
+		}
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of nicProcessIST_impl() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Verify the CHIP ID
+*
+* @param prAdapter      a pointer to adapter private data structure.
+*
+*
+* @retval TRUE          CHIP ID is the same as the setting compiled
+* @retval FALSE         CHIP ID is different from the setting compiled
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 u4CIR = 0;
+
+	ASSERT(prAdapter);
+
+	HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR);
+
+	DBGLOG(NIC, TRACE, "Chip ID: 0x%x\n", (UINT_32) (u4CIR & WCIR_CHIP_ID));
+	DBGLOG(NIC, TRACE, "Revision ID: 0x%x\n", (UINT_32) ((u4CIR & WCIR_REVISION_ID) >> 16));
+
+#if 0
+	if (((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_72) && ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_82))
+		return FALSE;
+#endif
+
+	prAdapter->ucRevID = (UINT_8) (((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF);
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Initialize the MCR to the appropriate init value, and verify the init
+*        value
+*
+* @param prAdapter      a pointer to adapter private data structure.
+*
+* @return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicMCRInit(IN P_ADAPTER_T prAdapter)
+{
+
+	ASSERT(prAdapter);
+
+	/* 4 <0> Initial value */
+}
+
+VOID nicHifInit(IN P_ADAPTER_T prAdapter)
+{
+
+	ASSERT(prAdapter);
+#if 0
+	/* reset event */
+	nicPutMailbox(prAdapter, 0, 0x52455345);	/* RESE */
+	nicPutMailbox(prAdapter, 1, 0x545F5746);	/* T_WF */
+	nicSetSwIntr(prAdapter, BIT(16));
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Initialize the Adapter soft variable
+*
+* @param prAdapter pointer to the Adapter handler
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter)
+{
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prAdapter);
+
+	prAdapter->fgIsIntEnableWithLPOwnSet = FALSE;
+
+	do {
+		if (!nicVerifyChipID(prAdapter)) {
+			u4Status = WLAN_STATUS_FAILURE;
+			break;
+		}
+		/* 4 <1> MCR init */
+		nicMCRInit(prAdapter);
+
+#if CFG_SDIO_INTR_ENHANCE
+		nicSDIOInit(prAdapter);
+#endif /* CFG_SDIO_INTR_ENHANCE */
+
+		HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT);
+
+		/* 4 <2> init FW HIF */
+		nicHifInit(prAdapter);
+	} while (FALSE);
+
+	return u4Status;
+}
+
+#if defined(_HIF_SPI)
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Restore the SPI Mode Select to default mode,
+*        this is important while driver is unload, and this must be last mcr
+*        since the operation will let the hif use 8bit mode access
+*
+* \param[in] prAdapter      a pointer to adapter private data structure.
+* \param[in] eGPIO2_Mode    GPIO2 operation mode
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process rx interrupt. When the rx
+*        Interrupt is asserted, it means there are frames in queue.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 u4Value = 0;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	prGlueInfo->IsrAbnormalCnt++;
+	HAL_MCR_RD(prAdapter, MCR_WASR, &u4Value);
+	DBGLOG(REQ, WARN, "MCR_WASR: 0x%x\n", u4Value);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief .
+*
+* @param prAdapter  Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicProcessFwOwnBackInterrupt(IN P_ADAPTER_T prAdapter)
+{
+
+}				/* end of nicProcessFwOwnBackInterrupt() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief .
+*
+* @param prAdapter  Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 u4IntrBits;
+
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+	u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31);
+
+	prGlueInfo->IsrSoftWareCnt++;
+
+	if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) {
+		nicPrintFirmwareAssertInfo(prAdapter);
+#if CFG_CHIP_RESET_SUPPORT
+		glSendResetRequest();
+#endif
+	}
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+	ASSERT((u4IntrBits & (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT))
+	       != (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT));
+
+	if (u4IntrBits & ACK_GATING_ENABLE_D2H_INT)
+		prAdapter->fgIsClockGatingEnabled = TRUE;
+
+	if (u4IntrBits & ACK_GATING_DISABLE_D2H_INT) {
+		prAdapter->fgIsClockGatingEnabled = FALSE;
+
+		/* Indicate Service Thread for TX */
+		if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0)
+			kalSetEvent(prAdapter->prGlueInfo);
+	}
+#endif
+
+	DBGLOG(REQ, WARN, "u4IntrBits: 0x%x\n", u4IntrBits);
+}				/* end of nicProcessSoftwareInterrupt() */
+
+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data)
+{
+	if (u4MailboxNum == 0) {
+		/* HAL_MCR_WR */
+		HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data);
+	} else if (u4MailboxNum == 1) {
+		/* HAL_MCR_WR */
+		HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data);
+	} else {
+		ASSERT(0);
+	}
+}
+
+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data)
+{
+	if (u4MailboxNum == 0) {
+		/* HAL_MCR_RD */
+		HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data);
+	} else if (u4MailboxNum == 1) {
+		/* HAL_MCR_RD */
+		HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data);
+	} else {
+		ASSERT(0);
+	}
+}
+
+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap)
+{
+	/* NOTE:
+	 *  SW interrupt in HW bit 16 is mapping to SW bit 0 (shift 16bit in HW transparancy)
+	 *  SW interrupt valid from b0~b15
+	 */
+	ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0);
+/* DBGLOG(NIC, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap)); */
+
+	HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue
+*        with specified sequential number
+*
+* @param    prAdapter   Pointer of ADAPTER_T
+*           ucSeqNum    Sequential Number
+*
+* @retval - P_CMD_INFO_T
+*/
+/*----------------------------------------------------------------------------*/
+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+
+	prCmdQue = &prAdapter->rPendingCmdQueue;
+	QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+	QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+		prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+		if (prCmdInfo->ucCmdSeqNum == ucSeqNum)
+			break;
+
+		QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+
+		prCmdInfo = NULL;
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+	QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
+
+	return prCmdInfo;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This procedure is used to dequeue from prAdapter->rTxCtrl.rTxMgmtTxingQueue
+*        with specified sequential number
+*
+* @param    prAdapter   Pointer of ADAPTER_T
+*           ucSeqNum    Sequential Number
+*
+* @retval - P_MSDU_INFO_T
+*/
+/*----------------------------------------------------------------------------*/
+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum)
+{
+	P_QUE_T prTxingQue;
+	QUE_T rTempQue;
+	P_QUE_T prTempQue = &rTempQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+
+	prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue);
+	QUEUE_MOVE_ALL(prTempQue, prTxingQue);
+
+	QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+		prMsduInfo = (P_MSDU_INFO_T) prQueueEntry;
+
+		if (prMsduInfo->ucTxSeqNum == ucSeqNum)
+			break;
+
+		QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry);
+
+		prMsduInfo = NULL;
+
+		QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+	QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue);
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+
+	return prMsduInfo;
+}
+
+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx)
+{
+	P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL;
+	P_QUE_T prTxingQue = (P_QUE_T) NULL;
+	QUE_T rTempQue;
+	P_QUE_T prTempQue = &rTempQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL;
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	if (prAdapter == NULL) {
+		ASSERT(FALSE);
+		return NULL;
+	}
+
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+	do {
+
+		prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue);
+		QUEUE_MOVE_ALL(prTempQue, prTxingQue);
+
+		QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
+		while (prQueueEntry) {
+			prMsduInfo = (P_MSDU_INFO_T) prQueueEntry;
+
+			if ((prMsduInfo->ucStaRecIndex == ucStaRecIdx) && (prMsduInfo->pfTxDoneHandler != NULL)) {
+				QM_TX_SET_NEXT_MSDU_INFO(prMsduInfo, prMsduInfoListHead);
+				prMsduInfoListHead = prMsduInfo;
+			} else {
+				QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry);
+
+				prMsduInfo = NULL;
+			}
+
+			QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
+		}
+
+	} while (FALSE);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+
+	return prMsduInfoListHead;
+}				/* nicGetPendingStaMMPDU */
+
+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType)
+{
+	P_QUE_T prTxingQue;
+	QUE_T rTempQue;
+	P_QUE_T prTempQue = &rTempQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL;
+	P_MSDU_INFO_T prMsduInfoListTail = (P_MSDU_INFO_T) NULL;
+	P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+
+	prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue);
+	QUEUE_MOVE_ALL(prTempQue, prTxingQue);
+
+	QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+		prMsduInfo = (P_MSDU_INFO_T) prQueueEntry;
+
+		if ((ENUM_NETWORK_TYPE_INDEX_T) (prMsduInfo->ucNetworkType) == eNetworkType) {
+			if (prMsduInfoListHead == NULL) {
+				prMsduInfoListHead = prMsduInfoListTail = prMsduInfo;
+			} else {
+				QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, prMsduInfo);
+				prMsduInfoListTail = prMsduInfo;
+			}
+		} else {
+			QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry);
+
+			prMsduInfo = NULL;
+		}
+
+		QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+	QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue);
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+
+	/* free */
+	if (prMsduInfoListHead)
+		nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead);
+
+	return;
+
+}				/* end of nicFreePendingTxMsduInfoByNetwork() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This procedure is used to retrieve a CMD sequence number atomically
+*
+* @param    prAdapter   Pointer of ADAPTER_T
+*
+* @retval - UINT_8
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 ucRetval;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM);
+
+	prAdapter->ucCmdSeqNum++;
+	ucRetval = prAdapter->ucCmdSeqNum;
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM);
+
+	return ucRetval;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This procedure is used to retrieve a TX sequence number atomically
+*
+* @param    prAdapter   Pointer of ADAPTER_T
+*
+* @retval - UINT_8
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 ucRetval;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM);
+
+	prAdapter->ucTxSeqNum++;
+	ucRetval = prAdapter->ucTxSeqNum;
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM);
+
+	return ucRetval;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to handle
+*        media state change event
+*
+* @param
+*
+* @retval
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+nicMediaStateChange(IN P_ADAPTER_T prAdapter,
+		    IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus)
+{
+	P_GLUE_INFO_T prGlueInfo;
+
+	ASSERT(prAdapter);
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	switch (eNetworkType) {
+	case NETWORK_TYPE_AIS_INDEX:
+		if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) {	/* disconnected */
+			if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) {
+
+				DBGLOG(NIC, TRACE, "DisByMC\n");
+				kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+
+				prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
+			}
+
+			/* reset buffered link quality information */
+			prAdapter->fgIsLinkQualityValid = FALSE;
+			prAdapter->fgIsLinkRateValid = FALSE;
+		} else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) {	/* connected */
+			prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
+
+			/* fill information for association result */
+			prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen;
+			kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
+				   prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen);
+			kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress,
+				   prConnectionStatus->aucBssid, MAC_ADDR_LEN);
+			prAdapter->rWlanInfo.rCurrBssId.u4Privacy
+				= prConnectionStatus->ucEncryptStatus;	/* @FIXME */
+			prAdapter->rWlanInfo.rCurrBssId.rRssi = 0;	/* @FIXME */
+			prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse
+				= PARAM_NETWORK_TYPE_AUTOMODE;	/* @FIXME */
+			prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod
+			    = prConnectionStatus->u2BeaconPeriod;
+			prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow = prConnectionStatus->u2ATIMWindow;
+			prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig = prConnectionStatus->u4FreqInKHz;
+			prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType;
+			prAdapter->rWlanInfo.rCurrBssId.eOpMode
+			    = (ENUM_PARAM_OP_MODE_T) prConnectionStatus->ucInfraMode;
+
+			/* always indicate to OS according to MSDN (re-association/roaming) */
+			if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) {
+				kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0);
+			} else {
+				/* connected -> connected : roaming ? */
+				kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_ROAM_OUT_FIND_BEST, NULL, 0);
+			}
+		}
+		break;
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	case NETWORK_TYPE_BOW_INDEX:
+		break;
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+	case NETWORK_TYPE_P2P_INDEX:
+		break;
+#endif
+	default:
+		ASSERT(0);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}				/* nicMediaStateChange */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to convert between
+*        frequency and channel number
+*
+* @param u4ChannelNum
+*
+* @retval - Frequency in unit of KHz, 0 for invalid channel number
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 nicChannelNum2Freq(UINT_32 u4ChannelNum)
+{
+	UINT_32 u4ChannelInMHz;
+
+	if (u4ChannelNum >= 1 && u4ChannelNum <= 13)
+		u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5;
+	else if (u4ChannelNum == 14)
+		u4ChannelInMHz = 2484;
+	else if (u4ChannelNum == 133)
+		u4ChannelInMHz = 3665;	/* 802.11y */
+	else if (u4ChannelNum == 137)
+		u4ChannelInMHz = 3685;	/* 802.11y */
+	else if (u4ChannelNum >= 34 && u4ChannelNum <= 165)
+		u4ChannelInMHz = 5000 + u4ChannelNum * 5;
+	else if (u4ChannelNum >= 183 && u4ChannelNum <= 196)
+		u4ChannelInMHz = 4000 + u4ChannelNum * 5;
+	else
+		u4ChannelInMHz = 0;
+
+	return 1000 * u4ChannelInMHz;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to convert between
+*        frequency and channel number
+*
+* @param u4FreqInKHz
+*
+* @retval - Frequency Number, 0 for invalid freqency
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 nicFreq2ChannelNum(UINT_32 u4FreqInKHz)
+{
+	switch (u4FreqInKHz) {
+	case 2412000:
+		return 1;
+	case 2417000:
+		return 2;
+	case 2422000:
+		return 3;
+	case 2427000:
+		return 4;
+	case 2432000:
+		return 5;
+	case 2437000:
+		return 6;
+	case 2442000:
+		return 7;
+	case 2447000:
+		return 8;
+	case 2452000:
+		return 9;
+	case 2457000:
+		return 10;
+	case 2462000:
+		return 11;
+	case 2467000:
+		return 12;
+	case 2472000:
+		return 13;
+	case 2484000:
+		return 14;
+	case 3665000:
+		return 133;	/* 802.11y */
+	case 3685000:
+		return 137;	/* 802.11y */
+	case 4915000:
+		return 183;
+	case 4920000:
+		return 184;
+	case 4925000:
+		return 185;
+	case 4930000:
+		return 186;
+	case 4935000:
+		return 187;
+	case 4940000:
+		return 188;
+	case 4945000:
+		return 189;
+	case 4960000:
+		return 192;
+	case 4980000:
+		return 196;
+	case 5170000:
+		return 34;
+	case 5180000:
+		return 36;
+	case 5190000:
+		return 38;
+	case 5200000:
+		return 40;
+	case 5210000:
+		return 42;
+	case 5220000:
+		return 44;
+	case 5230000:
+		return 46;
+	case 5240000:
+		return 48;
+	case 5250000:
+		return 50;
+	case 5260000:
+		return 52;
+	case 5270000:
+		return 54;
+	case 5280000:
+		return 56;
+	case 5290000:
+		return 58;
+	case 5300000:
+		return 60;
+	case 5320000:
+		return 64;
+	case 5500000:
+		return 100;
+	case 5520000:
+		return 104;
+	case 5540000:
+		return 108;
+	case 5560000:
+		return 112;
+	case 5580000:
+		return 116;
+	case 5600000:
+		return 120;
+	case 5620000:
+		return 124;
+	case 5640000:
+		return 128;
+	case 5660000:
+		return 132;
+	case 5680000:
+		return 136;
+	case 5700000:
+		return 140;
+	case 5745000:
+		return 149;
+	case 5765000:
+		return 153;
+	case 5785000:
+		return 157;
+	case 5805000:
+		return 161;
+	case 5825000:
+		return 165;
+	case 5845000:
+		return 169;
+	case 5865000:
+		return 173;
+	default:
+		return 0;
+	}
+}
+
+/* firmware command wrapper */
+/* NETWORK (WIFISYS) */
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to activate WIFISYS for specified network
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eNetworkTypeIdx    Index of network type
+*
+* @retval -
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl;
+	P_BSS_INFO_T prBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx;
+	rCmdActivateCtrl.ucActive = 1;
+
+	if (((UINT_8) eNetworkTypeIdx) < NETWORK_TYPE_INDEX_NUM) {
+		prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx];
+		prBssInfo->fg40mBwAllowed = FALSE;
+		prBssInfo->fgAssoc40mBwAllowed = FALSE;
+	}
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_BSS_ACTIVATE_CTRL,
+				   TRUE,
+				   FALSE,
+				   FALSE,
+				   NULL, NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to deactivate WIFISYS for specified network
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eNetworkTypeIdx    Index of network type
+*
+* @retval -
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	WLAN_STATUS u4Status;
+	CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx;
+	rCmdActivateCtrl.ucActive = 0;
+
+	u4Status = wlanSendSetQueryCmd(prAdapter,
+				       CMD_ID_BSS_ACTIVATE_CTRL,
+				       TRUE,
+				       FALSE,
+				       FALSE,
+				       NULL,
+				       NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0);
+
+	/* free all correlated station records */
+	cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE);
+	qmFreeAllByNetType(prAdapter, eNetworkTypeIdx);
+	nicFreePendingTxMsduInfoByNetwork(prAdapter, eNetworkTypeIdx);
+	kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx);
+
+	return u4Status;
+}
+
+/* BSS-INFO */
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to sync bss info with firmware
+*        when a new BSS has been connected or disconnected
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eNetworkTypeIdx    Index of BSS-INFO type
+*
+* @retval -
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	WLAN_STATUS u4Status;
+	P_BSS_INFO_T prBssInfo;
+	CMD_SET_BSS_INFO rCmdSetBssInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
+
+	kalMemZero(&rCmdSetBssInfo, sizeof(CMD_SET_BSS_INFO));
+
+	rCmdSetBssInfo.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx;
+	rCmdSetBssInfo.ucConnectionState = (UINT_8) prBssInfo->eConnectionState;
+	rCmdSetBssInfo.ucCurrentOPMode = (UINT_8) prBssInfo->eCurrentOPMode;
+	rCmdSetBssInfo.ucSSIDLen = (UINT_8) prBssInfo->ucSSIDLen;
+	kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
+	COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID);
+	rCmdSetBssInfo.ucIsQBSS = (UINT_8) prBssInfo->fgIsQBSS;
+	rCmdSetBssInfo.ucNonHTBasicPhyType = prBssInfo->ucNonHTBasicPhyType;
+	rCmdSetBssInfo.u2OperationalRateSet = prBssInfo->u2OperationalRateSet;
+	rCmdSetBssInfo.u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet;
+	rCmdSetBssInfo.ucPhyTypeSet = prBssInfo->ucPhyTypeSet;
+	rCmdSetBssInfo.fgHiddenSsidMode = prBssInfo->eHiddenSsidType;
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prAdapter->fgIsP2PRegistered)
+		COPY_MAC_ADDR(rCmdSetBssInfo.aucOwnMac, prBssInfo->aucOwnMacAddr);
+#endif
+
+	rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, prBssInfo);
+
+	rCmdSetBssInfo.fgWapiMode = (UINT_8) FALSE;
+
+	if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
+		P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+		rCmdSetBssInfo.ucAuthMode = (UINT_8) prConnSettings->eAuthMode;
+		rCmdSetBssInfo.ucEncStatus = (UINT_8) prConnSettings->eEncStatus;
+		rCmdSetBssInfo.fgWapiMode = (UINT_8) prConnSettings->fgWapiMode;
+	}
+#if CFG_ENABLE_BT_OVER_WIFI
+	else if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) {
+		/* P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); */
+		rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK;
+		rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT;
+	}
+#endif
+	else {
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered) {
+			if (kalP2PGetCipher(prAdapter->prGlueInfo)) {
+				rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK;
+				rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT;
+			} else {
+				rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_OPEN;
+				rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION_DISABLED;
+			}
+			/* Need the probe response to detect the PBC overlap */
+			rCmdSetBssInfo.fgIsApMode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo);
+		}
+#else
+		rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK;
+		rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT;
+#endif
+	}
+
+	if (eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX &&
+	    prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && prBssInfo->prStaRecOfAP != NULL) {
+		rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex;
+
+		cnmAisInfraConnectNotify(prAdapter);
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	else if ((prAdapter->fgIsP2PRegistered) &&
+		 (eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) &&
+		 (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && (prBssInfo->prStaRecOfAP != NULL)) {
+		rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex;
+	}
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	else if (eNetworkTypeIdx == NETWORK_TYPE_BOW_INDEX &&
+		 prBssInfo->eCurrentOPMode == OP_MODE_BOW && prBssInfo->prStaRecOfAP != NULL) {
+		rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex;
+	}
+#endif
+	else
+		rCmdSetBssInfo.ucStaRecIdxOfAP = STA_REC_INDEX_NOT_FOUND;
+
+	u4Status = wlanSendSetQueryCmd(prAdapter,
+				       CMD_ID_SET_BSS_INFO,
+				       TRUE,
+				       FALSE,
+				       FALSE,
+				       NULL, NULL, sizeof(CMD_SET_BSS_INFO), (PUINT_8)&rCmdSetBssInfo, NULL, 0);
+
+	/* if BSS-INFO is going to be disconnected state, free all correlated station records */
+	if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
+		/* clear client list */
+		bssClearClientList(prAdapter, prBssInfo);
+
+		/* free all correlated station records */
+		cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE);
+		qmFreeAllByNetType(prAdapter, eNetworkTypeIdx);
+		kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx);
+#if CFG_ENABLE_GTK_FRAME_FILTER
+		if (prBssInfo->prIpV4NetAddrList)
+			FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList);
+#endif
+	}
+
+	return u4Status;
+}
+
+/* BSS-INFO Indication (PM) */
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to indicate PM that
+*        a BSS has been created. (for AdHoc / P2P-GO)
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eNetworkTypeIdx    Index of BSS-INFO
+*
+* @retval -
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	P_BSS_INFO_T prBssInfo;
+	CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
+
+	rCmdIndicatePmBssCreated.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx;
+	rCmdIndicatePmBssCreated.ucDtimPeriod = prBssInfo->ucDTIMPeriod;
+	rCmdIndicatePmBssCreated.u2BeaconInterval = prBssInfo->u2BeaconInterval;
+	rCmdIndicatePmBssCreated.u2AtimWindow = prBssInfo->u2ATIMWindow;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_INDICATE_PM_BSS_CREATED,
+				   TRUE,
+				   FALSE,
+				   FALSE,
+				   NULL,
+				   NULL,
+				   sizeof(CMD_INDICATE_PM_BSS_CREATED), (PUINT_8)&rCmdIndicatePmBssCreated, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to indicate PM that
+*        a BSS has been connected
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eNetworkTypeIdx    Index of BSS-INFO
+*
+* @retval -
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	P_BSS_INFO_T prBssInfo;
+	CMD_INDICATE_PM_BSS_CONNECTED rCmdIndicatePmBssConnected;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
+
+	rCmdIndicatePmBssConnected.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx;
+	rCmdIndicatePmBssConnected.ucDtimPeriod = prBssInfo->ucDTIMPeriod;
+	rCmdIndicatePmBssConnected.u2AssocId = prBssInfo->u2AssocId;
+	rCmdIndicatePmBssConnected.u2BeaconInterval = prBssInfo->u2BeaconInterval;
+	rCmdIndicatePmBssConnected.u2AtimWindow = prBssInfo->u2ATIMWindow;
+
+	rCmdIndicatePmBssConnected.ucBmpDeliveryAC = prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC;
+	rCmdIndicatePmBssConnected.ucBmpTriggerAC = prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC;
+
+	/* DBGPRINTF("nicPmIndicateBssConnected: ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x", */
+	/* rCmdIndicatePmBssConnected.ucBmpDeliveryAC, */
+	/* rCmdIndicatePmBssConnected.ucBmpTriggerAC); */
+
+	if ((eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX)
+#if CFG_ENABLE_WIFI_DIRECT
+	    || ((eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->fgIsP2PRegistered))
+#endif
+	    ) {
+		if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) {
+			rCmdIndicatePmBssConnected.fgIsUapsdConnection =
+			    (UINT_8) prBssInfo->prStaRecOfAP->fgIsUapsdSupported;
+		} else {
+			rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0;	/* @FIXME */
+		}
+	} else {
+		rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0;
+	}
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_INDICATE_PM_BSS_CONNECTED,
+				   TRUE,
+				   FALSE,
+				   FALSE,
+				   NULL,
+				   NULL,
+				   sizeof(CMD_INDICATE_PM_BSS_CONNECTED),
+				   (PUINT_8)&rCmdIndicatePmBssConnected, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to indicate PM that
+*        a BSS has been disconnected
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eNetworkTypeIdx    Index of BSS-INFO
+*
+* @retval -
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	rCmdIndicatePmBssAbort.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_INDICATE_PM_BSS_ABORT,
+				   TRUE,
+				   FALSE,
+				   FALSE,
+				   NULL,
+				   NULL,
+				   sizeof(CMD_INDICATE_PM_BSS_ABORT), (PUINT_8)&rCmdIndicatePmBssAbort, NULL, 0);
+}
+
+WLAN_STATUS
+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter,
+			  ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent)
+{
+	DEBUGFUNC("nicConfigPowerSaveProfile");
+	DBGLOG(NIC, TRACE, "eNetTypeIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n",
+			     eNetTypeIndex, ePwrMode, fgEnCmdEvent);
+
+	ASSERT(prAdapter);
+
+	if (eNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) {
+		ASSERT(0);
+		return WLAN_STATUS_NOT_SUPPORTED;
+	}
+/* prAdapter->rWlanInfo.ePowerSaveMode.ucNetTypeIndex = eNetTypeIndex; */
+/* prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile = (UINT_8)ePwrMode; */
+	prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucNetTypeIndex = eNetTypeIndex;
+	prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucPsProfile = (UINT_8) ePwrMode;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_POWER_SAVE_MODE,
+				   TRUE,
+				   FALSE,
+				   (fgEnCmdEvent ? TRUE : FALSE),
+				   (fgEnCmdEvent ? nicCmdEventSetCommon : NULL),
+				   (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL),
+				   sizeof(CMD_PS_PROFILE_T),
+				   (PUINT_8)&(prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex]),
+				   NULL, sizeof(PARAM_POWER_MODE)
+	    );
+
+}				/* end of wlanoidSetAcpiDevicePowerStateMode() */
+
+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent)
+{
+	CMD_SW_DBG_CTRL_T rCmdSwCtrl;
+	CMD_ACCESS_REG rCmdAccessReg;
+	WLAN_STATUS rWlanStatus;
+
+	DEBUGFUNC("nicEnterCtiaMode");
+	DBGLOG(NIC, TRACE, "nicEnterCtiaMode: %d\n", fgEnterCtia);
+
+	ASSERT(prAdapter);
+
+	rWlanStatus = WLAN_STATUS_SUCCESS;
+
+	if (fgEnterCtia) {
+		/* 1. Disable On-Lin Scan */
+		prAdapter->fgEnOnlineScan = FALSE;
+
+		/* 3. Disable FIFO FULL no ack */
+		rCmdAccessReg.u4Address = 0x60140028;
+		rCmdAccessReg.u4Data = 0x904;
+		wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE,	/* FALSE, */
+				    FALSE,	/* TRUE, */
+				    FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0);
+
+		/* 4. Disable Roaming */
+		rCmdSwCtrl.u4Id = 0x90000204;
+		rCmdSwCtrl.u4Data = 0x0;
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SW_DBG_CTRL,
+				    TRUE,
+				    FALSE,
+				    FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0);
+
+		rCmdSwCtrl.u4Id = 0x90000200;
+		rCmdSwCtrl.u4Data = 0x820000;
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SW_DBG_CTRL,
+				    TRUE,
+				    FALSE,
+				    FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0);
+
+		/* Disalbe auto tx power */
+		rCmdSwCtrl.u4Id = 0xa0100003;
+		rCmdSwCtrl.u4Data = 0x0;
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SW_DBG_CTRL,
+				    TRUE,
+				    FALSE,
+				    FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0);
+
+		/* 2. Keep at CAM mode */
+		{
+			PARAM_POWER_MODE ePowerMode;
+
+			prAdapter->u4CtiaPowerMode = 0;
+			prAdapter->fgEnCtiaPowerMode = TRUE;
+
+			ePowerMode = Param_PowerModeCAM;
+			rWlanStatus = nicConfigPowerSaveProfile(prAdapter,
+								NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent);
+		}
+
+		/* 5. Disable Beacon Timeout Detection */
+		prAdapter->fgDisBcnLostDetection = TRUE;
+	} else {
+		/* 1. Enaable On-Lin Scan */
+		prAdapter->fgEnOnlineScan = TRUE;
+
+		/* 3. Enable FIFO FULL no ack */
+		rCmdAccessReg.u4Address = 0x60140028;
+		rCmdAccessReg.u4Data = 0x905;
+		wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE,	/* FALSE, */
+				    FALSE,	/* TRUE, */
+				    FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0);
+
+		/* 4. Enable Roaming */
+		rCmdSwCtrl.u4Id = 0x90000204;
+		rCmdSwCtrl.u4Data = 0x1;
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SW_DBG_CTRL,
+				    TRUE,
+				    FALSE,
+				    FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0);
+
+		rCmdSwCtrl.u4Id = 0x90000200;
+		rCmdSwCtrl.u4Data = 0x820000;
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SW_DBG_CTRL,
+				    TRUE,
+				    FALSE,
+				    FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0);
+
+		/* Enable auto tx power */
+		/*  */
+
+		rCmdSwCtrl.u4Id = 0xa0100003;
+		rCmdSwCtrl.u4Data = 0x1;
+		wlanSendSetQueryCmd(prAdapter,
+				    CMD_ID_SW_DBG_CTRL,
+				    TRUE,
+				    FALSE,
+				    FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0);
+
+		/* 2. Keep at Fast PS */
+		{
+			PARAM_POWER_MODE ePowerMode;
+
+			prAdapter->u4CtiaPowerMode = 2;
+			prAdapter->fgEnCtiaPowerMode = TRUE;
+
+			ePowerMode = Param_PowerModeFast_PSP;
+			rWlanStatus = nicConfigPowerSaveProfile(prAdapter,
+								NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent);
+		}
+
+		/* 5. Enable Beacon Timeout Detection */
+		prAdapter->fgDisBcnLostDetection = FALSE;
+
+	}
+
+	return rWlanStatus;
+}				/* end of nicEnterCtiaMode() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to indicate firmware domain
+*        for beacon generation parameters
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eIeUpdMethod,      Update Method
+*        eNetTypeIndex      Index of Network
+*        u2Capability       Capability
+*        aucIe              Pointer to buffer of IEs
+*        u2IELen            Length of IEs
+*
+* @retval - WLAN_STATUS_SUCCESS
+*           WLAN_STATUS_FAILURE
+*           WLAN_STATUS_PENDING
+*           WLAN_STATUS_INVALID_DATA
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter,
+			  IN ENUM_IE_UPD_METHOD_T eIeUpdMethod,
+			  IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
+			  IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen)
+{
+	P_CMD_BEACON_TEMPLATE_UPDATE prCmdBcnUpdate;
+	UINT_16 u2CmdBufLen = 0;
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_INFO_T prCmdInfo;
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_8 ucCmdSeqNum;
+
+	DEBUGFUNC("wlanUpdateBeaconIETemplate");
+
+	DBGLOG(NIC, LOUD, "\nnicUpdateBeaconIETemplate\n");
+
+	ASSERT(prAdapter);
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	if (u2IELen > MAX_IE_LENGTH)
+		return WLAN_STATUS_INVALID_DATA;
+
+	if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) {
+		u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, aucIE) + u2IELen;
+	} else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) {
+		u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, u2IELen);
+	} else {
+		ASSERT(0);
+		return WLAN_STATUS_FAILURE;
+	}
+
+	/* prepare command info */
+	prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u2CmdBufLen));
+	if (!prCmdInfo) {
+		DBGLOG(NIC, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
+		return WLAN_STATUS_FAILURE;
+	}
+	/* increase command sequence number */
+	ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
+	DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum);
+
+	/* Setup common CMD Info Packet */
+	prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
+	prCmdInfo->eNetworkType = eNetTypeIndex;
+	prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u2CmdBufLen);
+	prCmdInfo->pfCmdDoneHandler = NULL;	/* @FIXME */
+	prCmdInfo->pfCmdTimeoutHandler = NULL;	/* @FIXME */
+	prCmdInfo->fgIsOid = FALSE;
+	prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT;
+	prCmdInfo->fgSetQuery = TRUE;
+	prCmdInfo->fgNeedResp = FALSE;
+	prCmdInfo->fgDriverDomainMCR = FALSE;
+	prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
+	prCmdInfo->u4SetInfoLen = u2CmdBufLen;
+	prCmdInfo->pvInformationBuffer = NULL;
+	prCmdInfo->u4InformationBufferLength = 0;
+
+	/* Setup WIFI_CMD_T (no payload) */
+	prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
+	prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
+	prWifiCmd->ucCID = prCmdInfo->ucCID;
+	prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
+	prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
+
+	prCmdBcnUpdate = (P_CMD_BEACON_TEMPLATE_UPDATE) (prWifiCmd->aucBuffer);
+
+	/* fill beacon updating command */
+	prCmdBcnUpdate->ucUpdateMethod = (UINT_8) eIeUpdMethod;
+	prCmdBcnUpdate->ucNetTypeIndex = (UINT_8) eNetTypeIndex;
+	prCmdBcnUpdate->u2Capability = u2Capability;
+	prCmdBcnUpdate->u2IELen = u2IELen;
+	if (u2IELen > 0)
+		kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen);
+
+	/* insert into prCmdQueue */
+	kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+
+	/* wakeup txServiceThread later */
+	GLUE_SET_EVENT(prGlueInfo);
+	return WLAN_STATUS_PENDING;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to initialization PHY related
+*        varaibles
+*
+* @param prAdapter  Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	ASSERT(prAdapter);
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+
+	if (prConnSettings->eDesiredPhyConfig >= PHY_CONFIG_NUM) {
+		ASSERT(0);
+		return;
+	}
+
+	prAdapter->rWifiVar.ucAvailablePhyTypeSet = aucPhyCfg2PhyTypeSet[prConnSettings->eDesiredPhyConfig];
+
+	if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_BIT_ERP)
+		prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_ERP_INDEX;
+	/* NOTE(Kevin): Because we don't have N only mode, TBD */
+	else {			/* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */
+
+		prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_HR_DSSS_INDEX;
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update WMM Parms
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        eNetworkTypeIdx    Index of BSS-INFO
+*
+* @retval -
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	P_BSS_INFO_T prBssInfo;
+	CMD_UPDATE_WMM_PARMS_T rCmdUpdateWmmParms;
+
+	ASSERT(prAdapter);
+	ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	DBGLOG(QM, EVENT, "sizeof(AC_QUE_PARMS_T): %zu\n", sizeof(AC_QUE_PARMS_T));
+	DBGLOG(QM, EVENT, "sizeof(CMD_UPDATE_WMM_PARMS): %zu\n", sizeof(CMD_UPDATE_WMM_PARMS_T));
+	DBGLOG(QM, EVENT, "sizeof(WIFI_CMD_T): %zu\n", sizeof(WIFI_CMD_T));
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
+	rCmdUpdateWmmParms.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx;
+	kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], &prBssInfo->arACQueParms[0], (sizeof(AC_QUE_PARMS_T) * AC_NUM));
+
+	rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_UPDATE_WMM_PARMS,
+				   TRUE,
+				   FALSE,
+				   FALSE,
+				   NULL, NULL, sizeof(CMD_UPDATE_WMM_PARMS_T), (PUINT_8)&rCmdUpdateWmmParms, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update TX power gain corresponding to
+*        each band/modulation combination
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        prTxPwrParam       Pointer of TX power parameters
+*
+* @retval WLAN_STATUS_PENDING
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam)
+{
+	DEBUGFUNC("nicUpdateTxPower");
+
+	ASSERT(prAdapter);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_TX_PWR,
+				   TRUE,
+				   FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to set auto tx power parameter
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        prTxPwrParam       Pointer of Auto TX power parameters
+*
+* @retval WLAN_STATUS_PENDING
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam)
+{
+	DEBUGFUNC("nicSetAutoTxPower");
+
+	ASSERT(prAdapter);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_AUTOPWR_CTRL,
+				   TRUE,
+				   FALSE,
+				   FALSE,
+				   NULL, NULL, sizeof(CMD_AUTO_POWER_PARAM_T), (PUINT_8) prAutoPwrParam, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update TX power gain corresponding to
+*        each band/modulation combination
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        prTxPwrParam       Pointer of TX power parameters
+*
+* @retval WLAN_STATUS_PENDING
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicSetAutoTxPowerControl(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam)
+{
+	DEBUGFUNC("nicUpdateTxPower");
+
+	ASSERT(prAdapter);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_TX_PWR,
+				   TRUE,
+				   FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update power offset around 5GHz band
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        pr5GPwrOffset      Pointer of 5GHz power offset parameter
+*
+* @retval WLAN_STATUS_PENDING
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset)
+{
+	DEBUGFUNC("nicUpdate5GOffset");
+
+	ASSERT(prAdapter);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_5G_PWR_OFFSET,
+				   TRUE,
+				   FALSE,
+				   FALSE, NULL, NULL, sizeof(CMD_5G_PWR_OFFSET_T), (PUINT_8) pr5GPwrOffset, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update DPD calibration result
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*        pr5GPwrOffset      Pointer of parameter for DPD calibration result
+*
+* @retval WLAN_STATUS_PENDING
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult)
+{
+	DEBUGFUNC("nicUpdateDPD");
+
+	ASSERT(prAdapter);
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_PWR_PARAM,
+				   TRUE,
+				   FALSE,
+				   FALSE, NULL, NULL, sizeof(CMD_PWR_PARAM_T), (PUINT_8) prDpdCalResult, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function starts system service such as timer and
+*        memory pools
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	/* <1> Initialize MGMT Memory pool and STA_REC */
+	cnmMemInit(prAdapter);
+	cnmStaRecInit(prAdapter);
+	cmdBufInitialize(prAdapter);
+
+	/* <2> Mailbox Initialization */
+	mboxInitialize(prAdapter);
+
+	/* <3> Timer Initialization */
+	cnmTimerInitialize(prAdapter);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function reset some specific system service,
+*        such as STA-REC
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update WMM Parms
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	/* Timer Destruction */
+	cnmTimerDestroy(prAdapter);
+
+	/* Mailbox Destruction */
+	mboxDestroy(prAdapter);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update WMM Parms
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo)
+{
+	ASSERT(prAdapter);
+
+	/* CNM Module - initialization */
+	cnmInit(prAdapter);
+
+	/* RLM Module - initialization */
+	rlmFsmEventInit(prAdapter);
+
+	/* SCN Module - initialization */
+	scnInit(prAdapter);
+
+	/* AIS Module - intiailization */
+	aisInitializeConnectionSettings(prAdapter, prRegInfo);
+	aisFsmInit(prAdapter);
+
+#if CFG_SUPPORT_ROAMING
+	/* Roaming Module - intiailization */
+	roamingFsmInit(prAdapter);
+#endif /* CFG_SUPPORT_ROAMING */
+
+#if CFG_SUPPORT_SWCR
+	swCrDebugInit(prAdapter);
+#endif /* CFG_SUPPORT_SWCR */
+
+#if (CFG_SUPPORT_TDLS == 1)
+	TdlsexInit(prAdapter);
+#endif /* CFG_SUPPORT_TDLS */
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to update WMM Parms
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+#if CFG_SUPPORT_SWCR
+	swCrDebugUninit(prAdapter);
+#endif /* CFG_SUPPORT_SWCR */
+
+#if CFG_SUPPORT_ROAMING
+	/* Roaming Module - unintiailization */
+	roamingFsmUninit(prAdapter);
+#endif /* CFG_SUPPORT_ROAMING */
+
+	/* AIS Module - unintiailization */
+	aisFsmUninit(prAdapter);
+
+	/* SCN Module - unintiailization */
+	scnUninit(prAdapter);
+
+	/* RLM Module - uninitialization */
+	rlmFsmEventUninit(prAdapter);
+
+	/* CNM Module - uninitialization */
+	cnmUninit(prAdapter);
+
+#if (CFG_SUPPORT_TDLS == 1)
+	TdlsexUninit(prAdapter);
+#endif /* CFG_SUPPORT_TDLS */
+
+}
+
+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is to inform firmware to enable MCU clock gating
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i, u4WHISR = 0;
+
+	ASSERT(prAdapter);
+
+	if (prAdapter->fgIsClockGatingEnabled == TRUE)
+		return WLAN_STATUS_SUCCESS;
+
+	nicSetSwIntr(prAdapter, REQ_GATING_ENABLE_H2D_INT);
+
+	i = 0;
+	while (i < GATING_CONTROL_POLL_LIMIT) {
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE)
+			return WLAN_STATUS_FAILURE;
+
+		HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR);
+
+		if (u4WHISR & ACK_GATING_ENABLE_D2H_INT) {
+			prAdapter->fgIsClockGatingEnabled = TRUE;
+			return WLAN_STATUS_SUCCESS;
+		}
+	}
+
+	ASSERT(0);
+	return WLAN_STATUS_PENDING;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is to inform firmware to disable MCU clock gating
+*
+* @param prAdapter          Pointer of ADAPTER_T
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i, u4WHISR = 0;
+
+	ASSERT(prAdapter);
+
+	if (prAdapter->fgIsClockGatingEnabled == FALSE)
+		return WLAN_STATUS_SUCCESS;
+
+	nicSetSwIntr(prAdapter, REQ_GATING_DISABLE_H2D_INT);
+
+	i = 0;
+	while (i < GATING_CONTROL_POLL_LIMIT) {
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE)
+			return WLAN_STATUS_FAILURE;
+
+		HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR);
+
+		if (u4WHISR & ACK_GATING_DISABLE_D2H_INT) {
+			prAdapter->fgIsClockGatingEnabled = FALSE;
+			return WLAN_STATUS_SUCCESS;
+		}
+	}
+
+	ASSERT(0);
+	return WLAN_STATUS_PENDING;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is invoked to buffer scan result
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param rMacAddr           BSSID
+* @param prSsid             Pointer to SSID
+* @param u4Privacy          Privacy settings (0: Open / 1: WEP/WPA/WPA2 enabled)
+* @param rRssi              Received Strength (-10 ~ -200 dBm)
+* @param eNetworkType       Network Type (a/b/g)
+* @param prConfiguration    Network Parameter
+* @param eOpMode            Infra/Ad-Hoc
+* @param rSupportedRates    Supported basic rates
+* @param u2IELength         IE Length
+* @param pucIEBuf           Pointer to Information Elements(IEs)
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+nicAddScanResult(IN P_ADAPTER_T prAdapter,
+		 IN PARAM_MAC_ADDRESS rMacAddr,
+		 IN P_PARAM_SSID_T prSsid,
+		 IN UINT_32 u4Privacy,
+		 IN PARAM_RSSI rRssi,
+		 IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType,
+		 IN P_PARAM_802_11_CONFIG_T prConfiguration,
+		 IN ENUM_PARAM_OP_MODE_T eOpMode,
+		 IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf)
+{
+	BOOLEAN bReplace;
+	UINT_32 i;
+	UINT_32 u4IdxWeakest = 0;
+	PARAM_RSSI rWeakestRssi;
+	UINT_32 u4BufferSize;
+
+	ASSERT(prAdapter);
+
+	rWeakestRssi = (PARAM_RSSI) INT_MAX;
+	u4BufferSize = sizeof(prAdapter->rWlanInfo.aucScanIEBuf) / sizeof(prAdapter->rWlanInfo.aucScanIEBuf[0]);
+
+	bReplace = FALSE;
+
+	/* decide to replace or add */
+	for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
+		/* find weakest entry && not connected one */
+		if (UNEQUAL_MAC_ADDR
+		    (prAdapter->rWlanInfo.arScanResult[i].arMacAddress, prAdapter->rWlanInfo.rCurrBssId.arMacAddress)
+		    && prAdapter->rWlanInfo.arScanResult[i].rRssi < rWeakestRssi) {
+			u4IdxWeakest = i;
+			rWeakestRssi = prAdapter->rWlanInfo.arScanResult[i].rRssi;
+		}
+
+		if (prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode &&
+		    EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo.arScanResult[i].arMacAddress), rMacAddr) &&
+		    (EQUAL_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
+				prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
+				prSsid->aucSsid, prSsid->u4SsidLen)
+		     || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == 0)) {
+			/* replace entry */
+			bReplace = TRUE;
+
+			/* free IE buffer then zero */
+			nicFreeScanResultIE(prAdapter, i);
+			kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
+
+			/* then fill buffer */
+			prAdapter->rWlanInfo.arScanResult[i].u4Length =
+			    OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength;
+			COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr);
+			COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
+				  prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
+				  prSsid->aucSsid, prSsid->u4SsidLen);
+			prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy;
+			prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi;
+			prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType;
+			kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration),
+				   prConfiguration, sizeof(PARAM_802_11_CONFIG_T));
+			prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode;
+			kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates),
+				   rSupportedRates, sizeof(PARAM_RATES_EX));
+			prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength;
+
+			/* IE - allocate buffer and update pointer */
+			if (u2IELength > 0) {
+				if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) {
+					kalMemCopy(&
+						   (prAdapter->
+						    rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]),
+						   pucIEBuf, u2IELength);
+
+					prAdapter->rWlanInfo.apucScanResultIEs[i] =
+					    &(prAdapter->
+					      rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]);
+
+					prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength);
+				} else {
+					/* buffer is not enough */
+					prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength;
+					prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0;
+					prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
+				}
+			} else {
+				prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
+			}
+
+			break;
+		}
+	}
+
+	if (bReplace == FALSE) {
+		if (prAdapter->rWlanInfo.u4ScanResultNum < (CFG_MAX_NUM_BSS_LIST - 1)) {
+			i = prAdapter->rWlanInfo.u4ScanResultNum;
+
+			/* zero */
+			kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
+
+			/* then fill buffer */
+			prAdapter->rWlanInfo.arScanResult[i].u4Length =
+			    OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength;
+			COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr);
+			COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
+				  prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
+				  prSsid->aucSsid, prSsid->u4SsidLen);
+			prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy;
+			prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi;
+			prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType;
+			kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration),
+				   prConfiguration, sizeof(PARAM_802_11_CONFIG_T));
+			prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode;
+			kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates),
+				   rSupportedRates, sizeof(PARAM_RATES_EX));
+			prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength;
+
+			/* IE - allocate buffer and update pointer */
+			if (u2IELength > 0) {
+				if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) {
+					kalMemCopy(&
+						   (prAdapter->
+						    rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]),
+						   pucIEBuf, u2IELength);
+
+					prAdapter->rWlanInfo.apucScanResultIEs[i] =
+					    &(prAdapter->
+					      rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]);
+
+					prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength);
+				} else {
+					/* buffer is not enough */
+					prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength;
+					prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0;
+					prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
+				}
+			} else {
+				prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
+			}
+
+			prAdapter->rWlanInfo.u4ScanResultNum++;
+		} else if (rWeakestRssi != (PARAM_RSSI) INT_MAX) {
+			/* replace weakest one */
+			i = u4IdxWeakest;
+
+			/* free IE buffer then zero */
+			nicFreeScanResultIE(prAdapter, i);
+			kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
+
+			/* then fill buffer */
+			prAdapter->rWlanInfo.arScanResult[i].u4Length =
+			    OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength;
+			COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr);
+			COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
+				  prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
+				  prSsid->aucSsid, prSsid->u4SsidLen);
+			prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy;
+			prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi;
+			prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType;
+			kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration),
+				   prConfiguration, sizeof(PARAM_802_11_CONFIG_T));
+			prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode;
+			kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates),
+				   rSupportedRates, sizeof(PARAM_RATES_EX));
+			prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength;
+
+			if (u2IELength > 0) {
+				/* IE - allocate buffer and update pointer */
+				if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) {
+					kalMemCopy(&
+						   (prAdapter->
+						    rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]),
+						   pucIEBuf, u2IELength);
+
+					prAdapter->rWlanInfo.apucScanResultIEs[i] =
+					    &(prAdapter->
+					      rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]);
+
+					prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength);
+				} else {
+					/* buffer is not enough */
+					prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength;
+					prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0;
+					prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
+				}
+			} else {
+				prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
+			}
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is invoked to free IE buffer for dedicated scan result
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param u4Idx              Index of Scan Result
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx)
+{
+	UINT_32 i;
+	PUINT_8 pucPivot, pucMovePivot;
+	UINT_32 u4MoveSize, u4FreeSize, u4ReserveSize;
+
+	ASSERT(prAdapter);
+	ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST);
+
+	if (prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0
+	    || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) {
+		return;
+	}
+
+	u4FreeSize = ALIGN_4(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength);
+
+	pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx];
+	pucMovePivot = (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize);
+
+	u4ReserveSize = ((ULONG) pucPivot) - (ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0]));
+	u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - u4ReserveSize - u4FreeSize;
+
+	/* 1. rest of buffer to move forward */
+	kalMemCopy(pucPivot, pucMovePivot, u4MoveSize);
+
+	/* 1.1 modify pointers */
+	for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
+		if (i != u4Idx) {
+			if (prAdapter->rWlanInfo.apucScanResultIEs[i] >= pucMovePivot) {
+				prAdapter->rWlanInfo.apucScanResultIEs[i] =
+				    (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[i]) - u4FreeSize);
+			}
+		}
+	}
+
+	/* 1.2 reset the freed one */
+	prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0;
+	prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
+
+	/* 2. reduce IE buffer usage */
+	prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is to hack parameters for WLAN TABLE for
+*        fixed rate settings
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param eRateSetting
+* @param pu2DesiredNonHTRateSet,
+* @param pu2BSSBasicRateSet,
+* @param pucMcsSet
+* @param pucSupMcs32
+* @param pu2HtCapInfo
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+nicUpdateRateParams(IN P_ADAPTER_T prAdapter,
+		    IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting,
+		    IN PUINT_8 pucDesiredPhyTypeSet,
+		    IN PUINT_16 pu2DesiredNonHTRateSet,
+		    IN PUINT_16 pu2BSSBasicRateSet,
+		    IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 pu2HtCapInfo)
+{
+	ASSERT(prAdapter);
+	ASSERT(eRateSetting > FIXED_RATE_NONE && eRateSetting < FIXED_RATE_NUM);
+
+	switch (prAdapter->rWifiVar.eRateSetting) {
+	case FIXED_RATE_1M:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_1M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_1M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_2M:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_2M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_2M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_5_5M:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_5_5M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_11M:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_11M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_11M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_6M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_6M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_6M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_9M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_9M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_9M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_12M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_12M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_12M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_18M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_18M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_18M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_24M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_24M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_24M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_36M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_36M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_36M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_48M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_48M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_48M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_54M:
+		if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
+		else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM)
+			*pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
+
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_54M;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_54M;
+		*pucMcsSet = 0;
+		*pucSupMcs32 = 0;
+		*pu2HtCapInfo = 0;
+		break;
+
+	case FIXED_RATE_MCS0_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS0_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS1_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS1_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS2_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS2_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS3_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS3_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS4_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS4_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS5_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS5_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS6_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS6_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS7_20M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS7_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
+				     | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		break;
+
+	case FIXED_RATE_MCS0_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS0_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS1_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS1_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS2_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS2_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS3_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS3_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS4_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS4_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS5_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS5_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS6_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS6_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS7_20M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS7_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
+		break;
+
+	case FIXED_RATE_MCS0_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS0_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS1_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS1_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS2_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS2_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS3_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS3_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS4_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS4_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS5_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS5_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS6_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS6_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS7_40M_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS7_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS32_800NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS32_INDEX;
+		*pucSupMcs32 = 1;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
+		break;
+
+	case FIXED_RATE_MCS0_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS0_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS1_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS1_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS2_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS2_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS3_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS3_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS4_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS4_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS5_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS5_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS6_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS6_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS7_40M_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS7_INDEX;
+		*pucSupMcs32 = 0;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	case FIXED_RATE_MCS32_400NS:
+		*pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
+		*pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
+		*pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
+		*pucMcsSet = HT_RATE_MCS32_INDEX;
+		*pucSupMcs32 = 1;
+		(*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF);
+		(*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M);
+		break;
+
+	default:
+		ASSERT(0);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to write the register
+*
+* @param u4Address         Register address
+*        u4Value           the value to be written
+*
+* @retval WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*/
+/*----------------------------------------------------------------------------*/
+
+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value)
+{
+	CMD_ACCESS_REG rCmdAccessReg;
+
+	rCmdAccessReg.u4Address = u4Address;
+	rCmdAccessReg.u4Data = u4Value;
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_ACCESS_REG,
+				   TRUE,
+				   FALSE,
+				   FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8) &rCmdAccessReg, NULL, 0);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to modify the auto rate parameters
+*
+* @param u4ArSysParam0  see description below
+*        u4ArSysParam1
+*        u4ArSysParam2
+*        u4ArSysParam3
+*
+*
+* @retval WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*
+* @note
+*   ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2)
+*   ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2)
+*   ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2)
+*   ArSysParam0[8:15]-> HT rate clear mask
+*   ArSysParam0[16:31]-> Legacy rate clear mask
+*   ArSysParam1[0:7]-> Auto Rate check weighting window
+*   ArSysParam1[8:15]-> Auto Rate v1 Force Rate down
+*   ArSysParam1[16:23]-> Auto Rate v1 PerH
+*   ArSysParam1[24:31]-> Auto Rate v1 PerL
+*
+*   Examples
+*   ArSysParam0 = 1,
+*   Enable auto rate version 1
+*
+*   ArSysParam0 = 983041,
+*   Enable auto rate version 1
+*   Remove CCK 1M, 2M, 5.5M, 11M
+*
+*   ArSysParam0 = 786433
+*   Enable auto rate version 1
+*   Remove CCK 5.5M 11M
+*/
+/*----------------------------------------------------------------------------*/
+
+WLAN_STATUS
+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter,
+		    IN UINT_32 u4ArSysParam0,
+		    IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3)
+{
+	UINT_8 ucArVer, ucAbwVer, ucAgiVer;
+	UINT_16 u2HtClrMask;
+	UINT_16 u2LegacyClrMask;
+	UINT_8 ucArCheckWindow;
+	UINT_8 ucArPerL;
+	UINT_8 ucArPerH;
+	UINT_8 ucArPerForceRateDownPer;
+
+	ucArVer = (UINT_8) (u4ArSysParam0 & BITS(0, 3));
+	ucAbwVer = (UINT_8) ((u4ArSysParam0 & BITS(4, 5)) >> 4);
+	ucAgiVer = (UINT_8) ((u4ArSysParam0 & BITS(6, 7)) >> 6);
+	u2HtClrMask = (UINT_16) ((u4ArSysParam0 & BITS(8, 15)) >> 8);
+	u2LegacyClrMask = (UINT_16) ((u4ArSysParam0 & BITS(16, 31)) >> 16);
+
+#if 0
+	ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7));
+	ucArPerForceRateDownPer = (UINT_8) ((u4ArSysParam1 & BITS(8, 15) >> 8));
+	ucArPerH = (UINT_8) ((u4ArSysParam1 & BITS(16, 23)) >> 16);
+	ucArPerL = (UINT_8) ((u4ArSysParam1 & BITS(24, 31)) >> 24);
+#endif
+
+	ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7));
+	ucArPerForceRateDownPer = (UINT_8) (((u4ArSysParam1 >> 8) & BITS(0, 7)));
+	ucArPerH = (UINT_8) (((u4ArSysParam1 >> 16) & BITS(0, 7)));
+	ucArPerL = (UINT_8) (((u4ArSysParam1 >> 24) & BITS(0, 7)));
+
+	DBGLOG(NIC, INFO, "ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3);
+	DBGLOG(NIC, INFO, "ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer);
+	DBGLOG(NIC, INFO, "HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask);
+	DBGLOG(NIC, INFO,
+	       "CheckWin %u RateDownPer %u PerH %u PerL %u\n", ucArCheckWindow, ucArPerForceRateDownPer, ucArPerH,
+		ucArPerL);
+
+#define SWCR_DATA_ADDR(MOD, ADDR) (0x90000000+(MOD<<8)+(ADDR))
+#define SWCR_DATA_CMD(CATE, WRITE, INDEX, OPT0, OPT1) ((CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 << 8) | OPT1)
+#define SWCR_DATA0 0x0
+#define SWCR_DATA1 0x4
+#define SWCR_DATA2 0x8
+#define SWCR_DATA3 0xC
+#define SWCR_DATA4 0x10
+#define SWCR_WRITE 1
+#define SWCR_READ 0
+
+	if (ucArVer > 0) {
+		/* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */
+		/* dummy = WiFi.WriteMCR(&h90000100, &h00850000) */
+
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 1);
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0));
+	} else {
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 0);
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0));
+	}
+
+	/* ucArVer 0: none 1:PER 2:Rcpi */
+	nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArVer);
+	nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 7, 0, 0));
+
+	/* Candidate rate Ht mask */
+	nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2HtClrMask);
+	nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1c, 0, 0));
+
+	/* Candidate rate legacy mask */
+	nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2LegacyClrMask);
+	nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1d, 0, 0));
+
+#if 0
+	if (ucArCheckWindow != 0) {
+		/* TX DONE MCS INDEX CHECK STA RATE DOWN TH */
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow);
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x14, 0, 0));
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow);
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0xc, 0, 0));
+	}
+
+	if (ucArPerForceRateDownPer != 0) {
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerForceRateDownPer);
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x18, 0, 0));
+	}
+	if (ucArPerH != 0) {
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerH);
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1, 0, 0));
+	}
+	if (ucArPerL != 0) {
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerL);
+		nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x2, 0, 0));
+	}
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This utility function is used to enable roaming
+*
+* @param u4EnableRoaming
+*
+*
+* @retval WLAN_STATUS_SUCCESS
+*         WLAN_STATUS_FAILURE
+*
+* @note
+*   u4EnableRoaming -> Enable Romaing
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming)
+{
+	P_CONNECTION_SETTINGS_T prConnSettings;
+
+	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
+	prConnSettings->fgIsEnableRoaming = ((u4EnableRoaming > 0) ? (TRUE) : (FALSE));
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief dump firmware Assert message
+*
+* \param[in]
+*           prAdapter
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 u4MailBox0, u4MailBox1;
+	UINT_32 line = 0;
+	UINT_8 aucAssertFile[7];
+	UINT_32 u4ChipId;
+
+#if CFG_SDIO_INTR_ENHANCE
+	u4MailBox0 = prAdapter->prSDIOCtrl->u4RcvMailbox0;
+	u4MailBox1 = prAdapter->prSDIOCtrl->u4RcvMailbox1;
+#else
+	nicGetMailbox(prAdapter, 0, &u4MailBox0);
+	nicGetMailbox(prAdapter, 1, &u4MailBox1);
+#endif
+
+	line = u4MailBox0 & 0x0000FFFF;
+
+	u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF);
+
+	kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2);
+	kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4);
+
+	aucAssertFile[6] = '\0';
+
+#if defined(MT6620)
+	u4ChipId = 6620;
+#elif defined(MT6628)
+	u4ChipId = 6582;
+#endif
+
+	kalPrint("\n[MT%u][wifi][Firmware] Assert at \"%s\" #%u\n\n", u4ChipId, aucAssertFile, line);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to update Link Quality information
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*        eNetTypeIdx
+*        prEventLinkQuality
+*        cRssi
+*        cLinkQuality
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter,
+		     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality)
+{
+	ASSERT(prAdapter);
+	ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM);
+	ASSERT(prEventLinkQuality);
+
+	switch (eNetTypeIdx) {
+	case NETWORK_TYPE_AIS_INDEX:
+		if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+			/* check is to prevent RSSI to be updated by incorrect initial RSSI from hardware */
+			/* buffer statistics for further query */
+			if (prAdapter->fgIsLinkQualityValid == FALSE
+			    || (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) {
+				nicUpdateRSSI(prAdapter, eNetTypeIdx, prEventLinkQuality->cRssi,
+					      prEventLinkQuality->cLinkQuality);
+			}
+
+			if (prAdapter->fgIsLinkRateValid == FALSE
+			    || (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) {
+				nicUpdateLinkSpeed(prAdapter, eNetTypeIdx, prEventLinkQuality->u2LinkSpeed);
+			}
+		}
+		break;
+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY
+	case NETWORK_TYPE_P2P_INDEX:
+		if (prAdapter->fgIsP2pLinkQualityValid == FALSE
+		    || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) {
+			P_EVENT_LINK_QUALITY_EX prEventLQEx = (P_EVENT_LINK_QUALITY_EX) prEventLinkQuality;
+
+			nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, prEventLQEx->cRssiP2P,
+				      prEventLQEx->cLinkQualityP2P);
+		}
+		break;
+#endif
+	default:
+		break;
+
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to update RSSI and Link Quality information
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*        eNetTypeIdx
+*        cRssi
+*        cLinkQuality
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+nicUpdateRSSI(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality)
+{
+	ASSERT(prAdapter);
+	ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	switch (eNetTypeIdx) {
+	case NETWORK_TYPE_AIS_INDEX:
+		if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+			prAdapter->fgIsLinkQualityValid = TRUE;
+			prAdapter->rLinkQualityUpdateTime = kalGetTimeTick();
+
+			prAdapter->rLinkQuality.cRssi = cRssi;
+			prAdapter->rLinkQuality.cLinkQuality = cLinkQuality;
+
+			/* indicate to glue layer */
+			kalUpdateRSSI(prAdapter->prGlueInfo,
+				      KAL_NETWORK_TYPE_AIS_INDEX,
+				      prAdapter->rLinkQuality.cRssi, prAdapter->rLinkQuality.cLinkQuality);
+		}
+
+		break;
+#if CFG_ENABLE_WIFI_DIRECT
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+	case NETWORK_TYPE_P2P_INDEX:
+		prAdapter->fgIsP2pLinkQualityValid = TRUE;
+		prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick();
+
+		prAdapter->rP2pLinkQuality.cRssi = cRssi;
+		prAdapter->rP2pLinkQuality.cLinkQuality = cLinkQuality;
+
+		kalUpdateRSSI(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_P2P_INDEX, cRssi, cLinkQuality);
+		break;
+#endif
+#endif
+	default:
+		break;
+
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called to update Link Quality information
+*
+* @param prAdapter      Pointer of Adapter Data Structure
+*        eNetTypeIdx
+*        prEventLinkQuality
+*        cRssi
+*        cLinkQuality
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed)
+{
+	ASSERT(prAdapter);
+	ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM);
+
+	switch (eNetTypeIdx) {
+	case NETWORK_TYPE_AIS_INDEX:
+		if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+			/* buffer statistics for further query */
+			prAdapter->fgIsLinkRateValid = TRUE;
+			prAdapter->rLinkRateUpdateTime = kalGetTimeTick();
+
+			prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed;
+		}
+		break;
+
+	default:
+		break;
+
+	}
+
+}
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam)
+{
+	DEBUGFUNC("nicUpdateRddTestMode.\n");
+
+	ASSERT(prAdapter);
+
+/* aisFsmScanRequest(prAdapter, NULL); */
+
+	return wlanSendSetQueryCmd(prAdapter,
+				   CMD_ID_SET_RDD_CH,
+				   TRUE,
+				   FALSE, FALSE, NULL, NULL, sizeof(CMD_RDD_CH_T), (PUINT_8) prRddChParam, NULL, 0);
+}
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c
new file mode 100644
index 0000000000000..3c9c24f9542bc
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c
@@ -0,0 +1,1636 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_cmd_event.c#1
+*/
+
+/*! \file   nic_cmd_event.c
+    \brief  Callback functions for Command packets.
+
+	Various Event packet handlers which will be setup in the callback function of
+    a command packet.
+*/
+
+/*
+** Log: nic_cmd_event.c
+ *
+ * 04 10 2012 yuche.tsai
+ * NULL
+ * Update address for wifi direct connection issue.
+ *
+ * 06 15 2011 cm.chang
+ * [WCXRP00000785] [MT6620 Wi-Fi][Driver][FW] P2P/BOW MAC address is XOR with AIS MAC address
+ * P2P/BOW mac address XOR with local bit instead of OR
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add security check code.
+ *
+ * 02 24 2011 cp.wu
+ * [WCXRP00000493] [MT6620 Wi-Fi][Driver] Do not indicate redundant disconnection to host when entering into RF
+ * test mode
+ * only indicate DISCONNECTION to host when entering RF test if necessary (connected -> disconnected cases)
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Add Oid for sw control debug command
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to
+ * system scheduling
+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
+ * loaded
+ *
+ * 12 01 2010 cp.wu
+ * [WCXRP00000223] MT6620 Wi-Fi][Driver][FW] Adopt NVRAM parameters when enter/exit RF test mode
+ * reload NVRAM settings before entering RF test mode and leaving from RF test mode.
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 20 2010 cp.wu
+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
+ * use OID_CUSTOM_TEST_MODE as indication for driver reset
+ * by dropping pending TX packets
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
+ * The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
+ * associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 15 2010 yuche.tsai
+ * NULL
+ * Start to test AT GO only when P2P state is not IDLE.
+ *
+ * 09 09 2010 yuche.tsai
+ * NULL
+ * Add AT GO Test mode after MAC address available.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
+ * There is no CFG_SUPPORT_BOW in driver domain source.
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
+ *
+ * 08 11 2010 yuche.tsai
+ * NULL
+ * Add support for P2P Device Address query from FW.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * Centralize mgmt/system service procedures into independent calls.
+ *
+ * 08 02 2010 cp.wu
+ * NULL
+ * reset FSMs before entering RF test mode.
+ *
+ * 07 22 2010 cp.wu
+ *
+ * 1) refine AIS-FSM indent.
+ * 2) when entering RF Test mode, flush 802.1X frames as well
+ * 3) when entering D3 state, flush 802.1X frames as well
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 05 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet.
+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * remove duplicate variable for migration.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 29 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change upon request: indicate as disconnected in driver domain when leaving from RF test mode
+ *
+ * 05 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * do not clear scanning list array after disassociation
+ *
+ * 05 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally.
+ * 2) finish statistics OIDs
+ *
+ * 05 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * change OID behavior to meet WHQL requirement.
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) do not take timeout mechanism for power mode oids
+ * 2) retrieve network type from connection status
+ * 3) after disassciation, set radio state to off
+ * 4) TCP option over IPv6 is supported
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct OID_802_11_DISASSOCIATE handling.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 04 16 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * treat BUS access failure as kind of card removal.
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * information buffer for query oid/ioctl is now buffered in prCmdInfo
+ *  *  *  *  *  * instead of glue-layer variable to improve multiple oid/ioctl capability
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * accessing to firmware load/start address, and access to OID handling information
+ * are now handled in glue layer
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  *  * are done in adapter layer.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer.
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glude code portability
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * sync statistics data structure definition with firmware implementation
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * statistics information OIDs are now handled by querying from firmware domain
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * indicate media stream mode after set is done
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement custom OID: EEPROM read/write access
+ *
+ * 03 03 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_3_MULTICAST_LIST oid handling
+ *
+ * 02 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * limit RSSI return value to micxxsoft defined range.
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  *  *  *  *  *  * 2. follow MSDN defined behavior when associates to another AP
+ *  *  *  *  *  *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 01 29 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * block until firmware finished RF test enter/leave then indicate completion to upper layer
+ *
+ * 01 29 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * when entering RF test mode and leaving from RF test mode, wait for W_FUNC_RDY bit to be asserted forever until it
+ * is set or card is removed.
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  *  *  *  *  *  *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  *  *  *  *  *  *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  *  *  *  *  *  *  * 4. correct some HAL implementation
+ *
+ * 01 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer
+ *
+ * 01 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement following 802.11 OIDs:
+ *  *  *  *  * OID_802_11_RSSI,
+ *  *  *  *  * OID_802_11_RSSI_TRIGGER,
+ *  *  *  *  * OID_802_11_STATISTICS,
+ *  *  *  *  * OID_802_11_DISASSOCIATE,
+ *  *  *  *  * OID_802_11_POWER_MODE
+ *
+ * 01 21 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement OID_802_11_MEDIA_STREAM_MODE
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  *  *  *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  *  *  *  *  *  * and result is retrieved by get ATInfo instead
+ *  *  *  *  *  *  *  * 2) add 4 counter for recording aggregation statistics
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:47:47 GMT mtk02752
+**  only handle MCR read when accessing FW domain register
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 17:37:28 GMT mtk02752
+**  * refine nicCmdEventQueryMcrRead
+**  + add TxStatus/RxStatus for RF test QueryInformation OIDs
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 22:05:45 GMT mtk02752
+**  kalOidComplete() will decrease i4OidPendingCount
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-01 23:02:57 GMT mtk02752
+**  remove unnecessary spin locks
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-01 22:51:18 GMT mtk02752
+**  maintein i4OidPendingCount
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-30 10:55:03 GMT mtk02752
+**  modify for compatibility
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 14:46:32 GMT mtk02752
+**  add another version of command-done handler upon new event structure
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:33 GMT mtk01461
+**  Add comment
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 19:32:42 GMT mtk01461
+**  Add nicCmdEventSetCommon() for general set OID
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:35 GMT mtk01461
+**  Command Done Handler
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo;
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_ACCESS_REG prCmdAccessReg;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prCmdAccessReg = (P_CMD_ACCESS_REG) (pucEventBuf);
+
+		u4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T);
+
+		prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) prCmdInfo->pvInformationBuffer;
+		prMcrRdInfo->u4McrOffset = prCmdAccessReg->u4Address;
+		prMcrRdInfo->u4McrData = prCmdAccessReg->u4Data;
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+	return;
+
+}
+
+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo;
+	P_GLUE_INFO_T prGlueInfo;
+	P_CMD_SW_DBG_CTRL_T prCmdSwCtrl;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prCmdSwCtrl = (P_CMD_SW_DBG_CTRL_T) (pucEventBuf);
+
+		u4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T);
+
+		prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) prCmdInfo->pvInformationBuffer;
+		prSwCtrlInfo->u4Id = prCmdSwCtrl->u4Id;
+		prSwCtrlInfo->u4Data = prCmdSwCtrl->u4Data;
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+	return;
+
+}
+
+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	if (prCmdInfo->fgIsOid) {
+		/* Update Set Information Length */
+		kalOidComplete(prAdapter->prGlueInfo,
+			       prCmdInfo->fgSetQuery, prCmdInfo->u4InformationBufferLength, WLAN_STATUS_SUCCESS);
+	}
+
+}
+
+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	if (prCmdInfo->fgIsOid) {
+		/* Update Set Information Length */
+		kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
+	}
+
+	DBGLOG(NIC, TRACE, "DisByCmdE\n");
+	kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+
+#if !defined(LINUX)
+	prAdapter->fgIsRadioOff = TRUE;
+#endif
+
+}
+
+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4Count;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	u4Count = (prCmdInfo->u4SetInfoLen - OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress))
+	    / sizeof(IPV4_NETWORK_ADDRESS);
+
+	if (prCmdInfo->fgIsOid) {
+		/* Update Set Information Length */
+		kalOidComplete(prAdapter->prGlueInfo,
+			       prCmdInfo->fgSetQuery,
+			       OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress) + u4Count *
+			       (OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP)),
+			       WLAN_STATUS_SUCCESS);
+	}
+
+}
+
+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_TEST_STATUS prTestStatus, prQueryBuffer;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prTestStatus = (P_EVENT_TEST_STATUS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prQueryBuffer = (P_EVENT_TEST_STATUS) prCmdInfo->pvInformationBuffer;
+
+		kalMemCopy(prQueryBuffer, prTestStatus, sizeof(EVENT_TEST_STATUS));
+
+		u4QueryInfoLen = sizeof(EVENT_TEST_STATUS);
+
+		/* Update Query Information Length */
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+}
+
+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	PARAM_RSSI rRssi, *prRssi;
+	P_EVENT_LINK_QUALITY prLinkQuality;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf;
+
+	rRssi = (PARAM_RSSI) prLinkQuality->cRssi;	/* ranged from (-128 ~ 30) in unit of dBm */
+	DBGLOG(NIC, INFO, "<rxm> %s: rRssi = %d\n", __func__, rRssi);
+
+	if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
+		if (rRssi > PARAM_WHQL_RSSI_MAX_DBM)
+			rRssi = PARAM_WHQL_RSSI_MAX_DBM;
+		else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM)
+			rRssi = PARAM_WHQL_RSSI_MIN_DBM;
+	} else {
+		rRssi = PARAM_WHQL_RSSI_MIN_DBM;
+	}
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prRssi = (PARAM_RSSI *) prCmdInfo->pvInformationBuffer;
+
+		kalMemCopy(prRssi, &rRssi, sizeof(PARAM_RSSI));
+		u4QueryInfoLen = sizeof(PARAM_RSSI);
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This routine is in response of OID_GEN_LINK_SPEED query request
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param prCmdInfo      Pointer to the pending command info
+* @param pucEventBuf
+*
+* @retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_LINK_QUALITY prLinkQuality;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4LinkSpeed;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		pu4LinkSpeed = (PUINT_32) (prCmdInfo->pvInformationBuffer);
+
+		*pu4LinkSpeed = prLinkQuality->u2LinkSpeed * 5000;
+
+		u4QueryInfoLen = sizeof(UINT_32);
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics;
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		u4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+		prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) prCmdInfo->pvInformationBuffer;
+
+		prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T);
+		prStatistics->rTransmittedFragmentCount = prEventStatistics->rTransmittedFragmentCount;
+		prStatistics->rMulticastTransmittedFrameCount = prEventStatistics->rMulticastTransmittedFrameCount;
+		prStatistics->rFailedCount = prEventStatistics->rFailedCount;
+		prStatistics->rRetryCount = prEventStatistics->rRetryCount;
+		prStatistics->rMultipleRetryCount = prEventStatistics->rMultipleRetryCount;
+		prStatistics->rRTSSuccessCount = prEventStatistics->rRTSSuccessCount;
+		prStatistics->rRTSFailureCount = prEventStatistics->rRTSFailureCount;
+		prStatistics->rACKFailureCount = prEventStatistics->rACKFailureCount;
+		prStatistics->rFrameDuplicateCount = prEventStatistics->rFrameDuplicateCount;
+		prStatistics->rReceivedFragmentCount = prEventStatistics->rReceivedFragmentCount;
+		prStatistics->rMulticastReceivedFrameCount = prEventStatistics->rMulticastReceivedFrameCount;
+		prStatistics->rFCSErrorCount = prEventStatistics->rFCSErrorCount;
+		prStatistics->rTKIPLocalMICFailures.QuadPart = 0;
+		prStatistics->rTKIPICVErrors.QuadPart = 0;
+		prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0;
+		prStatistics->rTKIPReplays.QuadPart = 0;
+		prStatistics->rCCMPFormatErrors.QuadPart = 0;
+		prStatistics->rCCMPReplays.QuadPart = 0;
+		prStatistics->rCCMPDecryptErrors.QuadPart = 0;
+		prStatistics->rFourWayHandshakeFailures.QuadPart = 0;
+		prStatistics->rWEPUndecryptableCount.QuadPart = 0;
+		prStatistics->rWEPICVErrorCount.QuadPart = 0;
+		prStatistics->rDecryptSuccessCount.QuadPart = 0;
+		prStatistics->rDecryptFailureCount.QuadPart = 0;
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+#define WAIT_FW_READY_RETRY_CNT 200
+
+	UINT_32 u4WHISR = 0, u4Value = 0;
+	UINT_8 aucTxCount[8];
+	UINT_16 u2RetryCnt = 0;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	/* [driver-land] */
+	prAdapter->fgTestMode = TRUE;
+
+	/* 0. always indicate disconnection */
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED)
+		kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+	/* 1. Remove pending TX */
+	nicTxRelease(prAdapter);
+
+	/* 1.1 clear pending Security / Management Frames */
+	kalClearSecurityFrames(prAdapter->prGlueInfo);
+	kalClearMgmtFrames(prAdapter->prGlueInfo);
+
+	/* 1.2 clear pending TX packet queued in glue layer */
+	kalFlushPendingTxPackets(prAdapter->prGlueInfo);
+
+	/* 2. Reset driver-domain FSMs */
+	nicUninitMGMT(prAdapter);
+
+	nicResetSystemService(prAdapter);
+	nicInitMGMT(prAdapter, NULL);
+
+	/* 3. Disable Interrupt */
+	HAL_INTR_DISABLE(prAdapter);
+
+	/* 4. Block til firmware completed entering into RF test mode */
+	kalMsleep(500);
+	while (1) {
+		HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
+
+		if (u4Value & WCIR_WLAN_READY) {
+			break;
+		} else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE ||
+			kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) {
+			if (prCmdInfo->fgIsOid) {
+				/* Update Set Information Length */
+				kalOidComplete(prAdapter->prGlueInfo,
+					       prCmdInfo->fgSetQuery,
+					       prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED);
+
+			}
+			return;
+		}
+		kalMsleep(10);
+		u2RetryCnt++;
+	}
+
+	/* 5. Clear Interrupt Status */
+	HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR);
+	if (HAL_IS_TX_DONE_INTR(u4WHISR))
+		HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount);
+	/* 6. Reset TX Counter */
+	nicTxResetResource(prAdapter);
+
+	/* 7. Re-enable Interrupt */
+	HAL_INTR_ENABLE(prAdapter);
+
+	/* 8. completion indication */
+	if (prCmdInfo->fgIsOid) {
+		/* Update Set Information Length */
+		kalOidComplete(prAdapter->prGlueInfo,
+			       prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS);
+	}
+#if CFG_SUPPORT_NVRAM
+	/* 9. load manufacture data */
+	wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo));
+#endif
+
+}
+
+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+#define WAIT_FW_READY_RETRY_CNT 200
+
+	UINT_32 u4WHISR = 0, u4Value = 0;
+	UINT_8 aucTxCount[8];
+	UINT_16 u2RetryCnt = 0;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	/* 1. Disable Interrupt */
+	HAL_INTR_DISABLE(prAdapter);
+
+	/* 2. Block til firmware completed leaving from RF test mode */
+	kalMsleep(500);
+	while (1) {
+		HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
+
+		if (u4Value & WCIR_WLAN_READY) {
+			break;
+		} else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE ||
+				kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) {
+			if (prCmdInfo->fgIsOid) {
+				/* Update Set Information Length */
+				kalOidComplete(prAdapter->prGlueInfo,
+					       prCmdInfo->fgSetQuery,
+					       prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED);
+
+			}
+			return;
+		}
+		kalMsleep(10);
+		u2RetryCnt++;
+	}
+
+	/* 3. Clear Interrupt Status */
+	HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR);
+	if (HAL_IS_TX_DONE_INTR(u4WHISR))
+		HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount);
+	/* 4. Reset TX Counter */
+	nicTxResetResource(prAdapter);
+
+	/* 5. Re-enable Interrupt */
+	HAL_INTR_ENABLE(prAdapter);
+
+	/* 6. set driver-land variable */
+	prAdapter->fgTestMode = FALSE;
+
+	/* 7. completion indication */
+	if (prCmdInfo->fgIsOid) {
+		/* Update Set Information Length */
+		kalOidComplete(prAdapter->prGlueInfo,
+			       prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+	/* 8. Indicate as disconnected */
+	if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) {
+
+		kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+
+		prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
+	}
+#if CFG_SUPPORT_NVRAM
+	/* 9. load manufacture data */
+	wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo));
+#endif
+
+	/* 10. Override network address */
+	wlanUpdateNetworkAddress(prAdapter);
+
+}
+
+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_GLUE_INFO_T prGlueInfo;
+	P_EVENT_BASIC_CONFIG prEventBasicConfig;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (pucEventBuf);
+
+	/* copy to adapter */
+	kalMemCopy(&(prAdapter->rMyMacAddr), &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		kalMemCopy(prCmdInfo->pvInformationBuffer, &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN);
+		u4QueryInfoLen = MAC_ADDR_LEN;
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+	/* 4 <3> Update new MAC address and all 3 networks */
+	COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, prAdapter->rMyMacAddr);
+	COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, prAdapter->rMyMacAddr);
+	prAdapter->rWifiVar.aucDeviceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN;
+
+	COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress, prAdapter->rMyMacAddr);
+	prAdapter->rWifiVar.aucInterfaceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN;
+
+	COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucOwnMacAddr, prAdapter->rMyMacAddr);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prAdapter->fgIsP2PRegistered) {
+		COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].aucOwnMacAddr,
+			      prAdapter->rWifiVar.aucDeviceAddress);
+	}
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].aucOwnMacAddr,
+		      prAdapter->rWifiVar.aucDeviceAddress);
+#endif
+
+#if CFG_TEST_WIFI_DIRECT_GO
+	if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_IDLE) {
+		wlanEnableP2pFunction(prAdapter);
+
+		wlanEnableATGO(prAdapter);
+	}
+#endif
+
+	kalUpdateMACAddress(prAdapter->prGlueInfo, prAdapter->rWifiVar.aucMacAddress);
+
+}
+
+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_GLUE_INFO_T prGlueInfo;
+	P_EVENT_MAC_MCAST_ADDR prEventMacMcastAddr;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEventMacMcastAddr = (P_EVENT_MAC_MCAST_ADDR) (pucEventBuf);
+
+		u4QueryInfoLen = prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN;
+
+		/* buffer length check */
+		if (prCmdInfo->u4InformationBufferLength < u4QueryInfoLen) {
+			kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_BUFFER_TOO_SHORT);
+		} else {
+			kalMemCopy(prCmdInfo->pvInformationBuffer,
+				   prEventMacMcastAddr->arAddress,
+				   prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN);
+
+			kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+		}
+	}
+}
+
+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRdInfo;
+	P_GLUE_INFO_T prGlueInfo;
+	P_EVENT_ACCESS_EEPROM prEventAccessEeprom;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEventAccessEeprom = (P_EVENT_ACCESS_EEPROM) (pucEventBuf);
+
+		u4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T);
+
+		prEepromRdInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) prCmdInfo->pvInformationBuffer;
+		prEepromRdInfo->ucEepromIndex = (UINT_8) (prEventAccessEeprom->u2Offset);
+		prEepromRdInfo->u2EepromData = prEventAccessEeprom->u2Data;
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+	return;
+
+}
+
+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	PARAM_MEDIA_STREAMING_INDICATION rParamMediaStreamIndication;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	if (prCmdInfo->fgIsOid) {
+		/* Update Set Information Length */
+		kalOidComplete(prAdapter->prGlueInfo,
+			       prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+	rParamMediaStreamIndication.rStatus.eStatusType = ENUM_STATUS_TYPE_MEDIA_STREAM_MODE;
+	rParamMediaStreamIndication.eMediaStreamMode =
+	    prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON;
+
+	kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+				     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+				     (PVOID)&rParamMediaStreamIndication, sizeof(PARAM_MEDIA_STREAMING_INDICATION));
+}
+
+/* Statistics responder */
+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) prEventStatistics->rTransmittedFragmentCount.QuadPart;
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = prEventStatistics->rTransmittedFragmentCount.QuadPart;
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) prEventStatistics->rReceivedFragmentCount.QuadPart;
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = prEventStatistics->rReceivedFragmentCount.QuadPart;
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart;
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart;
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart;
+			/* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = prEventStatistics->rFCSErrorCount.QuadPart;
+			/* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = 0;	/* @FIXME? */
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = 0;	/* @FIXME? */
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart;
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = prEventStatistics->rFCSErrorCount.QuadPart;
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) 0;	/* @FIXME */
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = 0;	/* @FIXME */
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data =
+			    (UINT_32) (prEventStatistics->rMultipleRetryCount.QuadPart -
+				       prEventStatistics->rRetryCount.QuadPart);
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data =
+			    (UINT_64) (prEventStatistics->rMultipleRetryCount.QuadPart -
+				       prEventStatistics->rRetryCount.QuadPart);
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) prEventStatistics->rMultipleRetryCount.QuadPart;
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = (UINT_64) prEventStatistics->rMultipleRetryCount.QuadPart;
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	P_EVENT_STATISTICS prEventStatistics;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4QueryInfoLen;
+	PUINT_32 pu4Data;
+	PUINT_64 pu8Data;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf;
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+
+		if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) {
+			u4QueryInfoLen = sizeof(UINT_32);
+
+			pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer;
+			*pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart;
+		} else {
+			u4QueryInfoLen = sizeof(UINT_64);
+
+			pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer;
+			*pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart;
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when command by OID/ioctl has been timeout
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo          Pointer to the command information
+*
+* @return TRUE
+*         FALSE
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	ASSERT(prAdapter);
+
+	kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is a generic command timeout handler
+*
+* @param pfnOidHandler      Pointer to the OID handler
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	ASSERT(prAdapter);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when command for entering RF test has
+*        failed sending due to timeout (highly possibly by firmware crash)
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo          Pointer to the command information
+*
+* @return none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
+{
+	ASSERT(prAdapter);
+
+	/* 1. Remove pending TX frames */
+	nicTxRelease(prAdapter);
+
+	/* 1.1 clear pending Security / Management Frames */
+	kalClearSecurityFrames(prAdapter->prGlueInfo);
+	kalClearMgmtFrames(prAdapter->prGlueInfo);
+
+	/* 1.2 clear pending TX packet queued in glue layer */
+	kalFlushPendingTxPackets(prAdapter->prGlueInfo);
+
+	/* 2. indicate for OID failure */
+	kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when command for memory dump has
+*        replied a event.
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo         Pointer to the command information
+* @param pucEventBuf       Pointer to event buffer
+*
+* @return none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo;
+	P_GLUE_INFO_T prGlueInfo;
+	P_EVENT_DUMP_MEM_T prEventDumpMem;
+	static UINT_8 aucPath[256];
+	static UINT_32 u4CurTimeTick;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEventDumpMem = (P_EVENT_DUMP_MEM_T) (pucEventBuf);
+
+		u4QueryInfoLen = sizeof(P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T);
+
+		prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) prCmdInfo->pvInformationBuffer;
+		prMemDumpInfo->u4Address = prEventDumpMem->u4Address;
+		prMemDumpInfo->u4Length = prEventDumpMem->u4Length;
+		prMemDumpInfo->u4RemainLength = prEventDumpMem->u4RemainLength;
+		prMemDumpInfo->ucFragNum = prEventDumpMem->ucFragNum;
+
+#if 0
+		do {
+			UINT_32 i = 0;
+
+			DBGLOG(REQ, TRACE, "Rx dump address 0x%X, Length %d, FragNum %d, remain %d\n",
+			       prEventDumpMem->u4Address,
+			       prEventDumpMem->u4Length, prEventDumpMem->ucFragNum, prEventDumpMem->u4RemainLength);
+#if 0
+			for (i = 0; i < prEventDumpMem->u4Length; i++) {
+				DBGLOG(REQ, TRACE, "%02X ", prEventDumpMem->aucBuffer[i]);
+				if (i % 32 == 31)
+					DBGLOG(REQ, TRACE, "\n");
+			}
+#endif
+		} while (FALSE);
+#endif
+
+		if (prEventDumpMem->ucFragNum == 1) {
+			/* Store memory dump into sdcard,
+			 * path /sdcard/dump_<current  system tick>_<memory address>_<memory length>.hex
+			 */
+			u4CurTimeTick = kalGetTimeTick();
+			sprintf(aucPath, "/sdcard/dump_%d_0x%08X_%d.hex",
+				u4CurTimeTick,
+				prEventDumpMem->u4Address, prEventDumpMem->u4Length + prEventDumpMem->u4RemainLength);
+			kalWriteToFile(aucPath, FALSE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length);
+		} else {
+			/* Append current memory dump to the hex file */
+			kalWriteToFile(aucPath, TRUE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length);
+		}
+
+		if (prEventDumpMem->u4RemainLength == 0 || prEventDumpMem->u4Address == 0xFFFFFFFF) {
+			/* The request is finished or firmware response a error */
+			/* Reply time tick to iwpriv */
+			*((PUINT_32) prCmdInfo->pvInformationBuffer) = u4CurTimeTick;
+			kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+		} else {
+			/* The memory dump request is not finished, Send next command */
+			wlanSendMemDumpCmd(prAdapter,
+					   prCmdInfo->pvInformationBuffer, prCmdInfo->u4InformationBufferLength);
+		}
+	}
+
+	return;
+
+}
+
+#if CFG_SUPPORT_BATCH_SCAN
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when event for SUPPORT_BATCH_SCAN
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo          Pointer to the command information
+* @param pucEventBuf        Pointer to the event buffer
+*
+* @return none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_EVENT_BATCH_RESULT_T prEventBatchResult;
+	P_GLUE_INFO_T prGlueInfo;
+
+	DBGLOG(SCN, TRACE, "nicCmdEventBatchScanResult");
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pucEventBuf;
+
+		u4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T);
+		kalMemCopy(prCmdInfo->pvInformationBuffer, prEventBatchResult, sizeof(EVENT_BATCH_RESULT_T));
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+}
+#endif
+
+#if CFG_SUPPORT_BUILD_DATE_CODE
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when event for build date code information
+*        has been retrieved
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo          Pointer to the command information
+* @param pucEventBuf        Pointer to the event buffer
+*
+* @return none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_EVENT_BUILD_DATE_CODE prEvent;
+	P_GLUE_INFO_T prGlueInfo;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEvent = (P_EVENT_BUILD_DATE_CODE) pucEventBuf;
+
+		u4QueryInfoLen = sizeof(UINT_8) * 16;
+		kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent->aucDateCode, sizeof(UINT_8) * 16);
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when event for query STA link status
+*        has been retrieved
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo          Pointer to the command information
+* @param pucEventBuf        Pointer to the event buffer
+*
+* @return none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_EVENT_STA_STATISTICS_T prEvent;
+	P_GLUE_INFO_T prGlueInfo;
+	P_PARAM_GET_STA_STATISTICS prStaStatistics;
+
+	if ((prAdapter == NULL)
+		|| (prCmdInfo == NULL)
+		|| (pucEventBuf == NULL)
+		|| (prCmdInfo->pvInformationBuffer == NULL)) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEvent = (P_EVENT_STA_STATISTICS_T) pucEventBuf;
+		prStaStatistics = (P_PARAM_GET_STA_STATISTICS) prCmdInfo->pvInformationBuffer;
+
+		u4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS);
+
+		/* Statistics from FW is valid */
+		if (prEvent->u4Flags & BIT(0)) {
+			prStaStatistics->ucPer = prEvent->ucPer;
+			prStaStatistics->ucRcpi = prEvent->ucRcpi;
+			prStaStatistics->u4PhyMode = prEvent->u4PhyMode;
+			prStaStatistics->u2LinkSpeed = prEvent->u2LinkSpeed;
+
+			prStaStatistics->u4TxFailCount = prEvent->u4TxFailCount;
+			prStaStatistics->u4TxLifeTimeoutCount = prEvent->u4TxLifeTimeoutCount;
+
+			if (prEvent->u4TxCount) {
+				UINT_32 u4TxDoneAirTimeMs = USEC_TO_MSEC(prEvent->u4TxDoneAirTime * 32);
+
+				prStaStatistics->u4TxAverageAirTime = (u4TxDoneAirTimeMs / prEvent->u4TxCount);
+			} else {
+				prStaStatistics->u4TxAverageAirTime = 0;
+			}
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+}
+
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+
+/* 4  Auto Channel Selection */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when event for query STA link status
+*        has been retrieved
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo          Pointer to the command information
+* @param pucEventBuf        Pointer to the event buffer
+*
+* @return none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_EVENT_CHN_LOAD_T prEvent;
+	P_GLUE_INFO_T prGlueInfo;
+	P_PARAM_GET_CHN_LOAD prChnLoad;
+
+	if ((prAdapter == NULL)
+		|| (prCmdInfo == NULL)
+		|| (pucEventBuf == NULL)
+		|| (prCmdInfo->pvInformationBuffer == NULL)) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEvent = (P_EVENT_CHN_LOAD_T) pucEventBuf;	/* 4 The firmware responsed data */
+		/* 4 Fill the firmware data in and send it back to host */
+		prChnLoad = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer;
+
+		u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD);
+
+		/* Statistics from FW is valid */
+		if (prEvent->u4Flags & BIT(0)) {
+			prChnLoad->rEachChnLoad[0].ucChannel = prEvent->ucChannel;
+			prChnLoad->rEachChnLoad[0].u2ChannelLoad = prEvent->u2ChannelLoad;
+			DBGLOG(P2P, INFO, "CHN[%d]=%d\n", prEvent->ucChannel, prEvent->u2ChannelLoad);
+
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+}
+
+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_8 ucIdx = 0;
+	UINT_32 u4QueryInfoLen;
+	P_EVENT_LTE_MODE_T prEvent;
+	P_GLUE_INFO_T prGlueInfo;
+	P_PARAM_GET_CHN_LOAD prLteSafeChnInfo;
+
+	if ((prAdapter == NULL)
+		|| (prCmdInfo == NULL)
+		|| (pucEventBuf == NULL)
+		|| (prCmdInfo->pvInformationBuffer == NULL)) {
+		ASSERT(FALSE);
+		return;
+	}
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEvent = (P_EVENT_LTE_MODE_T) pucEventBuf;	/* 4 The firmware responsed data */
+
+		prLteSafeChnInfo = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer;
+
+		u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD);
+
+		/* Statistics from FW is valid */
+		if (prEvent->u4Flags & BIT(0)) {
+			for (ucIdx = 0; ucIdx < (NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1); ucIdx++) {
+				prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx] =
+				    prEvent->rLteSafeChn.au4SafeChannelBitmask[ucIdx];
+
+				DBGLOG(P2P, INFO,
+				       "[Auto Channel]LTE safe channels [%d]=[%x]\n", ucIdx,
+					(UINT32) prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx]);
+			}
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+}
+#endif
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is called when event for query FW bss info
+*        has been retrieved
+*
+* @param prAdapter          Pointer to the Adapter structure.
+* @param prCmdInfo          Pointer to the command information
+* @param pucEventBuf        Pointer to the event buffer
+*
+* @return none
+*
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+	UINT_32 u4QueryInfoLen;
+	P_EVENT_AIS_BSS_INFO_T prEvent;
+	P_GLUE_INFO_T prGlueInfo;
+	P_BSS_INFO_T prAisBssInfo;
+
+	ASSERT(prAdapter);
+
+	ASSERT(prCmdInfo);
+	ASSERT(pucEventBuf);
+
+	/* 4 <2> Update information of OID */
+	if (prCmdInfo->fgIsOid) {
+		prGlueInfo = prAdapter->prGlueInfo;
+		prEvent = (P_EVENT_AIS_BSS_INFO_T) pucEventBuf;
+
+		u4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T);
+		kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent, sizeof(EVENT_AIS_BSS_INFO_T));
+		prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+
+		if (prEvent->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) {
+			if (prEvent->eConnectionState != prAisBssInfo->eConnectionState) {
+				DBGLOG(NIC, ERROR, "driver[%d] & FW[%d] status didn't sync !!!\n",
+						     prAisBssInfo->eConnectionState, prEvent->eCurrentOPMode);
+				aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, FALSE);
+			}
+		}
+
+		kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+	}
+
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c
new file mode 100644
index 0000000000000..cf80fd999a240
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c
@@ -0,0 +1,669 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1
+*/
+
+/*! \file   "nic_pwr_mgt.c"
+    \brief  In this file we define the STATE and EVENT for Power Management FSM.
+
+    The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter
+    ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail
+    description.
+*/
+
+/*
+** Log: nic_pwr_mgt.c
+ *
+ * 11 28 2011 cp.wu
+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when
+ * returining to ROM code
+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware
+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not
+ *
+ * 10 03 2011 cp.wu
+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality
+ * add firmware download path in divided scatters.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * reuse firmware download logic of MT6620 for MT6628.
+ *
+ * 05 11 2011 cp.wu
+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke.
+ *
+ * 04 29 2011 cp.wu
+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
+ * fix for compilation error when applied with FW_DOWNLOAD = 0
+ *
+ * 04 18 2011 cp.wu
+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h)
+ * 1) add API for glue layer to query ACPI state
+ * 2) Windows glue should not access to hardware after switched into D3 state
+ *
+ * 04 13 2011 cp.wu
+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
+ * refine for MT5931/MT6620 logic separation.
+ *
+ * 04 13 2011 cp.wu
+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete
+ * bugfix: firmware download procedure for ACPI state transition is not complete.
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
+ * memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system
+ * scheduling
+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
+ * loaded
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
+ * check success or failure for setting fw-own
+ *
+ * 12 30 2010 cp.wu
+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
+ * host driver not to set FW-own when there is still pending interrupts
+ *
+ * 10 07 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * add firmware download for MT5931.
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
+ * associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * reset ACPI power state before waking up MT6620 Wi-Fi firmware.
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * Centralize mgmt/system service procedures into independent calls.
+ *
+ * 07 22 2010 cp.wu
+ *
+ * 1) refine AIS-FSM indent.
+ * 2) when entering RF Test mode, flush 802.1X frames as well
+ * 3) when entering D3 state, flush 802.1X frames as well
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change MAC address updating logic.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll
+ * 2) correct address list parsing
+ *
+ * 05 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * sleepy notify is only used for sleepy state,
+ * while wake-up state is automatically set when host needs to access device
+ *
+ * 05 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct hibernation problem.
+ *
+ * 04 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) surpress compiler warning
+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * when acquiring driver-own, wait for up to 8 seconds.
+ *
+ * 04 21 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add for private ioctl support
+ *
+ * 04 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove redundant firmware image unloading
+ *  * 2) use compile-time macros to separate logic related to accquiring own
+ *
+ * 04 16 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * treat BUS access failure as kind of card removal.
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * accessing to firmware load/start address, and access to OID handling information
+ *  * are now handled in glue layer
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * ePowerCtrl is not necessary as a glue variable.
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct typo.
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ *  *  *  *  *  *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX
+ * response
+ *
+ * 03 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
+ *  * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084
+**  update for new HW design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084
+**  remove CMD52 access
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084
+**  modify lines in nicpmSetDriverOwn()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084
+**  modify nicpmSetDriverOwn()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084
+**  update for basic power management functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084
+**  Initial version
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to process the POWER ON procedure.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt)
+{
+	UINT_32 u4RegValue = 0;
+
+	ASSERT(prAdapter);
+
+	if (prAdapter->fgIsFwOwn == TRUE)
+		return;
+
+	if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
+		/* pending interrupts */
+		return;
+	}
+
+	if (fgEnableGlobalInt) {
+		prAdapter->fgIsIntEnableWithLPOwnSet = TRUE;
+	} else {
+		HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
+
+		HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
+		if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
+			/* if set firmware own not successful (possibly pending interrupts), */
+			/* indicate an own clear event */
+			HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
+
+			return;
+		}
+
+		prAdapter->fgIsFwOwn = TRUE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to process the POWER OFF procedure.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 u4OriRegValue = 0;
+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter)
+{
+#define LP_OWN_BACK_TOTAL_DELAY_MS      2000	/* exponential of 2 */
+#define LP_OWN_BACK_LOOP_DELAY_MS       1	/* exponential of 2 */
+#define LP_OWN_BACK_CLR_OWN_ITERATION   256	/* exponential of 2 */
+
+	BOOLEAN fgStatus = TRUE;
+	UINT_32 i, u4CurrTick;
+	UINT_32 u4RegValue = 0;
+	GL_HIF_INFO_T *HifInfo;
+
+	ASSERT(prAdapter);
+
+	if (prAdapter->fgIsFwOwn == FALSE)
+		return fgStatus;
+
+	HifInfo = &prAdapter->prGlueInfo->rHifInfo;
+
+	u4CurrTick = kalGetTimeTick();
+	STATS_DRIVER_OWN_START_RECORD();
+	i = 0;
+
+	while (1) {
+		HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
+
+		if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
+			HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue);
+			prAdapter->fgIsFwOwn = FALSE;
+			break;
+		} else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
+			   || fgIsBusAccessFailed == TRUE
+			   || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) {
+			/* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */
+			fgStatus = FALSE;
+			if (fgIsResetting != TRUE) {
+				UINT_32 u4FwCnt;
+				static unsigned int u4OwnCnt;
+				/* MCR_D2HRM2R: low 4 bit means interrupt times,
+				 * high 4 bit means firmware response times.
+				 * ORI_MCR_D2HRM2R: the last successful value.
+				 * for example:
+				 * MCR_D2HRM2R = 0x44, ORI_MCR_D2HRM2R = 0x44
+				 * means firmware no receive interrupt form hardware.
+				 * MCR_D2HRM2R = 0x45, ORI_MCR_D2HRM2R = 0x44
+				 * means firmware no send response.
+				 * MCR_D2HRM2R = 0x55, ORI_MCR_D2HRM2R = 0x44
+				 * means firmware send response, but driver no receive. */
+				HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue);
+				DBGLOG(NIC, WARN, "<WiFi> [1]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n",
+					u4RegValue, u4OriRegValue);
+
+				HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
+				HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue);
+				if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) {
+					HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue);
+					prAdapter->fgIsFwOwn = FALSE;
+					break;
+				}
+				HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue);
+				DBGLOG(NIC, WARN, "<WiFi> [2]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n",
+					u4RegValue, u4OriRegValue);
+				DBGLOG(NIC, WARN,
+					"<WiFi> Fatal error! Driver own fail!!!!!!!!!!!! %d, fgIsBusAccessFailed: %d\n",
+					u4OwnCnt++, fgIsBusAccessFailed);
+
+				DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n");
+				for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++)
+					DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR));
+				/* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */
+				kalSendAeeWarning("[Fatal error! Driver own fail!]", __func__);
+				glDoChipReset();
+			}
+			break;
+		}
+		if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) {
+			/* Software get LP ownership - per 256 iterations */
+			HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR);
+		}
+
+		/* Delay for LP engine to complete its operation. */
+		kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS);
+		i++;
+	}
+
+	STATS_DRIVER_OWN_END_RECORD();
+	STATS_DRIVER_OWN_STOP();
+
+	return fgStatus;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to set ACPI power mode to D0.
+*
+* \param[in] pvAdapter Pointer to the Adapter structure.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter)
+{
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+	UINT_32 u4Value = 0, u4WHISR = 0;
+	UINT_8 aucTxCount[8];
+	UINT_32 i;
+#if CFG_ENABLE_FW_DOWNLOAD
+	UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize;
+	PVOID prFwMappingHandle;
+	PVOID pvFwImageMapFile = NULL;
+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
+	UINT_32 j;
+	P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead;
+	BOOLEAN fgValidHead;
+	const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries);
+#endif
+#endif
+
+	DEBUGFUNC("nicpmSetAcpiPowerD0");
+	ASSERT(prAdapter);
+
+	do {
+		/* 0. Reset variables in ADAPTER_T */
+		prAdapter->fgIsFwOwn = TRUE;
+		prAdapter->fgWiFiInSleepyState = FALSE;
+		prAdapter->rAcpiState = ACPI_STATE_D0;
+		prAdapter->fgIsEnterD3ReqIssued = FALSE;
+
+		/* 1. Request Ownership to enter F/W download state */
+		ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter);
+#if !CFG_ENABLE_FULL_PM
+		nicpmSetDriverOwn(prAdapter);
+#endif
+
+		/* 2. Initialize the Adapter */
+		u4Status = nicInitializeAdapter(prAdapter);
+		if (u4Status != WLAN_STATUS_SUCCESS) {
+			DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+			break;
+		}
+
+#if CFG_ENABLE_FW_DOWNLOAD
+		prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength);
+		if (!prFwMappingHandle) {
+			DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n");
+			pvFwImageMapFile = NULL;
+		}
+
+		if (pvFwImageMapFile == NULL) {
+			u4Status = WLAN_STATUS_FAILURE;
+			break;
+		}
+
+		/* 3.1 disable interrupt, download is done by polling mode only */
+		nicDisableInterrupt(prAdapter);
+
+		/* 3.2 Initialize Tx Resource to fw download state */
+		nicTxInitResetResource(prAdapter);
+
+		/* 3.3 FW download here */
+		u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo);
+
+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD
+		/* 3a. parse file header for decision of divided firmware download or not */
+		prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile;
+
+		if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE &&
+		    prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset,
+						 u4FwImgLength - u4CRCOffset)) {
+			fgValidHead = TRUE;
+		} else {
+			fgValidHead = FALSE;
+		}
+
+		/* 3b. engage divided firmware downloading */
+		if (fgValidHead == TRUE) {
+			for (i = 0; i < prFwHead->u4NumOfEntries; i++) {
+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
+				if (wlanImageSectionDownloadAggregated(prAdapter,
+					prFwHead->arSection[i].u4DestAddr,
+					prFwHead->arSection[i].u4Length,
+					(PUINT_8) pvFwImageMapFile +
+					prFwHead->arSection[i].u4Offset) !=
+					WLAN_STATUS_SUCCESS) {
+					DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n");
+					u4Status = WLAN_STATUS_FAILURE;
+				}
+#else
+				for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) {
+					if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length)
+						u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
+					else
+						u4ImgSecSize = prFwHead->arSection[i].u4Length - j;
+
+					if (wlanImageSectionDownload(prAdapter,
+						prFwHead->arSection[i].u4DestAddr + j,
+						u4ImgSecSize,
+						(PUINT_8) pvFwImageMapFile +
+						prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) {
+						DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n");
+						u4Status = WLAN_STATUS_FAILURE;
+						break;
+					}
+				}
+#endif
+				/* escape from loop if any pending error occurs */
+				if (u4Status == WLAN_STATUS_FAILURE)
+					break;
+			}
+		} else
+#endif
+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION
+		if (wlanImageSectionDownloadAggregated(prAdapter,
+			u4FwLoadAddr,
+			u4FwImgLength,
+			(PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) {
+			DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n");
+			u4Status = WLAN_STATUS_FAILURE;
+		}
+#else
+			for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) {
+				if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength)
+					u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE;
+				else
+					u4ImgSecSize = u4FwImgLength - i;
+
+				if (wlanImageSectionDownload(prAdapter,
+					u4FwLoadAddr + i,
+					u4ImgSecSize,
+					(PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) {
+					DBGLOG(NIC, ERROR, "wlanImageSectionDownload failed!\n");
+					u4Status = WLAN_STATUS_FAILURE;
+					break;
+				}
+			}
+#endif
+
+		if (u4Status != WLAN_STATUS_SUCCESS) {
+			kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
+			break;
+		}
+#if !CFG_ENABLE_FW_DOWNLOAD_ACK
+		/* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */
+		if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) {
+			kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
+			u4Status = WLAN_STATUS_FAILURE;
+			break;
+		}
+#endif
+		kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile);
+
+		/* 4. send Wi-Fi Start command */
+#if CFG_OVERRIDE_FW_START_ADDRESS
+		wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo));
+#else
+		wlanConfigWifiFunc(prAdapter, FALSE, 0);
+#endif
+#endif /* if CFG_ENABLE_FW_DOWNLOAD */
+
+		/* 5. check Wi-Fi FW asserts ready bit */
+		DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n");
+		i = 0;
+		while (1) {
+			HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
+
+			if (u4Value & WCIR_WLAN_READY) {
+				DBGLOG(NIC, TRACE, "Ready bit asserted\n");
+				break;
+			} else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+				u4Status = WLAN_STATUS_FAILURE;
+				break;
+			} else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) {
+				DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n");
+				u4Status = WLAN_STATUS_FAILURE;
+				break;
+			}
+			i++;
+			kalMsleep(10);
+		}
+
+		if (u4Status == WLAN_STATUS_SUCCESS) {
+			/* 6.1 reset interrupt status */
+			HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)(&u4WHISR));
+			if (HAL_IS_TX_DONE_INTR(u4WHISR))
+				HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount);
+
+			/* 6.2 reset TX Resource for normal operation */
+			nicTxResetResource(prAdapter);
+
+			/* 6.3 Enable interrupt */
+			nicEnableInterrupt(prAdapter);
+
+			/* 6.4 Override network address */
+			wlanUpdateNetworkAddress(prAdapter);
+
+			/* 6.5 indicate disconnection as default status */
+			kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+		}
+
+		RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE);
+
+		/* MGMT Initialization */
+		nicInitMGMT(prAdapter, NULL);
+
+	} while (FALSE);
+
+	if (u4Status != WLAN_STATUS_SUCCESS)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This routine is used to set ACPI power mode to D3.
+*
+* @param prAdapter pointer to the Adapter handler
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i;
+
+	ASSERT(prAdapter);
+
+	/* 1. MGMT - unitialization */
+	nicUninitMGMT(prAdapter);
+
+	/* 2. Disable Interrupt */
+	nicDisableInterrupt(prAdapter);
+
+	/* 3. emit CMD_NIC_POWER_CTRL command packet */
+	wlanSendNicPowerCtrlCmd(prAdapter, 1);
+
+	/* 4. Clear Interrupt Status */
+	i = 0;
+	while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) {
+		i++;
+	};
+
+	/* 5. Remove pending TX */
+	nicTxRelease(prAdapter);
+
+	/* 5.1 clear pending Security / Management Frames */
+	kalClearSecurityFrames(prAdapter->prGlueInfo);
+	kalClearMgmtFrames(prAdapter->prGlueInfo);
+
+	/* 5.2 clear pending TX packet queued in glue layer */
+	kalFlushPendingTxPackets(prAdapter->prGlueInfo);
+
+	/* 6. Set Onwership to F/W */
+	nicpmSetFWOwn(prAdapter, FALSE);
+
+	/* 7. Set variables */
+	prAdapter->rAcpiState = ACPI_STATE_D3;
+
+	return TRUE;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c
new file mode 100644
index 0000000000000..ba4840414da85
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c
@@ -0,0 +1,3782 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_rx.c#3
+*/
+
+/*! \file   nic_rx.c
+    \brief  Functions that provide many rx-related functions
+
+    This file includes the functions used to process RFB and dispatch RFBs to
+    the appropriate related rx functions for protocols.
+*/
+
+/*
+** Log: nic_rx.c
+**
+** 08 31 2012 yuche.tsai
+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously,
+** one device reboots automatically with KE
+** Fix possible KE when concurrent & disconnect.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 02 14 2012 cp.wu
+ * NULL
+ * remove another assertion by error message dump
+ *
+ * 01 05 2012 tsaiyuan.hsu
+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
+ * add timing measurement support for 802.11v.
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Update RSSI for P2P.
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 17 2011 tsaiyuan.hsu
+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
+ * avoid deactivating staRec when changing state from 3 to 3.
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 10 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Modify the QM xlog level and remove LOG_FUNC.
+ *
+ * 11 09 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add xlog for beacon timeout and sta aging timeout.
+ *
+ * 11 08 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add xlog function.
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 10 21 2011 eddie.chen
+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout
+ * Add switch to ignore the STA aging timeout.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 08 26 2011 cp.wu
+ * [WCXRP00000958] [MT6620 Wi-Fi][Driver] Extend polling timeout from 25ms to 1sec due to RF calibration might took
+ * up to 600ms
+ * extend polling RX response timeout period from 25ms to 1000ms.
+ *
+ * 08 11 2011 cp.wu
+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
+ * sparse channel detection:
+ * driver: collect sparse channel information with scan-done event
+ *
+ * 07 28 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS cmd and event.
+ *
+ * 07 27 2011 cp.wu
+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count
+ * correct comment.
+ *
+ * 07 27 2011 cp.wu
+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count
+ * take use of QUE_MGT exported function to estimate currently RX buffer usage count.
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 06 09 2011 tsaiyuan.hsu
+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size
+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size.
+ *
+ * 05 11 2011 eddie.chen
+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
+ * Fix dest type when GO packet copying.
+ *
+ * 05 09 2011 eddie.chen
+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
+ * Check free number before copying broadcast packet.
+ *
+ * 05 05 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * add delay after whole-chip resetting for MT5931 E1 ASIC.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 08 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Add device discoverability support for GO.
+ *
+ * 04 01 2011 tsaiyuan.hsu
+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues
+ * fix the klocwork issues, 57500, 57501, 57502 and 57503.
+ *
+ * 03 19 2011 yuche.tsai
+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
+ * Add beacon timeout support for WiFi Direct Network.
+ *
+ * 03 18 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * enable the Anti_piracy check at driver .
+ *
+ * 03 17 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * use pre-allocated buffer for storing enhanced interrupt response as well
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
+ * memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add security check code.
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after
+ * connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
+ *
+ * 02 10 2011 yuche.tsai
+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to target station for AAA
+ * module.
+ * Remove Station Record after Aging timeout.
+ *
+ * 02 10 2011 cp.wu
+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers
+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle.
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add MLME deauthentication support for Hot-Spot mode.
+ *
+ * 02 09 2011 eddie.chen
+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
+ * Adjust variable order.
+ *
+ * 02 08 2011 eddie.chen
+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
+ * Add event STA agint timeout
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * .
+ *
+ * 01 24 2011 eddie.chen
+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
+ * Remove comments.
+ *
+ * 01 24 2011 eddie.chen
+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
+ * Add destination decision in AP mode.
+ *
+ * 01 24 2011 cm.chang
+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec
+ * is freed
+ * Process received 20/40 coexistence action frame for AP mode
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
+ * implementation of separate BT_OVER_WIFI data path.
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 12 15 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * update beacon for NoA
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 27 2010 george.huang
+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB
+ * Support registry option for disable beacon lost detection.
+ *
+ * 10 20 2010 wh.su
+ * NULL
+ * add a cmd to reset the p2p key
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Add the code to support disconnect p2p group
+ *
+ * 09 29 2010 wh.su
+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
+ * fixed compilier error.
+ *
+ * 09 29 2010 wh.su
+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
+ * associated
+ * release RX packet to packet pool when in RF test mode
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
+ @ associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 08 2010 cp.wu
+ * NULL
+ * use static memory pool for storing IEs of scanning result.
+ *
+ * 09 07 2010 yuche.tsai
+ * NULL
+ * Add a common buffer, store the IE of a P2P device in this common buffer.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 20 2010 cm.chang
+ * NULL
+ * Migrate RLM code to host from FW
+ *
+ * 08 20 2010 yuche.tsai
+ * NULL
+ * When enable WiFi Direct function, check each packet to tell which interface to indicate.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * Add P2P Device Discovery Function.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 08 03 2010 george.huang
+ * NULL
+ * handle event for updating NOA parameters indicated from FW
+ *
+ * 08 02 2010 yuche.tsai
+ * NULL
+ * Add support API for RX public action frame.
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * 1) modify tx service thread to avoid busy looping
+ * 2) add spin lock declartion for linux build
+ *
+ * 07 30 2010 cp.wu
+ * NULL
+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
+ *
+ * 07 26 2010 yuche.tsai
+ *
+ * Update Device Capability Bitmap & Group Capability Bitmap from 16 bits to 8 bits.
+ *
+ * 07 24 2010 wh.su
+ *
+ * .support the Wi-Fi RSN
+ *
+ * 07 23 2010 cp.wu
+ *
+ * add AIS-FSM handling for beacon timeout event.
+ *
+ * 07 21 2010 yuche.tsai
+ *
+ * Add P2P Scan & Scan Result Parsing & Saving.
+ *
+ * 07 19 2010 cm.chang
+ *
+ * Set RLM parameters and enable CNM channel manager
+ *
+ * 07 19 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration.
+ * Add Ad-Hoc support to AIS-FSM
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 16 2010 yarco.yang
+ *
+ * 1. Support BSS Absence/Presence Event
+ * 2. Support STA change PS mode Event
+ * 3. Support BMC forwarding for AP mode.
+ *
+ * 07 15 2010 cp.wu
+ *
+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * fill ucStaRecIdx into SW_RFB_T.
+ *
+ * 07 02 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) for event packet, no need to fill RFB.
+ * 2) when wlanAdapterStart() failed, no need to initialize state machines
+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
+ *
+ * 07 01 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implementation of DRV-SCN and related mailbox message handling.
+ *
+ * 06 29 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * replace g_rQM with Adpater->rQM
+ *
+ * 06 23 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Merge g_arStaRec[] into adapter->arStaRec[]
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * refine TX-DONE callback.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * implement TX_DONE callback path.
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Add TX Done Event handle entry
+ *
+ * 06 21 2010 wh.su
+ * [WPD00003840][MT6620 5931] Security migration
+ * remove duplicate variable for migration.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * .
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * .
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * saa_fsm.c is migrated.
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add management dispatching function table.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
+ * 2) when disconnected, indicate nic directly (no event is needed)
+ *
+ * 06 08 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * cnm_timer has been migrated.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * merge wlan_def.h.
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * sync with MT6620 driver for scan result replacement policy
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
+ * 2) buffer statistics data for 2 seconds
+ * 3) use default value for adhoc parameters instead of 0
+ *
+ * 05 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) do not take timeout mechanism for power mode oids
+ * 2) retrieve network type from connection status
+ * 3) after disassciation, set radio state to off
+ * 4) TCP option over IPv6 is supported
+ *
+ * 04 29 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * fixing the PMKID candicate indicate code.
+ *
+ * 04 28 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change prefix for data structure used to communicate with 802.11 PAL
+ * to avoid ambiguous naming with firmware interface
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * basic implementation for EVENT_BT_OVER_WIFI
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 22 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ *
+ * 1) modify rx path code for supporting Wi-Fi direct
+ * 2) modify config.h since Linux dont need to consider retaining packet
+ *
+ * 04 16 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * treat BUS access failure as kind of card removal.
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * nicRxProcessEvent packet doesn't access spin-lock directly from now on.
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * do not need to release the spin lock due to it is done inside nicGetPendingCmdInfo()
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add channel frequency <-> number conversion
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) add spinlock
+ * 2) add KAPI for handling association info
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  *  *  * are done in adapter layer.
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 04 01 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve Linux supplicant compliance
+ *
+ * 03 31 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix ioctl which may cause cmdinfo memory leak
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * remove driver-land statistics.
+ *
+ * 03 29 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 03 28 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * rWlanInfo is modified before data is indicated to OS
+ *
+ * 03 28 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * rWlanInfo is modified before data is indicated to OS
+ *
+ * 03 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add a temporary flag for integration with CMD/EVENT v0.9.
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior.
+ *  *  * the frequency is used for adhoc connection only
+ *  *  * 2) update with SD1 v0.9 CMD/EVENT documentation
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * .
+ *
+ * 03 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
+ *  *  *  *
+ *
+ * 03 19 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add ACPI D0/D3 state switching support
+ *  *  *  *  *  *  *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX
+ * response
+ *
+ * 03 15 2010 kevin.huang
+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test
+ * Add event for activate STA_RECORD_T
+ *
+ * 03 12 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct fgSetQuery/fgNeedResp check
+ *
+ * 03 11 2010 cp.wu
+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING
+ *
+ * 03 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code clean: removing unused variables and structure definitions
+ *
+ * 03 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
+ *  *  * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock
+ *  *  *  * 2) ensure wlanReleasePendingOid will clear all command queues
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add mutex to avoid multiple access to qmTxQueue simultaneously.
+ *
+ * 02 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c
+ *  * 'cause it involves OS dependent data structure handling
+ *
+ * 02 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE
+ *
+ * 02 24 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Updated API interfaces for qmHandleEventRxAddBa() and qmHandleEventRxDelBa()
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement host-side firmware download logic
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
+ *  *  *  *  * 2) firmware image length is now retrieved via NdisFileOpen
+ *  *  *  *  * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
+ *  *  *  *  * 4) nicRxWaitResponse() revised
+ *  *  *  *  * 5) another set of TQ counter default value is added for fw-download state
+ *  *  *  *  * 6) Wi-Fi load address is now retrieved from registry too
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  *  *  *  *  *  *  * 2. follow MSDN defined behavior when associates to another AP
+ *  *  *  *  *  *  *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 01 27 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * .
+ *
+ * 01 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * implement following 802.11 OIDs:
+ *  *  *  *  *  * OID_802_11_RSSI,
+ *  *  *  *  *  * OID_802_11_RSSI_TRIGGER,
+ *  *  *  *  *  * OID_802_11_STATISTICS,
+ *  *  *  *  *  * OID_802_11_DISASSOCIATE,
+ *  *  *  *  *  * OID_802_11_POWER_MODE
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  *  *  *  *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  *  *  *  *  *  *  * and result is retrieved by get ATInfo instead
+ *  *  *  *  *  *  *  *  * 2) add 4 counter for recording aggregation statistics
+ *
+ * 12 23 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add a precheck: if free sw rfb is not enough, do not invoke read transactionu1rwduu`wvpghlqg|fu+rp
+ *
+ * 12 22 2009 cp.wu
+ * [WPD00003809][Bug] Host driver will crash when processing reordered MSDUs
+ * The root cause is pointer accessing by mistake. After dequeued from reordering-buffer, handling logic should access
+ * returned pointer instead of pointer which has been passed in before.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\58 2009-12-17 13:40:33 GMT mtk02752
+**  always update prAdapter->rSDIOCtrl when enhanced response is read by RX
+**  \main\maintrunk.MT6620WiFiDriver_Prj\57 2009-12-16 18:01:38 GMT mtk02752
+**  if interrupt enhanced response is fetched by RX enhanced response, RX needs to invoke interrupt handlers too
+**  \main\maintrunk.MT6620WiFiDriver_Prj\56 2009-12-16 14:16:52 GMT mtk02752
+**  \main\maintrunk.MT6620WiFiDriver_Prj\55 2009-12-15 20:03:12 GMT mtk02752
+**  ASSERT when RX FreeSwRfb is not enough
+**  \main\maintrunk.MT6620WiFiDriver_Prj\54 2009-12-15 17:01:29 GMT mtk02752
+**  when CFG_SDIO_RX_ENHANCE is enabled, after enhanced response is read, rx procedure should process
+**  1) TX_DONE_INT 2) D2H INT as well
+**  \main\maintrunk.MT6620WiFiDriver_Prj\53 2009-12-14 20:45:28 GMT mtk02752
+**  when CFG_SDIO_RX_ENHANCE is set, TC counter must be updated each time RX enhance response is read
+**
+**  \main\maintrunk.MT6620WiFiDriver_Prj\52 2009-12-14 11:34:16 GMT mtk02752
+**  correct a trivial logic issue
+**  \main\maintrunk.MT6620WiFiDriver_Prj\51 2009-12-14 10:28:25 GMT mtk02752
+**  add a protection to avoid out-of-boundary access
+**  \main\maintrunk.MT6620WiFiDriver_Prj\50 2009-12-10 16:55:18 GMT mtk02752
+**  code clean
+**  \main\maintrunk.MT6620WiFiDriver_Prj\49 2009-12-09 14:06:47 GMT MTK02468
+**  Added parsing event packets with EVENT_ID_RX_ADDBA or EVENT_ID_RX_DELBA
+**  \main\maintrunk.MT6620WiFiDriver_Prj\48 2009-12-08 17:37:51 GMT mtk02752
+**  handle EVENT_ID_TEST_STATUS as well
+**  \main\maintrunk.MT6620WiFiDriver_Prj\47 2009-12-04 17:59:11 GMT mtk02752
+**  to pass free-build compilation check
+**  \main\maintrunk.MT6620WiFiDriver_Prj\46 2009-12-04 12:09:52 GMT mtk02752
+**  correct trivial mistake
+**  \main\maintrunk.MT6620WiFiDriver_Prj\45 2009-12-04 11:53:37 GMT mtk02752
+**  all API should be compilable under SD1_SD3_DATAPATH_INTEGRATION == 0
+**  \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-03 16:19:48 GMT mtk01461
+**  Fix the Connected Event
+**  \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-11-30 10:56:18 GMT mtk02752
+**  1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-11-30 10:11:27 GMT mtk02752
+**  implement replacement for bss scan result
+**  \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-11-27 11:08:05 GMT mtk02752
+**  add flush for reset
+**  \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-11-26 09:38:59 GMT mtk02752
+**  \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-11-26 09:29:40 GMT mtk02752
+**  enable packet forwarding path (for AP mode)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-11-25 21:37:00 GMT mtk02752
+**  sync. with EVENT_SCAN_RESULT_T change, and add an assert for checking event size
+**  \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-25 20:17:41 GMT mtk02752
+**  fill HIF_TX_HEADER_T.u2SeqNo
+**  \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-25 18:18:57 GMT mtk02752
+**  buffer scan result to prGlueInfo->rWlanInfo.arScanResult directly.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-24 22:42:45 GMT mtk02752
+**  add nicRxAddScanResult() to prepare to handle SCAN_RESULT event (not implemented yet)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-24 20:51:41 GMT mtk02752
+**  integrate with SD1's data path API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-24 19:56:17 GMT mtk02752
+**  adopt P_HIF_RX_HEADER_T in new path
+**  \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-23 20:31:21 GMT mtk02752
+**  payload to send into pfCmdDoneHandler() will not include WIFI_EVENT_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-23 17:51:34 GMT mtk02752
+**  when event packet corresponding to some pendingOID is received, pendingOID should be cleared
+**  \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 14:46:54 GMT mtk02752
+**  implement nicRxProcessEventPacket()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-17 22:40:54 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-16 21:48:22 GMT mtk02752
+**  add SD1_SD3_DATAPATH_INTEGRATION data path handling
+**  \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-16 15:41:18 GMT mtk01084
+**  modify the length to be read in emu mode
+**  \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-13 17:00:12 GMT mtk02752
+**  add blank function for event packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-13 13:54:24 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 14:41:51 GMT mtk02752
+**  fix typo
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-11 14:33:46 GMT mtk02752
+**  add protection when there is no packet avilable
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 12:33:36 GMT mtk02752
+**  add RX1 read path for aggregated/enhanced/normal packet read procedures
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:18 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-04 14:11:08 GMT mtk01084
+**  modify lines in RX aggregation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:23 GMT mtk01084
+**  modify RX aggregation handling
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:56:12 GMT mtk01084
+**  modify HAL part
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:34 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:20 GMT mtk01084
+**  update for new HW design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-02 13:59:08 GMT mtk01725
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-21 23:39:05 GMT mtk01461
+**  Fix the paste error of RX STATUS in OOB of HIF Loopback CTRL
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-20 12:25:32 GMT mtk01461
+**  Fix process of Read Done, and add u4MaxEventBufferLen to nicRxWaitResponse()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 21:13:18 GMT mtk01426
+**  Fixed compiler error
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:05:29 GMT mtk01426
+**  Fixed nicRxSDIOAggReceiveRFBs() ASSERT issue
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:38:43 GMT mtk01461
+**  Fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode and refine  nicRxSDIOAggeceiveRFBs() for RX Aggregation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-22 09:12:17 GMT mtk01461
+**  Fix nicRxProcessHIFLoopbackPacket(), the size of HIF CTRL LENGTH field is 1 byte
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426
+**  Update RX OOB Setting
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426
+**  Fixed logical error
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461
+**  Rename the HIF_PKT_TYPE_DATA
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461
+**  Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426
+**  Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426
+**  Add nicRxWaitResponse function
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426
+**  Init for develop
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#ifndef LINUX
+#include <limits.h>
+#else
+#include <linux/limits.h>
+#endif
+
+#include "gl_os.h"
+#include "debug.h"
+#include "wlan_lib.h"
+#include "gl_wext.h"
+#include <linux/can/netlink.h>
+#include <net/netlink.h>
+#include <net/cfg80211.h>
+#include "gl_cfg80211.h"
+#include "gl_vendor.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define RX_RESPONSE_TIMEOUT (1000)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+#if CFG_MGMT_FRAME_HANDLING
+static PROCESS_RX_MGT_FUNCTION apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = {
+#if CFG_SUPPORT_AAA
+	aaaFsmRunEventRxAssoc,	/* subtype 0000: Association request */
+#else
+	NULL,			/* subtype 0000: Association request */
+#endif /* CFG_SUPPORT_AAA */
+	saaFsmRunEventRxAssoc,	/* subtype 0001: Association response */
+#if CFG_SUPPORT_AAA
+	aaaFsmRunEventRxAssoc,	/* subtype 0010: Reassociation request */
+#else
+	NULL,			/* subtype 0010: Reassociation request */
+#endif /* CFG_SUPPORT_AAA */
+	saaFsmRunEventRxAssoc,	/* subtype 0011: Reassociation response */
+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA)
+	bssProcessProbeRequest,	/* subtype 0100: Probe request */
+#else
+	NULL,			/* subtype 0100: Probe request */
+#endif /* CFG_SUPPORT_ADHOC */
+	scanProcessBeaconAndProbeResp,	/* subtype 0101: Probe response */
+	NULL,			/* subtype 0110: reserved */
+	NULL,			/* subtype 0111: reserved */
+	scanProcessBeaconAndProbeResp,	/* subtype 1000: Beacon */
+	NULL,			/* subtype 1001: ATIM */
+	saaFsmRunEventRxDisassoc,	/* subtype 1010: Disassociation */
+	authCheckRxAuthFrameTransSeq,	/* subtype 1011: Authentication */
+	saaFsmRunEventRxDeauth,	/* subtype 1100: Deauthentication */
+	nicRxProcessActionFrame,	/* subtype 1101: Action */
+	NULL,			/* subtype 1110: reserved */
+	NULL			/* subtype 1111: reserved */
+};
+#endif
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Initialize the RFBs
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter)
+{
+	P_RX_CTRL_T prRxCtrl;
+	PUINT_8 pucMemHandle;
+	P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL;
+	UINT_32 i;
+
+	DEBUGFUNC("nicRxInitialize");
+
+	ASSERT(prAdapter);
+	prRxCtrl = &prAdapter->rRxCtrl;
+
+	/* 4 <0> Clear allocated memory. */
+	kalMemZero((PVOID) prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize);
+
+	/* 4 <1> Initialize the RFB lists */
+	QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList);
+	QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList);
+	QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList);
+
+	pucMemHandle = prRxCtrl->pucRxCached;
+	for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) {
+		prSwRfb = (P_SW_RFB_T) pucMemHandle;
+
+		nicRxSetupRFB(prAdapter, prSwRfb);
+		nicRxReturnRFB(prAdapter, prSwRfb);
+
+		pucMemHandle += ALIGN_4(sizeof(SW_RFB_T));
+	}
+
+	ASSERT(prRxCtrl->rFreeSwRfbList.u4NumElem == CFG_RX_MAX_PKT_NUM);
+	/* Check if the memory allocation consist with this initialization function */
+	ASSERT((ULONG) (pucMemHandle - prRxCtrl->pucRxCached) == prRxCtrl->u4RxCachedSize);
+
+	/* 4 <2> Clear all RX counters */
+	RX_RESET_ALL_CNTS(prRxCtrl);
+
+#if CFG_SDIO_RX_AGG
+	prRxCtrl->pucRxCoalescingBufPtr = prAdapter->pucCoalescingBufCached;
+	HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM);
+#else
+	HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1);
+#endif
+
+#if CFG_HIF_STATISTICS
+	prRxCtrl->u4TotalRxAccessNum = 0;
+	prRxCtrl->u4TotalRxPacketNum = 0;
+#endif
+
+#if CFG_HIF_RX_STARVATION_WARNING
+	prRxCtrl->u4QueuedCnt = 0;
+	prRxCtrl->u4DequeuedCnt = 0;
+#endif
+
+}				/* end of nicRxInitialize() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Uninitialize the RFBs
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	nicRxFlush(prAdapter);
+
+	do {
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		if (prSwRfb) {
+			if (prSwRfb->pvPacket)
+				kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket);
+			prSwRfb->pvPacket = NULL;
+		} else {
+			break;
+		}
+	} while (TRUE);
+
+	do {
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		if (prSwRfb) {
+			if (prSwRfb->pvPacket)
+				kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket);
+			prSwRfb->pvPacket = NULL;
+		} else {
+			break;
+		}
+	} while (TRUE);
+
+}				/* end of nicRxUninitialize() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Fill RFB
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb   specify the RFB to receive rx data
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb)
+{
+	P_HIF_RX_HEADER_T prHifRxHdr;
+
+	UINT_32 u4PktLen = 0;
+	UINT_32 u4MacHeaderLen;
+	UINT_32 u4HeaderOffset;
+
+	DEBUGFUNC("nicRxFillRFB");
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	ASSERT(prHifRxHdr);
+
+	u4PktLen = prHifRxHdr->u2PacketLen;
+
+	u4HeaderOffset = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK);
+	u4MacHeaderLen = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_LEN)
+	    >> HIF_RX_HDR_HEADER_LEN_OFFSET;
+
+	/* DBGLOG(RX, TRACE, ("u4HeaderOffset = %d, u4MacHeaderLen = %d\n", */
+	/* u4HeaderOffset, u4MacHeaderLen)); */
+
+	prSwRfb->u2HeaderLen = (UINT_16) u4MacHeaderLen;
+	prSwRfb->pvHeader = (PUINT_8) prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset;
+	prSwRfb->u2PacketLen = (UINT_16) (u4PktLen - (HIF_RX_HDR_SIZE + u4HeaderOffset));
+
+	/* DBGLOG(RX, TRACE, ("Dump Rx packet, u2PacketLen = %d\n", prSwRfb->u2PacketLen)); */
+	/* DBGLOG_MEM8(RX, TRACE, prSwRfb->pvHeader, prSwRfb->u2PacketLen); */
+
+#if 0
+	if (prHifRxHdr->ucReorder & HIF_RX_HDR_80211_HEADER_FORMAT) {
+		prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT;
+		DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n");
+	}
+
+	if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) {
+		prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING;
+		DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n");
+
+		/* Get Seq. No and TID, Wlan Index info */
+		if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) {
+			prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME;
+			DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n");
+		}
+
+		prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_SEQ_NO_MASK;
+		prSwRfb->ucTid = (UINT_8) ((prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_TID_MASK)
+					   >> HIF_RX_HDR_TID_OFFSET);
+		DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", prSwRfb->u2SSN, prSwRfb->ucTid);
+	}
+
+	if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) {
+		prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS;
+		DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n");
+	}
+#endif
+}
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Fill checksum status in RFB
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+* @param u4TcpUdpIpCksStatus specify the Checksum status
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus)
+{
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED) {
+		if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv4) {	/* IPv4 packet */
+			prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE;
+			if (u4TcpUdpIpCksStatus & RX_CS_STATUS_IP) {	/* IP packet csum failed */
+				prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_FAILED;
+			} else {
+				prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_SUCCESS;
+			}
+
+			if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) {	/* TCP packet */
+				prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
+				if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) {	/* TCP packet csum failed */
+					prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED;
+				} else {
+					prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS;
+				}
+			} else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) {	/* UDP packet */
+				prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
+				if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) {	/* UDP packet csum failed */
+					prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED;
+				} else {
+					prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS;
+				}
+			} else {
+				prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
+				prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
+			}
+		} else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv6) {	/* IPv6 packet */
+			prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE;
+			prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS;
+
+			if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) {	/* TCP packet */
+				prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
+				if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) {	/* TCP packet csum failed */
+					prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED;
+				} else {
+					prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS;
+				}
+			} else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) {	/* UDP packet */
+				prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
+				if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) {	/* UDP packet csum failed */
+					prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED;
+				} else {
+					prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS;
+				}
+			} else {
+				prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
+				prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
+			}
+		} else {
+			prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE;
+			prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE;
+		}
+	}
+
+}
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process packet doesn't need to do buffer reordering
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_TX_CTRL_T prTxCtrl;
+	BOOLEAN fgIsRetained = FALSE;
+	UINT_32 u4CurrentRxBufferCount;
+	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
+
+	DEBUGFUNC("nicRxProcessPktWithoutReorder");
+	/* DBGLOG(RX, TRACE, ("\n")); */
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	ASSERT(prTxCtrl);
+
+	u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem;
+	/* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C
+	 * TOTAL = $A + $B + $C
+	 *
+	 * Case #1 (Retain)
+	 * -------------------------------------------------------
+	 * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C := $TOTAL - THRESHOLD < $C
+	 * => $C used too much, retain
+	 *
+	 * Case #2 (Non-Retain)
+	 * -------------------------------------------------------
+	 * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C := $TOTAL - THRESHOLD > $C
+	 * => still available for $C to use
+	 *
+	 */
+	fgIsRetained = (((u4CurrentRxBufferCount +
+			  qmGetRxReorderQueuedBufferCount(prAdapter) +
+			  prTxCtrl->i4PendingFwdFrameCount) < CFG_RX_RETAINED_PKT_THRESHOLD) ? TRUE : FALSE);
+
+	/* DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained)); */
+
+	if (kalProcessRxPacket(prAdapter->prGlueInfo,
+			       prSwRfb->pvPacket,
+			       prSwRfb->pvHeader,
+			       (UINT_32) prSwRfb->u2PacketLen, fgIsRetained, prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) {
+		DBGLOG(RX, ERROR, "kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n");
+		ASSERT(0);
+
+		nicRxReturnRFB(prAdapter, prSwRfb);
+		return;
+	}
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+		if (prStaRec) {
+#if CFG_ENABLE_WIFI_DIRECT
+			if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX && prAdapter->fgIsP2PRegistered == TRUE)
+				GLUE_SET_PKT_FLAG_P2P(prSwRfb->pvPacket);
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+			if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX)
+				GLUE_SET_PKT_FLAG_PAL(prSwRfb->pvPacket);
+#endif
+
+			/* record the count to pass to os */
+			STATS_RX_PASS2OS_INC(prStaRec, prSwRfb);
+		}
+		prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = prSwRfb->pvPacket;
+		prRxCtrl->ucNumIndPacket++;
+
+	if (fgIsRetained) {
+		prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = prSwRfb->pvPacket;
+		prRxCtrl->ucNumRetainedPacket++;
+		/* TODO : error handling of nicRxSetupRFB */
+		nicRxSetupRFB(prAdapter, prSwRfb);
+		nicRxReturnRFB(prAdapter, prSwRfb);
+	} else {
+		prSwRfb->pvPacket = NULL;
+		nicRxReturnRFB(prAdapter, prSwRfb);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process forwarding data packet
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_MSDU_INFO_T prMsduInfo, prRetMsduInfoList;
+	P_TX_CTRL_T prTxCtrl;
+	P_RX_CTRL_T prRxCtrl;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicRxProcessForwardPkt");
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	prRxCtrl = &prAdapter->rRxCtrl;
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+	QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+
+	if (prMsduInfo && kalProcessRxPacket(prAdapter->prGlueInfo,
+					     prSwRfb->pvPacket,
+					     prSwRfb->pvHeader,
+					     (UINT_32) prSwRfb->u2PacketLen,
+					     prRxCtrl->rFreeSwRfbList.u4NumElem <
+					     CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE,
+					     prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) {
+
+		prMsduInfo->eSrc = TX_PACKET_FORWARDING;
+		/* pack into MSDU_INFO_T */
+		nicTxFillMsduInfo(prAdapter, prMsduInfo, (P_NATIVE_PACKET) (prSwRfb->pvPacket));
+		/* Overwrite the ucNetworkType */
+		prMsduInfo->ucNetworkType = HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr);
+
+		/* release RX buffer (to rIndicatedRfbList) */
+		prSwRfb->pvPacket = NULL;
+		nicRxReturnRFB(prAdapter, prSwRfb);
+
+		/* increase forward frame counter */
+		GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
+
+		/* send into TX queue */
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+		prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, prMsduInfo);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+
+		if (prRetMsduInfoList != NULL) {	/* TX queue refuses queuing the packet */
+			nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList);
+			nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList);
+		}
+		/* indicate service thread for sending */
+		if (prTxCtrl->i4PendingFwdFrameCount > 0)
+			kalSetEvent(prAdapter->prGlueInfo);
+	} else		/* no TX resource */
+		nicRxReturnRFB(prAdapter, prSwRfb);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process broadcast data packet for both host and forwarding
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_SW_RFB_T prSwRfbDuplicated;
+	P_TX_CTRL_T prTxCtrl;
+	P_RX_CTRL_T prRxCtrl;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicRxProcessGOBroadcastPkt");
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	prRxCtrl = &prAdapter->rRxCtrl;
+
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	ASSERT(prHifRxHdr);
+
+	ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16);
+
+	if (prRxCtrl->rFreeSwRfbList.u4NumElem
+	    >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - 16 /* Reserved for others */))) {
+
+		/* 1. Duplicate SW_RFB_T */
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfbDuplicated, P_SW_RFB_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+		if (prSwRfbDuplicated) {
+			kalMemCopy(prSwRfbDuplicated->pucRecvBuff,
+				   prSwRfb->pucRecvBuff, ALIGN_4(prHifRxHdr->u2PacketLen + HIF_RX_HW_APPENDED_LEN));
+
+			prSwRfbDuplicated->ucPacketType = HIF_RX_PKT_TYPE_DATA;
+			prSwRfbDuplicated->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx);
+			nicRxFillRFB(prAdapter, prSwRfbDuplicated);
+
+			/* 2. Modify eDst */
+			prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD;
+
+			/* 4. Forward */
+			nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated);
+		}
+	} else {
+		DBGLOG(RX, WARN, "Stop to forward BMC packet due to less free Sw Rfb %u\n",
+				  prRxCtrl->rFreeSwRfbList.u4NumElem);
+	}
+
+	/* 3. Indicate to host */
+	prSwRfb->eDst = RX_PKT_DESTINATION_HOST;
+	nicRxProcessPktWithoutReorder(prAdapter, prSwRfb);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process HIF data packet
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_SW_RFB_T prRetSwRfb, prNextSwRfb;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	P_STA_RECORD_T prStaRec;
+	BOOLEAN fIsDummy = FALSE;
+
+	DEBUGFUNC("nicRxProcessDataPacket");
+	/* DBGLOG(RX, TRACE, ("\n")); */
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	prRxCtrl = &prAdapter->rRxCtrl;
+
+	fIsDummy = (prHifRxHdr->u2PacketLen >= 12) ? FALSE : TRUE;
+
+	nicRxFillRFB(prAdapter, prSwRfb);
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60
+	{
+		UINT_32 u4TcpUdpIpCksStatus;
+
+		u4TcpUdpIpCksStatus = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen))));
+		nicRxFillChksumStatus(prAdapter, prSwRfb, u4TcpUdpIpCksStatus);
+
+	}
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prHifRxHdr->ucStaRecIdx);
+	if (secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE && prAdapter->fgTestMode == FALSE) {
+#if CFG_HIF_RX_STARVATION_WARNING
+		prRxCtrl->u4QueuedCnt++;
+#endif
+		prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb);
+		if (prRetSwRfb != NULL) {
+			do {
+				/* save next first */
+				prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prRetSwRfb);
+				if (fIsDummy == TRUE) {
+					nicRxReturnRFB(prAdapter, prRetSwRfb);
+					RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
+					DBGLOG(RX, WARN, "Drop Dummy Packets");
+
+				} else {
+					switch (prRetSwRfb->eDst) {
+					case RX_PKT_DESTINATION_HOST:
+#if ARP_MONITER_ENABLE
+					if (IS_STA_IN_AIS(prStaRec))
+						qmHandleRxArpPackets(prAdapter, prRetSwRfb);
+#endif
+						nicRxProcessPktWithoutReorder(prAdapter, prRetSwRfb);
+						break;
+
+					case RX_PKT_DESTINATION_FORWARD:
+						nicRxProcessForwardPkt(prAdapter, prRetSwRfb);
+						break;
+
+					case RX_PKT_DESTINATION_HOST_WITH_FORWARD:
+						nicRxProcessGOBroadcastPkt(prAdapter, prRetSwRfb);
+						break;
+
+					case RX_PKT_DESTINATION_NULL:
+						nicRxReturnRFB(prAdapter, prRetSwRfb);
+						RX_INC_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT);
+						RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
+						break;
+
+					default:
+						break;
+					}
+				}
+#if CFG_HIF_RX_STARVATION_WARNING
+				prRxCtrl->u4DequeuedCnt++;
+#endif
+				prRetSwRfb = prNextSwRfb;
+			} while (prRetSwRfb);
+		}
+	} else {
+		nicRxReturnRFB(prAdapter, prSwRfb);
+		RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT);
+		RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process HIF event packet
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+
+UINT_8 nicRxProcessGSCNEvent(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb)
+{
+	P_WIFI_EVENT_T prEvent;
+	P_GLUE_INFO_T prGlueInfo;
+	struct sk_buff *skb;
+	struct wiphy *wiphy;
+
+	UINT_32 real_num = 0;
+
+	P_EVENT_GSCAN_SCAN_AVAILABLE_T prEventGscnAvailable;
+	P_EVENT_GSCAN_RESULT_T prEventBuffer;
+	P_WIFI_GSCAN_RESULT_T prEventGscnResult;
+	INT_32 i4Status = -EINVAL;
+	struct nlattr *attr;
+	UINT_32 scan_id;
+	UINT_8 scan_flag;
+	P_EVENT_GSCAN_CAPABILITY_T prEventGscnCapbiblity;
+	P_EVENT_GSCAN_SCAN_COMPLETE_T prEventGscnScnDone;
+	P_WIFI_GSCAN_RESULT_T prEventGscnFullResult;
+	P_PARAM_WIFI_GSCAN_RESULT prParamGscnFullResult;
+	P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnSignificantChange;
+	P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnGeofenceFound;
+
+	P_PARAM_WIFI_GSCAN_RESULT prResults;
+
+	DEBUGFUNC("nicRxProcessGSCNEvent");
+	/* DBGLOG(RX, TRACE, ("\n")); */
+
+	DBGLOG(SCN, INFO, "nicRxProcessGSCNEvent\n");
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff;
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	/* Push the data to the skb */
+	wiphy = priv_to_wiphy(prGlueInfo);
+
+	/* prGlueInfo-> */
+
+	/* Event Handling */
+	switch (prEvent->ucEID) {
+	case EVENT_ID_GSCAN_SCAN_AVAILABLE:
+		{
+			DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n");
+
+			prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer);
+			memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer),
+			       sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T));
+
+			mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr,
+									 prEventGscnAvailable->u2Num);
+		}
+		break;
+
+	case EVENT_ID_GSCAN_RESULT:
+		{
+			DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_RESULT 2\n");
+
+			prEventBuffer = (P_EVENT_GSCAN_RESULT_T) (prEvent->aucBuffer);
+			prEventGscnResult = prEventBuffer->rResult;
+/*
+    the following event struct should moved to kal and use the kal api to avoid future porting effort
+
+*/
+			scan_id = prEventBuffer->u2ScanId;
+			scan_flag = prEventBuffer->u2ScanFlags;
+			real_num = prEventBuffer->u2NumOfResults;
+
+			DBGLOG(SCN, INFO, "scan_id=%d, scan_flag =%d, real_num=%d\r\n", scan_id, scan_flag, real_num);
+
+			skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num);
+			if (!skb) {
+				DBGLOG(RX, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status);
+				return -ENOMEM;
+			}
+
+			attr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS);
+			/*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_SCAN_ID, scan_id);*/
+			{
+				unsigned int __tmp = scan_id;
+
+				if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_ID, sizeof(unsigned int), &__tmp) < 0))
+					goto nla_put_failure;
+			}
+			/*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, 1);*/
+			{
+				unsigned char __tmp = 1;
+
+				if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, sizeof(u8), &__tmp) < 0))
+					goto nla_put_failure;
+			}
+			/*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, real_num);*/
+			{
+				unsigned int __tmp = real_num;
+
+				if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS,
+					sizeof(unsigned int), &__tmp) < 0))
+					goto nla_put_failure;
+			}
+
+			prResults = (P_PARAM_WIFI_GSCAN_RESULT) prEventGscnResult;
+			if (prResults)
+				DBGLOG(SCN, INFO, "ssid=%s, rssi=%d, channel=%d \r\n",
+					prResults->ssid, prResults->rssi, prResults->channel);
+			/*NLA_PUT(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num,
+					prResults);*/
+
+			if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS,
+				sizeof(PARAM_WIFI_GSCAN_RESULT)*real_num, prResults) < 0))
+				goto nla_put_failure;
+
+			DBGLOG(SCN, INFO, "NLA_PUT scan results over\t");
+
+			if (attr)
+				nla_nest_end(skb, attr);
+			/* report_events=1 */
+			/*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, 1);*/
+			{
+				unsigned char __tmp = 1;
+
+				if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE,
+					sizeof(unsigned int), &__tmp) < 0))
+					goto nla_put_failure;
+			}
+
+
+			i4Status = cfg80211_vendor_cmd_reply(skb);
+			skb = NULL;
+			DBGLOG(SCN, INFO, " i4Status %d\n", i4Status);
+		}
+		break;
+
+	case EVENT_ID_GSCAN_CAPABILITY:
+		{
+			DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_CAPABILITY\n");
+
+			prEventGscnCapbiblity = (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer);
+			memcpy(prEventGscnCapbiblity, (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer),
+			       sizeof(EVENT_GSCAN_CAPABILITY_T));
+
+			mtk_cfg80211_vendor_get_gscan_capabilities(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr,
+				prEventGscnCapbiblity, sizeof(EVENT_GSCAN_CAPABILITY_T));
+		}
+		break;
+
+	case EVENT_ID_GSCAN_SCAN_COMPLETE:
+		{
+			DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n");
+			prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer);
+			memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer),
+			       sizeof(EVENT_GSCAN_SCAN_COMPLETE_T));
+
+			mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr,
+								prEventGscnScnDone->ucScanState);
+		}
+		break;
+
+	case EVENT_ID_GSCAN_FULL_RESULT:
+		{
+			DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_FULL_RESULT\n");
+
+			prEventGscnFullResult = kalMemAlloc(sizeof(WIFI_GSCAN_RESULT_T), VIR_MEM_TYPE);
+			if (prEventGscnFullResult)
+				memcpy(prEventGscnFullResult, (P_WIFI_GSCAN_RESULT_T) (prEvent->aucBuffer),
+					sizeof(WIFI_GSCAN_RESULT_T));
+
+			prParamGscnFullResult = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_RESULT), VIR_MEM_TYPE);
+			if (prEventGscnFullResult && prParamGscnFullResult) {
+				kalMemZero(prParamGscnFullResult, sizeof(PARAM_WIFI_GSCAN_RESULT));
+				memcpy(prParamGscnFullResult, prEventGscnFullResult, sizeof(WIFI_GSCAN_RESULT_T));
+
+				mtk_cfg80211_vendor_event_full_scan_results(wiphy,
+								    prGlueInfo->prDevHandler->ieee80211_ptr,
+								    prParamGscnFullResult,
+								    sizeof(PARAM_WIFI_GSCAN_RESULT));
+			}
+		}
+		break;
+
+	case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE:
+		{
+			prEventGscnSignificantChange = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer);
+			memcpy(prEventGscnSignificantChange, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer),
+			       sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T));
+		}
+		break;
+
+	case EVENT_ID_GSCAN_GEOFENCE_FOUND:
+		{
+			prEventGscnGeofenceFound = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer);
+			memcpy(prEventGscnGeofenceFound, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer),
+			       sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T));
+		}
+		break;
+
+	default:
+		DBGLOG(SCN, INFO, "not GSCN event ????\n");
+		break;
+	}
+
+	DBGLOG(SCN, INFO, "Done with GSCN event handling\n");
+	return real_num;	/* cfg80211_vendor_cmd_reply(skb); */
+
+nla_put_failure:
+	if (skb != NULL)
+		kfree_skb(skb);
+	DBGLOG(SCN, INFO, "nla_put_failure\n");
+	return 0;		/* cfg80211_vendor_cmd_reply(skb); */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process HIF event packet
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+*
+* @return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb)
+{
+	P_CMD_INFO_T prCmdInfo;
+	P_MSDU_INFO_T prMsduInfo;
+	P_WIFI_EVENT_T prEvent;
+	P_GLUE_INFO_T prGlueInfo;
+
+	DEBUGFUNC("nicRxProcessEventPacket");
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff;
+	prGlueInfo = prAdapter->prGlueInfo;
+
+	DBGLOG(RX, EVENT, "prEvent->ucEID = 0x%02x\n", prEvent->ucEID);
+	/* Event Handling */
+	switch (prEvent->ucEID) {
+	case EVENT_ID_CMD_RESULT:
+		prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
+
+		if (prCmdInfo != NULL) {
+			P_EVENT_CMD_RESULT prCmdResult;
+
+			prCmdResult = (P_EVENT_CMD_RESULT) ((PUINT_8) prEvent + EVENT_HDR_SIZE);
+
+			/* CMD_RESULT should be only in response to Set commands */
+			ASSERT(prCmdInfo->fgSetQuery == FALSE || prCmdInfo->fgNeedResp == TRUE);
+
+			if (prCmdResult->ucStatus == 0) {	/* success */
+				if (prCmdInfo->pfCmdDoneHandler) {
+					prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
+				} else if (prCmdInfo->fgIsOid == TRUE) {
+					kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0,
+						       WLAN_STATUS_SUCCESS);
+				}
+			} else if (prCmdResult->ucStatus == 1) {	/* reject */
+				if (prCmdInfo->fgIsOid == TRUE)
+					kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0,
+						       WLAN_STATUS_FAILURE);
+			} else if (prCmdResult->ucStatus == 2) {	/* unknown CMD */
+				if (prCmdInfo->fgIsOid == TRUE)
+					kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0,
+						       WLAN_STATUS_NOT_SUPPORTED);
+			}
+			/* return prCmdInfo */
+			cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+		}
+
+		break;
+
+#if 0
+	case EVENT_ID_CONNECTION_STATUS:
+		/* OBSELETE */
+		{
+			P_EVENT_CONNECTION_STATUS prConnectionStatus;
+
+			prConnectionStatus = (P_EVENT_CONNECTION_STATUS) (prEvent->aucBuffer);
+
+			DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", prConnectionStatus->ucMediaStatus);
+			if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) {
+				/* disconnected */
+				if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) {
+
+					kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
+
+					prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
+				}
+			} else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) {
+				/* connected */
+				prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
+
+				/* fill information for association result */
+				prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen;
+				kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
+					   prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen);
+
+				kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress,
+					prConnectionStatus->aucBssid, MAC_ADDR_LEN);
+
+				/* @FIXME */
+				prAdapter->rWlanInfo.rCurrBssId.u4Privacy = prConnectionStatus->ucEncryptStatus;
+				prAdapter->rWlanInfo.rCurrBssId.rRssi = 0;	/* @FIXME */
+				/* @FIXME */
+				prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse = PARAM_NETWORK_TYPE_AUTOMODE;
+				prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod
+					= prConnectionStatus->u2BeaconPeriod;
+				prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow
+					= prConnectionStatus->u2ATIMWindow;
+				prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig
+					= prConnectionStatus->u4FreqInKHz;
+				prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType;
+
+				switch (prConnectionStatus->ucInfraMode) {
+				case 0:
+					prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_IBSS;
+					break;
+				case 1:
+					prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_INFRA;
+					break;
+				case 2:
+				default:
+					prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_AUTO_SWITCH;
+					break;
+				}
+				/* always indicate to OS according to MSDN (re-association/roaming) */
+				kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0);
+			}
+		}
+		break;
+
+	case EVENT_ID_SCAN_RESULT:
+		/* OBSELETE */
+		break;
+#endif
+
+	case EVENT_ID_RX_ADDBA:
+		/* The FW indicates that an RX BA agreement will be established */
+		qmHandleEventRxAddBa(prAdapter, prEvent);
+		break;
+
+	case EVENT_ID_RX_DELBA:
+		/* The FW indicates that an RX BA agreement has been deleted */
+		qmHandleEventRxDelBa(prAdapter, prEvent);
+		break;
+
+	case EVENT_ID_LINK_QUALITY:
+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY
+		if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof(EVENT_LINK_QUALITY_EX)) {
+			P_EVENT_LINK_QUALITY_EX prLqEx = (P_EVENT_LINK_QUALITY_EX) (prEvent->aucBuffer);
+
+			if (prLqEx->ucIsLQ0Rdy)
+				nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) prLqEx);
+			if (prLqEx->ucIsLQ1Rdy)
+				nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_P2P_INDEX, (P_EVENT_LINK_QUALITY) prLqEx);
+		} else {
+			/* For old FW, P2P may invoke link quality query, and make driver flag becone TRUE. */
+			DBGLOG(P2P, WARN, "Old FW version, not support P2P RSSI query.\n");
+
+			/* Must not use NETWORK_TYPE_P2P_INDEX, cause the structure is mismatch. */
+			nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX,
+					     (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer));
+		}
+#else
+		nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer));
+#endif
+
+		/* command response handling */
+		prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
+
+		if (prCmdInfo != NULL) {
+			if (prCmdInfo->pfCmdDoneHandler)
+				prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
+			else if (prCmdInfo->fgIsOid)
+				kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
+			/* return prCmdInfo */
+			cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+		}
+#ifndef LINUX
+		if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_GREATER &&
+		    prAdapter->rWlanInfo.rRssiTriggerValue >= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) {
+			prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED;
+
+			kalIndicateStatusAndComplete(prGlueInfo,
+						     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+						     (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue),
+						     sizeof(PARAM_RSSI));
+		} else if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_LESS
+			   && prAdapter->rWlanInfo.rRssiTriggerValue <= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) {
+			prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED;
+
+			kalIndicateStatusAndComplete(prGlueInfo,
+						     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+						     (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue),
+						     sizeof(PARAM_RSSI));
+		}
+#endif
+
+		break;
+
+	case EVENT_ID_MIC_ERR_INFO:
+		{
+			P_EVENT_MIC_ERR_INFO prMicError;
+			/* P_PARAM_AUTH_EVENT_T prAuthEvent; */
+			P_STA_RECORD_T prStaRec;
+
+			DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n");
+
+			prMicError = (P_EVENT_MIC_ERR_INFO) (prEvent->aucBuffer);
+			prStaRec = cnmGetStaRecByAddress(prAdapter,
+							 (UINT_8) NETWORK_TYPE_AIS_INDEX,
+							 prAdapter->rWlanInfo.rCurrBssId.arMacAddress);
+			ASSERT(prStaRec);
+
+			if (prStaRec)
+				rsnTkipHandleMICFailure(prAdapter, prStaRec, (BOOLEAN) prMicError->u4Flags);
+			else
+				DBGLOG(RSN, WARN, "No STA rec!!\n");
+#if 0
+			prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer;
+
+			/* Status type: Authentication Event */
+			prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION;
+
+			/* Authentication request */
+			prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T);
+			kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid,
+				(PVOID) prAdapter->rWlanInfo.rCurrBssId.arMacAddress,
+				/* whsu:Todo? */PARAM_MAC_ADDR_LEN);
+
+			if (prMicError->u4Flags != 0)
+				prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR;
+			else
+				prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR;
+
+			kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+						     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+						     (PVOID) prAuthEvent,
+						     sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T));
+#endif
+		}
+		break;
+
+	case EVENT_ID_ASSOC_INFO:
+		{
+			P_EVENT_ASSOC_INFO prAssocInfo;
+
+			prAssocInfo = (P_EVENT_ASSOC_INFO) (prEvent->aucBuffer);
+
+			kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo);
+		}
+		break;
+
+	case EVENT_ID_802_11_PMKID:
+		{
+			P_PARAM_AUTH_EVENT_T prAuthEvent;
+			PUINT_8 cp;
+			UINT_32 u4LenOfUsedBuffer;
+
+			prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer;
+
+			prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST;
+
+			u4LenOfUsedBuffer = (UINT_32) (prEvent->u2PacketLen - 8);
+
+			prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer;
+
+			cp = (PUINT_8) &prAuthEvent->arRequest[0];
+
+			/* Status type: PMKID Candidatelist Event */
+			kalMemCopy(cp, (P_EVENT_PMKID_CANDIDATE_LIST_T) (prEvent->aucBuffer), prEvent->u2PacketLen - 8);
+
+			kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+						     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
+						     (PVOID) prAuthEvent,
+						     sizeof(PARAM_STATUS_INDICATION_T) + u4LenOfUsedBuffer);
+		}
+		break;
+
+#if 0
+	case EVENT_ID_ACTIVATE_STA_REC_T:
+		{
+			P_EVENT_ACTIVATE_STA_REC_T prActivateStaRec;
+
+			prActivateStaRec = (P_EVENT_ACTIVATE_STA_REC_T) (prEvent->aucBuffer);
+
+			DbgPrint("RX EVENT: EVENT_ID_ACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n",
+				 prActivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr);
+
+			qmActivateStaRec(prAdapter,
+					 (UINT_32) prActivateStaRec->ucStaRecIdx,
+					 ((prActivateStaRec->fgIsQoS) ? TRUE : FALSE),
+					 prActivateStaRec->ucNetworkTypeIndex,
+					 ((prActivateStaRec->fgIsAP) ? TRUE : FALSE), prActivateStaRec->aucMacAddr);
+
+		}
+		break;
+
+	case EVENT_ID_DEACTIVATE_STA_REC_T:
+		{
+			P_EVENT_DEACTIVATE_STA_REC_T prDeactivateStaRec;
+
+			prDeactivateStaRec = (P_EVENT_DEACTIVATE_STA_REC_T) (prEvent->aucBuffer);
+
+			DbgPrint("RX EVENT: EVENT_ID_DEACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n",
+				 prDeactivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr);
+
+			qmDeactivateStaRec(prAdapter, prDeactivateStaRec->ucStaRecIdx);
+		}
+		break;
+#endif
+
+	case EVENT_ID_SCAN_DONE:
+		scnEventScanDone(prAdapter, (P_EVENT_SCAN_DONE) (prEvent->aucBuffer));
+		break;
+
+	case EVENT_ID_TX_DONE_STATUS:
+		STATS_TX_PKT_DONE_INFO_DISPLAY(prAdapter, prEvent->aucBuffer);
+		break;
+
+	case EVENT_ID_TX_DONE:
+	{
+		P_EVENT_TX_DONE_T prTxDone;
+
+		prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer);
+		if (prTxDone->ucStatus)
+			DBGLOG(RX, INFO, "EVENT_ID_TX_DONE PacketSeq:%u ucStatus: %u SN: %u\n",
+					    prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber);
+
+		/* call related TX Done Handler */
+		prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucPacketSeq);
+
+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
+		DBGLOG(RX, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n",
+					    prTxDone->au4Reserved1, prTxDone->au4Reserved2);
+
+		wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex,
+					   prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2);
+#endif
+
+		if (prMsduInfo) {
+			prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo,
+							   (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus));
+
+			cnmMgtPktFree(prAdapter, prMsduInfo);
+		}
+	}
+		break;
+	case EVENT_ID_SLEEPY_NOTIFY:
+		{
+			P_EVENT_SLEEPY_NOTIFY prEventSleepyNotify;
+
+			prEventSleepyNotify = (P_EVENT_SLEEPY_NOTIFY) (prEvent->aucBuffer);
+
+			/* DBGLOG(RX, INFO, ("ucSleepyState = %d\n", prEventSleepyNotify->ucSleepyState)); */
+
+			prAdapter->fgWiFiInSleepyState = (BOOLEAN) (prEventSleepyNotify->ucSleepyState);
+		}
+		break;
+	case EVENT_ID_BT_OVER_WIFI:
+#if CFG_ENABLE_BT_OVER_WIFI
+		{
+			UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)];
+			P_EVENT_BT_OVER_WIFI prEventBtOverWifi;
+			P_AMPC_EVENT prBowEvent;
+			P_BOW_LINK_CONNECTED prBowLinkConnected;
+			P_BOW_LINK_DISCONNECTED prBowLinkDisconnected;
+
+			prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer);
+
+			/* construct event header */
+			prBowEvent = (P_AMPC_EVENT) aucTmp;
+
+			if (prEventBtOverWifi->ucLinkStatus == 0) {
+				/* Connection */
+				prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED;
+				prBowEvent->rHeader.ucSeqNumber = 0;
+				prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED);
+
+				/* fill event body */
+				prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prBowEvent->aucPayload);
+				prBowLinkConnected->rChannel.ucChannelNum = prEventBtOverWifi->ucSelectedChannel;
+				kalMemZero(prBowLinkConnected->aucPeerAddress, MAC_ADDR_LEN);	/* @FIXME */
+
+				kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent);
+			} else {
+				/* Disconnection */
+				prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED;
+				prBowEvent->rHeader.ucSeqNumber = 0;
+				prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED);
+
+				/* fill event body */
+				prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prBowEvent->aucPayload);
+				prBowLinkDisconnected->ucReason = 0;	/* @FIXME */
+				kalMemZero(prBowLinkDisconnected->aucPeerAddress, MAC_ADDR_LEN);	/* @FIXME */
+
+				kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent);
+			}
+		}
+		break;
+#endif
+	case EVENT_ID_STATISTICS:
+		/* buffer statistics for further query */
+		prAdapter->fgIsStatValid = TRUE;
+		prAdapter->rStatUpdateTime = kalGetTimeTick();
+		kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, sizeof(EVENT_STATISTICS));
+
+		/* command response handling */
+		prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
+
+		if (prCmdInfo != NULL) {
+			if (prCmdInfo->pfCmdDoneHandler)
+				prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
+			else if (prCmdInfo->fgIsOid)
+				kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
+			/* return prCmdInfo */
+			cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+		}
+
+		break;
+
+	case EVENT_ID_CH_PRIVILEGE:
+		cnmChMngrHandleChEvent(prAdapter, prEvent);
+		break;
+
+	case EVENT_ID_BSS_ABSENCE_PRESENCE:
+		qmHandleEventBssAbsencePresence(prAdapter, prEvent);
+		break;
+
+	case EVENT_ID_STA_CHANGE_PS_MODE:
+		qmHandleEventStaChangePsMode(prAdapter, prEvent);
+		break;
+#if CFG_ENABLE_WIFI_DIRECT
+	case EVENT_ID_STA_UPDATE_FREE_QUOTA:
+		qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent);
+		break;
+#endif
+	case EVENT_ID_BSS_BEACON_TIMEOUT:
+		if (prAdapter->fgDisBcnLostDetection == FALSE) {
+			P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout;
+
+			prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T) (prEvent->aucBuffer);
+
+			DBGLOG(RX, INFO, "Beacon Timeout Reason = %u\n", prEventBssBeaconTimeout->ucReason);
+
+			if (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
+				/* Request stats report before beacon timeout */
+				P_BSS_INFO_T prBssInfo;
+				P_STA_RECORD_T prStaRec;
+
+				prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+				if (prBssInfo) {
+					prStaRec = cnmGetStaRecByAddress(prAdapter,
+									NETWORK_TYPE_AIS_INDEX,
+									prBssInfo->aucBSSID);
+					if (prStaRec)
+						STATS_ENV_REPORT_DETECT(prAdapter, prStaRec->ucIndex);
+				}
+				aisBssBeaconTimeout(prAdapter);
+			}
+#if CFG_ENABLE_WIFI_DIRECT
+			else if ((prAdapter->fgIsP2PRegistered) &&
+				 (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX))
+
+				p2pFsmRunEventBeaconTimeout(prAdapter);
+#endif
+			else {
+				DBGLOG(RX, ERROR, "EVENT_ID_BSS_BEACON_TIMEOUT: (ucNetTypeIdx = %d)\n",
+						   prEventBssBeaconTimeout->ucNetTypeIndex);
+			}
+		}
+
+		break;
+	case EVENT_ID_UPDATE_NOA_PARAMS:
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered) {
+			P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam;
+
+			prEventUpdateNoaParam = (P_EVENT_UPDATE_NOA_PARAMS_T) (prEvent->aucBuffer);
+
+			if (prEventUpdateNoaParam->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
+				p2pProcessEvent_UpdateNOAParam(prAdapter,
+							       prEventUpdateNoaParam->ucNetTypeIndex,
+							       prEventUpdateNoaParam);
+			} else {
+				ASSERT(0);
+			}
+		}
+#else
+		ASSERT(0);
+#endif
+		break;
+
+	case EVENT_ID_STA_AGING_TIMEOUT:
+#if CFG_ENABLE_WIFI_DIRECT
+		{
+			if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) {
+				P_EVENT_STA_AGING_TIMEOUT_T prEventStaAgingTimeout;
+				P_STA_RECORD_T prStaRec;
+				P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL;
+
+				prEventStaAgingTimeout = (P_EVENT_STA_AGING_TIMEOUT_T) (prEvent->aucBuffer);
+				prStaRec = cnmGetStaRecByIndex(prAdapter, prEventStaAgingTimeout->ucStaRecIdx);
+				if (prStaRec == NULL)
+					break;
+
+				DBGLOG(RX, INFO, "EVENT_ID_STA_AGING_TIMEOUT %u %pM\n",
+						    prEventStaAgingTimeout->ucStaRecIdx,
+						    prStaRec->aucMacAddr);
+
+				prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+				bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec);
+
+				/* Call False Auth */
+				if (prAdapter->fgIsP2PRegistered)
+					p2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY);
+
+			}
+			/* gDisStaAgingTimeoutDetection */
+		}
+#endif
+		break;
+
+	case EVENT_ID_AP_OBSS_STATUS:
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered)
+			rlmHandleObssStatusEventPkt(prAdapter, (P_EVENT_AP_OBSS_STATUS_T) prEvent->aucBuffer);
+#endif
+		break;
+
+	case EVENT_ID_ROAMING_STATUS:
+#if CFG_SUPPORT_ROAMING
+		{
+			P_ROAMING_PARAM_T prParam;
+
+			prParam = (P_ROAMING_PARAM_T) (prEvent->aucBuffer);
+			roamingFsmProcessEvent(prAdapter, prParam);
+		}
+#endif /* CFG_SUPPORT_ROAMING */
+		break;
+	case EVENT_ID_SEND_DEAUTH:
+		{
+			P_WLAN_MAC_HEADER_T prWlanMacHeader;
+			P_STA_RECORD_T prStaRec;
+
+			prWlanMacHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0];
+			DBGLOG(RSN, INFO, "nicRx: aucAddr1: %pM, nicRx: aucAddr2: %pM\n",
+					prWlanMacHeader->aucAddr1, prWlanMacHeader->aucAddr2);
+			prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanMacHeader->aucAddr2);
+			if (prStaRec != NULL && prStaRec->ucStaState == STA_STATE_3) {
+				DBGLOG(RSN, WARN, "Ignore Deauth for Rx Class 3 error!\n");
+			} else {
+				/* receive packets without StaRec */
+				prSwRfb->pvHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0];
+				if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter,
+									       NULL,
+									       prSwRfb,
+									       REASON_CODE_CLASS_3_ERR,
+									       (PFN_TX_DONE_HANDLER) NULL))
+					DBGLOG(RSN, INFO, "Send Deauth for Rx Class3 Error\n");
+				else
+					DBGLOG(RSN, WARN, "failed to send deauth for Rx class3 error\n");
+			}
+		}
+		break;
+
+#if CFG_SUPPORT_RDD_TEST_MODE
+	case EVENT_ID_UPDATE_RDD_STATUS:
+		{
+			P_EVENT_RDD_STATUS_T prEventRddStatus;
+
+			prEventRddStatus = (P_EVENT_RDD_STATUS_T) (prEvent->aucBuffer);
+
+			prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus;
+		}
+
+		break;
+#endif
+
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
+	case EVENT_ID_UPDATE_BWCS_STATUS:
+		{
+			P_PTA_IPC_T prEventBwcsStatus;
+
+			prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer);
+
+#if CFG_SUPPORT_BCM_BWCS_DEBUG
+			DBGLOG(RSN, INFO,
+			"BCM BWCS Event: %02x%02x%02x%02x\n",
+			prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1],
+			prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]);
+
+			DBGLOG(RSN, INFO,
+			"BCM BWCS Event: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n",
+			prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1],
+			prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]);
+#endif
+
+			kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
+						     WLAN_STATUS_BWCS_UPDATE,
+						     (PVOID) prEventBwcsStatus, sizeof(PTA_IPC_T));
+		}
+
+		break;
+
+	case EVENT_ID_UPDATE_BCM_DEBUG:
+		{
+			P_PTA_IPC_T prEventBwcsStatus;
+
+			prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer);
+
+#if CFG_SUPPORT_BCM_BWCS_DEBUG
+			DBGLOG(RSN, INFO,
+			"BCM FW status: %02x%02x%02x%02x\n",
+			prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1],
+			prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]);
+
+			DBGLOG(RSN, INFO,
+			"BCM FW status: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n",
+			prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1],
+			prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3];
+#endif
+		}
+
+		break;
+#endif
+
+	case EVENT_ID_DEBUG_CODE:	/* only for debug */
+		{
+			UINT_32 u4CodeId;
+
+			DBGLOG(RSN, INFO, "[wlan-fw] function sequence: ");
+			for (u4CodeId = 0; u4CodeId < 1000; u4CodeId++)
+				DBGLOG(RSN, INFO, "%d ", prEvent->aucBuffer[u4CodeId]);
+			DBGLOG(RSN, INFO, "\n\n");
+		}
+		break;
+
+	case EVENT_ID_RFTEST_READY:
+
+		/* command response handling */
+		prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
+
+		if (prCmdInfo != NULL) {
+			if (prCmdInfo->pfCmdDoneHandler)
+				prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
+			else if (prCmdInfo->fgIsOid)
+				kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
+			/* return prCmdInfo */
+			cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+		}
+
+		break;
+
+	case EVENT_ID_GSCAN_SCAN_AVAILABLE:
+	case EVENT_ID_GSCAN_CAPABILITY:
+	case EVENT_ID_GSCAN_SCAN_COMPLETE:
+	case EVENT_ID_GSCAN_FULL_RESULT:
+	case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE:
+	case EVENT_ID_GSCAN_GEOFENCE_FOUND:
+		nicRxProcessGSCNEvent(prAdapter, prSwRfb);
+		break;
+
+	case EVENT_ID_GSCAN_RESULT:
+		{
+
+			UINT_8 realnum = 0;
+
+			DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent  ----->\n");
+			realnum = nicRxProcessGSCNEvent(prAdapter, prSwRfb);
+			DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent  <-----\n");
+
+#if 0			/* workaround for FW events cnt mis-match with the actual reqirements from wifi_hal */
+			if (g_GetResultsCmdCnt == 0) {
+				DBGLOG(SCN, INFO,
+					"FW report events more than the wifi_hal asked number, buffer the results\n");
+				UINT_8 i = 0;
+
+				for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) {
+#if 1
+					if (!g_arGscanResultsIndicateNumber[i]) {
+						DBGLOG(SCN, INFO,
+						"found available index %d to insert results number %d into buffer\r\n",
+						i, realnum);
+
+						g_arGscnResultsTempBuffer[i] = prSwRfb;
+						g_arGscanResultsIndicateNumber[i] = realnum;
+						g_GetResultsBufferedCnt++;
+						fgKeepprSwRfb = TRUE;
+						DBGLOG(SCN, INFO, "results buffered in index[%d] \r\n", i);
+						break;
+					}
+#endif
+				}
+				if (i == MAX_BUFFERED_GSCN_RESULTS)
+					DBGLOG(SCN, INFO,
+					"Gscn results buffer is full(all valid), no space to buffer result\r\n");
+			} else if (g_GetResultsCmdCnt > 0) {
+				DBGLOG(SCN, INFO, "FW report events match the wifi_hal asked number\n");
+				g_GetResultsCmdCnt--;
+			} else
+				DBGLOG(SCN, INFO, "g_GetResultsCmdCnt < 0 ??? unexpected case\n");
+#endif
+			/* end of workaround */
+
+		}
+		break;
+
+	case EVENT_ID_NLO_DONE:
+		prAdapter->rWifiVar.rScanInfo.fgPscnOnnning = FALSE;
+
+		DBGLOG(INIT, INFO, "EVENT_ID_NLO_DONE\n");
+		scnEventNloDone(prAdapter, (P_EVENT_NLO_DONE_T) (prEvent->aucBuffer));
+
+		break;
+
+#if CFG_SUPPORT_BATCH_SCAN
+	case EVENT_ID_BATCH_RESULT:
+		DBGLOG(SCN, TRACE, "Got EVENT_ID_BATCH_RESULT");
+
+		/* command response handling */
+		prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
+
+		if (prCmdInfo != NULL) {
+			if (prCmdInfo->pfCmdDoneHandler)
+				prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
+			else if (prCmdInfo->fgIsOid)
+				kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
+			/* return prCmdInfo */
+			cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+		}
+
+		break;
+#endif /* CFG_SUPPORT_BATCH_SCAN */
+
+#if (CFG_SUPPORT_TDLS == 1)
+	case EVENT_ID_TDLS:
+		TdlsexEventHandle(prAdapter->prGlueInfo,
+				  (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8));
+		break;
+#endif /* CFG_SUPPORT_TDLS */
+
+#if (CFG_SUPPORT_STATISTICS == 1)
+	case EVENT_ID_STATS_ENV:
+		statsEventHandle(prAdapter->prGlueInfo,
+				 (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8));
+		break;
+#endif /* CFG_SUPPORT_STATISTICS */
+
+	case EVENT_ID_FW_LOG_ENV:
+		{
+			P_EVENT_FW_LOG_T prEventLog;
+
+			prEventLog = (P_EVENT_FW_LOG_T) (prEvent->aucBuffer);
+			DBGLOG(RX, INFO, "[F-L]%s\n", prEventLog->log);
+		}
+		break;
+
+	default:
+		prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
+
+		if (prCmdInfo != NULL) {
+			if (prCmdInfo->pfCmdDoneHandler)
+				prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
+			else if (prCmdInfo->fgIsOid)
+				kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
+			/* return prCmdInfo */
+			cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+		}
+
+		break;
+	}
+
+	nicRxReturnRFB(prAdapter, prSwRfb);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief nicRxProcessMgmtPacket is used to dispatch management frames
+*        to corresponding modules
+*
+* @param prAdapter Pointer to the Adapter structure.
+* @param prSWRfb the RFB to receive rx data
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb)
+{
+	UINT_8 ucSubtype;
+#if CFG_SUPPORT_802_11W
+	BOOLEAN fgMfgDrop = FALSE;
+#endif
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	nicRxFillRFB(prAdapter, prSwRfb);
+
+	ucSubtype = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE;
+
+#if 0				/* CFG_RX_PKTS_DUMP */
+	{
+		P_HIF_RX_HEADER_T prHifRxHdr;
+		UINT_16 u2TxFrameCtrl;
+
+		prHifRxHdr = prSwRfb->prHifRxHdr;
+		u2TxFrameCtrl = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FRAME_TYPE);
+		/* if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_MANAGEMENT)) { */
+		/* if (u2TxFrameCtrl == MAC_FRAME_BEACON || */
+		/* u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { */
+
+		DBGLOG(RX, INFO, "QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n",
+		(UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), prHifRxHdr->ucStaRecIdx,
+		prSwRfb->ucWlanIdx, (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr),/* The new SN of the frame */
+		prSwRfb->ucPacketType, ucSubtype, HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr));
+
+		/* DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prSwRfb->pvHeader, prSwRfb->u2PacketLen); */
+		/* } */
+		/* } */
+	}
+#endif
+
+	if ((prAdapter->fgTestMode == FALSE) && (prAdapter->prGlueInfo->fgIsRegistered == TRUE)) {
+#if CFG_MGMT_FRAME_HANDLING
+#if CFG_SUPPORT_802_11W
+		fgMfgDrop = rsnCheckRxMgmt(prAdapter, prSwRfb, ucSubtype);
+		if (fgMfgDrop) {
+#if DBG
+			LOG_FUNC("QM RX MGT: Drop Unprotected Mgmt frame!!!\n");
+#endif
+			nicRxReturnRFB(prAdapter, prSwRfb);
+			RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
+			return;
+		}
+#endif
+		if (apfnProcessRxMgtFrame[ucSubtype]) {
+			switch (apfnProcessRxMgtFrame[ucSubtype] (prAdapter, prSwRfb)) {
+			case WLAN_STATUS_PENDING:
+				return;
+			case WLAN_STATUS_SUCCESS:
+			case WLAN_STATUS_FAILURE:
+				break;
+
+			default:
+				DBGLOG(RX, WARN,
+				       "Unexpected MMPDU(0x%02X) returned with abnormal status\n", ucSubtype);
+				break;
+			}
+		}
+#endif
+	}
+
+	nicRxReturnRFB(prAdapter, prSwRfb);
+}
+
+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG
+static VOID nicRxCheckWakeupReason(P_SW_RFB_T prSwRfb)
+{
+	PUINT_8 pvHeader = NULL;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	UINT_16 u2PktLen = 0;
+	UINT_32 u4HeaderOffset;
+
+	if (!prSwRfb)
+		return;
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	if (!prHifRxHdr)
+		return;
+
+	switch (prSwRfb->ucPacketType) {
+	case HIF_RX_PKT_TYPE_DATA:
+	{
+		UINT_16 u2Temp = 0;
+
+		if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) {
+			DBGLOG(RX, INFO, "BAR frame[SSN:%d, TID:%d] wakeup host\n",
+				(UINT_16)HIF_RX_HDR_GET_SN(prHifRxHdr), (UINT_8)HIF_RX_HDR_GET_TID(prHifRxHdr));
+			break;
+		}
+		u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK);
+		pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset;
+		u2PktLen = (UINT_16)(prHifRxHdr->u2PacketLen - (HIF_RX_HDR_SIZE + u4HeaderOffset));
+		if (!pvHeader) {
+			DBGLOG(RX, ERROR, "data packet but pvHeader is NULL!\n");
+			break;
+		}
+		u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | (pvHeader[ETH_TYPE_LEN_OFFSET + 1]);
+
+		switch (u2Temp) {
+		case ETH_P_IPV4:
+			u2Temp = *(UINT_16 *) &pvHeader[ETH_HLEN + 4];
+			DBGLOG(RX, INFO, "IP Packet from:%d.%d.%d.%d, IP ID 0x%04x wakeup host\n",
+				pvHeader[ETH_HLEN + 12], pvHeader[ETH_HLEN + 13],
+				pvHeader[ETH_HLEN + 14], pvHeader[ETH_HLEN + 15], u2Temp);
+			break;
+		case ETH_P_ARP:
+		{
+			PUINT_8 pucEthBody = &pvHeader[ETH_HLEN];
+			UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7];
+
+			if (u2OpCode == ARP_PRO_REQ)
+				DBGLOG(RX, INFO, "Arp Req From IP: %d.%d.%d.%d wakeup host\n",
+					pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]);
+			else if (u2OpCode == ARP_PRO_RSP)
+				DBGLOG(RX, INFO, "Arp Rsp from IP: %d.%d.%d.%d wakeup host\n",
+					pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]);
+			break;
+		}
+		case ETH_P_1X:
+		case ETH_P_PRE_1X:
+#if CFG_SUPPORT_WAPI
+		case ETH_WPI_1X:
+#endif
+		case ETH_P_AARP:
+		case ETH_P_IPV6:
+		case ETH_P_IPX:
+		case 0x8100: /* VLAN */
+		case 0x890d: /* TDLS */
+			DBGLOG(RX, INFO, "Data Packet, EthType 0x%04x wakeup host\n", u2Temp);
+			break;
+		default:
+			DBGLOG(RX, WARN, "maybe abnormal data packet, EthType 0x%04x wakeup host, dump it\n",
+				u2Temp);
+			DBGLOG_MEM8(RX, INFO, pvHeader, u2PktLen > 50 ? 50:u2PacketLen);
+			break;
+		}
+		break;
+	}
+	case HIF_RX_PKT_TYPE_EVENT:
+	{
+		P_WIFI_EVENT_T prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff;
+
+		DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", prEvent->ucEID);
+		break;
+	}
+	case HIF_RX_PKT_TYPE_MANAGEMENT:
+	{
+		UINT_8 ucSubtype;
+		P_WLAN_MAC_MGMT_HEADER_T prWlanMgmtHeader;
+
+		u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK);
+		pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset;
+		if (!pvHeader) {
+			DBGLOG(RX, ERROR, "Mgmt Frame but pvHeader is NULL!\n");
+			break;
+		}
+		prWlanMgmtHeader = (P_WLAN_MAC_MGMT_HEADER_T)pvHeader;
+		ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >>
+				OFFSET_OF_FC_SUBTYPE;
+		DBGLOG(RX, INFO, "MGMT frame subtype: %d SeqCtrl %d wakeup host\n",
+				ucSubtype, prWlanMgmtHeader->u2SeqCtrl);
+		break;
+	}
+	default:
+		DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", prSwRfb->ucPacketType);
+		break;
+	}
+}
+#endif
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue.
+*
+* @param prAdapter Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicRxProcessRFBs");
+
+	ASSERT(prAdapter);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	prRxCtrl->ucNumIndPacket = 0;
+	prRxCtrl->ucNumRetainedPacket = 0;
+
+	do {
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+		if (prSwRfb) {
+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG
+			if (kalIsWakeupByWlan(prAdapter))
+				nicRxCheckWakeupReason(prSwRfb);
+#endif
+			switch (prSwRfb->ucPacketType) {
+			case HIF_RX_PKT_TYPE_DATA:
+				nicRxProcessDataPacket(prAdapter, prSwRfb);
+				break;
+
+			case HIF_RX_PKT_TYPE_EVENT:
+				nicRxProcessEventPacket(prAdapter, prSwRfb);
+				break;
+
+			case HIF_RX_PKT_TYPE_TX_LOOPBACK:
+#if (CONF_HIF_LOOPBACK_AUTO == 1)
+				{
+					kalDevLoopbkRxHandle(prAdapter, prSwRfb);
+					nicRxReturnRFB(prAdapter, prSwRfb);
+				}
+#else
+				DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType);
+#endif /* CONF_HIF_LOOPBACK_AUTO */
+				break;
+
+			case HIF_RX_PKT_TYPE_MANAGEMENT:
+				nicRxProcessMgmtPacket(prAdapter, prSwRfb);
+				break;
+
+			default:
+				RX_INC_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT);
+				RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
+				DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType);
+				nicRxReturnRFB(prAdapter, prSwRfb);	/* need to free it */
+				break;
+			}
+		} else {
+			break;
+		}
+	} while (TRUE);
+
+	if (prRxCtrl->ucNumIndPacket > 0) {
+		RX_ADD_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT, prRxCtrl->ucNumIndPacket);
+		RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, prRxCtrl->ucNumRetainedPacket);
+
+		/* DBGLOG(RX, INFO, ("%d packets indicated, Retained cnt = %d\n", */
+		/* prRxCtrl->ucNumIndPacket, prRxCtrl->ucNumRetainedPacket)); */
+#if CFG_NATIVE_802_11
+		kalRxIndicatePkts(prAdapter->prGlueInfo, (UINT_32) prRxCtrl->ucNumIndPacket,
+				  (UINT_32) prRxCtrl->ucNumRetainedPacket);
+#else
+		kalRxIndicatePkts(prAdapter->prGlueInfo, prRxCtrl->apvIndPacket, (UINT_32) prRxCtrl->ucNumIndPacket);
+#endif
+	}
+
+}				/* end of nicRxProcessRFBs() */
+
+#if !CFG_SDIO_INTR_ENHANCE
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Read the rx data from data port and setup RFB
+*
+* @param prAdapter pointer to the Adapter handler
+* @param prSWRfb the RFB to receive rx data
+*
+* @retval WLAN_STATUS_SUCCESS: SUCCESS
+* @retval WLAN_STATUS_FAILURE: FAILURE
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb)
+{
+	P_RX_CTRL_T prRxCtrl;
+	PUINT_8 pucBuf;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	UINT_32 u4PktLen = 0, u4ReadBytes;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+	BOOLEAN fgResult = TRUE;
+	UINT_32 u4RegValue;
+	UINT_32 rxNum;
+
+	DEBUGFUNC("nicRxReadBuffer");
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	pucBuf = prSwRfb->pucRecvBuff;
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	ASSERT(pucBuf);
+	DBGLOG(RX, TRACE, "pucBuf= 0x%x, prHifRxHdr= 0x%x\n", pucBuf, prHifRxHdr);
+
+	do {
+		/* Read the RFB DW length and packet length */
+		HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue);
+		if (!fgResult) {
+			DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n");
+			return WLAN_STATUS_FAILURE;
+		}
+		/* 20091021 move the line to get the HIF RX header (for RX0/1) */
+		if (u4RegValue == 0) {
+			DBGLOG(RX, ERROR, "No RX packet\n");
+			return WLAN_STATUS_FAILURE;
+		}
+
+		u4PktLen = u4RegValue & BITS(0, 15);
+		if (u4PktLen != 0) {
+			rxNum = 0;
+		} else {
+			rxNum = 1;
+			u4PktLen = (u4RegValue & BITS(16, 31)) >> 16;
+		}
+
+		DBGLOG(RX, TRACE, "RX%d: u4PktLen = %d\n", rxNum, u4PktLen);
+
+		/* 4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status) */
+		u4ReadBytes = ALIGN_4(u4PktLen) + 4;
+		HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE);
+
+		/* 20091021 move the line to get the HIF RX header */
+		/* u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen; */
+		if (u4PktLen != (UINT_32) prHifRxHdr->u2PacketLen) {
+			DBGLOG(RX, ERROR, "Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n",
+					   u4PktLen, prHifRxHdr->u2PacketLen);
+#if DBG
+			dumpMemory8((PUINT_8) prHifRxHdr,
+				    (prHifRxHdr->u2PacketLen > 4096) ? 4096 : prHifRxHdr->u2PacketLen);
+#endif
+			ASSERT(0);
+		}
+		/* u4PktLen is byte unit, not inlude HW appended DW */
+
+		prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK);
+		DBGLOG(RX, TRACE, "ucPacketType = %d\n", prSwRfb->ucPacketType);
+
+		prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx);
+
+		/* fgResult will be updated in MACRO */
+		if (!fgResult)
+			return WLAN_STATUS_FAILURE;
+
+		DBGLOG(RX, TRACE, "Dump RX buffer, length = 0x%x\n", u4ReadBytes);
+		DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes);
+	} while (FALSE);
+
+	return u4Status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Read frames from the data port, fill RFB
+*        and put each frame into the rReceivedRFBList queue.
+*
+* @param prAdapter   Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+
+	UINT_32 u4HwAppendDW;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicRxReceiveRFBs");
+
+	ASSERT(prAdapter);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	do {
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+		if (!prSwRfb) {
+			DBGLOG(RX, TRACE, "No More RFB\n");
+			break;
+		}
+		/* need to consider */
+		if (nicRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) {
+			DBGLOG(RX, TRACE, "halRxFillRFB failed\n");
+			nicRxReturnRFB(prAdapter, prSwRfb);
+			break;
+		}
+
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry);
+		RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+		prHifRxHdr = prSwRfb->prHifRxHdr;
+		u4HwAppendDW = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen))));
+		DBGLOG(RX, TRACE, "u4HwAppendDW = 0x%x\n", u4HwAppendDW);
+		DBGLOG(RX, TRACE, "u2PacketLen = 0x%x\n", prHifRxHdr->u2PacketLen);
+	} while (FALSE);	/* while (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW)); */
+
+	return;
+
+}				/* end of nicReceiveRFBs() */
+
+#else
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Read frames from the data port, fill RFB
+*        and put each frame into the rReceivedRFBList queue.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param u4DataPort     Specify which port to read
+* @param u2RxLength     Specify to the the rx packet length in Byte.
+* @param prSwRfb        the RFB to receive rx data.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+
+WLAN_STATUS
+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter,
+		       IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb)
+{
+	P_RX_CTRL_T prRxCtrl;
+	PUINT_8 pucBuf;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	UINT_32 u4PktLen = 0;
+	WLAN_STATUS u4Status = WLAN_STATUS_FAILURE;
+	BOOLEAN fgResult = TRUE;
+
+	DEBUGFUNC("nicRxEnhanceReadBuffer");
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	pucBuf = prSwRfb->pucRecvBuff;
+	ASSERT(pucBuf);
+
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	ASSERT(prHifRxHdr);
+
+	/* DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength)); */
+
+	do {
+		/* 4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW */
+		HAL_READ_RX_PORT(prAdapter,
+				 u4DataPort, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN), pucBuf, CFG_RX_MAX_PKT_SIZE);
+
+		if (!fgResult) {
+			DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n");
+			break;
+		}
+
+		u4PktLen = (UINT_32) (prHifRxHdr->u2PacketLen);
+		/* DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen)); */
+
+		prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK);
+		/* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */
+
+		prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx);
+
+		/* 4 <2> if the RFB dw size or packet size is zero */
+		if (u4PktLen == 0) {
+			DBGLOG(RX, ERROR, "Packet Length = %u\n", u4PktLen);
+			ASSERT(0);
+			break;
+		}
+		/* 4 <3> if the packet is too large or too small */
+		if (u4PktLen > CFG_RX_MAX_PKT_SIZE) {
+			DBGLOG(RX, TRACE, "Read RX Packet Lentgh Error (%u)\n", u4PktLen);
+			ASSERT(0);
+			break;
+		}
+
+		u4Status = WLAN_STATUS_SUCCESS;
+	} while (FALSE);
+
+	DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN));
+	return u4Status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Read frames from the data port for SDIO
+*        I/F, fill RFB and put each frame into the rReceivedRFBList queue.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter)
+{
+	P_SDIO_CTRL_T prSDIOCtrl;
+	P_RX_CTRL_T prRxCtrl;
+	P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL;
+	UINT_32 i, rxNum;
+	UINT_16 u2RxPktNum, u2RxLength = 0, u2Tmp = 0;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicRxSDIOReceiveRFBs");
+
+	ASSERT(prAdapter);
+
+	prSDIOCtrl = prAdapter->prSDIOCtrl;
+	ASSERT(prSDIOCtrl);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	for (rxNum = 0; rxNum < 2; rxNum++) {
+		u2RxPktNum =
+		    (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len);
+
+		if (u2RxPktNum == 0)
+			continue;
+
+		for (i = 0; i < u2RxPktNum; i++) {
+			if (rxNum == 0) {
+				/* HAL_READ_RX_LENGTH */
+				HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp);
+			} else if (rxNum == 1) {
+				/* HAL_READ_RX_LENGTH */
+				HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength);
+			}
+
+			if (!u2RxLength)
+				break;
+
+			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+			QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+			if (!prSwRfb) {
+				DBGLOG(RX, TRACE, "No More RFB\n");
+				break;
+			}
+			ASSERT(prSwRfb);
+
+			if (nicRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) {
+				DBGLOG(RX, TRACE, "nicRxEnhanceRxReadBuffer failed\n");
+				nicRxReturnRFB(prAdapter, prSwRfb);
+				break;
+			}
+			/* prSDIOCtrl->au4RxLength[i] = 0; */
+
+			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+			QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry);
+			RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT);
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+		}
+	}
+
+	prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0;
+	prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0;
+
+}				/* end of nicRxSDIOReceiveRFBs() */
+
+#endif /* CFG_SDIO_INTR_ENHANCE */
+
+#if CFG_SDIO_RX_AGG
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Read frames from the data port for SDIO with Rx aggregation enabled
+*        I/F, fill RFB and put each frame into the rReceivedRFBList queue.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter)
+{
+	P_ENHANCE_MODE_DATA_STRUCT_T prEnhDataStr;
+	P_RX_CTRL_T prRxCtrl;
+	P_SDIO_CTRL_T prSDIOCtrl;
+	P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL;
+	UINT_32 u4RxLength;
+	UINT_32 i, rxNum;
+	UINT_32 u4RxAggCount = 0, u4RxAggLength = 0;
+	UINT_32 u4RxAvailAggLen, u4CurrAvailFreeRfbCnt;
+	PUINT_8 pucSrcAddr;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	BOOLEAN fgResult = TRUE;
+	BOOLEAN fgIsRxEnhanceMode;
+	UINT_16 u2RxPktNum;
+#if CFG_SDIO_RX_ENHANCE
+	UINT_32 u4MaxLoopCount = CFG_MAX_RX_ENHANCE_LOOP_COUNT;
+#endif
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicRxSDIOAggReceiveRFBs");
+
+	ASSERT(prAdapter);
+	prEnhDataStr = prAdapter->prSDIOCtrl;
+	prRxCtrl = &prAdapter->rRxCtrl;
+	prSDIOCtrl = prAdapter->prSDIOCtrl;
+
+#if CFG_SDIO_RX_ENHANCE
+	fgIsRxEnhanceMode = TRUE;
+#else
+	fgIsRxEnhanceMode = FALSE;
+#endif
+
+	do {
+#if CFG_SDIO_RX_ENHANCE
+		/* to limit maximum loop for RX */
+		u4MaxLoopCount--;
+		if (u4MaxLoopCount == 0)
+			break;
+#endif
+
+		if (prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0)
+			break;
+
+		for (rxNum = 0; rxNum < 2; rxNum++) {
+			u2RxPktNum =
+			    (rxNum ==
+			     0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : prEnhDataStr->rRxInfo.u.u2NumValidRx1Len);
+
+			/* if this assertion happened, it is most likely a F/W bug */
+			ASSERT(u2RxPktNum <= 16);
+
+			if (u2RxPktNum > 16)
+				continue;
+
+			if (u2RxPktNum == 0)
+				continue;
+
+#if CFG_HIF_STATISTICS
+			prRxCtrl->u4TotalRxAccessNum++;
+			prRxCtrl->u4TotalRxPacketNum += u2RxPktNum;
+#endif
+
+			u4CurrAvailFreeRfbCnt = prRxCtrl->rFreeSwRfbList.u4NumElem;
+
+			/* if SwRfb is not enough, abort reading this time */
+			if (u4CurrAvailFreeRfbCnt < u2RxPktNum) {
+#if CFG_HIF_RX_STARVATION_WARNING
+				DbgPrint("FreeRfb is not enough: %d available, need %d\n", u4CurrAvailFreeRfbCnt,
+					 u2RxPktNum);
+				DbgPrint("Queued Count: %d / Dequeud Count: %d\n", prRxCtrl->u4QueuedCnt,
+					 prRxCtrl->u4DequeuedCnt);
+#endif
+				continue;
+			}
+#if CFG_SDIO_RX_ENHANCE
+			u4RxAvailAggLen =
+			    CFG_RX_COALESCING_BUFFER_SIZE - (sizeof(ENHANCE_MODE_DATA_STRUCT_T) +
+							     4 /* extra HW padding */);
+#else
+			u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE;
+#endif
+			u4RxAggCount = 0;
+
+			for (i = 0; i < u2RxPktNum; i++) {
+				u4RxLength = (rxNum == 0 ?
+					      (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx0Len[i] :
+					      (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx1Len[i]);
+
+				if (!u4RxLength) {
+					ASSERT(0);
+					break;
+				}
+
+				if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) {
+					if (u4RxAggCount < u4CurrAvailFreeRfbCnt) {
+						u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN);
+						u4RxAggCount++;
+					} else {
+						/* no FreeSwRfb for rx packet */
+						ASSERT(0);
+						break;
+					}
+				} else {
+					/* CFG_RX_COALESCING_BUFFER_SIZE is not large enough */
+					ASSERT(0);
+					break;
+				}
+			}
+
+			u4RxAggLength = (CFG_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen);
+			/* DBGLOG(RX, INFO, ("u4RxAggCount = %d, u4RxAggLength = %d\n", */
+			/* u4RxAggCount, u4RxAggLength)); */
+
+			HAL_READ_RX_PORT(prAdapter,
+					 rxNum,
+					 u4RxAggLength, prRxCtrl->pucRxCoalescingBufPtr, CFG_RX_COALESCING_BUFFER_SIZE);
+			if (!fgResult) {
+				DBGLOG(RX, ERROR, "Read RX Agg Packet Error\n");
+				continue;
+			}
+
+			pucSrcAddr = prRxCtrl->pucRxCoalescingBufPtr;
+			for (i = 0; i < u4RxAggCount; i++) {
+				UINT_16 u2PktLength;
+
+				u2PktLength = (rxNum == 0 ?
+					       prEnhDataStr->rRxInfo.u.au2Rx0Len[i] :
+					       prEnhDataStr->rRxInfo.u.au2Rx1Len[i]);
+
+				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+				QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
+				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+				ASSERT(prSwRfb);
+				kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr,
+					   ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN));
+
+				/* record the rx time */
+				STATS_RX_ARRIVE_TIME_RECORD(prSwRfb);	/* ms */
+
+				prHifRxHdr = prSwRfb->prHifRxHdr;
+				ASSERT(prHifRxHdr);
+
+				prSwRfb->ucPacketType =
+				    (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK);
+				/* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */
+
+				prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx);
+
+				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+				QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry);
+				RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT);
+				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+				pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN);
+				/* prEnhDataStr->au4RxLength[i] = 0; */
+			}
+
+#if CFG_SDIO_RX_ENHANCE
+			kalMemCopy(prAdapter->prSDIOCtrl, (pucSrcAddr + 4), sizeof(ENHANCE_MODE_DATA_STRUCT_T));
+
+			/* do the same thing what nicSDIOReadIntStatus() does */
+			if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 &&
+			    (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) {
+				prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT;
+			}
+
+			if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 &&
+			    HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE &&
+			    (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) {
+				prSDIOCtrl->u4WHISR |= BIT(31);
+			}
+
+			/* dispatch to interrupt handler with RX bits masked */
+			nicProcessIST_impl(prAdapter,
+					   prSDIOCtrl->u4WHISR & (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)));
+#endif
+		}
+
+#if !CFG_SDIO_RX_ENHANCE
+		prEnhDataStr->rRxInfo.u.u2NumValidRx0Len = 0;
+		prEnhDataStr->rRxInfo.u.u2NumValidRx1Len = 0;
+#endif
+	} while ((prEnhDataStr->rRxInfo.u.u2NumValidRx0Len || prEnhDataStr->rRxInfo.u.u2NumValidRx1Len)
+		&& fgIsRxEnhanceMode);
+
+}
+#endif /* CFG_SDIO_RX_AGG */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Setup a RFB and allocate the os packet to the RFB
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param prSwRfb        Pointer to the RFB
+*
+* @retval WLAN_STATUS_SUCCESS
+* @retval WLAN_STATUS_RESOURCES
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	PVOID pvPacket;
+	PUINT_8 pucRecvBuff;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	if (!prSwRfb->pvPacket) {
+		kalMemZero(prSwRfb, sizeof(SW_RFB_T));
+		pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, CFG_RX_MAX_PKT_SIZE, &pucRecvBuff);
+		if (pvPacket == NULL)
+			return WLAN_STATUS_RESOURCES;
+
+		prSwRfb->pvPacket = pvPacket;
+		prSwRfb->pucRecvBuff = (PVOID) pucRecvBuff;
+	} else {
+		kalMemZero(((PUINT_8) prSwRfb + OFFSET_OF(SW_RFB_T, prHifRxHdr)),
+			   (sizeof(SW_RFB_T) - OFFSET_OF(SW_RFB_T, prHifRxHdr)));
+	}
+
+	prSwRfb->prHifRxHdr = (P_HIF_RX_HEADER_T) (prSwRfb->pucRecvBuff);
+
+	return WLAN_STATUS_SUCCESS;
+
+}				/* end of nicRxSetupRFB() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This routine is called to put a RFB back onto the "RFB with Buffer" list
+*        or "RFB without buffer" list according to pvPacket.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param prSwRfb          Pointer to the RFB
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_RX_CTRL_T prRxCtrl;
+	P_QUE_ENTRY_T prQueEntry;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+	prRxCtrl = &prAdapter->rRxCtrl;
+	prQueEntry = &prSwRfb->rQueEntry;
+
+	ASSERT(prQueEntry);
+
+	/* The processing on this RFB is done, so put it back on the tail of
+	   our list */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+
+	if (prSwRfb->pvPacket) {
+		/* QUEUE_INSERT_TAIL */
+		QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry);
+	} else {
+		/* QUEUE_INSERT_TAIL */
+		QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry);
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
+}				/* end of nicRxReturnRFB() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process rx interrupt. When the rx
+*        Interrupt is asserted, it means there are frames in queue.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter)
+{
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+
+	prGlueInfo->IsrRxCnt++;
+#if CFG_SDIO_INTR_ENHANCE
+#if CFG_SDIO_RX_AGG
+	nicRxSDIOAggReceiveRFBs(prAdapter);
+#else
+	nicRxSDIOReceiveRFBs(prAdapter);
+#endif
+#else
+	nicRxReceiveRFBs(prAdapter);
+#endif /* CFG_SDIO_INTR_ENHANCE */
+
+	nicRxProcessRFBs(prAdapter);
+
+	return;
+
+}				/* end of nicProcessRxInterrupt() */
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Used to update IP/TCP/UDP checksum statistics of RX Module.
+*
+* @param prAdapter  Pointer to the Adapter structure.
+* @param aeCSUM     The array of checksum result.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[])
+{
+	P_RX_CTRL_T prRxCtrl;
+
+	ASSERT(prAdapter);
+	ASSERT(aeCSUM);
+
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) ||
+		(aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) {
+		RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT);
+	} else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) {
+		RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT);
+	} else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) {
+		RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT);
+	} else {
+		ASSERT(0);
+	}
+
+	if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) {
+		/* count success num */
+		RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT);
+	} else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) {
+		RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT);
+	} else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) {
+		RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT);
+	} else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) {
+		RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT);
+	} else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) {
+		RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT);
+	} else {
+		ASSERT(0);
+	}
+
+}				/* end of nicRxUpdateCSUMStatistics() */
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to query current status of RX Module.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param pucBuffer      Pointer to the message buffer.
+* @param pu4Count      Pointer to the buffer of message length count.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count)
+{
+	P_RX_CTRL_T prRxCtrl;
+	PUINT_8 pucCurrBuf = pucBuffer;
+
+	ASSERT(prAdapter);
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	/* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */
+	ASSERT(pu4Count);
+
+	SPRINTF(pucCurrBuf, ("\n\nRX CTRL STATUS:"));
+	SPRINTF(pucCurrBuf, ("\n==============="));
+	SPRINTF(pucCurrBuf, ("\nFREE RFB w/i BUF LIST :%9u", prRxCtrl->rFreeSwRfbList.u4NumElem));
+	SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9u", prRxCtrl->rIndicatedRfbList.u4NumElem));
+	SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST     :%9u", prRxCtrl->rReceivedRfbList.u4NumElem));
+
+	SPRINTF(pucCurrBuf, ("\n\n"));
+
+	/* *pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); */
+
+}				/* end of nicRxQueryStatus() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Clear RX related counters
+*
+* @param prAdapter Pointer of Adapter Data Structure
+*
+* @return - (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter)
+{
+	P_RX_CTRL_T prRxCtrl;
+
+	ASSERT(prAdapter);
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	RX_RESET_ALL_CNTS(prRxCtrl);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to query current statistics of RX Module.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param pucBuffer      Pointer to the message buffer.
+* @param pu4Count      Pointer to the buffer of message length count.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count)
+{
+	P_RX_CTRL_T prRxCtrl;
+	PUINT_8 pucCurrBuf = pucBuffer;
+
+	ASSERT(prAdapter);
+	prRxCtrl = &prAdapter->rRxCtrl;
+	ASSERT(prRxCtrl);
+
+	/* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */
+	ASSERT(pu4Count);
+
+#define SPRINTF_RX_COUNTER(eCounter) \
+	SPRINTF(pucCurrBuf, ("%-30s : %u\n", #eCounter, (UINT_32)prRxCtrl->au8Statistics[eCounter]))
+
+	SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT);
+	SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT);
+	SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT);
+	SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT);
+	SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT);
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60
+	SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT);
+	SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT);
+	SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT);
+	SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT);
+	SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT);
+	SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT);
+	SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT);
+	SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT);
+	SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT);
+#endif
+
+	/* *pu4Count = (UINT_32)(pucCurrBuf - pucBuffer); */
+
+	nicRxClearStatistics(prAdapter);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Read the Response data from data port
+*
+* @param prAdapter pointer to the Adapter handler
+* @param pucRspBuffer pointer to the Response buffer
+*
+* @retval WLAN_STATUS_SUCCESS: Response packet has been read
+* @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+nicRxWaitResponse(IN P_ADAPTER_T prAdapter,
+		  IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length)
+{
+	UINT_32 u4Value = 0, u4PktLen = 0;
+	UINT_32 i = 0;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+	BOOLEAN fgResult = TRUE;
+	UINT_32 u4Time, u4Current;
+
+	DEBUGFUNC("nicRxWaitResponse");
+
+	ASSERT(prAdapter);
+	ASSERT(pucRspBuffer);
+	ASSERT(ucPortIdx < 2);
+
+	u4Time = kalGetTimeTick();
+
+	do {
+		/* Read the packet length */
+		HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value);
+
+		if (!fgResult) {
+			DBGLOG(RX, ERROR, "Read Response Packet Error\n");
+			return WLAN_STATUS_FAILURE;
+		}
+
+		if (ucPortIdx == 0)
+			u4PktLen = u4Value & 0xFFFF;
+		else
+			u4PktLen = (u4Value >> 16) & 0xFFFF;
+
+/* DBGLOG(RX, TRACE, ("i = %d, u4PktLen = %d\n", i, u4PktLen)); */
+
+		if (u4PktLen == 0) {
+			/* timeout exceeding check */
+			u4Current = kalGetTimeTick();
+
+			if ((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) {
+				DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT1 %u %d %u\n", u4PktLen, i, u4Current);
+				return WLAN_STATUS_FAILURE;
+			} else if (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) {
+				DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT2 %u %d %u\n", u4PktLen, i, u4Current);
+				return WLAN_STATUS_FAILURE;
+			}
+
+			/* Response packet is not ready */
+			kalUdelay(50);
+
+			i++;
+			continue;
+		}
+		if (u4PktLen > u4MaxRespBufferLen) {
+			/*
+			   TO: buffer is not enough but we still need to read all data from HIF to avoid
+			   HIF crazy.
+			 */
+			DBGLOG(RX, ERROR,
+			       "Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n",
+				u4PktLen, u4MaxRespBufferLen);
+			DBGLOG(RX, ERROR, "i = %d, u4PktLen = %u\n", i, u4PktLen);
+			return WLAN_STATUS_FAILURE;
+		}
+		HAL_PORT_RD(prAdapter,
+			    ucPortIdx == 0 ? MCR_WRDR0 : MCR_WRDR1, u4PktLen, pucRspBuffer, u4MaxRespBufferLen);
+
+		/* fgResult will be updated in MACRO */
+		if (!fgResult) {
+			DBGLOG(RX, ERROR, "Read Response Packet Error\n");
+			return WLAN_STATUS_FAILURE;
+		}
+
+		DBGLOG(RX, TRACE, "Dump Response buffer, length = 0x%x\n", u4PktLen);
+		DBGLOG_MEM8(RX, TRACE, pucRspBuffer, u4PktLen);
+
+		*pu4Length = u4PktLen;
+		break;
+	} while (TRUE);
+
+	return u4Status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Set filter to enable Promiscuous Mode
+*
+* @param prAdapter          Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+}				/* end of nicRxEnablePromiscuousMode() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Set filter to disable Promiscuous Mode
+*
+* @param prAdapter  Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+}				/* end of nicRxDisablePromiscuousMode() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief this function flushes all packets queued in reordering module
+*
+* @param prAdapter              Pointer to the Adapter structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Flushed successfully
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter)
+{
+	P_SW_RFB_T prSwRfb;
+
+	ASSERT(prAdapter);
+
+	prSwRfb = qmFlushRxQueues(prAdapter);
+	if (prSwRfb != NULL) {
+		do {
+			P_SW_RFB_T prNextSwRfb;
+
+			/* save next first */
+			prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb);
+
+			/* free */
+			nicRxReturnRFB(prAdapter, prSwRfb);
+
+			prSwRfb = prNextSwRfb;
+		} while (prSwRfb);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief
+*
+* @param
+*
+* @retval
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+	P_WLAN_ACTION_FRAME prActFrame;
+
+	ASSERT(prAdapter);
+	ASSERT(prSwRfb);
+
+	if (prSwRfb->u2PacketLen < sizeof(WLAN_ACTION_FRAME) - 1)
+		return WLAN_STATUS_INVALID_PACKET;
+	prActFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader;
+	DBGLOG(RX, INFO, "Category %u\n", prActFrame->ucCategory);
+
+	switch (prActFrame->ucCategory) {
+	case CATEGORY_PUBLIC_ACTION:
+		if (HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) == NETWORK_TYPE_AIS_INDEX)
+			aisFuncValidateRxActionFrame(prAdapter, prSwRfb);
+#if CFG_ENABLE_WIFI_DIRECT
+		else if (prAdapter->fgIsP2PRegistered) {
+			rlmProcessPublicAction(prAdapter, prSwRfb);
+
+			p2pFuncValidateRxActionFrame(prAdapter, prSwRfb);
+
+		}
+#endif
+		break;
+
+	case CATEGORY_HT_ACTION:
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered)
+			rlmProcessHtAction(prAdapter, prSwRfb);
+#endif
+		break;
+	case CATEGORY_VENDOR_SPECIFIC_ACTION:
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prAdapter->fgIsP2PRegistered)
+			p2pFuncValidateRxActionFrame(prAdapter, prSwRfb);
+#endif
+		break;
+#if CFG_SUPPORT_802_11W
+	case CATEGORY_SA_QUERT_ACTION:
+		{
+			P_HIF_RX_HEADER_T prHifRxHdr;
+
+			prHifRxHdr = prSwRfb->prHifRxHdr;
+
+			if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX)
+					&& prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection	/* Use MFP */) {
+				if (!(prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC)) {
+					/* MFP test plan 5.3.3.4 */
+					rsnSaQueryAction(prAdapter, prSwRfb);
+				} else {
+					DBGLOG(RSN, TRACE, "Un-Protected SA Query, do nothing\n");
+				}
+			}
+		}
+		break;
+#endif
+#if CFG_SUPPORT_802_11V
+	case CATEGORY_WNM_ACTION:
+		{
+			wnmWNMAction(prAdapter, prSwRfb);
+		}
+		break;
+#endif
+
+#if CFG_SUPPORT_DFS		/* Add by Enlai */
+	case CATEGORY_SPEC_MGT:
+		{
+			if (prAdapter->fgEnable5GBand == TRUE)
+				rlmProcessSpecMgtAction(prAdapter, prSwRfb);
+		}
+		break;
+#endif
+
+#if (CFG_SUPPORT_TDLS == 1)
+	case 12:		/* shall not be here */
+		/*
+		   A received TDLS Action frame with the Type field set to Management shall
+		   be discarded. Note that the TDLS Discovery Response frame is not a TDLS
+		   frame but a Public Action frame.
+		 */
+		break;
+#endif /* CFG_SUPPORT_TDLS */
+
+	default:
+		break;
+	}			/* end of switch case */
+
+	return WLAN_STATUS_SUCCESS;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c
new file mode 100644
index 0000000000000..024bd95076037
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c
@@ -0,0 +1,2350 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#1
+*/
+
+/*! \file   nic_tx.c
+    \brief  Functions that provide TX operation in NIC Layer.
+
+    This file provides TX functions which are responsible for both Hardware and
+    Software Resource Management and keep their Synchronization.
+*/
+
+/*
+** Log: nic_tx.c
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 11 18 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add log counter for tx
+ *
+ * 11 09 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add xlog for beacon timeout and sta aging timeout.
+ *
+ * 11 08 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add xlog function.
+ *
+ * 05 17 2011 cp.wu
+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss
+ * disconnection
+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state.
+ *
+ * 04 12 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix the sta index in processing security frame
+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
+ * Add debug message.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame
+ * dropping cases for TC4 path
+ * remove unused variables.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame
+ * dropping cases for TC4 path
+ * 1. add nicTxGetResource() API for QM to make decisions.
+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case.
+ *
+ * 03 17 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * use pre-allocated buffer for storing enhanced interrupt response as well
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
+ * memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 02 16 2011 cp.wu
+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count
+ * and modify behavior
+ * 1. add new API: nicTxGetFreeCmdCount()
+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation
+ * needs such information
+ * fill mac header length information for 802.1x frames.
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system
+ * scheduling
+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
+ * loaded
+ *
+ * 11 01 2010 yarco.yang
+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
+ * Add GPIO debug function
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion
+ * 2. shorten polling count for shorter response time
+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * code reorganization to improve isolation between GLUE and CORE layers.
+ *
+ * 09 29 2010 wh.su
+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
+ *
+ * 09 27 2010 wh.su
+ * NULL
+ * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error
+ *
+ * 09 24 2010 wh.su
+ * NULL
+ * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra
+ * bytes padding.
+ *
+ * 09 01 2010 cp.wu
+ * NULL
+ * HIFSYS Clock Source Workaround
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * API added: nicTxPendingPackets(), for simplifying porting layer
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * eliminate klockwork errors
+ *
+ * 08 20 2010 wh.su
+ * NULL
+ * adding the eapol callback setting.
+ *
+ * 08 18 2010 yarco.yang
+ * NULL
+ * 1. Fixed HW checksum offload function not work under Linux issue.
+ * 2. Add debug message.
+ *
+ * 08 05 2010 yuche.tsai
+ * NULL
+ * .
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * 1) modify tx service thread to avoid busy looping
+ * 2) add spin lock declartion for linux build
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * simplify post-handling after TX_DONE interrupt is handled.
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 13 2010 cp.wu
+ *
+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network
+ * operation
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 29 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * replace g_rQM with Adpater->rQM
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add API in que_mgt to retrieve sta-rec index for security frames.
+ *
+ * 06 24 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
+ *
+ * 06 23 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Merge g_arStaRec[] into adapter->arStaRec[]
+ *
+ * 06 22 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) add command warpper for STA-REC/BSS-INFO sync.
+ * 2) enhance command packet sending procedure for non-oid part
+ * 3) add command packet definitions for STA-REC/BSS-INFO sync.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add checking for TX descriptor poll.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * TX descriptors are now allocated once for reducing allocation overhead
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change zero-padding for TX port access to HAL.
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * .
+ *
+ * 06 15 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * .
+ *
+ * 06 14 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * fill extra information for revised HIF_TX_HEADER.
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 10 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change to enqueue TX frame infinitely.
+ *
+ * 06 09 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * fill network type field while doing frame identification.
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Tag the packet for QoS on Tx path
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * remove driver-land statistics.
+ *
+ * 03 29 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+ * 03 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
+ *  *  *  *  *
+ *
+* 03 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code clean: removing unused variables and structure definitions
+ *
+ * 03 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
+ *  *  *  * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
+ *
+ * 03 02 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add mutex to avoid multiple access to qmTxQueue simultaneously.
+ *
+ * 02 26 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * avoid referring to NDIS-specific data structure directly from non-glue layer.
+ *
+ * 02 24 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add Ethernet destination address information in packet info for TX
+ *
+ * 02 10 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
+ *  *  *  *  *  * 2) firmware image length is now retrieved via NdisFileOpen
+ *  *  *  *  *  * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
+ *  *  *  *  *  * 4) nicRxWaitResponse() revised
+ *  *  *  *  *  * 5) another set of TQ counter default value is added for fw-download state
+ *  *  *  *  *  * 6) Wi-Fi load address is now retrieved from registry too
+ *
+ * 02 09 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
+ *  *  *  *  *  *  *  *  * 2. follow MSDN defined behavior when associates to another AP
+ *  *  *  *  *  *  *  *  * 3. for firmware download, packet size could be up to 2048 bytes
+ *
+ * 02 08 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * prepare for implementing fw download logic
+ *
+ * 01 27 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. eliminate improper variable in rHifInfo
+ *  *  *  *  *  *  *  *  * 2. block TX/ordinary OID when RF test mode is engaged
+ *  *  *  *  *  *  *  *  * 3. wait until firmware finish operation when entering into and leaving from RF test mode
+ *  *  *  *  *  *  *  *  * 4. correct some HAL implementation
+ *
+ * 01 13 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled the Burst_End Indication mechanism
+ *
+ * 01 13 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo
+ *
+ * 12 30 2009 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) According to CMD/EVENT documentation v0.8,
+ *  *  *  *  *  *  *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
+ *  *  *  *  *  *  *  *  *  * and result is retrieved by get ATInfo instead
+ *  *  *  *  *  *  *  *  *  * 2) add 4 counter for recording aggregation statistics
+**  \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752
+**  remove unused API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752
+**  correct assertion criterion
+**  \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752
+**  correct trivial mistake
+**  \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752
+**  + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data
+**  + add more assertion for packet size check
+**  \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752
+**  nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort
+**  \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752
+**  add 2 assertion for size check
+**  \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461
+**  Add debug message
+**  \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752
+**  1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T
+**  \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752
+**  use TC4 instead of TC5 for command packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752
+**  add flush for reset
+**  \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752
+**  fill prMsduInfo->ucUserPriority
+**  \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752
+**  fill u2SeqNo
+**  \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752
+**  integration with SD1's data path API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752
+**  nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList
+**  \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752
+**  add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum,
+**  WIFI_CMD_T will be created inside oid handler
+**  \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752
+**  use TxAccquireResource instead of accessing TCQ directly.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752
+**  add nicTxMsduInfoList () implementation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752
+**  add nicTxAdjustTcq() implementation
+**  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752
+**  move aucFreeBufferCount/aucMaxNumOfBuffer into another structure
+**  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752
+**  add SD1_SD3_DATAPATH_INTEGRATION data path handling
+**  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084
+**  modify TX hdr format, fix tx retransmission issue
+**  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084
+**  modify TX SW data structure
+**  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084
+**  modify HAL part
+**  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084
+**  update for new HW design
+**  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725
+**  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461
+**  Assign SeqNum to CMD Packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461
+**  Add debug message
+**  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461
+**  Fix Query Command need resp issue
+**  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461
+**  Move OS dependent code to kalQueryTxOOBData()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461
+**  Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461
+**  Update nicTxCmd() for moving wait RESP function call to wlanSendCommand()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461
+**  Move the CMD_INFO_T related function to cmd_buf.c
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426
+**  Update OOB query for TX packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426
+**  Support PKGUIO
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461
+**  Add virtual OOB for HIF LOOPBACK SW PRETEST
+**  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461
+**  Add function for SDIO_TX_ENHANCE
+**  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461
+**  Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test.
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461
+**  Add code for TX Data & Cmd Packet
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461
+**  Fix LINT warning
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461
+**  Update TX PATH API
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426
+**  Init for develop
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will initial all variables in regard to SW TX Queues and
+*        all free lists of MSDU_INFO_T and SW_TFCB_T.
+*
+* @param prAdapter  Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter)
+{
+	P_TX_CTRL_T prTxCtrl;
+	PUINT_8 pucMemHandle;
+	P_MSDU_INFO_T prMsduInfo;
+	UINT_32 i;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicTxInitialize");
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	/* 4 <1> Initialization of Traffic Class Queue Parameters */
+	nicTxResetResource(prAdapter);
+
+#if CFG_SDIO_TX_AGG
+	prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached;
+#endif /* CFG_SDIO_TX_AGG */
+
+	/* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */
+	QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList);
+
+	pucMemHandle = prTxCtrl->pucTxCached;
+	for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) {
+		prMsduInfo = (P_MSDU_INFO_T) pucMemHandle;
+		kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));
+
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+		QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+
+		pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T));
+	}
+
+	ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM);
+	/* Check if the memory allocation consist with this initialization function */
+	ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize);
+
+	QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue);
+	prTxCtrl->i4TxMgmtPendingNum = 0;
+
+#if CFG_HIF_STATISTICS
+	prTxCtrl->u4TotalTxAccessNum = 0;
+	prTxCtrl->u4TotalTxPacketNum = 0;
+#endif
+
+	prTxCtrl->i4PendingFwdFrameCount = 0;
+
+	qmInit(prAdapter);
+
+	TX_RESET_ALL_CNTS(prTxCtrl);
+
+}				/* end of nicTxInitialize() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Driver maintain a variable that is synchronous with the usage of individual
+*        TC Buffer Count. This function will check if has enough TC Buffer for incoming
+*        packet and then update the value after promise to provide the resources.
+*
+* \param[in] prAdapter              Pointer to the Adapter structure.
+* \param[in] ucTC                   Specify the resource of TC
+*
+* \retval WLAN_STATUS_SUCCESS   Resource is available and been assigned.
+* \retval WLAN_STATUS_RESOURCES Resource is not available.
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 u4CurrTick = 0;
+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt)
+{
+#define TC4_NO_RESOURCE_DELAY_MS      5    /* exponential of 5s */
+
+	P_TX_CTRL_T prTxCtrl;
+	WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES;
+	P_QUE_MGT_T prQM;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	prQM = &prAdapter->rQM;
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+
+/*	DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n",
+	ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); */
+	do {
+		if (pfgIsSecOrMgmt && (ucTC == TC4_INDEX)) {
+			if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] < 2) {
+				DBGLOG(TX, EVENT, "<wlan> aucFreeBufferCount = %d\n",
+				prTxCtrl->rTc.aucFreeBufferCount[ucTC]);
+
+				if (prTxCtrl->rTc.aucFreeBufferCount[ucTC])
+					u4CurrTick = 0;
+
+				break;
+			}
+		}
+
+		if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) {
+
+			if (ucTC == TC4_INDEX)
+				u4CurrTick = 0;
+			/* get a available TX entry */
+			prTxCtrl->rTc.aucFreeBufferCount[ucTC]--;
+
+			prQM->au4ResourceUsedCounter[ucTC]++;
+
+			DBGLOG(TX, EVENT, "Acquire: TC = %d aucFreeBufferCount = %d\n",
+					   ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]);
+
+			u4Status = WLAN_STATUS_SUCCESS;
+		}
+	} while (FALSE);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+
+	if (ucTC == TC4_INDEX) {
+		if (u4CurrTick == 0)
+			u4CurrTick = kalGetTimeTick();
+		if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick,
+				SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) {
+			wlanDumpTcResAndTxedCmd(NULL, 0);
+			cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, "waiting response CMD queue");
+			glDumpConnSysCpuInfo(prAdapter->prGlueInfo);
+			kalSendAeeWarning("[TC4 no resource delay 5s!]", __func__);
+			glDoChipReset();
+			u4CurrTick = 0;
+		}
+	}
+	return u4Status;
+
+}				/* end of nicTxAcquireResourceAndTFCBs() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Driver maintain a variable that is synchronous with the usage of individual
+*        TC Buffer Count. This function will do polling if FW has return the resource.
+*        Used when driver start up before enable interrupt.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param ucTC           Specify the resource of TC
+*
+* @retval WLAN_STATUS_SUCCESS   Resource is available.
+* @retval WLAN_STATUS_FAILURE   Resource is not available.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
+{
+	P_TX_CTRL_T prTxCtrl;
+	WLAN_STATUS u4Status = WLAN_STATUS_FAILURE;
+	INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT;
+	UINT_32 au4WTSR[2];
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	if (ucTC >= TC_NUM)
+		return WLAN_STATUS_FAILURE;
+
+	if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0)
+		return WLAN_STATUS_SUCCESS;
+
+	while (i-- > 0) {
+		HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR);
+
+		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
+			u4Status = WLAN_STATUS_FAILURE;
+			break;
+		} else if (nicTxReleaseResource(prAdapter, (PUINT_8) au4WTSR)) {
+			if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) {
+				u4Status = WLAN_STATUS_SUCCESS;
+				break;
+			}
+			kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
+
+		} else {
+			kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
+		}
+	}
+
+	if (i <= 0 && ucTC == TC4_INDEX) {
+		DBGLOG(TX, ERROR, "polling Tx resource for Tc4 timeout\n");
+		glDumpConnSysCpuInfo(prAdapter->prGlueInfo);
+	}
+#if DBG
+	{
+		INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1);
+
+		if (i4Times) {
+			DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %d times, %d msec\n",
+					   i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC));
+		}
+	}
+#endif /* DBG */
+
+	return u4Status;
+
+}				/* end of nicTxPollingResource() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Driver maintain a variable that is synchronous with the usage of individual
+*        TC Buffer Count. This function will release TC Buffer count according to
+*        the given TX_STATUS COUNTER after TX Done.
+*
+* \param[in] prAdapter              Pointer to the Adapter structure.
+* \param[in] u4TxStatusCnt          Value of TX STATUS
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN unsigned char *aucTxRlsCnt)
+{
+	PUINT_32 pu4Tmp = (PUINT_32) aucTxRlsCnt;
+	P_TX_CTRL_T prTxCtrl;
+	BOOLEAN bStatus = FALSE;
+	UINT_32 i;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	if (pu4Tmp[0] | pu4Tmp[1]) {
+
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+		for (i = 0; i < TC_NUM; i++)
+			prTxCtrl->rTc.aucFreeBufferCount[i] += aucTxRlsCnt[i];
+		for (i = 0; i < TC_NUM; i++)
+			prQM->au4QmTcResourceBackCounter[i] += aucTxRlsCnt[i];
+		if (aucTxRlsCnt[TC4_INDEX] != 0)
+			wlanTraceReleaseTcRes(prAdapter, aucTxRlsCnt, prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX]);
+
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+#if 0
+		for (i = 0; i < TC_NUM; i++) {
+			DBGLOG(TX, TRACE, "aucFreeBufferCount[%d]: %d, aucMaxNumOfBuffer[%d]: %d\n",
+					     i, prTxCtrl->rTc.aucFreeBufferCount[i], i,
+					     prTxCtrl->rTc.aucMaxNumOfBuffer[i]);
+		}
+		DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[0]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[0]);
+		DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[1]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[1]);
+		DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[2]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[2]);
+		DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[3]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[3]);
+		DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[4]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[4]);
+		DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[5]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[5]);
+#endif
+		ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX]);
+		ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX]);
+		ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX]);
+		ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX]);
+		ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX]);
+		ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX]);
+		bStatus = TRUE;
+	}
+
+	return bStatus;
+}				/* end of nicTxReleaseResource() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Reset TC Buffer Count to initialized value
+*
+* \param[in] prAdapter              Pointer to the Adapter structure.
+*
+* @return WLAN_STATUS_SUCCESS
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter)
+{
+	P_TX_CTRL_T prTxCtrl;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	DEBUGFUNC("nicTxResetResource");
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0;
+	prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1;
+	prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2;
+	prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3;
+	prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4;
+	prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5;
+	prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5;
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Driver maintain a variable that is synchronous with the usage of individual
+*        TC Buffer Count. This function will return the value for other component
+*        which needs this information for making decisions
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param ucTC           Specify the resource of TC
+*
+* @retval UINT_8        The number of corresponding TC number
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
+{
+	P_TX_CTRL_T prTxCtrl;
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	ASSERT(prTxCtrl);
+
+	if (ucTC >= TC_NUM)
+		return 0;
+	else
+		return prTxCtrl->rTc.aucFreeBufferCount[ucTC];
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief In this function, we'll aggregate frame(PACKET_INFO_T)
+* corresponding to HIF TX port
+*
+* @param prAdapter              Pointer to the Adapter structure.
+* @param prMsduInfoListHead     a link list of P_MSDU_INFO_T
+*
+* @retval WLAN_STATUS_SUCCESS   Bus access ok.
+* @retval WLAN_STATUS_FAILURE   Bus access fail.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
+{
+	P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
+	QUE_T qDataPort0, qDataPort1;
+	WLAN_STATUS status;
+	BOOLEAN pfgIsSecOrMgmt = FALSE;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfoListHead);
+
+	prMsduInfo = prMsduInfoListHead;
+
+	QUEUE_INITIALIZE(&qDataPort0);
+	QUEUE_INITIALIZE(&qDataPort1);
+
+	/* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */
+	while (prMsduInfo) {
+		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
+#if DBG && 0
+		LOG_FUNC("nicTxMsduInfoList Acquire TC %d net %u mac len %u len %u Type %u 1x %u 11 %u\n",
+			 prMsduInfo->ucTC,
+			 prMsduInfo->ucNetworkType,
+			 prMsduInfo->ucMacHeaderLength,
+			 prMsduInfo->u2FrameLength,
+			 prMsduInfo->ucPacketType, prMsduInfo->fgIs802_1x, prMsduInfo->fgIs802_11);
+
+		LOG_FUNC("Dest Mac: %pM\n", prMsduInfo->aucEthDestAddr);
+#endif
+
+		/* double-check available TX resouce (need to sync with CONNSYS FW) */
+		/* caller must guarantee that the TX resource is enough in the func; OR assert here */
+		switch (prMsduInfo->ucTC) {
+		case TC0_INDEX:
+		case TC1_INDEX:
+		case TC2_INDEX:
+		case TC3_INDEX:
+		case TC5_INDEX:	/* Broadcast/multicast data packets */
+			QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
+			QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
+			status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, FALSE);
+			ASSERT(status == WLAN_STATUS_SUCCESS)
+
+			    break;
+
+		case TC4_INDEX:	/* Command or 802.1x packets */
+			QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
+			QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
+
+			if ((prMsduInfo->fgIs802_1x == TRUE) ||
+				(prMsduInfo->fgIs802_11 == TRUE))
+				pfgIsSecOrMgmt = TRUE;
+
+			status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, pfgIsSecOrMgmt);
+			ASSERT(status == WLAN_STATUS_SUCCESS)
+
+			    break;
+
+		default:
+			ASSERT(0);
+			break;
+		}
+
+		prMsduInfo = prNextMsduInfo;
+	}
+
+	/* send packets to HIF port0 or port1 here */
+	if (qDataPort0.u4NumElem > 0)
+		nicTxMsduQueue(prAdapter, 0, &qDataPort0);
+
+	if (qDataPort1.u4NumElem > 0)
+		nicTxMsduQueue(prAdapter, 1, &qDataPort1);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+
+#if CFG_PRINT_RTP_PROFILE
+PKT_PROFILE_T rPrevRoundLastPkt;
+
+BOOLEAN
+nicTxLifetimePrintCheckRTP(IN P_MSDU_INFO_T prPrevProfileMsduInfo,
+			   IN P_PKT_PROFILE_T prPrevRoundLastPkt,
+			   IN P_PKT_PROFILE_T prPktProfile,
+			   IN OUT PBOOLEAN pfgGotFirst, IN UINT_32 u4MaxDeltaTime, IN UINT_8 ucSnToBePrinted)
+{
+	BOOLEAN fgPrintCurPkt = FALSE;
+
+	if (u4MaxDeltaTime) {
+		/* 4 1. check delta between current round first pkt and prevous round last pkt */
+		if (!*pfgGotFirst) {
+			*pfgGotFirst = TRUE;
+
+			if (prPrevRoundLastPkt->fgIsValid) {
+				if (CHK_PROFILES_DELTA(prPktProfile, prPrevRoundLastPkt, u4MaxDeltaTime)) {
+					PRINT_PKT_PROFILE(prPrevRoundLastPkt, "PR");
+					fgPrintCurPkt = TRUE;
+				}
+			}
+		}
+		/* 4 2. check delta between current pkt and previous pkt */
+		if (prPrevProfileMsduInfo) {
+			if (CHK_PROFILES_DELTA(prPktProfile, &prPrevProfileMsduInfo->rPktProfile, u4MaxDeltaTime)) {
+				PRINT_PKT_PROFILE(&prPrevProfileMsduInfo->rPktProfile, "P");
+				fgPrintCurPkt = TRUE;
+			}
+		}
+		/* 4 3. check delta of current pkt lifetime */
+		if (CHK_PROFILE_DELTA(prPktProfile, u4MaxDeltaTime))
+			fgPrintCurPkt = TRUE;
+	}
+	/* 4 4. print every X RTP packets */
+#if CFG_SUPPORT_WFD
+	if ((ucSnToBePrinted != 0) && (prPktProfile->u2RtpSn % ucSnToBePrinted) == 0)
+		fgPrintCurPkt = TRUE;
+#endif
+
+	return fgPrintCurPkt;
+}
+
+BOOLEAN
+nicTxLifetimePrintCheckSnOrder(IN P_MSDU_INFO_T prPrevProfileMsduInfo,
+			       IN P_PKT_PROFILE_T prPrevRoundLastPkt,
+			       IN P_PKT_PROFILE_T prPktProfile, IN OUT PBOOLEAN pfgGotFirst, IN UINT_8 ucLayer)
+{
+	BOOLEAN fgPrintCurPkt = FALSE;
+	P_PKT_PROFILE_T prTarPktProfile = NULL;
+	UINT_16 u2PredictSn = 0;
+	UINT_16 u2CurrentSn = 0;
+	UINT_8 aucNote[8];
+
+	/* 4 1. Get the target packet profile to compare */
+
+	/* 4 1.1 check SN between current round first pkt and prevous round last pkt */
+	if ((!*pfgGotFirst) && (prPrevRoundLastPkt->fgIsValid)) {
+		*pfgGotFirst = TRUE;
+		prTarPktProfile = prPrevRoundLastPkt;
+		kalMemCopy(aucNote, "PR\0", 3);
+	}
+	/* 4 1.2 check SN between current pkt and previous pkt */
+	else if (prPrevProfileMsduInfo) {
+		prTarPktProfile = &prPrevProfileMsduInfo->rPktProfile;
+		kalMemCopy(aucNote, "P\0", 2);
+	}
+
+	if (!prTarPktProfile)
+		return FALSE;
+	/* 4 2. Check IP or RTP SN */
+	switch (ucLayer) {
+		/* Check IP SN */
+	case 0:
+		u2PredictSn = prTarPktProfile->u2IpSn + 1;
+		u2CurrentSn = prPktProfile->u2IpSn;
+		break;
+		/* Check RTP SN */
+	case 1:
+	default:
+		u2PredictSn = prTarPktProfile->u2RtpSn + 1;
+		u2CurrentSn = prPktProfile->u2RtpSn;
+		break;
+
+	}
+	/* 4 */
+	/* 4 3. Compare SN */
+	if (u2CurrentSn != u2PredictSn) {
+		PRINT_PKT_PROFILE(prTarPktProfile, aucNote);
+		fgPrintCurPkt = TRUE;
+	}
+
+	return fgPrintCurPkt;
+}
+#endif
+
+VOID nicTxReturnMsduInfoProfiling(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
+{
+	P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo;
+	P_PKT_PROFILE_T prPktProfile;
+	UINT_16 u2MagicCode = 0;
+
+	UINT_8 ucDebugtMode = 0;
+#if CFG_PRINT_RTP_PROFILE
+	P_MSDU_INFO_T prPrevProfileMsduInfo = NULL;
+	P_PKT_PROFILE_T prPrevRoundLastPkt = &rPrevRoundLastPkt;
+
+	BOOLEAN fgPrintCurPkt = FALSE;
+	BOOLEAN fgGotFirst = FALSE;
+	UINT_8 ucSnToBePrinted = 0;
+
+	UINT_32 u4MaxDeltaTime = 50;	/* in ms */
+#endif
+
+#if CFG_ENABLE_PER_STA_STATISTICS
+	UINT_32 u4PktPrintPeriod = 0;
+#endif
+
+#if CFG_SUPPORT_WFD
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+	if (prAdapter->fgIsP2PRegistered) {
+		prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
+		u2MagicCode = prWfdCfgSettings->u2WfdMaximumTp;
+		ucDebugtMode = prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode;
+		/* if(prWfdCfgSettings->ucWfdEnable && (prWfdCfgSettings->u4WfdFlag & BIT(0))) { */
+		/* u2MagicCode = 0xE040; */
+		/* } */
+	}
+#endif
+
+#if CFG_PRINT_RTP_PROFILE
+	if ((u2MagicCode >= 0xF000)) {
+		ucSnToBePrinted = (UINT_8) (u2MagicCode & BITS(0, 7));
+		u4MaxDeltaTime = (UINT_8) (((u2MagicCode & BITS(8, 11)) >> 8) * 10);
+	} else {
+		ucSnToBePrinted = 0;
+		u4MaxDeltaTime = 0;
+	}
+
+#endif
+
+#if CFG_ENABLE_PER_STA_STATISTICS
+	if ((u2MagicCode >= 0xE000) && (u2MagicCode < 0xF000))
+		u4PktPrintPeriod = (UINT_32) ((u2MagicCode & BITS(0, 7)) * 32);
+	else
+		u4PktPrintPeriod = 0;
+#endif
+
+	while (prMsduInfo) {
+		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
+		prPktProfile = &prMsduInfo->rPktProfile;
+
+		if (prPktProfile->fgIsValid) {
+
+			prPktProfile->rHifTxDoneTimestamp = kalGetTimeTick();
+			if (ucDebugtMode > 1) {
+
+#if CFG_PRINT_RTP_PROFILE
+#if CFG_PRINT_RTP_SN_SKIP
+				fgPrintCurPkt = nicTxLifetimePrintCheckSnOrder(prPrevProfileMsduInfo,
+									       prPrevRoundLastPkt,
+									       prPktProfile, &fgGotFirst, 0);
+#else
+				fgPrintCurPkt = nicTxLifetimePrintCheckRTP(prPrevProfileMsduInfo,
+									   prPrevRoundLastPkt,
+									   prPktProfile,
+									   &fgGotFirst,
+									   u4MaxDeltaTime, ucSnToBePrinted);
+#endif
+
+				/* Print current pkt profile */
+				if (fgPrintCurPkt && ucDebugtMode > 1)
+					PRINT_PKT_PROFILE(prPktProfile, "C");
+
+				prPrevProfileMsduInfo = prMsduInfo;
+				fgPrintCurPkt = FALSE;
+#endif
+			}
+#if CFG_ENABLE_PER_STA_STATISTICS
+			{
+				P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+				UINT_32 u4DeltaTime;
+				UINT_32 u4DeltaHifTime;
+#if 0
+				P_QUE_MGT_T prQM = &prAdapter->rQM;
+#endif
+				UINT_8 ucNetIndex;
+
+				if (prStaRec) {
+					ucNetIndex = prStaRec->ucNetTypeIndex;
+					u4DeltaTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp -
+							prPktProfile->rHardXmitArrivalTimestamp);
+					u4DeltaHifTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp -
+							prPktProfile->rDequeueTimestamp);
+					prStaRec->u4TotalTxPktsNumber++;
+
+					prStaRec->u4TotalTxPktsTime += u4DeltaTime;
+					prStaRec->u4TotalTxPktsHifTime += u4DeltaHifTime;
+
+					if (u4DeltaTime > prStaRec->u4MaxTxPktsTime)
+						prStaRec->u4MaxTxPktsTime = u4DeltaTime;
+
+					if (u4DeltaHifTime > prStaRec->u4MaxTxPktsHifTime)
+						prStaRec->u4MaxTxPktsHifTime = u4DeltaHifTime;
+
+
+					if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD)
+						prStaRec->u4ThresholdCounter++;
+#if 0
+					if (u4PktPrintPeriod && (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) {
+
+						DBGLOG(TX, TRACE, "[%u]N[%4u]A[%5u]M[%4u]T[%4u]E[%4u]\n",
+						   prStaRec->ucIndex,
+						   prStaRec->u4TotalTxPktsNumber,
+						   prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber,
+						   prStaRec->u4MaxTxPktsTime,
+						   prStaRec->u4ThresholdCounter,
+						   prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX]);
+
+						prStaRec->u4TotalTxPktsNumber = 0;
+						prStaRec->u4TotalTxPktsTime = 0;
+						prStaRec->u4MaxTxPktsTime = 0;
+						prStaRec->u4ThresholdCounter = 0;
+						prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX] = 0;
+					}
+#endif
+				}
+
+			}
+#endif
+		}
+
+		prMsduInfo = prNextMsduInfo;
+	};
+
+#if CFG_PRINT_RTP_PROFILE
+	/* 4 4. record the lifetime of current round last pkt */
+	if (prPrevProfileMsduInfo) {
+		prPktProfile = &prPrevProfileMsduInfo->rPktProfile;
+		prPrevRoundLastPkt->u2IpSn = prPktProfile->u2IpSn;
+		prPrevRoundLastPkt->u2RtpSn = prPktProfile->u2RtpSn;
+		prPrevRoundLastPkt->rHardXmitArrivalTimestamp = prPktProfile->rHardXmitArrivalTimestamp;
+		prPrevRoundLastPkt->rEnqueueTimestamp = prPktProfile->rEnqueueTimestamp;
+		prPrevRoundLastPkt->rDequeueTimestamp = prPktProfile->rDequeueTimestamp;
+		prPrevRoundLastPkt->rHifTxDoneTimestamp = prPktProfile->rHifTxDoneTimestamp;
+		prPrevRoundLastPkt->ucTcxFreeCount = prPktProfile->ucTcxFreeCount;
+		prPrevRoundLastPkt->fgIsPrinted = prPktProfile->fgIsPrinted;
+		prPrevRoundLastPkt->fgIsValid = TRUE;
+	}
+#endif
+
+	nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead);
+
+}
+
+VOID nicTxLifetimeRecordEn(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket)
+{
+	P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile;
+
+	/* Enable packet lifetime profiling */
+	prPktProfile->fgIsValid = TRUE;
+
+	/* Packet arrival time at kernel Hard Xmit */
+	prPktProfile->rHardXmitArrivalTimestamp = GLUE_GET_PKT_ARRIVAL_TIME(prPacket);
+
+	/* Packet enqueue time */
+	prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) kalGetTimeTick();
+
+}
+
+#if CFG_PRINT_RTP_PROFILE
+/*
+    in:
+	data   RTP packet pointer
+	size   RTP size
+    return
+	0:audio 1: video, -1:none
+*/
+UINT8 checkRtpAV(PUINT_8 data, UINT_32 size)
+{
+	PUINT_8 buf = data + 12;
+
+	while (buf + 188 <= data + size) {
+		int pid = ((buf[1] << 8) & 0x1F00) | (buf[2] & 0xFF);
+
+		if (pid == 0 || pid == 0x100 || pid == 0x1000)
+			buf += 188;
+		else if (pid == 0x1100)
+			return 0;
+		else if (pid == 0x1011)
+			return 1;
+	}
+	return -1;
+}
+
+VOID
+nicTxLifetimeCheckRTP(IN P_ADAPTER_T prAdapter,
+		      IN P_MSDU_INFO_T prMsduInfo,
+		      IN P_NATIVE_PACKET prPacket, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType)
+{
+	struct sk_buff *prSkb = (struct sk_buff *)prPacket;
+	UINT_16 u2EtherTypeLen;
+	PUINT_8 aucLookAheadBuf = NULL;
+	P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile;
+
+	/* UINT_8 ucRtpHdrOffset = 28; */
+	UINT_8 ucRtpSnOffset = 30;
+	/* UINT_32 u4RtpSrcPort = 15550; */
+	P_TX_CTRL_T prTxCtrl;
+#if CFG_SUPPORT_WFD
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+	P_WFD_DBG_CFG_SETTINGS_T prWfdDbgSettings = (P_WFD_DBG_CFG_SETTINGS_T) NULL;
+
+	BOOLEAN fgEnProfiling = FALSE;
+
+	if (prAdapter->fgIsP2PRegistered) {
+		prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
+		prWfdDbgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting;
+#if CFG_PRINT_RTP_SN_SKIP
+		if (ucNetworkType == NETWORK_TYPE_P2P_INDEX) {
+			fgEnProfiling = TRUE;
+		} else
+#endif
+		if (((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000) ||
+			     (prWfdDbgSettings->ucWfdDebugMode > 0)) && (ucNetworkType == NETWORK_TYPE_P2P_INDEX)) {
+			fgEnProfiling = TRUE;
+		}
+	}
+
+	if (fgEnProfiling == FALSE) {
+		/* prPktProfile->fgIsValid = FALSE; */
+		return;
+	}
+#endif
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	/* prPktProfile->fgIsValid = FALSE; */
+
+	aucLookAheadBuf = prSkb->data;
+
+	u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]);
+
+	if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) {
+		PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN];
+		UINT_16 u2tmpIpSN = 0;
+		UINT_8 ucIpVersion;
+
+		ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
+		if (ucIpVersion == IPVERSION) {
+			if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) {
+
+				/* if(checkRtpAV(&pucIpHdr[ucRtpHdrOffset],
+						(u4PacketLen - ETH_HLEN - ucRtpHdrOffset)) == 0) { */
+
+				if (prPktProfile->fgIsValid == FALSE)
+					nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket);
+
+				prPktProfile->fgIsPrinted = FALSE;
+
+				prPktProfile->ucTcxFreeCount = prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX];
+
+				/* RTP SN */
+				prPktProfile->u2RtpSn = pucIpHdr[ucRtpSnOffset] << 8 | pucIpHdr[ucRtpSnOffset + 1];
+
+				/* IP SN */
+				prPktProfile->u2IpSn = pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET] << 8 |
+				    pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET + 1];
+				u2tmpIpSN = prPktProfile->u2IpSn;
+				if (prWfdDbgSettings->ucWfdDebugMode == 1) {
+					if ((u2tmpIpSN & (prWfdDbgSettings->u2WfdSNShowPeiroid)) == 0)
+						DBGLOG(TX, TRACE,
+							"RtpSn=%d IPId=%d j=%lu\n", prPktProfile->u2RtpSn,
+							prPktProfile->u2IpSn, jiffies);
+				}
+				/* } */
+			}
+		}
+	}
+
+}
+#endif
+#if CFG_ENABLE_PER_STA_STATISTICS
+VOID
+nicTxLifetimeCheckByAC(IN P_ADAPTER_T prAdapter,
+		       IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket, IN UINT_8 ucPriorityParam)
+{
+	switch (ucPriorityParam) {
+		/* BK */
+		/* case 1: */
+		/* case 2: */
+
+		/* BE */
+		/* case 0: */
+		/* case 3: */
+
+		/* VI */
+	case 4:
+	case 5:
+
+		/* VO */
+	case 6:
+	case 7:
+		nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket);
+		break;
+	default:
+		break;
+	}
+}
+
+#endif
+
+VOID
+nicTxLifetimeCheck(IN P_ADAPTER_T prAdapter,
+		   IN P_MSDU_INFO_T prMsduInfo,
+		   IN P_NATIVE_PACKET prPacket,
+		   IN UINT_8 ucPriorityParam, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType)
+{
+	P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile;
+
+	/* Reset packet profile */
+	prPktProfile->fgIsValid = FALSE;
+
+#if CFG_ENABLE_PER_STA_STATISTICS
+	nicTxLifetimeCheckByAC(prAdapter, prMsduInfo, prPacket, ucPriorityParam);
+#endif
+
+#if CFG_PRINT_RTP_PROFILE
+	nicTxLifetimeCheckRTP(prAdapter, prMsduInfo, prPacket, u4PacketLen, ucNetworkType);
+#endif
+
+}
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF.
+*
+* @param prAdapter              Pointer to the Adapter structure.
+* @param ucPortIdx              Port Number
+* @param prQue                  a link list of P_MSDU_INFO_T
+*
+* @retval WLAN_STATUS_SUCCESS   Bus access ok.
+* @retval WLAN_STATUS_FAILURE   Bus access fail.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue)
+{
+	P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
+	HIF_TX_HEADER_T rHwTxHeader;
+	P_NATIVE_PACKET prNativePacket;
+	UINT_16 u2OverallBufferLength;
+	UINT_8 ucEtherTypeOffsetInWord;
+	PUINT_8 pucOutputBuf = (PUINT_8) NULL;	/* Pointer to Transmit Data Structure Frame */
+	UINT_32 u4TxHdrSize;
+	UINT_32 u4ValidBufSize;
+	UINT_32 u4TotalLength;
+	P_TX_CTRL_T prTxCtrl;
+	QUE_T rFreeQueue;
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	UINT_8 ucChksumFlag;
+#endif
+
+	ASSERT(prAdapter);
+	ASSERT(ucPortIdx < 2);
+	ASSERT(prQue);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize;
+
+#if CFG_HIF_STATISTICS
+	prTxCtrl->u4TotalTxAccessNum++;
+	prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem;
+#endif
+
+	QUEUE_INITIALIZE(&rFreeQueue);
+
+	if (prQue->u4NumElem > 0) {
+		prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue);
+		pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
+		u4TotalLength = 0;
+
+		while (prMsduInfo) {
+
+#if (CFG_SUPPORT_TDLS_DBG == 1)
+			{
+				struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket;
+				UINT8 *pkt = prSkb->data;
+				UINT16 u2Identifier;
+
+				if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) {
+					/* ip */
+					u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19));
+					DBGLOG(TX, TRACE, "<hif> %d\n", u2Identifier);
+				}
+			}
+#endif
+#if (CFG_SUPPORT_MET_PROFILING == 1)
+			kalMetProfilingFinish(prAdapter, prMsduInfo);
+#endif
+			kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader));
+
+			prNativePacket = prMsduInfo->prPacket;
+
+			ASSERT(prNativePacket);
+
+			u4TxHdrSize = TX_HDR_SIZE;
+
+			u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) &
+						 (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
+
+			/* init TX header */
+			rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength;
+			rHwTxHeader.u2TxByteCount_UserPriority |=
+			    ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET);
+
+			if (prMsduInfo->fgIs802_11) {
+				ucEtherTypeOffsetInWord =
+				    (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1;
+			} else {
+				ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1;
+			}
+
+			rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK;
+
+			rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET;
+			rHwTxHeader.ucResource_PktType_CSflags |=
+			    (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) &
+				      (HIF_TX_HDR_PACKET_TYPE_MASK));
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+			if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
+				if (prAdapter->u4CSUMFlags &
+				    (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) {
+					kalQueryTxChksumOffloadParam(prNativePacket, &ucChksumFlag);
+
+					if (ucChksumFlag & TX_CS_IP_GEN)
+						rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_IP_CSUM;
+
+					if (ucChksumFlag & TX_CS_TCP_UDP_GEN)
+						rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_TCP_CSUM;
+				}
+			}
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+			rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH;
+			rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex;
+			rHwTxHeader.ucForwardingType_SessionID_Reserved =
+			    (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) <<
+								HIF_TX_HDR_PS_SESSION_ID_OFFSET)
+			    | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0);
+
+			rHwTxHeader.ucWlanHeaderLength =
+			    (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK);
+			rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK)
+			    | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) &
+			       HIF_TX_HDR_NETWORK_TYPE_MASK)
+			    | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) &
+			       HIF_TX_HDR_FLAG_1X_FRAME_MASK)
+			    | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) &
+			       HIF_TX_HDR_FLAG_802_11_FORMAT_MASK);
+
+			rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN;
+
+			if (prMsduInfo->pfTxDoneHandler) {
+				rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum;
+				rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK;
+			} else {
+				rHwTxHeader.ucPacketSeqNo = 0;
+				rHwTxHeader.ucAck_BIP_BasicRate = 0;
+			}
+
+			if (prMsduInfo->fgNeedTxDoneStatus == TRUE)
+				rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_NEED_TX_DONE_STATUS;
+
+			if (prMsduInfo->fgIsBIP)
+				rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP;
+
+			if (prMsduInfo->fgIsBasicRate)
+				rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE;
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+			if (prMsduInfo->rPktProfile.fgIsValid)
+				prMsduInfo->rPktProfile.rDequeueTimestamp = kalGetTimeTick();
+#endif
+
+			/* record the queue time in driver */
+			STATS_TX_TIME_TO_HIF(prMsduInfo, &rHwTxHeader);
+
+#if CFG_SDIO_TX_AGG
+			/* attach to coalescing buffer */
+			kalMemCopy(pucOutputBuf + u4TotalLength, &rHwTxHeader, u4TxHdrSize);
+			u4TotalLength += u4TxHdrSize;
+
+			if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING)
+				kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength);
+			else if (prMsduInfo->eSrc == TX_PACKET_MGMT)
+				kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength);
+			else
+				ASSERT(0);
+
+			u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength);
+
+#else
+			kalMemCopy(pucOutputBuf, &rHwTxHeader, u4TxHdrSize);
+
+			/* Copy Frame Body */
+			if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING)
+				kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TxHdrSize);
+			else if (prMsduInfo->eSrc == TX_PACKET_MGMT)
+				kalMemCopy(pucOutputBuf + u4TxHdrSize, prNativePacket, prMsduInfo->u2FrameLength);
+			else
+				ASSERT(0);
+
+			ASSERT(u2OverallBufferLength <= u4ValidBufSize);
+
+			HAL_WRITE_TX_PORT(prAdapter,
+					  ucPortIdx,
+					  (UINT_32) u2OverallBufferLength, (PUINT_8) pucOutputBuf, u4ValidBufSize);
+
+			/* send immediately */
+#endif
+			prNextMsduInfo = (P_MSDU_INFO_T)
+			    QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry);
+
+			if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
+				GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
+
+				if (prMsduInfo->pfTxDoneHandler == NULL) {
+					cnmMgtPktFree(prAdapter, prMsduInfo);
+				} else {
+					KAL_SPIN_LOCK_DECLARATION();
+					DBGLOG(TX, TRACE, "Wait TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum);
+					KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+					QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
+					KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+				}
+			} else {
+				/* only free MSDU when it is not a MGMT frame */
+				QUEUE_INSERT_TAIL(&rFreeQueue, (P_QUE_ENTRY_T) prMsduInfo);
+
+				if (prMsduInfo->eSrc == TX_PACKET_OS)
+					kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS);
+				else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING)
+					GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
+			}
+
+			prMsduInfo = prNextMsduInfo;
+		}
+
+#if CFG_SDIO_TX_AGG
+		ASSERT(u4TotalLength <= u4ValidBufSize);
+
+#if CFG_DBG_GPIO_PINS
+		{
+			/* Start port write */
+			mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_LOW);
+			kalUdelay(1);
+			mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_HIGH);
+		}
+#endif
+
+		/* send coalescing buffer */
+		HAL_WRITE_TX_PORT(prAdapter, ucPortIdx, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize);
+#endif
+
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+#if CFG_SUPPORT_WFD && CFG_PRINT_RTP_PROFILE && !CFG_ENABLE_PER_STA_STATISTICS
+		do {
+			P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+
+			prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
+
+			if ((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000)) {
+				/* Enable profiling */
+				nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
+			} else {
+				/* Skip profiling */
+				nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
+			}
+		} while (FALSE);
+#else
+		nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
+#endif
+#else
+		/* return */
+		nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
+#endif
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param prPacketInfo   Pointer of CMD_INFO_T
+* @param ucTC           Specify the resource of TC
+*
+* @retval WLAN_STATUS_SUCCESS   Bus access ok.
+* @retval WLAN_STATUS_FAILURE   Bus access fail.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC)
+{
+	P_WIFI_CMD_T prWifiCmd;
+	UINT_16 u2OverallBufferLength;
+	PUINT_8 pucOutputBuf = (PUINT_8) NULL;	/* Pointer to Transmit Data Structure Frame */
+	UINT_8 ucPortIdx;
+	HIF_TX_HEADER_T rHwTxHeader;
+	P_NATIVE_PACKET prNativePacket;
+	UINT_8 ucEtherTypeOffsetInWord;
+	P_MSDU_INFO_T prMsduInfo;
+	P_TX_CTRL_T prTxCtrl;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
+
+	/* <1> Assign Data Port */
+	if (ucTC != TC4_INDEX) {
+		ucPortIdx = 0;
+	} else {
+		/* Broadcast/multicast data frames, 1x frames, command packets, MMPDU */
+		ucPortIdx = 1;
+	}
+	wlanTraceTxCmd(prCmdInfo);
+
+	if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
+		/* <2> Compose HIF_TX_HEADER */
+		kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader));
+
+		prNativePacket = prCmdInfo->prPacket;
+
+		ASSERT(prNativePacket);
+
+		u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE)
+							     & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
+
+		rHwTxHeader.u2TxByteCount_UserPriority = ((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE)
+							  & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
+		ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1;
+
+		rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK;
+
+		rHwTxHeader.ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET);
+
+		rHwTxHeader.ucStaRecIdx = prCmdInfo->ucStaRecIndex;
+		rHwTxHeader.ucForwardingType_SessionID_Reserved = HIF_TX_HDR_BURST_END_MASK;
+
+		rHwTxHeader.ucWlanHeaderLength = (ETH_HLEN & HIF_TX_HDR_WLAN_HEADER_LEN_MASK);
+		rHwTxHeader.ucPktFormtId_Flags =
+		    (((UINT_8) (prCmdInfo->eNetworkType) << HIF_TX_HDR_NETWORK_TYPE_OFFSET) &
+		     HIF_TX_HDR_NETWORK_TYPE_MASK)
+		    | ((1 << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK);
+
+		rHwTxHeader.u2SeqNo = 0;
+		rHwTxHeader.ucPacketSeqNo = 0;
+		rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_TX_DONE_STATUS;
+		rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE /* | HIF_TX_HDR_RTS */;
+
+		/* <2.3> Copy HIF TX HEADER */
+		kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE);
+
+		/* <3> Copy Frame Body Copy */
+		kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + TX_HDR_SIZE);
+	} else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
+		prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket;
+
+		ASSERT(prMsduInfo->fgIs802_11 == TRUE);
+		ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
+
+		/* <2> Compose HIF_TX_HEADER */
+		kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader));
+
+		u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) &
+					 (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
+
+		rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength;
+		rHwTxHeader.u2TxByteCount_UserPriority |=
+		    ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET);
+
+		ucEtherTypeOffsetInWord = (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1;
+
+		rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK;
+
+		rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET;
+		rHwTxHeader.ucResource_PktType_CSflags |=
+		    (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) &
+			      (HIF_TX_HDR_PACKET_TYPE_MASK));
+
+		rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH;
+		rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex;
+		rHwTxHeader.ucForwardingType_SessionID_Reserved =
+		    (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << HIF_TX_HDR_PS_SESSION_ID_OFFSET)
+		    | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0);
+
+		rHwTxHeader.ucWlanHeaderLength = (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK);
+		rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK)
+		    | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & HIF_TX_HDR_NETWORK_TYPE_MASK)
+		    | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK)
+		    | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) &
+		       HIF_TX_HDR_FLAG_802_11_FORMAT_MASK);
+
+		rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN;
+
+		if (prMsduInfo->pfTxDoneHandler) {
+			rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum;
+			rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK;
+		} else {
+			rHwTxHeader.ucPacketSeqNo = 0;
+			rHwTxHeader.ucAck_BIP_BasicRate = 0;
+		}
+
+		if (prMsduInfo->fgIsBIP)
+			rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP;
+
+		if (prMsduInfo->fgIsBasicRate)
+			rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE;
+		/* <2.3> Copy HIF TX HEADER */
+		kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE);
+
+		/* <3> Copy Frame Body */
+		kalMemCopy(pucOutputBuf + TX_HDR_SIZE, prMsduInfo->prPacket, prMsduInfo->u2FrameLength);
+
+		/* <4> Management Frame Post-Processing */
+		GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
+
+		if (prMsduInfo->pfTxDoneHandler == NULL) {
+			cnmMgtPktFree(prAdapter, prMsduInfo);
+		} else {
+
+			DBGLOG(TX, TRACE, "Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum);
+
+			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+			QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
+			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+		}
+	} else {
+		prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer;
+
+		/* <2> Compose the Header of Transmit Data Structure for CMD Packet */
+		u2OverallBufferLength =
+		    TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
+
+		prWifiCmd->u2TxByteCount_UserPriority = u2OverallBufferLength;
+		prWifiCmd->ucEtherTypeOffset = 0;
+		prWifiCmd->ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET)
+		    | (UINT_8) ((HIF_TX_PKT_TYPE_CMD << HIF_TX_HDR_PACKET_TYPE_OFFSET) & (HIF_TX_HDR_PACKET_TYPE_MASK));
+
+		/* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */
+		kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen);
+
+		ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize);
+
+		if ((prCmdInfo->ucCID == CMD_ID_SCAN_REQ) ||
+			(prCmdInfo->ucCID == CMD_ID_SCAN_CANCEL) ||
+			(prCmdInfo->ucCID == CMD_ID_SCAN_REQ_V2))
+			DBGLOG(TX, INFO, "ucCmdSeqNum =%d, ucCID =%d\n", prCmdInfo->ucCmdSeqNum, prCmdInfo->ucCID);
+	}
+
+	/* <4> Write frame to data port */
+	HAL_WRITE_TX_PORT(prAdapter,
+			  ucPortIdx,
+			  (UINT_32) u2OverallBufferLength,
+			  (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize);
+
+	return WLAN_STATUS_SUCCESS;
+}				/* end of nicTxCmd() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function will clean up all the pending frames in internal SW Queues
+*        by return the pending TX packet to the system.
+*
+* @param prAdapter  Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicTxRelease(IN P_ADAPTER_T prAdapter)
+{
+	P_TX_CTRL_T prTxCtrl;
+	P_MSDU_INFO_T prMsduInfo;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	nicTxFlush(prAdapter);
+
+	/* free MSDU_INFO_T from rTxMgmtMsduInfoList */
+	do {
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+		QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
+
+		if (prMsduInfo) {
+			/* the packet must be mgmt frame with tx done callback */
+			ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
+
+			/* invoke done handler */
+			prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT);
+
+			cnmMgtPktFree(prAdapter, prMsduInfo);
+		} else {
+			break;
+		}
+	} while (TRUE);
+
+}				/* end of nicTxRelease() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Process the TX Done interrupt and pull in more pending frames in SW
+*        Queues for transmission.
+*
+* @param prAdapter  Pointer to the Adapter structure.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter)
+{
+	P_TX_CTRL_T prTxCtrl;
+#if CFG_SDIO_INTR_ENHANCE
+	P_SDIO_CTRL_T prSDIOCtrl;
+#else
+	UINT_32 au4TxCount[2];
+#endif /* CFG_SDIO_INTR_ENHANCE */
+
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	ASSERT(prTxCtrl);
+	prGlueInfo->IsrTxCnt++;
+
+	/* Get the TX STATUS */
+#if CFG_SDIO_INTR_ENHANCE
+
+	prSDIOCtrl = prAdapter->prSDIOCtrl;
+#if DBG
+	/* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */
+#endif
+
+	nicTxReleaseResource(prAdapter, (PUINT_8) &prSDIOCtrl->rTxInfo);
+	kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo));
+
+#else
+
+	HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]);
+	HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]);
+	DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]);
+
+	nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount);
+
+#endif /* CFG_SDIO_INTR_ENHANCE */
+
+	nicTxAdjustTcq(prAdapter);
+
+	/* Indicate Service Thread */
+	if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0)
+		kalSetEvent(prAdapter->prGlueInfo);
+
+}				/* end of nicProcessTxInterrupt() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief this function frees packet of P_MSDU_INFO_T linked-list
+*
+* @param prAdapter              Pointer to the Adapter structure.
+* @param prMsduInfoList         a link list of P_MSDU_INFO_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
+{
+	P_NATIVE_PACKET prNativePacket;
+	P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead;
+	P_TX_CTRL_T prTxCtrl;
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfoListHead);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	while (prMsduInfo) {
+		prNativePacket = prMsduInfo->prPacket;
+
+		if (prMsduInfo->eSrc == TX_PACKET_OS) {
+			kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE);
+		} else if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
+			P_MSDU_INFO_T prTempMsduInfo = prMsduInfo;
+
+			if (prMsduInfo->pfTxDoneHandler)
+				prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);
+			prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
+			cnmMgtPktFree(prAdapter, prTempMsduInfo);
+			continue;
+		} else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
+			GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
+		}
+
+		prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList
+*
+* @param prAdapter              Pointer to the Adapter structure.
+* @param prMsduInfoList         a link list of P_MSDU_INFO_T
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
+{
+	P_TX_CTRL_T prTxCtrl;
+	P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	ASSERT(prTxCtrl);
+
+	while (prMsduInfo) {
+		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
+
+		switch (prMsduInfo->eSrc) {
+		case TX_PACKET_FORWARDING:
+			wlanReturnPacket(prAdapter, prMsduInfo->prPacket);
+			break;
+		case TX_PACKET_OS:
+		case TX_PACKET_OS_OID:
+		case TX_PACKET_MGMT:
+		default:
+			break;
+		}
+
+		/* Reset MSDU_INFO fields */
+		kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));
+
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+		QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
+		prMsduInfo = prNextMsduInfo;
+	};
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief this function fills packet information to P_MSDU_INFO_T
+*
+* @param prAdapter              Pointer to the Adapter structure.
+* @param prMsduInfo             P_MSDU_INFO_T
+* @param prPacket               P_NATIVE_PACKET
+*
+* @retval TRUE      Success to extract information
+* @retval FALSE     Fail to extract correct information
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_8 ucPriorityParam;
+	UINT_8 ucMacHeaderLen;
+	UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN];
+	BOOLEAN fgIs1x = FALSE;
+	BOOLEAN fgIsPAL = FALSE;
+	UINT_32 u4PacketLen;
+	ULONG u4SysTime;
+	UINT_8 ucNetworkType;
+	struct sk_buff *prSkb = (struct sk_buff *)prPacket;
+
+	ASSERT(prAdapter);
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	ASSERT(prGlueInfo);
+
+	if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo,
+					       prPacket,
+					       &ucPriorityParam,
+					       &u4PacketLen,
+					       aucEthDestAddr,
+					       &fgIs1x, &fgIsPAL, &ucNetworkType,
+					       NULL) == FALSE) {
+		return FALSE;
+	}
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+	nicTxLifetimeCheck(prAdapter, prMsduInfo, prPacket, ucPriorityParam, u4PacketLen, ucNetworkType);
+#endif
+
+	/* Save the value of Priority Parameter */
+	GLUE_SET_PKT_TID(prPacket, ucPriorityParam);
+
+	if (fgIs1x)
+		GLUE_SET_PKT_FLAG_1X(prPacket);
+
+	if (fgIsPAL)
+		GLUE_SET_PKT_FLAG_PAL(prPacket);
+
+	ucMacHeaderLen = ETH_HLEN;
+
+	/* Save the value of Header Length */
+	GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen);
+
+	/* Save the value of Frame Length */
+	GLUE_SET_PKT_FRAME_LEN(prPacket, (UINT_16) u4PacketLen);
+
+	/* Save the value of Arrival Time */
+	u4SysTime = (OS_SYSTIME) kalGetTimeTick();
+	GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime);
+
+	prMsduInfo->prPacket = prPacket;
+	prMsduInfo->fgIs802_1x = fgIs1x;
+	prMsduInfo->fgIs802_11 = FALSE;
+	prMsduInfo->ucNetworkType = ucNetworkType;
+	prMsduInfo->ucUserPriority = ucPriorityParam;
+	prMsduInfo->ucMacHeaderLength = ucMacHeaderLen;
+	prMsduInfo->u2FrameLength = (UINT_16) u4PacketLen;
+	COPY_MAC_ADDR(prMsduInfo->aucEthDestAddr, aucEthDestAddr);
+
+	if (prSkb->len > ETH_HLEN)
+		STATS_TX_PKT_CALLBACK(prSkb->data, prMsduInfo);
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief this function update TCQ values by passing current status to txAdjustTcQuotas
+*
+* @param prAdapter              Pointer to the Adapter structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Updated successfully
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 u4Num;
+	TX_TCQ_ADJUST_T rTcqAdjust;
+	P_TX_CTRL_T prTxCtrl;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	ASSERT(prTxCtrl);
+
+	qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc);
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+
+	for (u4Num = 0; u4Num < TC_NUM; u4Num++) {
+		prTxCtrl->rTc.aucFreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num];
+		prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num];
+	}
+
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief this function flushes all packets queued in STA/AC queue
+*
+* @param prAdapter              Pointer to the Adapter structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Flushed successfully
+*/
+/*----------------------------------------------------------------------------*/
+
+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter)
+{
+	P_MSDU_INFO_T prMsduInfo;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+
+	/* ask Per STA/AC queue to be fllushed and return all queued packets */
+	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+	prMsduInfo = qmFlushTxQueues(prAdapter);
+	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+
+	if (prMsduInfo != NULL) {
+		nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo);
+		nicTxReturnMsduInfo(prAdapter, prMsduInfo);
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+#if CFG_ENABLE_FW_DOWNLOAD
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
+*        However this function is used for INIT_CMD.
+*
+*        In order to avoid further maintenance issues, these 2 functions are separated
+*
+* @param prAdapter      Pointer to the Adapter structure.
+* @param prPacketInfo   Pointer of CMD_INFO_T
+* @param ucTC           Specify the resource of TC
+*
+* @retval WLAN_STATUS_SUCCESS   Bus access ok.
+* @retval WLAN_STATUS_FAILURE   Bus access fail.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC)
+{
+	P_INIT_HIF_TX_HEADER_T prInitTxHeader;
+	UINT_16 u2OverallBufferLength;
+	PUINT_8 pucOutputBuf = (PUINT_8) NULL;	/* Pointer to Transmit Data Structure Frame */
+	UINT_32 ucPortIdx;
+	P_TX_CTRL_T prTxCtrl;
+
+	ASSERT(prAdapter);
+	ASSERT(prCmdInfo);
+	ASSERT(ucTC == TC0_INDEX);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
+	prInitTxHeader = (P_INIT_HIF_TX_HEADER_T) prCmdInfo->pucInfoBuffer;
+
+	/* <1> Compose the Header of Transmit Data Structure for CMD Packet */
+	u2OverallBufferLength =
+	    TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
+
+	prInitTxHeader->u2TxByteCount = u2OverallBufferLength;
+	prInitTxHeader->ucEtherTypeOffset = 0;
+	prInitTxHeader->ucCSflags = 0;
+
+	/* <2> Assign Data Port */
+	if (ucTC != TC4_INDEX) {
+		ucPortIdx = 0;
+	} else {		/* Broadcast/multicast data packets */
+		ucPortIdx = 1;
+	}
+
+	/* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */
+	kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen);
+
+	ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize);
+
+	/* <4> Write frame to data port */
+	HAL_WRITE_TX_PORT(prAdapter,
+			  ucPortIdx,
+			  (UINT_32) u2OverallBufferLength,
+			  (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief In this function, we'll reset TX resource counter to initial value used
+*        in F/W download state
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @retval WLAN_STATUS_SUCCESS   Reset is done successfully.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter)
+{
+	P_TX_CTRL_T prTxCtrl;
+
+	DEBUGFUNC("nicTxInitResetResource");
+
+	ASSERT(prAdapter);
+	prTxCtrl = &prAdapter->rTxCtrl;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0;
+	prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1;
+	prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2;
+	prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3;
+	prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4;
+	prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4;
+
+	prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5;
+	prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5;
+
+	return WLAN_STATUS_SUCCESS;
+
+}
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief this function enqueues MSDU_INFO_T into queue management,
+*        or command queue
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*        prMsduInfo     Pointer to MSDU
+*
+* @retval WLAN_STATUS_SUCCESS   Reset is done successfully.
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_TX_CTRL_T prTxCtrl;
+	P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead;
+	QUE_T qDataPort0, qDataPort1;
+	P_CMD_INFO_T prCmdInfo;
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+
+	KAL_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prAdapter);
+	ASSERT(prMsduInfo);
+
+	prTxCtrl = &prAdapter->rTxCtrl;
+	ASSERT(prTxCtrl);
+
+	QUEUE_INITIALIZE(&qDataPort0);
+	QUEUE_INITIALIZE(&qDataPort1);
+
+	/* check how many management frame are being queued */
+	while (prMsduInfo) {
+		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
+
+		QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
+
+		if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
+			/* MMPDU: force stick to TC4 */
+			prMsduInfo->ucTC = TC4_INDEX;
+
+			QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
+		} else {
+			QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
+		}
+
+		prMsduInfo = prNextMsduInfo;
+	}
+
+	if (qDataPort0.u4NumElem) {
+		/* send to QM: queue the packet to different TX queue by policy */
+		KAL_SPIN_LOCK_DECLARATION();
+		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+		prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort0));
+		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
+
+		/* post-process for "dropped" packets */
+		if (prRetMsduInfo != NULL) {	/* unable to enqueue */
+			nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo);
+			nicTxReturnMsduInfo(prAdapter, prRetMsduInfo);
+		}
+	}
+
+	if (qDataPort1.u4NumElem) {
+		prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort1);
+
+		if (qDataPort1.u4NumElem > nicTxGetFreeCmdCount(prAdapter)) {
+			/* not enough descriptors for sending */
+			u4Status = WLAN_STATUS_FAILURE;
+
+			/* free all MSDUs */
+			while (prMsduInfoHead) {
+				prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);
+
+				if (prMsduInfoHead->pfTxDoneHandler != NULL) {
+					prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead,
+									TX_RESULT_DROPPED_IN_DRIVER);
+				}
+
+				cnmMgtPktFree(prAdapter, prMsduInfoHead);
+
+				prMsduInfoHead = prNextMsduInfo;
+			}
+		} else {
+			/* send to command queue */
+			while (prMsduInfoHead) {
+				prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);
+
+				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+				QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T);
+				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
+
+				if (prCmdInfo) {
+					GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
+
+					kalMemZero(prCmdInfo, sizeof(CMD_INFO_T));
+
+					prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME;
+					prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength;
+					prCmdInfo->pucInfoBuffer = NULL;
+					prCmdInfo->prPacket = (P_NATIVE_PACKET) prMsduInfoHead;
+					prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex;
+					prCmdInfo->eNetworkType = prMsduInfoHead->ucNetworkType;
+					prCmdInfo->pfCmdDoneHandler = NULL;
+					prCmdInfo->pfCmdTimeoutHandler = NULL;
+					prCmdInfo->fgIsOid = FALSE;
+					prCmdInfo->fgSetQuery = TRUE;
+					prCmdInfo->fgNeedResp = FALSE;
+
+					kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
+				} else {
+					/* Cmd free count is larger than expected, but allocation fail. */
+					ASSERT(0);
+
+					u4Status = WLAN_STATUS_FAILURE;
+					cnmMgtPktFree(prAdapter, prMsduInfoHead);
+				}
+
+				prMsduInfoHead = prNextMsduInfo;
+			}
+		}
+	}
+
+	/* indicate service thread for sending */
+	if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0)
+		kalSetEvent(prAdapter->prGlueInfo);
+
+	return u4Status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief this function returns available count in command queue
+*
+* @param prAdapter      Pointer to the Adapter structure.
+*
+* @retval
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter)
+{
+	ASSERT(prAdapter);
+
+	return prAdapter->rFreeCmdList.u4NumElem;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c
new file mode 100644
index 0000000000000..38e4569bc04f9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c
@@ -0,0 +1,192 @@
+/*
+** Id: @(#) p2p_nic.c@@
+*/
+
+/*! \file   p2p_nic.c
+    \brief  Wi-Fi Direct Functions that provide operation in NIC's (Network Interface Card) point of view.
+
+    This file includes functions which unite multiple hal(Hardware) operations
+    and also take the responsibility of Software Resource Management in order
+    to keep the synchronization with Hardware Manipulation.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief When Probe Rsp & Beacon frame is received and decide a P2P device,
+*        this function will be invoked to buffer scan result
+*
+* @param prAdapter              Pointer to the Adapter structure.
+* @param prEventScanResult      Pointer of EVENT_SCAN_RESULT_T.
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter,
+		  IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength)
+{
+	P_P2P_INFO_T prP2pInfo = (P_P2P_INFO_T) NULL;
+	P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL;
+	UINT_32 u4Idx = 0;
+	BOOLEAN bUpdate = FALSE;
+
+	PUINT_8 pucIeBuf = (PUINT_8) NULL;
+	UINT_16 u2IELength = 0;
+	UINT_8 zeroMac[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+	ASSERT(prAdapter);
+
+	prP2pInfo = prAdapter->prP2pInfo;
+
+	for (u4Idx = 0; u4Idx < prP2pInfo->u4DeviceNum; u4Idx++) {
+		prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx];
+
+		if (EQUAL_MAC_ADDR(prTargetResult->aucDeviceAddr, prP2pResult->aucDeviceAddr)) {
+			bUpdate = TRUE;
+
+			/* Backup OLD buffer result. */
+			pucIeBuf = prTargetResult->pucIeBuf;
+			u2IELength = prTargetResult->u2IELength;
+
+			/* Update Device Info. */
+			/* zero */
+			kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T));
+
+			/* then buffer */
+			kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T));
+
+			/* See if new IE length is longer or not. */
+			if ((u2RxIELength > u2IELength) && (u2IELength != 0)) {
+				/* Buffer is not enough. */
+				u2RxIELength = u2IELength;
+			} else if ((u2IELength == 0) && (u2RxIELength != 0)) {
+				/* RX new IE buf. */
+				ASSERT(pucIeBuf == NULL);
+				pucIeBuf = prP2pInfo->pucCurrIePtr;
+
+				if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) >
+				    (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) {
+					/* Common Buffer is no enough. */
+					u2RxIELength =
+					    (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] -
+						       (ULONG) prP2pInfo->pucCurrIePtr);
+				}
+
+				/* Step to next buffer address. */
+				prP2pInfo->pucCurrIePtr =
+				    (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength);
+			}
+
+			/* Restore buffer pointer. */
+			prTargetResult->pucIeBuf = pucIeBuf;
+
+			if (pucRxIEBuf) {
+				/* If new received IE is available.
+				 * Replace the old one & update new IE length.
+				 */
+				kalMemCopy(pucIeBuf, pucRxIEBuf, u2RxIELength);
+				prTargetResult->u2IELength = u2RxIELength;
+			} else {
+				/* There is no new IE information, keep the old one. */
+				prTargetResult->u2IELength = u2IELength;
+			}
+		}
+	}
+
+	if (!bUpdate) {
+		/* We would flush the whole scan result after each scan request is issued.
+		 * If P2P device is too many, it may over the scan list.
+		 */
+		if ((u4Idx < CFG_MAX_NUM_BSS_LIST) && (UNEQUAL_MAC_ADDR(zeroMac, prP2pResult->aucDeviceAddr))) {
+			/* whsu:XXX */
+			prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx];
+
+			/* zero */
+			kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T));
+
+			/* then buffer */
+			kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T));
+
+			/* printk("DVC FND %d %pM, %pM\n",
+				prP2pInfo->u4DeviceNum,
+				prP2pResult->aucDeviceAddr,
+				prTargetResult->aucDeviceAddr); */
+
+			if (u2RxIELength) {
+				prTargetResult->pucIeBuf = prP2pInfo->pucCurrIePtr;
+
+				if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) >
+				    (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) {
+					/* Common Buffer is no enough. */
+					u2IELength =
+					    (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] -
+						       (ULONG) prP2pInfo->pucCurrIePtr);
+				} else {
+					u2IELength = u2RxIELength;
+				}
+
+				prP2pInfo->pucCurrIePtr =
+				    (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2IELength);
+
+				kalMemCopy((PVOID) prTargetResult->pucIeBuf, (PVOID) pucRxIEBuf, (UINT_32) u2IELength);
+				prTargetResult->u2IELength = u2IELength;
+			} else {
+				prTargetResult->pucIeBuf = NULL;
+				prTargetResult->u2IELength = 0;
+			}
+
+			prP2pInfo->u4DeviceNum++;
+
+		} else {
+			/* TODO: Fixme to replace an old one. (?) */
+			ASSERT(FALSE);
+		}
+	}
+}				/* nicRxAddP2pDevice */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c
new file mode 100644
index 0000000000000..dd00859d46082
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c
@@ -0,0 +1,5038 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/que_mgt.c#1
+*/
+
+/*! \file   "que_mgt.c"
+    \brief  TX/RX queues management
+
+    The main tasks of queue management include TC-based HIF TX flow control,
+    adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save
+    forwarding control, RX packet reordering, and RX BA agreement management.
+*/
+
+/*
+** Log: que_mgt.c
+**
+** 04 11 2013 yuche.tsai
+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop.
+** Drop the probe response packet when absent.
+**
+** 04 09 2013 yuche.tsai
+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop.
+** Fix CMD buffer short issue.
+**
+** 04 09 2013 yuche.tsai
+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop.
+** Fix CMD buffer short issue.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 02 23 2012 eddie.chen
+ * [WCXRP00001194] [MT6620][DRV/FW] follow admission control bit to change the enqueue rule
+ * Change the enqueue policy when ACM = 1.
+ *
+ * 11 22 2011 yuche.tsai
+ * NULL
+ * Code refine, remove one #if 0 code.
+ *
+ * 11 19 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add xlog for tx
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 18 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Fix xlog format to hex format
+ *
+ * 11 17 2011 tsaiyuan.hsu
+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
+ * avoid deactivating staRec when changing state from 3 to 3.
+ *
+ * 11 11 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug msg for xlog.
+ *
+ * 11 11 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters of bb and ar for xlog.
+ *
+ * 11 10 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Use short name for xlog.
+ *
+ * 11 10 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Modify the QM xlog level and remove LOG_FUNC.
+ *
+ * 11 10 2011 chinglan.wang
+ * NULL
+ * [WiFi WPS]Can't switch to new AP via WPS PBC when there existing a connection to another AP.
+ *
+ * 11 09 2011 chinglan.wang
+ * NULL
+ * [WiFi direct]Can't make P2P connect via PBC.
+ *
+ * 11 08 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add xlog function.
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 11 01 2011 chinglan.wang
+ * NULL
+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP.
+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to
+ * the AP..
+ *
+ * 10 25 2011 wh.su
+ * [WCXRP00001059] [MT6620 Wi-Fi][Driver][P2P] Fixed sometimes data (1x) will not indicate to upper layer due ba check
+ * un-expect
+ * let the Rx BA accept even the sta not valid.
+ *
+ * 09 28 2011 tsaiyuan.hsu
+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX
+ * enlarge window size only by 4.
+ *
+ * 09 01 2011 tsaiyuan.hsu
+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX
+ * set rx window size as twice buffer size.
+ *
+ * 08 23 2011 yuche.tsai
+ * NULL
+ * Fix multicast address list issue.
+ *
+ * 08 03 2011 tsaiyuan.hsu
+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX
+ * force window size at least 16.
+ *
+ * 08 02 2011 yuche.tsai
+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device
+ * issue.
+ * Fix GO send deauth frame issue.
+ *
+ * 07 26 2011 eddie.chen
+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter
+ * API for query the RX reorder queued packets counter.
+ *
+ * 07 07 2011 eddie.chen
+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV]  Send 1x packet when peer STA is in PS.
+ * Add setEvent when free quota is updated.
+ *
+ * 07 05 2011 eddie.chen
+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV]  Send 1x packet when peer STA is in PS.
+ * Send 1x when peer STA is in PS.
+ *
+ * 05 31 2011 eddie.chen
+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931
+ * Fix the QM quota in MT5931.
+ *
+ * 05 11 2011 eddie.chen
+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
+ * Fix dest type when GO packet copying.
+ *
+ * 05 09 2011 yuche.tsai
+ * [WCXRP00000712] [Volunteer Patch][MT6620][Driver] Sending deauth issue when Hot spot is disabled. (GO is dissolved)
+ * Deauthentication frame is not bound to network active status.
+ *
+ * 05 09 2011 eddie.chen
+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
+ * Check free number before copying broadcast packet.
+ *
+ * 04 14 2011 eddie.chen
+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
+ * Check the SW RFB free. Fix the compile warning..
+ *
+ * 04 12 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix the sta index in processing security frame
+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
+ * Add debug message.
+ *
+ * 04 11 2011 yuche.tsai
+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue.
+ * Fix kernel panic issue when MMPDU of P2P is pending in driver.
+ *
+ * 04 08 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix for sigma
+ *
+ * 03 28 2011 eddie.chen
+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
+ * Fix Klockwork warning.
+ *
+ * 03 28 2011 eddie.chen
+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW
+ * Fix wmm parameters in beacon for BOW.
+ *
+ * 03 15 2011 eddie.chen
+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter
+ * Add sw debug counter for QM.
+ *
+ * 02 23 2011 eddie.chen
+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap
+ * Fix parsing WMM INFO and bmp delivery bitmap definition.
+ *
+ * 02 17 2011 eddie.chen
+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel
+ * 1) Change GetFrameAction decision when BSS is absent.
+ * 2) Check channel and resource in processing ProbeRequest
+ *
+ * 02 08 2011 eddie.chen
+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
+ * Add event STA agint timeout
+ *
+ * 01 27 2011 tsaiyuan.hsu
+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
+ * add roaming fsm
+ * 1. not support 11r, only use strength of signal to determine roaming.
+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
+ * 4. assume that change of link quality in smooth way.
+ *
+ * 01 25 2011 yuche.tsai
+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
+ *
+ * 01 24 2011 eddie.chen
+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
+ * Remove comments.
+ *
+ * 01 24 2011 eddie.chen
+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
+ * Add destination decision in AP mode.
+ *
+ * 01 14 2011 wh.su
+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out[WCXRP00000326]
+ * [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!!
+ * Allow 802.1x can be send even the net is not active due the drver / fw sync issue.
+ *
+ * 01 13 2011 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+ * Fix typo and compile error.
+ *
+ * 01 12 2011 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+ * Fix WMM parameter condition for STA
+ *
+ * 01 12 2011 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+ * 1) Check Bss if support QoS before adding WMMIE
+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control
+ *
+ * 01 12 2011 george.huang
+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability
+ * Update MQM for WMM IE generation method
+ *
+ * 01 11 2011 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * Add per STA flow control when STA is in PS mode
+ *
+ * 01 03 2011 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * update prStaRec->fgIsUapsdSupported flag.
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * Add WMM parameter for broadcast.
+ *
+ * 12 29 2010 eddie.chen
+ * [WCXRP00000322] Add WMM IE in beacon,
+Add per station flow control when STA is in PS
+
+ * 1) PS flow control event
+ *
+ * 2) WMM IE in beacon, assoc resp, probe resp
+ *
+ * 12 23 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * 1. update WMM IE parsing, with ASSOC REQ handling
+ * 2. extend U-APSD parameter passing from driver to FW
+ *
+ * 10 14 2010 wh.su
+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out
+ * use the #14 and modify the add code for check MMPDU.
+ *
+ * 10 14 2010 wh.su
+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out
+ * only MMPDU not check the netActive flag.
+ *
+ * 10 14 2010 wh.su
+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out
+ * not check the netActive flag for mgmt .
+ *
+ * 10 04 2010 cp.wu
+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by
+ * ENUM_NETWORK_TYPE_INDEX_T only
+ * remove ENUM_NETWORK_TYPE_T definitions
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 08 30 2010 yarco.yang
+ * NULL
+ * Fixed klockwork error message
+ *
+ * 08 18 2010 yarco.yang
+ * NULL
+ * 1. Fixed HW checksum offload function not work under Linux issue.
+ * 2. Add debug message.
+ *
+ * 08 10 2010 yarco.yang
+ * NULL
+ * Code refine
+ *
+ * 08 06 2010 yarco.yang
+ * NULL
+ * Update qmGetFrameAction() to allow P2P MGMT frame w/o STA_Record  still can perform TX action
+ *
+ * 07 26 2010 cp.wu
+ *
+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet
+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found
+ *
+ * 07 20 2010 yarco.yang
+ *
+ * Add to SetEvent when BSS is from Absent to Present or STA from PS to Awake
+ *
+ * 07 16 2010 yarco.yang
+ *
+ * 1. Support BSS Absence/Presence Event
+ * 2. Support STA change PS mode Event
+ * 3. Support BMC forwarding for AP mode.
+ *
+ * 07 14 2010 yarco.yang
+ *
+ * 1. Remove CFG_MQM_MIGRATION
+ * 2. Add CMD_UPDATE_WMM_PARMS command
+ *
+ * 07 13 2010 yarco.yang
+ *
+ * [WPD00003849]
+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing
+ *
+ * 07 09 2010 yarco.yang
+ *
+ * [MT6620 and MT5931] SW Migration: Add ADDBA support
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 07 08 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * .
+ *
+ * 07 06 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Use fgInUse instead of fgIsValid for De-queue judgement
+ *
+ * 07 06 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * For MMPDU, STA_REC will be decided by caller module
+ *
+ * 07 06 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Add MGMT Packet type for HIF_TX_HEADER
+ *
+ * 06 29 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * replace g_rQM with Adpater->rQM
+ *
+ * 06 25 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * add API in que_mgt to retrieve sta-rec index for security frames.
+ *
+ * 06 23 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Merge g_arStaRec[] into adapter->arStaRec[]
+ *
+ * 06 21 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Support CFG_MQM_MIGRATION flag
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 31 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Refined the debug msg
+ *
+ * 03 30 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * comment out one assertion which refer to undefined data member.
+ *
+ * 03 30 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled adaptive TC resource control
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+ *
+* 03 17 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST)
+ *
+ * 03 11 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Fixed buffer leak when processing BAR frames
+ *
+ * 03 02 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * For TX packets with STA_REC index = STA_REC_INDEX_NOT_FOUND, use TC5
+ *
+ * 03 01 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Fixed STA_REC index determination bug (fgIsValid shall be checked)
+ *
+ * 02 25 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Refined function qmDetermineStaRecIndex() for BMCAST packets
+ *
+ * 02 25 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled multi-STA TX path with fairness
+ *
+ * 02 24 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled dynamically activating and deactivating STA_RECs
+ *
+ * 02 24 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Added code for dynamic activating and deactivating STA_RECs.
+ *
+ * 01 13 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled the 802.1x path
+ *
+ * 01 13 2010 tehuang.liu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * Enabled the Burst_End Indication mechanism
+**  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-14 15:01:37 GMT MTK02468
+**  Fixed casting for qmAddRxBaEntry()
+**  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:51:03 GMT mtk02752
+**  remove SD1_SD3.. flag
+**  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-09 14:07:25 GMT MTK02468
+**  Added RX buffer reordering functions
+**  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-04 13:34:16 GMT MTK02468
+**  Modified Flush Queue function to let queues be reinitialized
+**  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-04 13:18:25 GMT MTK02468
+**  Added flushing per-Type queues code
+**  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 23:39:49 GMT MTK02468
+**  Added Debug msgs and fixed incorrect assert
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-26 23:50:27 GMT MTK02468
+**  Bug fixing (qmDequeueTxPackets local variable initialization)
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-26 09:39:25 GMT mtk02752
+**  correct and surpress PREfast warning
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-11-23 22:10:55 GMT mtk02468
+**  Used SD1_SD3_DATAPATH_INTEGRATION
+**  \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 22:02:30 GMT mtk02468
+**  Initial version
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+OS_SYSTIME g_arMissTimeout[CFG_STA_REC_NUM][CFG_RX_MAX_BA_TID_NUM];
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if ARP_MONITER_ENABLE
+static UINT_16 arpMoniter;
+static UINT_8 apIp[4];
+#endif
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static inline VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+
+static inline VOID
+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter,
+				   OUT P_QUE_T prQue,
+				   IN UINT_8 ucTC, IN UINT_8 ucCurrentAvailableQuota, IN UINT_8 ucTotalQuota);
+
+static inline VOID
+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Init Queue Management for TX
+*
+* \param[in] (none)
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmInit(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 u4QueArrayIdx;
+	UINT_32 i;
+
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	/* DbgPrint("QM: Enter qmInit()\n"); */
+#if CFG_SUPPORT_QOS
+	prAdapter->rWifiVar.fgSupportQoS = TRUE;
+#else
+	prAdapter->rWifiVar.fgSupportQoS = FALSE;
+#endif
+
+#if CFG_SUPPORT_AMPDU_RX
+	prAdapter->rWifiVar.fgSupportAmpduRx = TRUE;
+#else
+	prAdapter->rWifiVar.fgSupportAmpduRx = FALSE;
+#endif
+
+#if CFG_SUPPORT_AMPDU_TX
+	prAdapter->rWifiVar.fgSupportAmpduTx = TRUE;
+#else
+	prAdapter->rWifiVar.fgSupportAmpduTx = FALSE;
+#endif
+
+#if CFG_SUPPORT_TSPEC
+	prAdapter->rWifiVar.fgSupportTspec = TRUE;
+#else
+	prAdapter->rWifiVar.fgSupportTspec = FALSE;
+#endif
+
+#if CFG_SUPPORT_UAPSD
+	prAdapter->rWifiVar.fgSupportUAPSD = TRUE;
+#else
+	prAdapter->rWifiVar.fgSupportUAPSD = FALSE;
+#endif
+
+#if CFG_SUPPORT_UL_PSMP
+	prAdapter->rWifiVar.fgSupportULPSMP = TRUE;
+#else
+	prAdapter->rWifiVar.fgSupportULPSMP = FALSE;
+#endif
+
+#if CFG_SUPPORT_RX_SGI
+	prAdapter->rWifiVar.u8SupportRxSgi20 = 0;
+	prAdapter->rWifiVar.u8SupportRxSgi40 = 0;
+#else
+	prAdapter->rWifiVar.u8SupportRxSgi20 = 2;
+	prAdapter->rWifiVar.u8SupportRxSgi40 = 2;
+#endif
+
+#if CFG_SUPPORT_RX_HT_GF
+	prAdapter->rWifiVar.u8SupportRxGf = 0;
+#else
+	prAdapter->rWifiVar.u8SupportRxGf = 2;
+#endif
+
+	/* 4 <2> Initialize other TX queues (queues not in STA_RECs) */
+	for (u4QueArrayIdx = 0; u4QueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; u4QueArrayIdx++)
+		QUEUE_INITIALIZE(&(prQM->arTxQueue[u4QueArrayIdx]));
+
+	/* 4 <3> Initialize the RX BA table and RX queues */
+	/* Initialize the RX Reordering Parameters and Queues */
+	for (u4QueArrayIdx = 0; u4QueArrayIdx < CFG_NUM_OF_RX_BA_AGREEMENTS; u4QueArrayIdx++) {
+		prQM->arRxBaTable[u4QueArrayIdx].fgIsValid = FALSE;
+		QUEUE_INITIALIZE(&(prQM->arRxBaTable[u4QueArrayIdx].rReOrderQue));
+		prQM->arRxBaTable[u4QueArrayIdx].u2WinStart = 0xFFFF;
+		prQM->arRxBaTable[u4QueArrayIdx].u2WinEnd = 0xFFFF;
+
+		prQM->arRxBaTable[u4QueArrayIdx].fgIsWaitingForPktWithSsn = FALSE;
+
+	}
+	prQM->ucRxBaCount = 0;
+
+	kalMemSet(&g_arMissTimeout, 0, sizeof(g_arMissTimeout));
+
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+	/* 4 <4> Initialize TC resource control variables */
+	for (i = 0; i < TC_NUM; i++)
+		prQM->au4AverageQueLen[i] = 0;
+	prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC;
+	prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN;
+	prQM->u4TxNumOfVi = 0;
+	prQM->u4TxNumOfVo = 0;
+
+/* ASSERT(prQM->u4TimeToAdjust && prQM->u4TimeToUpdateQueLen); */
+
+	/* 1 20 1 1 4 1 */
+	prQM->au4CurrentTcResource[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0;
+	prQM->au4CurrentTcResource[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1;
+	prQM->au4CurrentTcResource[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2;
+	prQM->au4CurrentTcResource[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3;
+	prQM->au4CurrentTcResource[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4;	/* Not adjustable (TX port 1) */
+	prQM->au4CurrentTcResource[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5;
+	DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC0 = %d\n", NIC_TX_BUFF_COUNT_TC0);
+	DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC1 = %d\n", NIC_TX_BUFF_COUNT_TC1);
+	DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC2 = %d\n", NIC_TX_BUFF_COUNT_TC2);
+	DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC3 = %d\n", NIC_TX_BUFF_COUNT_TC3);
+	DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC4 = %d\n", NIC_TX_BUFF_COUNT_TC4);
+	DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC5 = %d\n", NIC_TX_BUFF_COUNT_TC5);
+
+	/* 1 1 1 1 2 1 */
+	prQM->au4MinReservedTcResource[TC0_INDEX] = QM_MIN_RESERVED_TC0_RESOURCE;
+	prQM->au4MinReservedTcResource[TC1_INDEX] = QM_MIN_RESERVED_TC1_RESOURCE;
+	prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE;
+	prQM->au4MinReservedTcResource[TC3_INDEX] = QM_MIN_RESERVED_TC3_RESOURCE;
+	prQM->au4MinReservedTcResource[TC4_INDEX] = QM_MIN_RESERVED_TC4_RESOURCE;	/* Not adjustable (TX port 1) */
+	prQM->au4MinReservedTcResource[TC5_INDEX] = QM_MIN_RESERVED_TC5_RESOURCE;
+
+	/* 4 4 6 6 2 4 */
+	prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE;
+	prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE;
+	prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE;
+	prQM->au4GuaranteedTcResource[TC3_INDEX] = QM_GUARANTEED_TC3_RESOURCE;
+	prQM->au4GuaranteedTcResource[TC4_INDEX] = QM_GUARANTEED_TC4_RESOURCE;
+	prQM->au4GuaranteedTcResource[TC5_INDEX] = QM_GUARANTEED_TC5_RESOURCE;
+
+	prQM->fgTcResourcePostAnnealing = FALSE;
+
+	ASSERT(QM_INITIAL_RESIDUAL_TC_RESOURCE < 64);
+#endif
+
+#if QM_TEST_MODE
+	prQM->u4PktCount = 0;
+
+#if QM_TEST_FAIR_FORWARDING
+
+	prQM->u4CurrentStaRecIndexToEnqueue = 0;
+	{
+		UINT_8 aucMacAddr[MAC_ADDR_LEN];
+		P_STA_RECORD_T prStaRec;
+
+		/* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */
+		aucMacAddr[0] = 0x11;
+		aucMacAddr[1] = 0x22;
+		aucMacAddr[2] = 0xAA;
+		aucMacAddr[3] = 0xBB;
+		aucMacAddr[4] = 0xCC;
+		aucMacAddr[5] = 0xDD;
+
+		prStaRec = &prAdapter->arStaRec[1];
+		ASSERT(prStaRec);
+
+		prStaRec->fgIsValid = TRUE;
+		prStaRec->fgIsQoS = TRUE;
+		prStaRec->fgIsInPS = FALSE;
+		prStaRec->ucPsSessionID = 0xFF;
+		prStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+		prStaRec->fgIsAp = TRUE;
+		COPY_MAC_ADDR((prStaRec)->aucMacAddr, aucMacAddr);
+
+	}
+
+#endif
+
+#endif
+
+#if QM_FORWARDING_FAIRNESS
+	{
+		UINT_32 i;
+
+		for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) {
+			prQM->au4ForwardCount[i] = 0;
+			prQM->au4HeadStaRecIndex[i] = 0;
+		}
+	}
+#endif
+
+#if QM_TC_RESOURCE_EMPTY_COUNTER
+	kalMemZero(prQM->au4QmTcResourceEmptyCounter, sizeof(prQM->au4QmTcResourceEmptyCounter));
+#endif
+
+}
+
+#if QM_TEST_MODE
+VOID qmTestCases(IN P_ADAPTER_T prAdapter)
+{
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	DbgPrint("QM: ** TEST MODE **\n");
+
+	if (QM_TEST_STA_REC_DETERMINATION) {
+		if (prAdapter->arStaRec[0].fgIsValid) {
+			prAdapter->arStaRec[0].fgIsValid = FALSE;
+			DbgPrint("QM: (Test) Deactivate STA_REC[0]\n");
+		} else {
+			prAdapter->arStaRec[0].fgIsValid = TRUE;
+			DbgPrint("QM: (Test) Activate STA_REC[0]\n");
+		}
+	}
+
+	if (QM_TEST_STA_REC_DEACTIVATION) {
+		/* Note that QM_STA_REC_HARD_CODING shall be set to 1 for this test */
+
+		if (prAdapter->arStaRec[0].fgIsValid) {
+
+			DbgPrint("QM: (Test) Deactivate STA_REC[0]\n");
+			qmDeactivateStaRec(prAdapter, 0);
+		} else {
+
+			UINT_8 aucMacAddr[MAC_ADDR_LEN];
+
+			/* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */
+			aucMacAddr[0] = 0x11;
+			aucMacAddr[1] = 0x22;
+			aucMacAddr[2] = 0xAA;
+			aucMacAddr[3] = 0xBB;
+			aucMacAddr[4] = 0xCC;
+			aucMacAddr[5] = 0xDD;
+
+			DbgPrint("QM: (Test) Activate STA_REC[0]\n");
+			qmActivateStaRec(prAdapter,	/* Adapter pointer */
+					 0,	/* STA_REC index from FW */
+					 TRUE,	/* fgIsQoS */
+					 NETWORK_TYPE_AIS_INDEX,	/* Network type */
+					 TRUE,	/* fgIsAp */
+					 aucMacAddr	/* MAC address */
+			    );
+		}
+	}
+
+	if (QM_TEST_FAIR_FORWARDING) {
+		if (prAdapter->arStaRec[1].fgIsValid) {
+			prQM->u4CurrentStaRecIndexToEnqueue++;
+			prQM->u4CurrentStaRecIndexToEnqueue %= 2;
+			DbgPrint("QM: (Test) Switch to STA_REC[%u]\n", prQM->u4CurrentStaRecIndexToEnqueue);
+		}
+	}
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Activate a STA_REC
+*
+* \param[in] prAdapter  Pointer to the Adapter instance
+* \param[in] u4StaRecIdx The index of the STA_REC
+* \param[in] fgIsQoS    Set to TRUE if this is a QoS STA
+* \param[in] pucMacAddr The MAC address of the STA
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+
+	/* 4 <1> Deactivate first */
+	ASSERT(prStaRec);
+
+	if (prStaRec->fgIsValid) {	/* The STA_REC has been activated */
+		DBGLOG(QM, WARN, "QM: (WARNING) Activating a STA_REC which has been activated\n");
+		DBGLOG(QM, WARN, "QM: (WARNING) Deactivating a STA_REC before re-activating\n");
+		/* To flush TX/RX queues and del RX BA agreements */
+		qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
+	}
+	/* 4 <2> Activate the STA_REC */
+	/* Init the STA_REC */
+	prStaRec->fgIsValid = TRUE;
+	prStaRec->fgIsInPS = FALSE;
+	prStaRec->ucPsSessionID = 0xFF;
+	prStaRec->fgIsAp = (IS_AP_STA(prStaRec)) ? TRUE : FALSE;
+
+	/* Done in qmInit() or qmDeactivateStaRec() */
+#if 0
+	/* At the beginning, no RX BA agreements have been established */
+	for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++)
+		(prStaRec->aprRxReorderParamRefTbl)[i] = NULL;
+#endif
+
+	DBGLOG(QM, TRACE, "QM: +STA[%u]\n", (UINT_32) prStaRec->ucIndex);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Deactivate a STA_REC
+*
+* \param[in] prAdapter  Pointer to the Adapter instance
+* \param[in] u4StaRecIdx The index of the STA_REC
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_32 i;
+	P_MSDU_INFO_T prFlushedTxPacketList = NULL;
+
+	ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD);
+
+	prStaRec = &prAdapter->arStaRec[u4StaRecIdx];
+	ASSERT(prStaRec);
+
+	/* 4<1> Flush TX queues */
+	prFlushedTxPacketList = qmFlushStaTxQueues(prAdapter, u4StaRecIdx);
+
+	if (prFlushedTxPacketList)
+		wlanProcessQueuedMsduInfo(prAdapter, prFlushedTxPacketList);
+	/* 4 <2> Flush RX queues and delete RX BA agreements */
+	for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) {
+		/* Delete the RX BA entry with TID = i */
+		qmDelRxBaEntry(prAdapter, (UINT_8) u4StaRecIdx, (UINT_8) i, FALSE);
+	}
+
+	/* 4 <3> Deactivate the STA_REC */
+	prStaRec->fgIsValid = FALSE;
+	prStaRec->fgIsInPS = FALSE;
+
+	/* To reduce printk for IOT sta to connect all the time, */
+	/* DBGLOG(QM, INFO, ("QM: -STA[%ld]\n", u4StaRecIdx)); */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Deactivate a STA_REC
+*
+* \param[in] prAdapter  Pointer to the Adapter instance
+* \param[in] u4StaRecIdx The index of the network
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+
+	P_QUE_MGT_T prQM;
+	P_QUE_T prQue;
+	QUE_T rNeedToFreeQue;
+	QUE_T rTempQue;
+	P_QUE_T prNeedToFreeQue;
+	P_QUE_T prTempQue;
+	P_MSDU_INFO_T prMsduInfo;
+
+	prQM = &prAdapter->rQM;
+	prQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST];
+
+	QUEUE_INITIALIZE(&rNeedToFreeQue);
+	QUEUE_INITIALIZE(&rTempQue);
+
+	prNeedToFreeQue = &rNeedToFreeQue;
+	prTempQue = &rTempQue;
+
+	QUEUE_MOVE_ALL(prTempQue, prQue);
+
+	QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T);
+	while (prMsduInfo) {
+
+		if (prMsduInfo->ucNetworkType == eNetworkTypeIdx) {
+			/* QUEUE_INSERT_TAIL */
+			QUEUE_INSERT_TAIL(prNeedToFreeQue, (P_QUE_ENTRY_T) prMsduInfo);
+		} else {
+			/* QUEUE_INSERT_TAIL */
+			QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prMsduInfo);
+		}
+
+		QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T);
+	}
+	if (QUEUE_IS_NOT_EMPTY(prNeedToFreeQue))
+		wlanProcessQueuedMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prNeedToFreeQue));
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Flush all TX queues
+*
+* \param[in] (none)
+*
+* \return The flushed packets (in a list of MSDU_INFOs)
+*/
+/*----------------------------------------------------------------------------*/
+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter)
+{
+	UINT_8 ucStaArrayIdx;
+	UINT_8 ucQueArrayIdx;
+
+	P_MSDU_INFO_T prMsduInfoListHead;
+	P_MSDU_INFO_T prMsduInfoListTail;
+
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	DBGLOG(QM, TRACE, "QM: Enter qmFlushTxQueues()\n");
+
+	prMsduInfoListHead = NULL;
+	prMsduInfoListTail = NULL;
+
+	/* Concatenate all MSDU_INFOs in per-STA queues */
+	for (ucStaArrayIdx = 0; ucStaArrayIdx < CFG_NUM_OF_STA_RECORD; ucStaArrayIdx++) {
+
+		/* Always check each STA_REC when flushing packets no matter it is inactive or active */
+#if 0
+		if (!prAdapter->arStaRec[ucStaArrayIdx].fgIsValid)
+			continue;	/* Continue to check the next STA_REC */
+#endif
+
+		for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) {
+			if (QUEUE_IS_EMPTY(&(prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx])))
+				continue;	/* Continue to check the next TX queue of the same STA */
+
+			if (!prMsduInfoListHead) {
+
+				/* The first MSDU_INFO is found */
+				prMsduInfoListHead = (P_MSDU_INFO_T)
+				    QUEUE_GET_HEAD(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]);
+				prMsduInfoListTail = (P_MSDU_INFO_T)
+				    QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]);
+			} else {
+				/* Concatenate the MSDU_INFO list with the existing list */
+				QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail,
+							 QUEUE_GET_HEAD(&prAdapter->
+									arStaRec[ucStaArrayIdx].arTxQueue
+									[ucQueArrayIdx]));
+
+				prMsduInfoListTail = (P_MSDU_INFO_T)
+				    QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]);
+			}
+
+			QUEUE_INITIALIZE(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]);
+		}
+	}
+
+	/* Flush per-Type queues */
+	for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; ucQueArrayIdx++) {
+
+		if (QUEUE_IS_EMPTY(&(prQM->arTxQueue[ucQueArrayIdx])))
+			continue;	/* Continue to check the next TX queue of the same STA */
+
+		if (!prMsduInfoListHead) {
+
+			/* The first MSDU_INFO is found */
+			prMsduInfoListHead = (P_MSDU_INFO_T)
+			    QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx]);
+			prMsduInfoListTail = (P_MSDU_INFO_T)
+			    QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]);
+		} else {
+			/* Concatenate the MSDU_INFO list with the existing list */
+			QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx]));
+
+			prMsduInfoListTail = (P_MSDU_INFO_T)
+			    QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]);
+		}
+
+		QUEUE_INITIALIZE(&prQM->arTxQueue[ucQueArrayIdx]);
+
+	}
+
+	if (prMsduInfoListTail) {
+		/* Terminate the MSDU_INFO list with a NULL pointer */
+		QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, NULL);
+	}
+
+	return prMsduInfoListHead;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Flush TX packets for a particular STA
+*
+* \param[in] u4StaRecIdx STA_REC index
+*
+* \return The flushed packets (in a list of MSDU_INFOs)
+*/
+/*----------------------------------------------------------------------------*/
+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx)
+{
+	UINT_8 ucQueArrayIdx;
+	P_MSDU_INFO_T prMsduInfoListHead;
+	P_MSDU_INFO_T prMsduInfoListTail;
+	P_STA_RECORD_T prStaRec;
+
+	/* To reduce printk for IOT sta to connect all the time, */
+	/* DBGLOG(QM, TRACE, ("QM: Enter qmFlushStaTxQueues(%ld)\n", u4StaRecIdx)); */
+
+	ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD);
+
+	prMsduInfoListHead = NULL;
+	prMsduInfoListTail = NULL;
+
+	prStaRec = &prAdapter->arStaRec[u4StaRecIdx];
+	ASSERT(prStaRec);
+
+	/* No matter whether this is an activated STA_REC, do flush */
+#if 0
+	if (!prStaRec->fgIsValid)
+		return NULL;
+#endif
+
+	/* Concatenate all MSDU_INFOs in TX queues of this STA_REC */
+	for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) {
+		if (QUEUE_IS_EMPTY(&(prStaRec->arTxQueue[ucQueArrayIdx])))
+			continue;
+
+		if (!prMsduInfoListHead) {
+			/* The first MSDU_INFO is found */
+			prMsduInfoListHead = (P_MSDU_INFO_T)
+			    QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx]);
+			prMsduInfoListTail = (P_MSDU_INFO_T)
+			    QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]);
+		} else {
+			/* Concatenate the MSDU_INFO list with the existing list */
+			QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail,
+						 QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx]));
+
+			prMsduInfoListTail = (P_MSDU_INFO_T) QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]);
+		}
+
+		QUEUE_INITIALIZE(&prStaRec->arTxQueue[ucQueArrayIdx]);
+
+	}
+
+#if 0
+	if (prMsduInfoListTail) {
+		/* Terminate the MSDU_INFO list with a NULL pointer */
+		QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx));
+	} else {
+		prMsduInfoListHead = nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx);
+	}
+#endif
+
+	return prMsduInfoListHead;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Flush RX packets
+*
+* \param[in] (none)
+*
+* \return The flushed packets (in a list of SW_RFBs)
+*/
+/*----------------------------------------------------------------------------*/
+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i;
+	P_SW_RFB_T prSwRfbListHead;
+	P_SW_RFB_T prSwRfbListTail;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	prSwRfbListHead = prSwRfbListTail = NULL;
+
+	DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n");
+
+	for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) {
+		if (QUEUE_IS_NOT_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) {
+			if (!prSwRfbListHead) {
+
+				/* The first MSDU_INFO is found */
+				prSwRfbListHead = (P_SW_RFB_T)
+				    QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue));
+				prSwRfbListTail = (P_SW_RFB_T)
+				    QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue));
+			} else {
+				/* Concatenate the MSDU_INFO list with the existing list */
+				QM_TX_SET_NEXT_MSDU_INFO(prSwRfbListTail,
+							 QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue)));
+
+				prSwRfbListTail = (P_SW_RFB_T)
+				    QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue));
+			}
+
+			QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue));
+
+		} else {
+			continue;
+		}
+	}
+
+	if (prSwRfbListTail) {
+		/* Terminate the MSDU_INFO list with a NULL pointer */
+		QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL);
+	}
+	return prSwRfbListHead;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Flush RX packets with respect to a particular STA
+*
+* \param[in] u4StaRecIdx STA_REC index
+* \param[in] u4Tid TID
+*
+* \return The flushed packets (in a list of SW_RFBs)
+*/
+/*----------------------------------------------------------------------------*/
+P_SW_RFB_T qmFlushStaRxQueue(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx, IN UINT_32 u4Tid)
+{
+	/* UINT_32 i; */
+	P_SW_RFB_T prSwRfbListHead;
+	P_SW_RFB_T prSwRfbListTail;
+	P_RX_BA_ENTRY_T prReorderQueParm;
+	P_STA_RECORD_T prStaRec;
+
+	DBGLOG(QM, TRACE, "QM: Enter qmFlushStaRxQueues(%u)\n", u4StaRecIdx);
+
+	prSwRfbListHead = prSwRfbListTail = NULL;
+
+	prStaRec = &prAdapter->arStaRec[u4StaRecIdx];
+	ASSERT(prStaRec);
+
+	/* No matter whether this is an activated STA_REC, do flush */
+#if 0
+	if (!prStaRec->fgIsValid)
+		return NULL;
+#endif
+
+	/* Obtain the RX BA Entry pointer */
+	prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[u4Tid]);
+
+	/* Note: For each queued packet, prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST */
+	if (prReorderQueParm) {
+
+		if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) {
+
+			prSwRfbListHead = (P_SW_RFB_T)
+			    QUEUE_GET_HEAD(&(prReorderQueParm->rReOrderQue));
+			prSwRfbListTail = (P_SW_RFB_T)
+			    QUEUE_GET_TAIL(&(prReorderQueParm->rReOrderQue));
+
+			QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue));
+
+		}
+	}
+
+	if (prSwRfbListTail) {
+		/* Terminate the MSDU_INFO list with a NULL pointer */
+		QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL);
+	}
+	return prSwRfbListHead;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Enqueue TX packets
+*
+* \param[in] prMsduInfoListHead Pointer to the list of TX packets
+*
+* \return The freed packets, which are not enqueued
+*/
+/*----------------------------------------------------------------------------*/
+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
+{
+	P_MSDU_INFO_T prMsduInfoReleaseList;
+	P_MSDU_INFO_T prCurrentMsduInfo;
+	P_MSDU_INFO_T prNextMsduInfo;
+
+	P_STA_RECORD_T prStaRec;
+	QUE_T rNotEnqueuedQue;
+	P_QUE_T prTxQue = &rNotEnqueuedQue;
+
+	UINT_8 ucPacketType;
+	UINT_8 ucTC;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+	UINT_8 aucNextUP[WMM_AC_INDEX_NUM] = { 1 /* BEtoBK */ , 1 /*na */ , 0 /*VItoBE */ , 4 /*VOtoVI */  };
+
+	DBGLOG(QM, LOUD, "Enter qmEnqueueTxPackets\n");
+
+	ASSERT(prMsduInfoListHead);
+
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+	{
+		/* UINT_32         i; */
+		/* 4 <0> Update TC resource control related variables */
+		/* Keep track of the queue length */
+		if (--prQM->u4TimeToUpdateQueLen == 0) {	/* -- only here */
+			prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN;
+			qmUpdateAverageTxQueLen(prAdapter);
+		}
+	}
+#endif
+
+	/* Push TX packets into STA_REC (for UNICAST) or prAdapter->rQM (for BMCAST) */
+	prStaRec = NULL;
+	prMsduInfoReleaseList = NULL;
+	prCurrentMsduInfo = NULL;
+	QUEUE_INITIALIZE(&rNotEnqueuedQue);
+	prNextMsduInfo = prMsduInfoListHead;
+
+	do {
+		P_BSS_INFO_T prBssInfo;
+		BOOLEAN fgCheckACMAgain;
+		ENUM_WMM_ACI_T eAci = WMM_AC_BE_INDEX;
+
+		prCurrentMsduInfo = prNextMsduInfo;
+		prNextMsduInfo = QM_TX_GET_NEXT_MSDU_INFO(prCurrentMsduInfo);
+		ucTC = TC1_INDEX;
+
+		/* 4 <1> Lookup the STA_REC index */
+		/* The ucStaRecIndex will be set in this function */
+		qmDetermineStaRecIndex(prAdapter, prCurrentMsduInfo);
+		ucPacketType = HIF_TX_PACKET_TYPE_DATA;
+
+		STATS_ENV_REPORT_DETECT(prAdapter, prCurrentMsduInfo->ucStaRecIndex);
+
+		DBGLOG(QM, LOUD, "***** ucStaRecIndex = %d *****\n", prCurrentMsduInfo->ucStaRecIndex);
+
+		prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prCurrentMsduInfo->ucNetworkType]);
+
+#if (CONF_HIF_LOOPBACK_AUTO == 0)
+		if (IS_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType)) {
+#else
+		/* force to send the loopback test packet */
+		if (1) {
+			SET_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType);
+			prCurrentMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST;
+			ucPacketType = HIF_TX_PKT_TYPE_HIF_LOOPBACK;
+#endif /* End of CONF_HIF_LOOPBACK_AUTO */
+
+			switch (prCurrentMsduInfo->ucStaRecIndex) {
+			case STA_REC_INDEX_BMCAST:
+				prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST];
+				ucTC = TC5_INDEX;
+#if 0
+				if (prCurrentMsduInfo->ucNetworkType == NETWORK_TYPE_P2P_INDEX
+				    && prCurrentMsduInfo->eSrc != TX_PACKET_MGMT) {
+					if (LINK_IS_EMPTY
+					    (&prAdapter->rWifiVar.
+					     arBssInfo[NETWORK_TYPE_P2P_INDEX].rStaRecOfClientList)) {
+						prTxQue = &rNotEnqueuedQue;
+						TX_INC_CNT(&prAdapter->rTxCtrl, TX_AP_BORADCAST_DROP);
+					}
+				}
+#endif
+
+				QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23);
+				break;
+
+			case STA_REC_INDEX_NOT_FOUND:
+				ucTC = TC5_INDEX;
+
+				if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) {
+
+					/* if the packet is the forward type. the packet should be freed */
+					DBGLOG(QM, TRACE, "Forwarding packet but Sta is STA_REC_INDEX_NOT_FOUND\n");
+					/* prTxQue = &rNotEnqueuedQue; */
+				}
+				prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_NO_STA_REC];
+				QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24);
+
+				break;
+
+			default:
+				prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prCurrentMsduInfo->ucStaRecIndex);
+
+				if (!prStaRec) {
+					DBGLOG(QM, ERROR, "prStaRec is NULL\n");
+					break;
+				}
+				ASSERT(prStaRec->fgIsValid);
+
+				if (prCurrentMsduInfo->ucUserPriority < 8) {
+					QM_DBG_CNT_INC(prQM, prCurrentMsduInfo->ucUserPriority + 15);
+					/* QM_DBG_CNT_15 *//* QM_DBG_CNT_16 *//* QM_DBG_CNT_17 *//* QM_DBG_CNT_18 */
+					/* QM_DBG_CNT_19 *//* QM_DBG_CNT_20 *//* QM_DBG_CNT_21 *//* QM_DBG_CNT_22 */
+				}
+
+				eAci = WMM_AC_BE_INDEX;
+				do {
+					fgCheckACMAgain = FALSE;
+					if (!prStaRec->fgIsQoS) {
+						prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1];
+						ucTC = TC1_INDEX;
+						break;
+					}
+
+					switch (prCurrentMsduInfo->ucUserPriority) {
+					case 1:
+					case 2:
+						prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC0];
+						ucTC = TC0_INDEX;
+						eAci = WMM_AC_BK_INDEX;
+						break;
+					case 0:
+					case 3:
+						prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1];
+						ucTC = TC1_INDEX;
+						eAci = WMM_AC_BE_INDEX;
+						break;
+					case 4:
+					case 5:
+						prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC2];
+						ucTC = TC2_INDEX;
+						eAci = WMM_AC_VI_INDEX;
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+						prQM->u4TxNumOfVi++;
+#endif
+						break;
+					case 6:
+					case 7:
+						prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC3];
+						ucTC = TC3_INDEX;
+						eAci = WMM_AC_VO_INDEX;
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+						prQM->u4TxNumOfVo++;
+#endif
+						break;
+					default:
+						prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1];
+						ucTC = TC1_INDEX;
+						eAci = WMM_AC_BE_INDEX;
+						ASSERT(0);
+						break;
+					}
+					if (prBssInfo->arACQueParms[eAci].fgIsACMSet && eAci
+						!= WMM_AC_BK_INDEX) {
+						prCurrentMsduInfo->ucUserPriority = aucNextUP[eAci];
+						fgCheckACMAgain = TRUE;
+					}
+				} while (fgCheckACMAgain);
+
+				/* LOG_FUNC ("QoS %u UP %u TC %u", */
+				/*		prStaRec->fgIsQoS,prCurrentMsduInfo->ucUserPriority, ucTC); */
+
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+				/*
+				   In TDLS or AP mode, peer maybe enter "sleep mode".
+
+				   If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode,
+				   we need to wait 60 * u4TimeToAdjustTcResource = 180 packets
+				   u4TimeToAdjustTcResource = 3,
+				   then we will adjust TC resouce for VI or VO.
+
+				   But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7,
+				   we will to wait about 12 seconds to collect 180 packets.
+				   but the test time is only 20 seconds.
+				 */
+				if ((prQM->u4TxNumOfVi == 10) || (prQM->u4TxNumOfVo == 10)) {
+					/* force to do TC resouce update */
+					prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN;
+					prQM->u4TimeToAdjustTcResource = 1;
+				}
+#endif
+#if ARP_MONITER_ENABLE
+				if (IS_STA_IN_AIS(prStaRec) && prCurrentMsduInfo->eSrc == TX_PACKET_OS)
+					qmDetectArpNoResponse(prAdapter, prCurrentMsduInfo);
+#endif
+
+				break;	/*default */
+			}	/* switch (prCurrentMsduInfo->ucStaRecIndex) */
+
+			if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) {
+				if (prTxQue->u4NumElem > 32) {
+					DBGLOG(QM, WARN,
+					       "Drop the Packet for full Tx queue (forwarding) Bss %u\n",
+						prCurrentMsduInfo->ucNetworkType);
+					prTxQue = &rNotEnqueuedQue;
+					TX_INC_CNT(&prAdapter->rTxCtrl, TX_FORWARD_OVERFLOW_DROP);
+				}
+			}
+
+		} else {
+
+			DBGLOG(QM, WARN, "Drop the Packet for inactive Bss %u\n", prCurrentMsduInfo->ucNetworkType);
+			QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31);
+			prTxQue = &rNotEnqueuedQue;
+			TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP);
+		}
+
+		/* 4 <3> Fill the MSDU_INFO for constructing HIF TX header */
+
+		/* TODO: Fill MSDU_INFO according to the network type,
+		 *  EtherType, and STA status (for PS forwarding control).
+		 */
+
+		/* Note that the Network Type Index and STA_REC index are determined in
+		 *  qmDetermineStaRecIndex(prCurrentMsduInfo).
+		 */
+		QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(prCurrentMsduInfo,	/* MSDU_INFO ptr */
+						    ucTC,	/* TC tag */
+						    ucPacketType,	/* Packet Type */
+						    0,	/* Format ID */
+						    prCurrentMsduInfo->fgIs802_1x,	/* Flag 802.1x */
+						    prCurrentMsduInfo->fgIs802_11,	/* Flag 802.11 */
+						    0,	/* PAL LLH */
+						    0,	/* ACL SN */
+						    PS_FORWARDING_TYPE_NON_PS,	/* PS Forwarding Type */
+						    0	/* PS Session ID */
+		    );
+
+		/* 4 <4> Enqueue the packet to different AC queue (max 5 AC queues) */
+		QUEUE_INSERT_TAIL(prTxQue, (P_QUE_ENTRY_T) prCurrentMsduInfo);
+
+		if (prTxQue != &rNotEnqueuedQue) {
+			prQM->u4EnqeueuCounter++;
+			prQM->au4ResourceWantedCounter[ucTC]++;
+		}
+		if (prStaRec)
+			prStaRec->u4EnqeueuCounter++;
+
+#if QM_TC_RESOURCE_EMPTY_COUNTER
+		{
+			P_TX_CTRL_T prTxCtrl = &prAdapter->rTxCtrl;
+
+			if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] == 0) {
+				prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC]++;
+				/*
+				   DBGLOG(QM, TRACE, ("TC%d Q Empty Count: [%d]%ld\n",
+				   ucTC,
+				   prCurrentMsduInfo->ucNetworkType,
+				   prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC]));
+				 */
+			}
+
+		}
+#endif
+
+#if QM_TEST_MODE
+		if (++prQM->u4PktCount == QM_TEST_TRIGGER_TX_COUNT) {
+			prQM->u4PktCount = 0;
+			qmTestCases(prAdapter);
+		}
+#endif
+
+		DBGLOG(QM, LOUD, "Current queue length = %u\n", prTxQue->u4NumElem);
+	} while (prNextMsduInfo);
+
+	if (QUEUE_IS_NOT_EMPTY(&rNotEnqueuedQue)) {
+		QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rNotEnqueuedQue), NULL);
+		prMsduInfoReleaseList = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rNotEnqueuedQue);
+	}
+
+	return prMsduInfoReleaseList;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Determine the STA_REC index for a packet
+*
+* \param[in] prMsduInfo Pointer to the packet
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	UINT_32 i;
+
+	P_STA_RECORD_T prTempStaRec;
+	/* P_QUE_MGT_T prQM = &prAdapter->rQM; */
+
+	prTempStaRec = NULL;
+
+	ASSERT(prMsduInfo);
+
+	/* 4 <1> DA = BMCAST */
+	if (IS_BMCAST_MAC_ADDR(prMsduInfo->aucEthDestAddr)) {
+		/* For intrastructure mode and P2P (playing as a GC), BMCAST frames shall be sent to the AP.
+		 *  FW shall take care of this. The host driver is not able to distinguish these cases. */
+		prMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST;
+		DBGLOG(QM, LOUD, "TX with DA = BMCAST\n");
+		return;
+	}
+#if (CFG_SUPPORT_TDLS == 1)
+	/* Check if the peer is TDLS one */
+	if (TdlsexStaRecIdxGet(prAdapter, prMsduInfo) == TDLS_STATUS_SUCCESS)
+		return;		/* find a TDLS record */
+#endif /* CFG_SUPPORT_TDLS */
+
+	/* 4 <2> Check if an AP STA is present */
+	for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) {
+		prTempStaRec = &(prAdapter->arStaRec[i]);
+
+		if ((prTempStaRec->ucNetTypeIndex == prMsduInfo->ucNetworkType)
+		    && (prTempStaRec->fgIsAp)
+		    && (prTempStaRec->fgIsValid)) {
+			prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex;
+			return;
+		}
+	}
+
+	/* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */
+	for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) {
+		prTempStaRec = &(prAdapter->arStaRec[i]);
+		if (prTempStaRec->fgIsValid) {
+			if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prMsduInfo->aucEthDestAddr)) {
+				prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex;
+				return;
+			}
+		}
+	}
+
+	/* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */
+	prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND;
+	DBGLOG(QM, LOUD, "QM: TX with STA_REC_INDEX_NOT_FOUND\n");
+
+#if (QM_TEST_MODE && QM_TEST_FAIR_FORWARDING)
+	prMsduInfo->ucStaRecIndex = (UINT_8) prQM->u4CurrentStaRecIndexToEnqueue;
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Dequeue TX packets from a STA_REC for a particular TC
+*
+* \param[out] prQue The queue to put the dequeued packets
+* \param[in] ucTC The TC index (TC0_INDEX to TC5_INDEX)
+* \param[in] ucMaxNum The maximum amount of dequeued packets
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID
+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter,
+				   OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucCurrentQuota, IN UINT_8 ucTotalQuota)
+{
+
+#if QM_FORWARDING_FAIRNESS
+	UINT_32 i;		/* Loop for */
+
+	PUINT_32 pu4HeadStaRecIndex;	/* The Head STA index */
+	PUINT_32 pu4HeadStaRecForwardCount;	/* The total forwarded packets for the head STA */
+
+	P_STA_RECORD_T prStaRec;	/* The current focused STA */
+	P_BSS_INFO_T prBssInfo;	/* The Bss for current focused STA */
+	P_QUE_T prCurrQueue;	/* The current TX queue to dequeue */
+	P_MSDU_INFO_T prDequeuedPkt;	/* The dequeued packet */
+
+	UINT_32 u4ForwardCount;	/* To remember the total forwarded packets for a STA */
+	UINT_32 u4MaxForwardCount;	/* The maximum number of packets a STA can forward */
+	UINT_32 u4Resource;	/* The TX resource amount */
+
+	BOOLEAN fgChangeHeadSta;	/* Whether a new head STA shall be determined at the end of the function */
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	PUINT_8 pucFreeQuota = NULL;
+#if CFG_ENABLE_WIFI_DIRECT
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo;
+	/*NFC Beam + Indication */
+#endif
+	DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC);
+
+	ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX);
+
+	if (!ucCurrentQuota) {
+		prQM->au4DequeueNoTcResourceCounter[ucTC]++;
+		DBGLOG(TX, LOUD, "@@@@@ TC = %u ucCurrentQuota = %u @@@@@\n", ucTC, ucCurrentQuota);
+		return;
+	}
+
+	u4Resource = ucCurrentQuota;
+
+	/* 4 <1> Determine the head STA */
+	/* The head STA shall be an active STA */
+
+	pu4HeadStaRecIndex = &(prQM->au4HeadStaRecIndex[ucTC]);
+	pu4HeadStaRecForwardCount = &(prQM->au4ForwardCount[ucTC]);
+
+	DBGLOG(QM, LOUD, "(Fairness) TID = %u Init Head STA = %u Resource = %u\n",
+			  ucTC, *pu4HeadStaRecIndex, u4Resource);
+
+	/* From STA[x] to STA[x+1] to STA[x+2] to ... to STA[x] */
+	for (i = 0; i < CFG_NUM_OF_STA_RECORD + 1; i++) {
+		prStaRec = &prAdapter->arStaRec[(*pu4HeadStaRecIndex)];
+		ASSERT(prStaRec);
+
+		/* Only Data frame (1x was not included) will be queued in */
+		if (prStaRec->fgIsValid) {
+
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+			ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex);
+
+			/* Determine how many packets the head STA is allowed to send in a round */
+
+			QM_DBG_CNT_INC(prQM, QM_DBG_CNT_25);
+			u4MaxForwardCount = ucTotalQuota;
+#if CFG_ENABLE_WIFI_DIRECT
+
+			pucFreeQuota = NULL;
+			if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) {
+				/* TODO: Change the threshold in coorperation with the PS forwarding mechanism */
+				/* u4MaxForwardCount = ucTotalQuota; */
+				/* Per STA flow control when STA in PS mode */
+				/* The PHASE 1: only update from ucFreeQuota (now) */
+				/* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */
+				/* aucFreeQuotaPerQueue[] */
+				/* NOTE: other method to set u4Resource */
+
+				if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported
+				    /*  && prAdapter->rWifiVar.fgSupportQoS
+				       && prAdapter->rWifiVar.fgSupportUAPSD */) {
+
+					if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) {
+						u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery;
+						pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery;
+					} else {
+						u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery;
+						pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery;
+					}
+
+				} else {
+					ASSERT(prStaRec->ucFreeQuotaForDelivery == 0);
+					u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery;
+					pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery;
+				}
+
+			}	/* fgIsInPS */
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+#if CFG_ENABLE_WIFI_DIRECT
+
+			/*NFC Beam + Indication */
+
+			if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) {
+				if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
+					if ((prChnlReqInfo->NFC_BEAM != 1) &&
+						(u4MaxForwardCount > prBssInfo->ucBssFreeQuota))
+						u4MaxForwardCount = prBssInfo->ucBssFreeQuota;
+				} else {
+					if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota)
+						u4MaxForwardCount = prBssInfo->ucBssFreeQuota;
+				}
+			}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+			/* Determine whether the head STA can continue to forward packets in this round */
+			if ((*pu4HeadStaRecForwardCount) < u4MaxForwardCount)
+				break;
+
+		} /* prStaRec->fgIsValid */
+		else {
+			/* The current Head STA has been deactivated, so search for a new head STA */
+			prStaRec = NULL;
+			prBssInfo = NULL;
+			(*pu4HeadStaRecIndex)++;
+			(*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD;
+
+			/* Reset the forwarding count before searching (since this is for a new selected STA) */
+			(*pu4HeadStaRecForwardCount) = 0;
+		}
+	}			/* i < CFG_NUM_OF_STA_RECORD + 1 */
+
+	/* All STA_RECs are inactive, so exit */
+	if (!prStaRec) {
+		/* Under concurrent, it is possible that there is no candidcated STA. */
+		/* DBGLOG(TX, EVENT, ("All STA_RECs are inactive\n")); */
+		return;
+	}
+
+	DBGLOG(QM, LOUD, "(Fairness) TID = %u Round Head STA = %u\n", ucTC, *pu4HeadStaRecIndex);
+
+	/* 4 <2> Dequeue packets from the head STA */
+
+	prCurrQueue = &prStaRec->arTxQueue[ucTC];
+	prDequeuedPkt = NULL;
+	fgChangeHeadSta = FALSE;
+
+#if (CFG_SUPPORT_TDLS == 1)
+	if (pucFreeQuota != NULL)
+		TdlsexTxQuotaCheck(prAdapter->prGlueInfo, prStaRec, *pucFreeQuota);
+#endif /* CFG_SUPPORT_TDLS */
+
+	while (prCurrQueue) {
+
+#if QM_DEBUG_COUNTER
+
+		if (ucTC <= TC4_INDEX) {
+			if (QUEUE_IS_EMPTY(prCurrQueue)) {
+				QM_DBG_CNT_INC(prQM, ucTC);
+				/* QM_DBG_CNT_00 *//* QM_DBG_CNT_01 *//* QM_DBG_CNT_02 */
+				/* QM_DBG_CNT_03 *//* QM_DBG_CNT_04 */
+			}
+			if (u4Resource == 0) {
+				QM_DBG_CNT_INC(prQM, ucTC + 5);
+				/* QM_DBG_CNT_05 *//* QM_DBG_CNT_06 *//* QM_DBG_CNT_07 */
+				/* QM_DBG_CNT_08 *//* QM_DBG_CNT_09 */
+			}
+			if (((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) {
+				QM_DBG_CNT_INC(prQM, ucTC + 10);
+				/* QM_DBG_CNT_10 *//* QM_DBG_CNT_11 *//* QM_DBG_CNT_12 */
+				/* QM_DBG_CNT_13 *//* QM_DBG_CNT_14 */
+			}
+		}
+#endif
+
+		/* Three cases to break: (1) No resource (2) No packets (3) Fairness */
+		if (QUEUE_IS_EMPTY(prCurrQueue) || ((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) {
+			fgChangeHeadSta = TRUE;
+			break;
+		} else if (u4Resource == 0) {
+#if (CFG_SUPPORT_STATISTICS == 1)
+			prStaRec->u4NumOfNoTxQuota++;
+#endif /* CFG_SUPPORT_STATISTICS */
+			break;
+		}
+
+		QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T);
+		prStaRec->u4DeqeueuCounter++;
+		prQM->u4DequeueCounter++;
+
+#if (CFG_SUPPORT_TDLS_DBG == 1)
+		if (prDequeuedPkt != NULL) {
+			struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket;
+			UINT8 *pkt = prSkb->data;
+			UINT16 u2Identifier;
+
+			if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) {
+				/* ip */
+				u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19));
+				DBGLOG(QM, LOUD, "<d> %d\n", u2Identifier);
+			}
+		}
+#endif
+#if DBG && 0
+		LOG_FUNC("Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n",
+			 prDequeuedPkt->ucTC,
+			 prCurrQueue->u4NumElem,
+			 prDequeuedPkt->ucNetworkType,
+			 prDequeuedPkt->ucMacHeaderLength,
+			 prDequeuedPkt->u2FrameLength,
+			 prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11);
+
+		LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr);
+
+#if LINUX
+		{
+			struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket;
+
+			dumpMemory8((PUINT_8) prSkb->data, prSkb->len);
+		}
+#endif
+
+#endif
+
+		ASSERT(prDequeuedPkt->ucTC == ucTC);
+
+		if (!QUEUE_IS_EMPTY(prCurrQueue)) {
+			/* XXX: check all queues for STA */
+			prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED;
+		}
+
+		QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt);
+		u4Resource--;
+		(*pu4HeadStaRecForwardCount)++;
+
+#if CFG_ENABLE_WIFI_DIRECT
+		/* XXX The PHASE 2: decrease from  aucFreeQuotaPerQueue[] */
+		if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) {
+			if ((pucFreeQuota) && (*pucFreeQuota > 0))
+				*pucFreeQuota = *pucFreeQuota - 1;
+		}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) {
+			if (prBssInfo->ucBssFreeQuota > 0)
+				prBssInfo->ucBssFreeQuota--;
+		}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+	}
+
+	if (*pu4HeadStaRecForwardCount) {
+		DBGLOG(QM, LOUD,
+		       "TC = %u Round Head STA = %u, u4HeadStaRecForwardCount = %u\n", ucTC, *pu4HeadStaRecIndex,
+			(*pu4HeadStaRecForwardCount));
+	}
+#if QM_BURST_END_INFO_ENABLED
+	/* Let FW know which packet is the last one dequeued from the STA */
+	if (prDequeuedPkt)
+		prDequeuedPkt->fgIsBurstEnd = TRUE;
+#endif
+
+	/* 4 <3> Dequeue from the other STAs if there is residual TX resource */
+
+	/* Check all of the STAs to continue forwarding packets (including the head STA) */
+	for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) {
+		/* Break in case no reasource is available */
+		if (u4Resource == 0) {
+			prQM->au4DequeueNoTcResourceCounter[ucTC]++;
+			break;
+		}
+
+		/* The current head STA will be examined when i = CFG_NUM_OF_STA_RECORD-1 */
+		prStaRec = &prAdapter->arStaRec[((*pu4HeadStaRecIndex) + i + 1) % CFG_NUM_OF_STA_RECORD];
+		ASSERT(prStaRec);
+
+		if (prStaRec->fgIsValid) {
+
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+			ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex);
+
+			DBGLOG(QM, LOUD, "(Fairness) TID = %u Sharing STA = %u Resource = %u\n",
+					  ucTC, prStaRec->ucIndex, u4Resource);
+
+			prCurrQueue = &prStaRec->arTxQueue[ucTC];
+			u4ForwardCount = 0;
+			u4MaxForwardCount = ucTotalQuota;
+
+#if CFG_ENABLE_WIFI_DIRECT
+			pucFreeQuota = NULL;
+			if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) {
+				/* TODO: Change the threshold in coorperation with the PS forwarding mechanism */
+				/* u4MaxForwardCount = ucTotalQuota; */
+				/* Per STA flow control when STA in PS mode */
+				/* The PHASE 1: only update from ucFreeQuota (now) */
+				/* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */
+				/* aucFreeQuotaPerQueue[] */
+				/* NOTE: other method to set u4Resource */
+				if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported
+				    /*  && prAdapter->rWifiVar.fgSupportQoS
+				       && prAdapter->rWifiVar.fgSupportUAPSD */) {
+
+					if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) {
+						u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery;
+						pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery;
+					} else {
+						u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery;
+						pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery;
+					}
+
+				} else {
+					ASSERT(prStaRec->ucFreeQuotaForDelivery == 0);
+					u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery;
+					pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery;
+				}
+
+			}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+#if CFG_ENABLE_WIFI_DIRECT
+			if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) {
+				if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota)
+					u4MaxForwardCount = prBssInfo->ucBssFreeQuota;
+			}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+		} /* prStaRec->fgIsValid */
+		else {
+			prBssInfo = NULL;
+			/* Invalid STA, so check the next STA */
+			continue;
+		}
+
+		while (prCurrQueue) {
+			/* Three cases to break: (1) No resource (2) No packets (3) Fairness */
+			if ((u4Resource == 0) || QUEUE_IS_EMPTY(prCurrQueue) || (u4ForwardCount >= u4MaxForwardCount))
+				break;
+
+
+			QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T);
+
+#if DBG && 0
+			DBGLOG(QM, LOUD, "Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n",
+					  prDequeuedPkt->ucTC,
+					  prCurrQueue->u4NumElem,
+					  prDequeuedPkt->ucNetworkType,
+					  prDequeuedPkt->ucMacHeaderLength,
+					  prDequeuedPkt->u2FrameLength,
+					  prDequeuedPkt->ucPacketType,
+					  prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11));
+
+			DBGLOG(QM, LOUD, "Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr);
+
+#if LINUX
+			{
+				struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket;
+
+				dumpMemory8((PUINT_8) prSkb->data, prSkb->len);
+			}
+#endif
+
+#endif
+
+			ASSERT(prDequeuedPkt->ucTC == ucTC);
+
+			if (!QUEUE_IS_EMPTY(prCurrQueue))
+				/* more data field ? */
+				prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED;
+
+			QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt);
+			if (prStaRec)
+				prStaRec->u4DeqeueuCounter++;
+			prQM->u4DequeueCounter++;
+			u4Resource--;
+			u4ForwardCount++;
+
+#if CFG_ENABLE_WIFI_DIRECT
+			/* XXX The PHASE 2: decrease from  aucFreeQuotaPerQueue[] */
+			if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) {
+				ASSERT(pucFreeQuota);
+				ASSERT(*pucFreeQuota > 0);
+				if (*pucFreeQuota > 0)
+					*pucFreeQuota = *pucFreeQuota - 1;
+			}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+#if CFG_ENABLE_WIFI_DIRECT
+			ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex);
+			if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) {
+				if (prBssInfo->ucBssFreeQuota > 0)
+					prBssInfo->ucBssFreeQuota--;
+			}
+#endif /* CFG_ENABLE_WIFI_DIRECT */
+
+		}
+
+#if QM_BURST_END_INFO_ENABLED
+		/* Let FW know which packet is the last one dequeued from the STA */
+		if (u4ForwardCount)
+			prDequeuedPkt->fgIsBurstEnd = TRUE;
+#endif
+	}
+
+	if (fgChangeHeadSta) {
+		(*pu4HeadStaRecIndex)++;
+		(*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD;
+		(*pu4HeadStaRecForwardCount) = 0;
+		DBGLOG(QM, LOUD, "(Fairness) TID = %u Scheduled Head STA = %u Left Resource = %u\n",
+				  ucTC, (*pu4HeadStaRecIndex), u4Resource);
+	}
+
+/***************************************************************************************/
+#else
+	UINT_8 ucStaRecIndex;
+	P_STA_RECORD_T prStaRec;
+	P_QUE_T prCurrQueue;
+	UINT_8 ucPktCount;
+	P_MSDU_INFO_T prDequeuedPkt;
+
+	DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC);
+
+	if (ucCurrentQuota == 0)
+		return;
+	/* 4 <1> Determine the queue index and the head STA */
+
+	/* The head STA */
+	ucStaRecIndex = 0;	/* TODO: Get the current head STA */
+	prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIndex);
+	ASSERT(prStaRec);
+
+	if (prStaRec == NULL)
+		return;
+
+	/* The queue to pull out packets */
+	ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX);
+	prCurrQueue = &prStaRec->arTxQueue[ucTC];
+
+	ucPktCount = ucCurrentQuota;
+	prDequeuedPkt = NULL;
+
+	/* 4 <2> Dequeue packets for the head STA */
+	while (TRUE) {
+		if (!(prStaRec->fgIsValid) || ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) {
+			break;
+
+		} else {
+
+			QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T);
+			/* DbgPrint("QM: Remove Queue Head, TC= %d\n", prDequeuedPkt->ucTC); */
+			ASSERT(prDequeuedPkt->ucTC == ucTC);
+
+			QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt);
+			ucPktCount--;
+		}
+	}
+
+	/* DbgPrint("QM: Remaining number of queued packets = %d\n", prCurrQueue->u4NumElem); */
+
+#if QM_BURST_END_INFO_ENABLED
+	if (prDequeuedPkt)
+		prDequeuedPkt->fgIsBurstEnd = TRUE;
+#endif
+
+	/* 4 <3> Update scheduling info */
+	/* TODO */
+
+	/* 4 <4> Utilize the remainaing TX opportunities for non-head STAs */
+	/* TODO */
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Dequeue TX packets from a per-Type-based Queue for a particular TC
+*
+* \param[out] prQue The queue to put the dequeued packets
+* \param[in] ucTC The TC index (Shall always be TC5_INDEX)
+* \param[in] ucMaxNum The maximum amount of dequeued packets
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID
+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum)
+{
+	/* UINT_8          ucQueIndex; */
+	/* UINT_8          ucStaRecIndex; */
+	P_BSS_INFO_T prBssInfo;
+	P_BSS_INFO_T parBssInfo;
+	P_QUE_T prCurrQueue;
+	UINT_8 ucPktCount;
+	P_MSDU_INFO_T prDequeuedPkt;
+	P_MSDU_INFO_T prBurstEndPkt;
+	QUE_T rMergeQue;
+	P_QUE_T prMergeQue;
+	P_QUE_MGT_T prQM;
+
+	DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerTypeQueues (TC = %d, Max = %d)\n", ucTC, ucMaxNum);
+
+	/* TC5: Broadcast/Multicast data packets */
+	ASSERT(ucTC == TC5_INDEX);
+
+	if (ucMaxNum == 0)
+		return;
+
+	prQM = &prAdapter->rQM;
+	/* 4 <1> Determine the queue */
+
+	prCurrQueue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST];
+	ucPktCount = ucMaxNum;
+	prDequeuedPkt = NULL;
+	prBurstEndPkt = NULL;
+
+	parBssInfo = prAdapter->rWifiVar.arBssInfo;
+
+	QUEUE_INITIALIZE(&rMergeQue);
+	prMergeQue = &rMergeQue;
+
+	/* 4 <2> Dequeue packets */
+	while (TRUE) {
+		if (ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue))
+			break;
+
+		QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T);
+		ASSERT(prDequeuedPkt->ucTC == ucTC);
+
+		ASSERT(prDequeuedPkt->ucNetworkType < NETWORK_TYPE_INDEX_NUM);
+
+		prBssInfo = &parBssInfo[prDequeuedPkt->ucNetworkType];
+
+		if (IS_BSS_ACTIVE(prBssInfo)) {
+			if (!prBssInfo->fgIsNetAbsent) {
+				QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt);
+				prQM->u4DequeueCounter++;
+				prBurstEndPkt = prDequeuedPkt;
+				ucPktCount--;
+				QM_DBG_CNT_INC(prQM, QM_DBG_CNT_26);
+#if DBG && 0
+				LOG_FUNC
+				    ("DeqType TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n",
+				     prDequeuedPkt->ucTC, prCurrQueue->u4NumElem, prDequeuedPkt->ucNetworkType,
+				     prDequeuedPkt->ucMacHeaderLength, prDequeuedPkt->u2FrameLength,
+				     prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x,
+				     prDequeuedPkt->fgIs802_11);
+
+				LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr);
+
+#if LINUX
+				{
+					struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket;
+
+					dumpMemory8((PUINT_8) prSkb->data, prSkb->len);
+				}
+#endif
+
+#endif
+			} else {
+				QUEUE_INSERT_TAIL(prMergeQue, (P_QUE_ENTRY_T) prDequeuedPkt);
+			}
+		} else {
+			QM_TX_SET_NEXT_MSDU_INFO(prDequeuedPkt, NULL);
+			wlanProcessQueuedMsduInfo(prAdapter, prDequeuedPkt);
+		}
+	}
+
+	if (QUEUE_IS_NOT_EMPTY(prMergeQue)) {
+		QUEUE_CONCATENATE_QUEUES(prMergeQue, prCurrQueue);
+		QUEUE_MOVE_ALL(prCurrQueue, prMergeQue);
+		if (QUEUE_GET_TAIL(prCurrQueue))
+			QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(prCurrQueue), NULL);
+	}
+#if QM_BURST_END_INFO_ENABLED
+	if (prBurstEndPkt)
+		prBurstEndPkt->fgIsBurstEnd = TRUE;
+#endif
+}				/* qmDequeueTxPacketsFromPerTypeQueues */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Dequeue TX packets to send to HIF TX
+*
+* \param[in] prTcqStatus Info about the maximum amount of dequeued packets
+*
+* \return The list of dequeued TX packets
+*/
+/*----------------------------------------------------------------------------*/
+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus)
+{
+
+	INT32 i;
+	P_MSDU_INFO_T prReturnedPacketListHead;
+	QUE_T rReturnedQue;
+
+	DBGLOG(QM, LOUD, "Enter qmDequeueTxPackets\n");
+
+	QUEUE_INITIALIZE(&rReturnedQue);
+
+	prReturnedPacketListHead = NULL;
+
+	/* dequeue packets from different AC queue based on available aucFreeBufferCount */
+	/* TC0 to TC4: AC0~AC3, 802.1x (commands packets are not handled by QM) */
+	for (i = TC4_INDEX; i >= TC0_INDEX; i--) {
+		DBGLOG(QM, LOUD, "Dequeue packets from Per-STA queue[%d]\n", i);
+
+		/*
+		   in the function, we will re-calculate the ucFreeQuota.
+		   If any packet with any priority for the station will be sent, ucFreeQuota --
+
+		   Note1: ucFreeQuota will be decrease only when station is in power save mode.
+		   In active mode, we will sent the packet to the air directly.
+
+		   if(prStaRec->fgIsInPS && (ucTC!=TC4_INDEX)) {
+		   ASSERT(pucFreeQuota);
+		   ASSERT(*pucFreeQuota>0);
+		   if ((pucFreeQuota) && (*pucFreeQuota>0)) {
+		   *pucFreeQuota = *pucFreeQuota - 1;
+		   }
+		   }
+
+		   Note2: maximum queued number for a station is 10, TXM_MAX_BUFFER_PER_STA_DEF in fw
+		   i.e. default prStaRec->ucFreeQuota = 10
+
+		   Note3: In qmUpdateFreeQuota(), we will adjust
+		   ucFreeQuotaForNonDelivery = ucFreeQuota>>1;
+		   ucFreeQuotaForDelivery =  ucFreeQuota - ucFreeQuotaForNonDelivery;
+		 */
+		qmDequeueTxPacketsFromPerStaQueues(prAdapter,
+			&rReturnedQue,
+			(UINT_8) i,
+			prTcqStatus->aucFreeBufferCount[i],	/* maximum dequeue number */
+			prTcqStatus->aucMaxNumOfBuffer[i]);
+
+		/* The aggregate number of dequeued packets */
+		DBGLOG(QM, LOUD, "DQA)[%u](%u)\n", i, rReturnedQue.u4NumElem);
+	}
+
+	/* TC5 (BMCAST or STA-NOT-FOUND packets) */
+	qmDequeueTxPacketsFromPerTypeQueues(prAdapter,
+					    &rReturnedQue, TC5_INDEX, prTcqStatus->aucFreeBufferCount[TC5_INDEX]
+	    );
+
+	DBGLOG(QM, LOUD, "Current total number of dequeued packets = %u\n", rReturnedQue.u4NumElem);
+
+	if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) {
+		prReturnedPacketListHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rReturnedQue);
+		QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rReturnedQue), NULL);
+	}
+
+	return prReturnedPacketListHead;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Adjust the TC quotas according to traffic demands
+*
+* \param[out] prTcqAdjust The resulting adjustment
+* \param[in] prTcqStatus Info about the current TC quotas and counters
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus)
+{
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+	UINT_32 i;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	/* Must reset */
+	for (i = 0; i < TC_NUM; i++)
+		prTcqAdjust->acVariation[i] = 0;
+
+	/* 4 <1> If TC resource is not just adjusted, exit directly */
+	if (!prQM->fgTcResourcePostAnnealing)
+		return;
+	/* 4 <2> Adjust TcqStatus according to the updated prQM->au4CurrentTcResource */
+	else {
+		INT_32 i4TotalExtraQuota = 0;
+		INT_32 ai4ExtraQuota[TC_NUM];
+		BOOLEAN fgResourceRedistributed = TRUE;
+
+		/* Obtain the free-to-distribute resource */
+		for (i = 0; i < TC_NUM; i++) {
+			ai4ExtraQuota[i] =
+			    (INT_32) prTcqStatus->aucMaxNumOfBuffer[i] - (INT_32) prQM->au4CurrentTcResource[i];
+
+			if (ai4ExtraQuota[i] > 0) {	/* The resource shall be reallocated to other TCs */
+
+				if (ai4ExtraQuota[i] > prTcqStatus->aucFreeBufferCount[i]) {
+					/*
+					   we have residunt TC resources for the TC:
+					   EX: aucMaxNumOfBuffer[] = 20, au4CurrentTcResource[] = 5
+					   ai4ExtraQuota[] = 15, aucFreeBufferCount[] = 10
+
+					   so ai4ExtraQuota[] = aucFreeBufferCount[] = 10
+					   because we available TC resources actually is 10, not 20
+					 */
+					ai4ExtraQuota[i] = prTcqStatus->aucFreeBufferCount[i];
+
+					/*
+					   FALSE means we can re-do TC resource adjustment in tx done
+					   at next time, maybe more tx done is finished
+					 */
+					fgResourceRedistributed = FALSE;
+				}
+
+				/* accumulate current all available TC resources */
+				i4TotalExtraQuota += ai4ExtraQuota[i];
+
+				/* deduce unused TC resources for the TC */
+				prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]);
+			}
+		}
+
+		/* Distribute quotas to TCs which need extra resource according to prQM->au4CurrentTcResource */
+		for (i = 0; i < TC_NUM; i++) {
+			if (ai4ExtraQuota[i] < 0) {
+
+				/* The TC needs extra resources */
+				if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) {
+					/* the number of needed extra resources is larger than total available */
+					ai4ExtraQuota[i] = (-i4TotalExtraQuota);
+
+					/* wait for next tx done to do adjustment */
+					fgResourceRedistributed = FALSE;
+				}
+
+				/* decrease the total available */
+				i4TotalExtraQuota += ai4ExtraQuota[i];
+
+				/* mark to increase TC resources for the TC */
+				prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]);
+			}
+		}
+
+		/* In case some TC is waiting for TX Done, continue to adjust TC quotas upon TX Done */
+
+		/*
+		   if fgResourceRedistributed == TRUE, it means we will adjust at this time so
+		   we need to re-adjust TC resources (fgTcResourcePostAnnealing = FALSE).
+		 */
+		prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed);
+
+#if QM_PRINT_TC_RESOURCE_CTRL
+		DBGLOG(QM, LOUD, "QM: Curr Quota [0]=%u [1]=%u [2]=%u [3]=%u [4]=%u [5]=%u\n",
+				  prTcqStatus->aucFreeBufferCount[0],
+				  prTcqStatus->aucFreeBufferCount[1],
+				  prTcqStatus->aucFreeBufferCount[2],
+				  prTcqStatus->aucFreeBufferCount[3],
+				  prTcqStatus->aucFreeBufferCount[4], prTcqStatus->aucFreeBufferCount[5]
+		       ));
+#endif
+	}
+
+#else
+	UINT_32 i;
+
+	for (i = 0; i < TC_NUM; i++)
+		prTcqAdjust->acVariation[i] = 0;
+
+#endif
+}
+
+#if QM_ADAPTIVE_TC_RESOURCE_CTRL
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Update the average TX queue length for the TC resource control mechanism
+*
+* \param (none)
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter)
+{
+	INT_32 u4CurrQueLen, i, k;
+	P_STA_RECORD_T prStaRec;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	/* 4 <1> Update the queue lengths for TC0 to TC3 (skip TC4) and TC5 */
+	/* use moving average algorithm to calculate au4AverageQueLen for every TC queue */
+	for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES - 1; i++) {
+		u4CurrQueLen = 0;
+
+		for (k = 0; k < CFG_NUM_OF_STA_RECORD; k++) {
+			prStaRec = &prAdapter->arStaRec[k];
+			ASSERT(prStaRec);
+
+			/* If the STA is activated, get the queue length */
+			if (prStaRec->fgIsValid &&
+			    (!prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].fgIsNetAbsent)
+			    ) {
+
+				u4CurrQueLen += (prStaRec->arTxQueue[i].u4NumElem);
+			}
+		}
+
+		if (prQM->au4AverageQueLen[i] == 0) {
+			prQM->au4AverageQueLen[i] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR);	/* *8 */
+		} else {
+			/* len => len - len/8 = 7/8 * len + new len */
+			prQM->au4AverageQueLen[i] -= (prQM->au4AverageQueLen[i] >> QM_QUE_LEN_MOVING_AVE_FACTOR);
+			prQM->au4AverageQueLen[i] += (u4CurrQueLen);
+		}
+
+	}
+
+	/* Update the queue length for TC5 (BMCAST) */
+	u4CurrQueLen = prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST].u4NumElem;
+
+	if (prQM->au4AverageQueLen[TC_NUM - 1] == 0) {
+		prQM->au4AverageQueLen[TC_NUM - 1] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR);
+	} else {
+		prQM->au4AverageQueLen[TC_NUM - 1] -=
+		    (prQM->au4AverageQueLen[TC_NUM - 1] >> QM_QUE_LEN_MOVING_AVE_FACTOR);
+		prQM->au4AverageQueLen[TC_NUM - 1] += (u4CurrQueLen);
+	}
+
+	/* 4 <2> Adjust TC resource assignment every 3 times */
+	/* Check whether it is time to adjust the TC resource assignment */
+	if (--prQM->u4TimeToAdjustTcResource == 0) {	/* u4TimeToAdjustTcResource = 3 */
+
+		/* The last assignment has not been completely applied */
+		if (prQM->fgTcResourcePostAnnealing) {
+			/* Upon the next qmUpdateAverageTxQueLen function call, do this check again */
+
+			/* wait for next time to do qmReassignTcResource */
+			prQM->u4TimeToAdjustTcResource = 1;
+		} else {	/* The last assignment has been applied */
+			prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC;
+			qmReassignTcResource(prAdapter);
+		}
+	}
+
+	/* Debug */
+#if QM_PRINT_TC_RESOURCE_CTRL
+	for (i = 0; i < TC_NUM; i++) {
+		if (QM_GET_TX_QUEUE_LEN(prAdapter, i) >= 100) {
+			DBGLOG(QM, LOUD, "QM: QueLen [%u %u %u %u %u %u]\n",
+					  QM_GET_TX_QUEUE_LEN(prAdapter, 0),
+					  QM_GET_TX_QUEUE_LEN(prAdapter, 1),
+					  QM_GET_TX_QUEUE_LEN(prAdapter, 2),
+					  QM_GET_TX_QUEUE_LEN(prAdapter, 3),
+					  QM_GET_TX_QUEUE_LEN(prAdapter, 4), QM_GET_TX_QUEUE_LEN(prAdapter, 5)
+			       ));
+			break;
+		}
+	}
+#endif
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Assign TX resource for each TC according to TX queue length and current assignment
+*
+* \param (none)
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter)
+{
+	INT_32 i4TotalResourceDemand = 0;
+	UINT_32 u4ResidualResource = 0;
+	UINT_32 i;
+	INT_32 ai4PerTcResourceDemand[TC_NUM];
+	UINT_32 u4ShareCount = 0;
+	UINT_32 u4Share = 0;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	/* Note: After the new assignment is obtained, set prQM->fgTcResourcePostAnnealing to TRUE to
+	 *  start the TC-quota adjusting procedure, which will be invoked upon every TX Done
+	 */
+	/* tx done -> nicProcessTxInterrupt() -> nicTxAdjustTcq()
+	 * -> qmAdjustTcQuotas() -> check fgTcResourcePostAnnealing */
+
+	/* 4 <1> Determine the demands */
+	/* Determine the amount of extra resource to fulfill all of the demands */
+	for (i = 0; i < TC_NUM; i++) {
+		/* Skip TC4, which is not adjustable */
+		if (i == TC4_INDEX)
+			continue;
+
+		/*
+		   Define: extra_demand = average que_length (includes all station records) +
+		   min_reserved_quota -
+		   current available TC resources
+
+		   extra_demand means we need extra TC resources to transmit; other TCs can
+		   borrow their resources to us?
+		 */
+		ai4PerTcResourceDemand[i] =
+		    ((UINT_32) (QM_GET_TX_QUEUE_LEN(prAdapter, i)) +
+		     prQM->au4MinReservedTcResource[i] - prQM->au4CurrentTcResource[i]);
+
+		/* If there are queued packets, allocate extra resource for the TC (for TCP consideration) */
+		if (QM_GET_TX_QUEUE_LEN(prAdapter, i))
+			ai4PerTcResourceDemand[i] += QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY;	/* 0 */
+
+		/*
+		   accumulate all needed extra TC resources
+		   maybe someone need + resource, maybe someone need - resource
+		 */
+		i4TotalResourceDemand += ai4PerTcResourceDemand[i];
+	}
+
+	/* 4 <2> Case 1: Demand <= Total Resource */
+	if (i4TotalResourceDemand <= 0) {
+		/* 4 <2.1> Satisfy every TC */
+		/* total TC resources are enough, no extra TC resources is needed */
+
+		/* adjust used TC resources to average TC resources + min reserve TC resources */
+		for (i = 0; i < TC_NUM; i++) {
+			/* Skip TC4 (not adjustable) */
+			if (i == TC4_INDEX)
+				continue;
+
+			/*
+			   the number of resources that one TC releases can be used for
+			   other TCs
+
+			   EX:  TC0 au4CurrentTcResource[0] = 10 ai4PerTcResourceDemand[0] = -5
+			   TC1 au4CurrentTcResource[1] = 5 ai4PerTcResourceDemand[0] = +5
+			   =>  TC0 au4CurrentTcResource[0] = 10 + (-5) = 5
+			   TC1 au4CurrentTcResource[1] = 5 + (+5) = 10
+			 */
+			prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i];
+		}
+
+		/* 4 <2.2> Share the residual resource evenly */
+		u4ShareCount = (TC_NUM - 1);	/* 5, excluding TC4 */
+
+		/*
+		   EX: i4TotalResourceDemand = -10
+		   means we have 10 available resources can be used.
+		 */
+		u4ResidualResource = (UINT_32) (-i4TotalResourceDemand);
+		u4Share = (u4ResidualResource / u4ShareCount);
+
+		/* share available TC resources to all TCs averagely */
+		for (i = 0; i < TC_NUM; i++) {
+			/* Skip TC4 (not adjustable) */
+			if (i == TC4_INDEX)
+				continue;
+
+			/* allocate residual average resources to the TC */
+			prQM->au4CurrentTcResource[i] += u4Share;
+
+			/* Every TC is fully satisfied so no need extra resources */
+			ai4PerTcResourceDemand[i] = 0;
+
+			/* decrease the allocated resources */
+			u4ResidualResource -= u4Share;
+		}
+
+		/* if still have available resources, we decide to give them to VO (TC3) queue */
+		/* 4 <2.3> Allocate the left resource to TC3 (VO) */
+		prQM->au4CurrentTcResource[TC3_INDEX] += (u4ResidualResource);
+
+	}
+	/* 4 <3> Case 2: Demand > Total Resource --> Guarantee a minimum amount of resource for each TC */
+	else {
+		/*
+		   u4ResidualResource means we at least need to keep
+		   QM_INITIAL_RESIDUAL_TC_RESOURCE available TC resources
+
+		   in 6628, u4ResidualResource = 26, max 28
+		 */
+		u4ResidualResource = QM_INITIAL_RESIDUAL_TC_RESOURCE;
+
+		/* 4 <3.1> Allocated resource amount  = minimum of (guaranteed, total demand) */
+		for (i = 0; i < TC_NUM; i++) {
+
+			if (i == TC4_INDEX)
+				continue;	/* Skip TC4 (not adjustable) */
+
+			/* The demand can be fulfilled with the guaranteed resource amount 4 4 6 6 2 4 */
+
+			/*
+			   ai4PerTcResourceDemand[i] =
+			   ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) +
+			   prQM->au4MinReservedTcResource[i] -
+			   prQM->au4CurrentTcResource[i]);
+
+			   so au4CurrentTcResource + ai4PerTcResourceDemand =
+
+			   ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) +
+			   prQM->au4MinReservedTcResource[i] =
+
+			   current average queue len + min TC resources
+			 */
+			if (prQM->au4CurrentTcResource[i] + ai4PerTcResourceDemand[i] <
+			    prQM->au4GuaranteedTcResource[i]) {
+
+				/* avg queue len + min reserve still smaller than guarantee so enough */
+				prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i];
+
+				/* accumulate available TC resources from the TC */
+				u4ResidualResource +=
+				    (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]);
+				ai4PerTcResourceDemand[i] = 0;
+			}
+
+			/* The demand can not be fulfilled with the guaranteed resource amount */
+			else {
+
+				/* means even we use all guarantee resources for the TC is still not enough */
+
+				/*
+				   guarantee number is always for the TC so extra resource number cannot
+				   include the guarantee number.
+
+				   EX: au4GuaranteedTcResource = 10, au4CurrentTcResource = 5
+				   ai4PerTcResourceDemand = 6
+
+				   ai4PerTcResourceDemand -= (10 - 5) ==> 1
+				   only need extra 1 TC resouce is enough.
+				 */
+				ai4PerTcResourceDemand[i] -=
+				    (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]);
+
+				/* update current avg TC resource to guarantee number */
+				prQM->au4CurrentTcResource[i] = prQM->au4GuaranteedTcResource[i];
+
+				/* count how many TC queues need to get extra resources */
+				u4ShareCount++;
+			}
+		}
+
+		/* 4 <3.2> Allocate the residual resource */
+		do {
+			/* If there is no resource left, exit directly */
+			if (u4ResidualResource == 0)
+				break;
+
+			/* This shall not happen */
+			if (u4ShareCount == 0) {
+				prQM->au4CurrentTcResource[TC1_INDEX] += u4ResidualResource;
+				DBGLOG(QM, ERROR, "QM: (Error) u4ShareCount = 0\n");
+				break;
+			}
+
+			/* Share the residual resource evenly */
+			u4Share = (u4ResidualResource / u4ShareCount);
+
+			if (u4Share) {
+				for (i = 0; i < TC_NUM; i++) {
+					/* Skip TC4 (not adjustable) */
+					if (i == TC4_INDEX)
+						continue;
+
+					if (ai4PerTcResourceDemand[i] == 0)
+						continue;
+
+					if (ai4PerTcResourceDemand[i] - u4Share) {
+						/* still not enough but we just can give it u4Share resources */
+						prQM->au4CurrentTcResource[i] += u4Share;
+						u4ResidualResource -= u4Share;
+						ai4PerTcResourceDemand[i] -= u4Share;
+					} else {
+						/* enough */
+						prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i];
+						u4ResidualResource -= ai4PerTcResourceDemand[i];
+						ai4PerTcResourceDemand[i] = 0;
+					}
+				}
+			}
+
+			if (u4ResidualResource == 0)
+				break;
+			/* By priority, allocate the left resource that is not divisible by u4Share */
+
+			if (ai4PerTcResourceDemand[TC3_INDEX]) {	/* VO */
+				prQM->au4CurrentTcResource[TC3_INDEX]++;
+				if (--u4ResidualResource == 0)
+					break;
+			}
+
+			if (ai4PerTcResourceDemand[TC2_INDEX]) {	/* VI */
+				prQM->au4CurrentTcResource[TC2_INDEX]++;
+				if (--u4ResidualResource == 0)
+					break;
+			}
+
+			if (ai4PerTcResourceDemand[TC5_INDEX]) {	/* BMCAST */
+				prQM->au4CurrentTcResource[TC5_INDEX]++;
+				if (--u4ResidualResource == 0)
+					break;
+			}
+
+			if (ai4PerTcResourceDemand[TC1_INDEX]) {	/* BE */
+				prQM->au4CurrentTcResource[TC1_INDEX]++;
+				if (--u4ResidualResource == 0)
+					break;
+			}
+
+			if (ai4PerTcResourceDemand[TC0_INDEX]) {	/* BK */
+				prQM->au4CurrentTcResource[TC0_INDEX]++;
+				if (--u4ResidualResource == 0)
+					break;
+			}
+
+			/* Allocate the left resource */
+			prQM->au4CurrentTcResource[TC3_INDEX] += u4ResidualResource;
+
+		} while (FALSE);
+	}
+
+	/* mark the flag that we can start to do TC resource adjustment after TX done handle */
+	prQM->fgTcResourcePostAnnealing = TRUE;
+
+#if QM_PRINT_TC_RESOURCE_CTRL
+	/* Debug print */
+	DBGLOG(QM, LOUD, "QM: TC Rsc %u %u %u %u %u %u\n",
+			  prQM->au4CurrentTcResource[0],
+			  prQM->au4CurrentTcResource[1],
+			  prQM->au4CurrentTcResource[2],
+			  prQM->au4CurrentTcResource[3], prQM->au4CurrentTcResource[4], prQM->au4CurrentTcResource[5]
+	       ));
+#endif
+
+}
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* RX-Related Queue Management                                                */
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Init Queue Management for RX
+*
+* \param[in] (none)
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter)
+{
+	/* DbgPrint("QM: Enter qmInitRxQueues()\n"); */
+	/* TODO */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Handle RX packets (buffer reordering)
+*
+* \param[in] prSwRfbListHead The list of RX packets
+*
+* \return The list of packets which are not buffered for reordering
+*/
+/*----------------------------------------------------------------------------*/
+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead)
+{
+
+#if CFG_RX_REORDERING_ENABLED
+	/* UINT_32 i; */
+	P_SW_RFB_T prCurrSwRfb;
+	P_SW_RFB_T prNextSwRfb;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	QUE_T rReturnedQue;
+	PUINT_8 pucEthDestAddr;
+	BOOLEAN fgIsBMC;
+
+	/* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */
+
+	DEBUGFUNC("qmHandleRxPackets");
+
+	ASSERT(prSwRfbListHead);
+
+	QUEUE_INITIALIZE(&rReturnedQue);
+	prNextSwRfb = prSwRfbListHead;
+
+	do {
+		prCurrSwRfb = prNextSwRfb;
+		prNextSwRfb = QM_RX_GET_NEXT_SW_RFB(prCurrSwRfb);
+
+		prHifRxHdr = prCurrSwRfb->prHifRxHdr;	/* TODO: (Tehuang) Use macro to obtain the pointer */
+
+		/* TODO: (Tehuang) Check if relaying */
+		prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST;
+
+		/* Decide the Destination */
+#if CFG_RX_PKTS_DUMP
+		if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_DATA)) {
+			DBGLOG(SW4, INFO, "QM RX DATA: net %u sta idx %u wlan idx %u ssn %u tid %u ptype %u 11 %u\n",
+				(UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr),
+				prHifRxHdr->ucStaRecIdx, prCurrSwRfb->ucWlanIdx,
+				(UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr),	/* The new SN of the frame */
+				(UINT_32) HIF_RX_HDR_GET_TID(prHifRxHdr),
+				prCurrSwRfb->ucPacketType,
+				(UINT_32) HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr));
+
+			DBGLOG_MEM8(SW4, TRACE, (PUINT_8) prCurrSwRfb->pvHeader, prCurrSwRfb->u2PacketLen);
+		}
+#endif
+
+		fgIsBMC = FALSE;
+		if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) {
+
+			UINT_8 ucNetTypeIdx;
+			P_BSS_INFO_T prBssInfo;
+
+			pucEthDestAddr = prCurrSwRfb->pvHeader;
+			ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr);
+
+			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]);
+			/* DBGLOG_MEM8(QM, TRACE,prCurrSwRfb->pvHeader, 16); */
+			/*  */
+
+			if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) && (OP_MODE_ACCESS_POINT != prBssInfo->eCurrentOPMode))
+				fgIsBMC = TRUE;
+
+			if (prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem >
+				(CFG_RX_MAX_PKT_NUM - CFG_NUM_OF_QM_RX_PKT_NUM)) {
+
+				if (!IS_BSS_ACTIVE(prBssInfo)) {
+					DBGLOG(QM, WARN, "Mark NULL the Packet for inactive Bss %u\n", ucNetTypeIdx);
+					prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+					QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb);
+					continue;
+				}
+
+				if (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode) {
+					if (IS_BMCAST_MAC_ADDR(pucEthDestAddr))
+						prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD;
+					else if (UNEQUAL_MAC_ADDR(prBssInfo->aucOwnMacAddr, pucEthDestAddr) &&
+							bssGetClientByAddress(prBssInfo, pucEthDestAddr))
+						prCurrSwRfb->eDst = RX_PKT_DESTINATION_FORWARD;
+						/* TODO : need to check the dst mac is valid */
+						/* If src mac is invalid, the packet will be freed in fw */
+				}	/* OP_MODE_ACCESS_POINT */
+#if CFG_SUPPORT_HOTSPOT_2_0
+				else if (hs20IsFrameFilterEnabled(prAdapter, prBssInfo) &&
+					 hs20IsUnsecuredFrame(prAdapter, prBssInfo, prCurrSwRfb)) {
+					DBGLOG(QM, WARN,
+					       "Mark NULL the Packet for Dropped Packet %u\n", ucNetTypeIdx);
+					prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+					QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb);
+					continue;
+				}
+#endif
+			} else {
+				/* Dont not occupy other SW RFB */
+				DBGLOG(QM, WARN, "Mark NULL the Packet for less Free Sw Rfb\n");
+				prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+				QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb);
+				continue;
+			}
+
+		}
+#if CFG_SUPPORT_WAPI
+		if (prCurrSwRfb->u2PacketLen > ETHER_HEADER_LEN) {
+			PUINT_8 pc = (PUINT_8) prCurrSwRfb->pvHeader;
+			UINT_16 u2Etype = 0;
+
+			u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]);
+
+			/* for wapi integrity test. WPI_1x packet should be always in non-encrypted mode.
+				if we received any WPI(0x88b4) packet that is encrypted, drop here. */
+			if (u2Etype == ETH_WPI_1X && HIF_RX_HDR_GET_SEC_MODE(prHifRxHdr) != 0) {
+				DBGLOG(QM, INFO, "drop wpi packet with sec mode\n");
+				prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+				QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb);
+				continue;
+			}
+		}
+#endif
+		/* BAR frame */
+		if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) {
+			prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+			qmProcessBarFrame(prAdapter, prCurrSwRfb, &rReturnedQue);
+		}
+		/* Reordering is not required for this packet, return it without buffering */
+		else if (!HIF_RX_HDR_GET_REORDER_FLAG(prHifRxHdr) || fgIsBMC) {
+#if 0
+			if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) {
+				UINT_8 ucNetTypeIdx;
+				P_BSS_INFO_T prBssInfo;
+
+				pucEthDestAddr = prCurrSwRfb->pvHeader;
+				ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr);
+
+				prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]);
+
+				if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)
+				    && (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode)) {
+					prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD;
+				}
+			}
+#endif
+			QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb);
+		}
+		/* Reordering is required for this packet */
+		else {
+			/* If this packet should dropped or indicated to the host immediately,
+			 *  it should be enqueued into the rReturnedQue with specific flags. If
+			 *  this packet should be buffered for reordering, it should be enqueued
+			 *  into the reordering queue in the STA_REC rather than into the
+			 *  rReturnedQue.
+			 */
+			qmProcessPktWithReordering(prAdapter, prCurrSwRfb, &rReturnedQue);
+
+		}
+	} while (prNextSwRfb);
+
+	/* RX_PKT_DESTINATION_HOST_WITH_FORWARD or RX_PKT_DESTINATION_FORWARD */
+	/* The returned list of SW_RFBs must end with a NULL pointer */
+	if (QUEUE_IS_NOT_EMPTY(&rReturnedQue))
+		QM_TX_SET_NEXT_MSDU_INFO((P_SW_RFB_T) QUEUE_GET_TAIL(&rReturnedQue), NULL);
+
+	return (P_SW_RFB_T) QUEUE_GET_HEAD(&rReturnedQue);
+
+#else
+
+	/* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */
+	return prSwRfbListHead;
+
+#endif
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Reorder the received packet
+*
+* \param[in] prSwRfb The RX packet to process
+* \param[out] prReturnedQue The queue for indicating packets
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue)
+{
+
+	P_STA_RECORD_T prStaRec;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	P_RX_BA_ENTRY_T prReorderQueParm;
+
+	UINT_32 u4SeqNo;
+	UINT_32 u4WinStart;
+	UINT_32 u4WinEnd;
+	P_QUE_T prReorderQue;
+	/* P_SW_RFB_T prReorderedSwRfb; */
+	BOOLEAN fgIsBaTimeout;
+
+	DEBUGFUNC("qmProcessPktWithReordering");
+
+	if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx;
+	prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr);	/* The new SN of the frame */
+	prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr));
+	/* prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */
+
+	/* Incorrect STA_REC index */
+	if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) {
+		prSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+		QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb);
+		DBGLOG(QM, WARN, "Reordering for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx);
+		/* ASSERT(0); */
+		return;
+	}
+
+	/* Check whether the STA_REC is activated */
+	prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]);
+	ASSERT(prStaRec);
+
+#if 0
+	if (!(prStaRec->fgIsValid)) {
+		/* TODO: (Tehuang) Handle the Host-FW sync issue. */
+		prSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+		QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb);
+		DBGLOG(QM, WARN, "Reordering for an invalid STA_REC\n");
+		/* ASSERT(0); */
+		return;
+	}
+#endif
+
+	/* Check whether the BA agreement exists */
+	prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]);
+	if (!prReorderQueParm) {
+		/* TODO: (Tehuang) Handle the Host-FW sync issue. */
+		prSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+		QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb);
+		DBGLOG(QM, WARN, "Reordering for a NULL ReorderQueParm\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	/* Start to reorder packets */
+	u4SeqNo = (UINT_32) (prSwRfb->u2SSN);
+	prReorderQue = &(prReorderQueParm->rReOrderQue);
+	u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart);
+	u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd);
+
+	/* Debug */
+	/* DbgPrint("QM:(R)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */
+
+	/* Case 1: Fall within */
+	if			/* 0 - start - sn - end - 4095 */
+	    (((u4WinStart <= u4SeqNo) && (u4SeqNo <= u4WinEnd))
+	     /* 0 - end - start - sn - 4095 */
+	     || ((u4WinEnd < u4WinStart) && (u4WinStart <= u4SeqNo))
+	     /* 0 - sn - end - start - 4095 */
+	     || ((u4SeqNo <= u4WinEnd) && (u4WinEnd < u4WinStart))) {
+
+		qmInsertFallWithinReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue);
+
+#if QM_RX_WIN_SSN_AUTO_ADVANCING
+		if (prReorderQueParm->fgIsWaitingForPktWithSsn) {
+			/* Let the first received packet pass the reorder check */
+			DBGLOG(QM, LOUD, "QM:(A)[%d](%u){%u,%u}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd);
+
+			prReorderQueParm->u2WinStart = (UINT_16) u4SeqNo;
+			prReorderQueParm->u2WinEnd =
+			    ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT;
+			prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE;
+		}
+#endif
+
+		if (qmPopOutDueToFallWithin(prReorderQueParm, prReturnedQue, &fgIsBaTimeout) == FALSE)
+			STATS_RX_REORDER_HOLE_INC(prStaRec);	/* record hole count */
+		STATS_RX_REORDER_HOLE_TIMEOUT_INC(prStaRec, fgIsBaTimeout);
+	}
+	/* Case 2: Fall ahead */
+	else if
+	    /* 0 - start - end - sn - (start+2048) - 4095 */
+	    (((u4WinStart < u4WinEnd)
+	      && (u4WinEnd < u4SeqNo)
+	      && (u4SeqNo < (u4WinStart + HALF_SEQ_NO_COUNT)))
+	     /* 0 - sn - (start+2048) - start - end - 4095 */
+	     || ((u4SeqNo < u4WinStart)
+		 && (u4WinStart < u4WinEnd)
+		 && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT)))
+	     /* 0 - end - sn - (start+2048) - start - 4095 */
+	     || ((u4WinEnd < u4SeqNo)
+		 && (u4SeqNo < u4WinStart)
+		 && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT)))) {
+
+#if QM_RX_WIN_SSN_AUTO_ADVANCING
+		if (prReorderQueParm->fgIsWaitingForPktWithSsn)
+			prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE;
+#endif
+
+		qmInsertFallAheadReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue);
+
+		/* Advance the window after inserting a new tail */
+		prReorderQueParm->u2WinEnd = (UINT_16) u4SeqNo;
+		prReorderQueParm->u2WinStart =
+		    (((prReorderQueParm->u2WinEnd) - (prReorderQueParm->u2WinSize) + MAX_SEQ_NO_COUNT + 1)
+		     % MAX_SEQ_NO_COUNT);
+
+		qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue);
+
+		STATS_RX_REORDER_FALL_AHEAD_INC(prStaRec);
+
+	}
+	/* Case 3: Fall behind */
+	else {
+
+#if QM_RX_WIN_SSN_AUTO_ADVANCING
+#if QM_RX_INIT_FALL_BEHIND_PASS
+		if (prReorderQueParm->fgIsWaitingForPktWithSsn) {
+			/* ?? prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */
+			QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb);
+			/* DbgPrint("QM:(P)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */
+			return;
+		}
+#endif
+#endif
+
+		STATS_RX_REORDER_FALL_BEHIND_INC(prStaRec);
+		/* An erroneous packet */
+		prSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+		QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb);
+		/* DbgPrint("QM:(D)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */
+		return;
+	}
+
+	return;
+
+}
+
+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue)
+{
+
+	P_STA_RECORD_T prStaRec;
+	P_HIF_RX_HEADER_T prHifRxHdr;
+	P_RX_BA_ENTRY_T prReorderQueParm;
+
+	UINT_32 u4SSN;
+	UINT_32 u4WinStart;
+	UINT_32 u4WinEnd;
+	P_QUE_T prReorderQue;
+	/* P_SW_RFB_T prReorderedSwRfb; */
+
+	if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	prHifRxHdr = prSwRfb->prHifRxHdr;
+	prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx;
+	prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr);	/* The new SSN */
+	prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr));
+
+	prSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+	QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb);
+
+	/* Incorrect STA_REC index */
+	if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) {
+		DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx);
+		/* ASSERT(0); */
+		return;
+	}
+
+	/* Check whether the STA_REC is activated */
+	prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]);
+	ASSERT(prStaRec);
+
+#if 0
+	if (!(prStaRec->fgIsValid)) {
+		/* TODO: (Tehuang) Handle the Host-FW sync issue. */
+		DbgPrint("QM: (Warning) BAR for an invalid STA_REC\n");
+		/* ASSERT(0); */
+		return;
+	}
+#endif
+
+	/* Check whether the BA agreement exists */
+	prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]);
+	if (!prReorderQueParm) {
+		/* TODO: (Tehuang) Handle the Host-FW sync issue. */
+		DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL ReorderQueParm\n");
+		/* ASSERT(0); */
+		return;
+	}
+
+	u4SSN = (UINT_32) (prSwRfb->u2SSN);
+	prReorderQue = &(prReorderQueParm->rReOrderQue);
+	u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart);
+	u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd);
+
+	if (qmCompareSnIsLessThan(u4WinStart, u4SSN)) {
+		prReorderQueParm->u2WinStart = (UINT_16) u4SSN;
+		prReorderQueParm->u2WinEnd =
+		    ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT;
+		DBGLOG(QM, TRACE,
+		       "QM:(BAR)[%d](%u){%d,%d}\n", prSwRfb->ucTid, u4SSN, prReorderQueParm->u2WinStart,
+			prReorderQueParm->u2WinEnd);
+		qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue);
+	} else {
+		DBGLOG(QM, TRACE, "QM:(BAR)(%d)(%u){%u,%u}\n", prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd);
+	}
+}
+
+VOID qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue)
+{
+	P_SW_RFB_T prExaminedQueuedSwRfb;
+	P_QUE_T prReorderQue;
+
+	ASSERT(prSwRfb);
+	ASSERT(prReorderQueParm);
+	ASSERT(prReturnedQue);
+
+	prReorderQue = &(prReorderQueParm->rReOrderQue);
+	prExaminedQueuedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue);
+
+	/* There are no packets queued in the Reorder Queue */
+	if (prExaminedQueuedSwRfb == NULL) {
+		((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL;
+		((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL;
+		prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb;
+		prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb;
+		prReorderQue->u4NumElem++;
+	}
+
+	/* Determine the insert position */
+	else {
+		do {
+			/* Case 1: Terminate. A duplicate packet */
+			if (((prExaminedQueuedSwRfb->u2SSN) == (prSwRfb->u2SSN))) {
+				prSwRfb->eDst = RX_PKT_DESTINATION_NULL;
+				QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb);
+				return;
+			}
+
+			/* Case 2: Terminate. The insert point is found */
+			else if (qmCompareSnIsLessThan((prSwRfb->u2SSN), (prExaminedQueuedSwRfb->u2SSN)))
+				break;
+
+			/* Case 3: Insert point not found. Check the next SW_RFB in the Reorder Queue */
+			else
+				prExaminedQueuedSwRfb = (P_SW_RFB_T) (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prNext);
+		} while (prExaminedQueuedSwRfb);
+
+		/* Update the Reorder Queue Parameters according to the found insert position */
+		if (prExaminedQueuedSwRfb == NULL) {
+			/* The received packet shall be placed at the tail */
+			((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail;
+			((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL;
+			(prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb);
+			prReorderQue->prTail = (P_QUE_ENTRY_T) (prSwRfb);
+		} else {
+			((P_QUE_ENTRY_T) prSwRfb)->prPrev = ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev;
+			((P_QUE_ENTRY_T) prSwRfb)->prNext = (P_QUE_ENTRY_T) prExaminedQueuedSwRfb;
+			if (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb) == (prReorderQue->prHead)) {
+				/* The received packet will become the head */
+				prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb;
+			} else {
+				(((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev)->prNext = (P_QUE_ENTRY_T) prSwRfb;
+			}
+			((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev = (P_QUE_ENTRY_T) prSwRfb;
+		}
+
+		prReorderQue->u4NumElem++;
+
+	}
+
+}
+
+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue)
+{
+	P_QUE_T prReorderQue;
+
+	ASSERT(prSwRfb);
+	ASSERT(prReorderQueParm);
+	ASSERT(prReturnedQue);
+
+	prReorderQue = &(prReorderQueParm->rReOrderQue);
+
+	/* There are no packets queued in the Reorder Queue */
+	if (QUEUE_IS_EMPTY(prReorderQue)) {
+		((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL;
+		((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL;
+		prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb;
+	} else {
+		((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail;
+		((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL;
+		(prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb);
+	}
+	prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb;
+	prReorderQue->u4NumElem++;
+
+}
+
+BOOLEAN
+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout)
+{
+	P_SW_RFB_T prReorderedSwRfb;
+	P_QUE_T prReorderQue;
+	BOOLEAN fgDequeuHead, fgMissing;
+	OS_SYSTIME rCurrentTime, *prMissTimeout;
+
+	prReorderQue = &(prReorderQueParm->rReOrderQue);
+
+	*fgIsTimeout = FALSE;
+	fgMissing = FALSE;
+	rCurrentTime = 0;
+	prMissTimeout = &(g_arMissTimeout[prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid]);
+	if ((*prMissTimeout)) {
+		fgMissing = TRUE;
+		GET_CURRENT_SYSTIME(&rCurrentTime);
+	}
+
+	/* Check whether any packet can be indicated to the higher layer */
+	while (TRUE) {
+		if (QUEUE_IS_EMPTY(prReorderQue))
+			break;
+
+		/* Always examine the head packet */
+		prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue);
+		fgDequeuHead = FALSE;
+
+		/* SN == WinStart, so the head packet shall be indicated (advance the window) */
+		if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) {
+
+			fgDequeuHead = TRUE;
+			prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT);
+		}
+		/* SN > WinStart, break to update WinEnd */
+		else {
+			if ((fgMissing == TRUE) &&
+			    CHECK_FOR_TIMEOUT(rCurrentTime, (*prMissTimeout),
+					      MSEC_TO_SYSTIME(QM_RX_BA_ENTRY_MISS_TIMEOUT_MS))) {
+				DBGLOG(QM, TRACE,
+				       "QM:RX BA Timout Next Tid %d SSN %d\n", prReorderQueParm->ucTid,
+					prReorderedSwRfb->u2SSN);
+				fgDequeuHead = TRUE;
+				prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT);
+
+				fgMissing = FALSE;
+				*fgIsTimeout = TRUE;
+			} else
+				break;
+		}
+
+		/* Dequeue the head packet */
+		if (fgDequeuHead) {
+
+			if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) {
+				prReorderQue->prHead = NULL;
+				prReorderQue->prTail = NULL;
+			} else {
+				prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext;
+				(((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL;
+			}
+			prReorderQue->u4NumElem--;
+			/* DbgPrint("QM: [%d] %d (%d)\n",
+				prReorderQueParm->ucTid,
+				prReorderedSwRfb->u2PacketLen,
+				prReorderedSwRfb->u2SSN); */
+			QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb);
+		}
+	}
+
+	if (QUEUE_IS_EMPTY(prReorderQue))
+		*prMissTimeout = 0;
+	else {
+		if (fgMissing == FALSE)
+			GET_CURRENT_SYSTIME(prMissTimeout);
+	}
+
+	/* After WinStart has been determined, update the WinEnd */
+	prReorderQueParm->u2WinEnd =
+	    (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT);
+	return QUEUE_IS_EMPTY(prReorderQue);
+}
+
+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue)
+{
+	P_SW_RFB_T prReorderedSwRfb;
+	P_QUE_T prReorderQue;
+	BOOLEAN fgDequeuHead;
+
+	prReorderQue = &(prReorderQueParm->rReOrderQue);
+
+	/* Check whether any packet can be indicated to the higher layer */
+	while (TRUE) {
+		if (QUEUE_IS_EMPTY(prReorderQue))
+			break;
+
+		/* Always examine the head packet */
+		prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue);
+		fgDequeuHead = FALSE;
+
+		/* SN == WinStart, so the head packet shall be indicated (advance the window) */
+		if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) {
+
+			fgDequeuHead = TRUE;
+			prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT);
+		}
+
+		/* SN < WinStart, so the head packet shall be indicated (do not advance the window) */
+		else if (qmCompareSnIsLessThan((UINT_32) (prReorderedSwRfb->u2SSN),
+					       (UINT_32) (prReorderQueParm->u2WinStart)))
+			fgDequeuHead = TRUE;
+
+		/* SN > WinStart, break to update WinEnd */
+		else
+			break;
+
+		/* Dequeue the head packet */
+		if (fgDequeuHead) {
+
+			if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) {
+				prReorderQue->prHead = NULL;
+				prReorderQue->prTail = NULL;
+			} else {
+				prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext;
+				(((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL;
+			}
+			prReorderQue->u4NumElem--;
+			/* DbgPrint("QM: [%d] %d (%d)\n", */
+			/* prReorderQueParm->ucTid, prReorderedSwRfb->u2PacketLen, prReorderedSwRfb->u2SSN); */
+			QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb);
+		}
+	}
+
+	/* After WinStart has been determined, update the WinEnd */
+	prReorderQueParm->u2WinEnd =
+	    (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT);
+
+}
+
+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater)
+{
+	/* 0 <--->  SnLess   <--(gap>2048)--> SnGreater : SnLess > SnGreater */
+	if ((u4SnLess + HALF_SEQ_NO_COUNT) <= u4SnGreater)	/* Shall be <= */
+		return FALSE;
+
+	/* 0 <---> SnGreater <--(gap>2048)--> SnLess    : SnLess < SnGreater */
+	else if ((u4SnGreater + HALF_SEQ_NO_COUNT) < u4SnLess)
+		return TRUE;
+
+	/* 0 <---> SnGreater <--(gap<2048)--> SnLess    : SnLess > SnGreater */
+	/* 0 <--->  SnLess   <--(gap<2048)--> SnGreater : SnLess < SnGreater */
+	else if (u4SnLess < u4SnGreater)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Handle Mailbox RX messages
+*
+* \param[in] prMailboxRxMsg The received Mailbox message from the FW
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg)
+{
+	/* DbgPrint("QM: Enter qmHandleMailboxRxMessage()\n"); */
+	/* TODO */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Handle ADD RX BA Event from the FW
+*
+* \param[in] prAdapter Adapter pointer
+* \param[in] prEvent The event packet from the FW
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
+{
+	P_EVENT_RX_ADDBA_T prEventRxAddBa;
+	P_STA_RECORD_T prStaRec;
+	UINT_32 u4Tid;
+	UINT_32 u4WinSize;
+
+	DBGLOG(QM, INFO, "QM:Event +RxBa\n");
+
+	prEventRxAddBa = (P_EVENT_RX_ADDBA_T) prEvent;
+	prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxAddBa->ucStaRecIdx);
+
+	if (!prStaRec) {
+		/* Invalid STA_REC index, discard the event packet */
+		/* ASSERT(0); */
+		DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for a NULL STA_REC\n");
+		return;
+	}
+#if 0
+	if (!(prStaRec->fgIsValid)) {
+		/* TODO: (Tehuang) Handle the Host-FW synchronization issue */
+		DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for an invalid STA_REC\n");
+		/* ASSERT(0); */
+		/* return; */
+	}
+#endif
+
+	u4Tid = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_TID_MASK)
+		 >> BA_PARAM_SET_TID_MASK_OFFSET);
+
+	u4WinSize = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_BUFFER_SIZE_MASK)
+		     >> BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET);
+
+	if (!qmAddRxBaEntry(prAdapter,
+			    prStaRec->ucIndex,
+			    (UINT_8) u4Tid,
+			    (prEventRxAddBa->u2BAStartSeqCtrl >> OFFSET_BAR_SSC_SN), (UINT_16) u4WinSize)) {
+
+		/* FW shall ensure the availabiilty of the free-to-use BA entry */
+		DBGLOG(QM, ERROR, "QM: (Error) qmAddRxBaEntry() failure\n");
+		ASSERT(0);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Handle DEL RX BA Event from the FW
+*
+* \param[in] prAdapter Adapter pointer
+* \param[in] prEvent The event packet from the FW
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
+{
+	P_EVENT_RX_DELBA_T prEventRxDelBa;
+	P_STA_RECORD_T prStaRec;
+
+	/* DbgPrint("QM:Event -RxBa\n"); */
+
+	prEventRxDelBa = (P_EVENT_RX_DELBA_T) prEvent;
+	prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxDelBa->ucStaRecIdx);
+
+	if (!prStaRec)
+		/* Invalid STA_REC index, discard the event packet */
+		/* ASSERT(0); */
+		return;
+#if 0
+	if (!(prStaRec->fgIsValid))
+		/* TODO: (Tehuang) Handle the Host-FW synchronization issue */
+		/* ASSERT(0); */
+		return;
+#endif
+
+	qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, prEventRxDelBa->ucTid, TRUE);
+
+}
+
+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, UINT_8 ucStaRecIdx, UINT_8 ucTid)
+{
+	int i;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	/* DbgPrint("QM: Enter qmLookupRxBaEntry()\n"); */
+
+	for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) {
+		if (prQM->arRxBaTable[i].fgIsValid) {
+			if ((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) && (prQM->arRxBaTable[i].ucTid == ucTid))
+				return &prQM->arRxBaTable[i];
+		}
+	}
+	return NULL;
+}
+
+BOOLEAN
+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter,
+	       IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize)
+{
+	int i;
+	P_RX_BA_ENTRY_T prRxBaEntry = NULL;
+	P_STA_RECORD_T prStaRec;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD);
+
+	if (ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) {
+		/* Invalid STA_REC index, discard the event packet */
+		DBGLOG(QM, WARN, "QM: (WARNING) RX ADDBA Event for a invalid ucStaRecIdx = %d\n", ucStaRecIdx);
+		return FALSE;
+	}
+
+	prStaRec = &prAdapter->arStaRec[ucStaRecIdx];
+	ASSERT(prStaRec);
+
+	/* if(!(prStaRec->fgIsValid)){ */
+	/* DbgPrint("QM: (WARNING) Invalid STA when adding an RX BA\n"); */
+	/* return FALSE; */
+	/* } */
+
+	/* 4 <1> Delete before adding */
+	/* Remove the BA entry for the same (STA, TID) tuple if it exists */
+	if (qmLookupRxBaEntry(prAdapter, ucStaRecIdx, ucTid))
+		qmDelRxBaEntry(prAdapter, ucStaRecIdx, ucTid, TRUE);	/* prQM->ucRxBaCount-- */
+	/* 4 <2> Add a new BA entry */
+	/* No available entry to store the BA agreement info. Retrun FALSE. */
+	if (prQM->ucRxBaCount >= CFG_NUM_OF_RX_BA_AGREEMENTS) {
+		DBGLOG(QM, ERROR, "QM: **failure** (limited resource, ucRxBaCount=%d)\n", prQM->ucRxBaCount);
+		return FALSE;
+	}
+	/* Find the free-to-use BA entry */
+	for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) {
+		if (!prQM->arRxBaTable[i].fgIsValid) {
+			prRxBaEntry = &(prQM->arRxBaTable[i]);
+			prQM->ucRxBaCount++;
+			DBGLOG(QM, LOUD, "QM: ucRxBaCount=%d\n", prQM->ucRxBaCount);
+			break;
+		}
+	}
+	/* If a free-to-use entry is found, configure it and associate it with the STA_REC */
+	u2WinSize += CFG_RX_BA_INC_SIZE;
+	if (prRxBaEntry) {
+		prRxBaEntry->ucStaRecIdx = ucStaRecIdx;
+		prRxBaEntry->ucTid = ucTid;
+		prRxBaEntry->u2WinStart = u2WinStart;
+		prRxBaEntry->u2WinSize = u2WinSize;
+		prRxBaEntry->u2WinEnd = ((u2WinStart + u2WinSize - 1) % MAX_SEQ_NO_COUNT);
+		prRxBaEntry->fgIsValid = TRUE;
+		prRxBaEntry->fgIsWaitingForPktWithSsn = TRUE;
+
+		g_arMissTimeout[ucStaRecIdx][ucTid] = 0;
+
+		DBGLOG(QM, INFO, "QM: +RxBA(STA=%d TID=%d WinStart=%d WinEnd=%d WinSize=%d)\n",
+				  ucStaRecIdx, ucTid,
+				  prRxBaEntry->u2WinStart, prRxBaEntry->u2WinEnd, prRxBaEntry->u2WinSize);
+
+		/* Update the BA entry reference table for per-packet lookup */
+		prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry;
+	} else {
+		/* This shall not happen because FW should keep track of the usage of RX BA entries */
+		DBGLOG(QM, ERROR, "QM: **AddBA Error** (ucRxBaCount=%d)\n", prQM->ucRxBaCount);
+		return FALSE;
+	}
+	return TRUE;
+}
+
+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost)
+{
+	P_RX_BA_ENTRY_T prRxBaEntry;
+	P_STA_RECORD_T prStaRec;
+	P_SW_RFB_T prFlushedPacketList = NULL;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD);
+
+	prStaRec = &prAdapter->arStaRec[ucStaRecIdx];
+	ASSERT(prStaRec);
+
+#if 0
+	if (!(prStaRec->fgIsValid)) {
+		DbgPrint("QM: (WARNING) Invalid STA when deleting an RX BA\n");
+		return;
+	}
+#endif
+
+	/* Remove the BA entry for the same (STA, TID) tuple if it exists */
+	prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[ucTid];
+
+	if (prRxBaEntry) {
+
+		prFlushedPacketList = qmFlushStaRxQueue(prAdapter, ucStaRecIdx, ucTid);
+
+		if (prFlushedPacketList) {
+
+			if (fgFlushToHost) {
+				wlanProcessQueuedSwRfb(prAdapter, prFlushedPacketList);
+			} else {
+
+				P_SW_RFB_T prSwRfb;
+				P_SW_RFB_T prNextSwRfb;
+
+				prSwRfb = prFlushedPacketList;
+
+				do {
+					prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb);
+					nicRxReturnRFB(prAdapter, prSwRfb);
+					prSwRfb = prNextSwRfb;
+				} while (prSwRfb);
+
+			}
+
+		}
+#if ((QM_TEST_MODE == 0) && (QM_TEST_STA_REC_DEACTIVATION == 0))
+		/* Update RX BA entry state. Note that RX queue flush is not done here */
+		prRxBaEntry->fgIsValid = FALSE;
+		prQM->ucRxBaCount--;
+
+		/* Debug */
+#if 0
+		DbgPrint("QM: ucRxBaCount=%d\n", prQM->ucRxBaCount);
+#endif
+
+		/* Update STA RX BA table */
+		prStaRec->aprRxReorderParamRefTbl[ucTid] = NULL;
+#endif
+
+		DBGLOG(QM, INFO, "QM: -RxBA(STA=%d,TID=%d)\n", ucStaRecIdx, ucTid);
+
+	}
+
+	/* Debug */
+#if CFG_HIF_RX_STARVATION_WARNING
+	{
+		P_RX_CTRL_T prRxCtrl;
+
+		prRxCtrl = &prAdapter->rRxCtrl;
+		DBGLOG(QM, TRACE,
+		       "QM: (RX DEBUG) Enqueued: %d / Dequeued: %d\n", prRxCtrl->u4QueuedCnt,
+			prRxCtrl->u4DequeuedCnt);
+	}
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To process WMM related IEs in ASSOC_RSP
+*
+* \param[in] prAdapter Adapter pointer
+* \param[in] prSwRfb            The received frame
+* \param[in] pucIE              The pointer to the first IE in the frame
+* \param[in] u2IELength         The total length of IEs in the frame
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2Offset;
+	PUINT_8 pucIEStart;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+	P_IE_WMM_INFO_T prIeWmmInfo;
+	UINT_8 ucQosInfo;
+	UINT_8 ucQosInfoAC;
+	UINT_8 ucBmpAC;
+
+	DEBUGFUNC("mqmProcessAssocReq");
+
+	ASSERT(prSwRfb);
+	ASSERT(pucIE);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+
+	if (prStaRec == NULL)
+		return;
+
+	prStaRec->fgIsQoS = FALSE;
+	prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE;
+
+	pucIEStart = pucIE;
+
+	/* If the device does not support QoS or if WMM is not supported by the peer, exit. */
+	if (!prAdapter->rWifiVar.fgSupportQoS)
+		return;
+
+	/* Determine whether QoS is enabled with the association */
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_WMM:
+
+			if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) &&
+				(!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) {
+				switch (WMM_IE_OUI_SUBTYPE(pucIE)) {
+				case VENDOR_OUI_SUBTYPE_WMM_INFO:
+					if (IE_LEN(pucIE) != 7)
+						break;	/* WMM Info IE with a wrong length */
+					prStaRec->fgIsQoS = TRUE;
+					prStaRec->fgIsWmmSupported = TRUE;
+
+					prIeWmmInfo = (P_IE_WMM_INFO_T) pucIE;
+					ucQosInfo = prIeWmmInfo->ucQosInfo;
+					ucQosInfoAC = ucQosInfo & BITS(0, 3);
+
+					prStaRec->fgIsUapsdSupported = ((ucQosInfoAC) ? TRUE : FALSE) &
+					    prAdapter->rWifiVar.fgSupportUAPSD;
+
+					ucBmpAC = 0;
+
+					if (ucQosInfoAC & WMM_QOS_INFO_VO_UAPSD)
+						ucBmpAC |= BIT(ACI_VO);
+					if (ucQosInfoAC & WMM_QOS_INFO_VI_UAPSD)
+						ucBmpAC |= BIT(ACI_VI);
+					if (ucQosInfoAC & WMM_QOS_INFO_BE_UAPSD)
+						ucBmpAC |= BIT(ACI_BE);
+					if (ucQosInfoAC & WMM_QOS_INFO_BK_UAPSD)
+						ucBmpAC |= BIT(ACI_BK);
+
+					prStaRec->ucBmpTriggerAC = prStaRec->ucBmpDeliveryAC = ucBmpAC;
+
+					prStaRec->ucUapsdSp =
+					    (ucQosInfo & WMM_QOS_INFO_MAX_SP_LEN_MASK) >> 5;
+					break;
+				default:
+					/* Other WMM QoS IEs. Ignore any */
+					break;
+				}
+			}
+			/* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */
+
+			break;
+
+		case ELEM_ID_HT_CAP:
+			/* Some client won't put the WMM IE if client is 802.11n */
+			if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2))
+				prStaRec->fgIsQoS = TRUE;
+			break;
+		default:
+			break;
+		}
+	}
+
+	DBGLOG(QM, TRACE, "MQM: Assoc_Req Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To process WMM related IEs in ASSOC_RSP
+*
+* \param[in] prAdapter Adapter pointer
+* \param[in] prSwRfb            The received frame
+* \param[in] pucIE              The pointer to the first IE in the frame
+* \param[in] u2IELength         The total length of IEs in the frame
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2Offset;
+	PUINT_8 pucIEStart;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+
+	DEBUGFUNC("mqmProcessAssocRsp");
+
+	ASSERT(prSwRfb);
+	ASSERT(pucIE);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+
+	if (prStaRec == NULL)
+		return;
+
+	prStaRec->fgIsQoS = FALSE;
+
+	pucIEStart = pucIE;
+
+	DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgSupportQoS=%d)\n",
+			   prStaRec->fgIsWmmSupported, prAdapter->rWifiVar.fgSupportQoS);
+
+	/* If the device does not support QoS or if WMM is not supported by the peer, exit. */
+	/* if((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported)) */
+	if ((!prAdapter->rWifiVar.fgSupportQoS))
+		return;
+
+	/* Determine whether QoS is enabled with the association */
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_WMM:
+			if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) &&
+			    (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) {
+
+				switch (WMM_IE_OUI_SUBTYPE(pucIE)) {
+				case VENDOR_OUI_SUBTYPE_WMM_PARAM:
+					if (IE_LEN(pucIE) != 24)
+						break;	/* WMM Info IE with a wrong length */
+					prStaRec->fgIsQoS = TRUE;
+					break;
+
+				case VENDOR_OUI_SUBTYPE_WMM_INFO:
+					if (IE_LEN(pucIE) != 7)
+						break;	/* WMM Info IE with a wrong length */
+					prStaRec->fgIsQoS = TRUE;
+					break;
+
+				default:
+					/* Other WMM QoS IEs. Ignore any */
+					break;
+				}
+			}
+			/* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */
+			break;
+
+		case ELEM_ID_HT_CAP:
+			/* Some AP won't put the WMM IE if client is 802.11n */
+			if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2))
+				prStaRec->fgIsQoS = TRUE;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Parse AC parameters and write to HW CRs */
+	if ((prStaRec->fgIsQoS) && (prStaRec->eStaType == STA_TYPE_LEGACY_AP)) {
+		mqmParseEdcaParameters(prAdapter, prSwRfb, pucIEStart, u2IELength, TRUE);
+#if ARP_MONITER_ENABLE
+		qmResetArpDetect();
+#endif
+	}
+
+	DBGLOG(QM, TRACE, "MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS);
+	if (prStaRec->fgIsWmmSupported)
+		nicQmUpdateWmmParms(prAdapter, prStaRec->ucNetTypeIndex);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To parse WMM Parameter IE (in BCN or Assoc_Rsp)
+*
+* \param[in] prAdapter          Adapter pointer
+* \param[in] prSwRfb            The received frame
+* \param[in] pucIE              The pointer to the first IE in the frame
+* \param[in] u2IELength         The total length of IEs in the frame
+* \param[in] fgForceOverride    TRUE: If EDCA parameters are found, always set to HW CRs.
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter,
+		       IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride)
+{
+	P_STA_RECORD_T prStaRec;
+	UINT_16 u2Offset;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+	P_BSS_INFO_T prBssInfo;
+	P_AC_QUE_PARMS_T prAcQueParams;
+	P_IE_WMM_PARAM_T prIeWmmParam;
+	ENUM_WMM_ACI_T eAci;
+	PUINT_8 pucWmmParamSetCount;
+
+	DEBUGFUNC("mqmParseEdcaParameters");
+
+	ASSERT(prSwRfb);
+	ASSERT(pucIE);
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+	ASSERT(prStaRec);
+	if (prStaRec == NULL)
+		return;
+
+	DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgIsQoS=%d)\n", prStaRec->fgIsWmmSupported, prStaRec->fgIsQoS);
+
+	if ((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported) || (!prStaRec->fgIsQoS))
+		return;
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	/* Goal: Obtain the EDCA parameters */
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_WMM:
+			if ((WMM_IE_OUI_TYPE(pucIE) != VENDOR_OUI_TYPE_WMM) ||
+				(kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3)))
+				break;
+
+			switch (WMM_IE_OUI_SUBTYPE(pucIE)) {
+			case VENDOR_OUI_SUBTYPE_WMM_PARAM:
+				if (IE_LEN(pucIE) != 24)
+					break;	/* WMM Param IE with a wrong length */
+
+				pucWmmParamSetCount = &(prBssInfo->ucWmmParamSetCount);
+				prIeWmmParam = (P_IE_WMM_PARAM_T) pucIE;
+
+				/* Check the Parameter Set Count to determine whether EDCA parameters */
+				/* have been changed */
+				if (!fgForceOverride && (*pucWmmParamSetCount
+					== (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT)))
+					break;	/* Ignore the IE without updating HW CRs */
+
+				/* Update Parameter Set Count */
+				*pucWmmParamSetCount =
+				    (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT);
+
+				/* Update EDCA parameters */
+				for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {
+
+					prAcQueParams = &prBssInfo->arACQueParms[eAci];
+					mqmFillAcQueParam(prIeWmmParam, eAci, prAcQueParams);
+
+					prAcQueParams->fgIsACMSet =
+					    (prAcQueParams->u2Aifsn & WMM_ACIAIFSN_ACM) ? TRUE : FALSE;
+					prAcQueParams->u2Aifsn &= WMM_ACIAIFSN_AIFSN;
+
+					DBGLOG(QM, LOUD,
+					"eAci:%d, ACM:%d, Aifsn:%d, CWmin:%d, CWmax:%d, TxopLmt:%d\n",
+					eAci, prAcQueParams->fgIsACMSet, prAcQueParams->u2Aifsn,
+					prAcQueParams->u2CWmin, prAcQueParams->u2CWmax,
+					prAcQueParams->u2TxopLimit);
+				}
+				break;
+			default:
+				/* Other WMM QoS IEs. Ignore */
+				break;
+			}
+
+			/* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is used for parsing EDCA parameters specified in the WMM Parameter IE
+*
+* \param[in] prAdapter           Adapter pointer
+* \param[in] prIeWmmParam        The pointer to the WMM Parameter IE
+* \param[in] u4AcOffset          The offset specifying the AC queue for parsing
+* \param[in] prHwAcParams        The parameter structure used to configure the HW CRs
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams)
+{
+	prAcQueParams->u2Aifsn = *((PUINT_8) (&(prIeWmmParam->ucAciAifsn_BE)) + (u4AcOffset * 4));
+
+	prAcQueParams->u2CWmax = BIT(((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMAX_MASK)
+				     >> WMM_ECW_WMAX_OFFSET) - 1;
+
+	prAcQueParams->u2CWmin =
+	    BIT((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMIN_MASK) - 1;
+
+	WLAN_GET_FIELD_16(((PUINT_8) (&(prIeWmmParam->aucTxopLimit_BE)) + (u4AcOffset * 4)),
+			  &(prAcQueParams->u2TxopLimit));
+
+	prAcQueParams->ucGuradTime = TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To parse WMM/11n related IEs in scan results (only for AP peers)
+*
+* \param[in] prAdapter       Adapter pointer
+* \param[in]  prScanResult   The scan result which shall be parsed to obtain needed info
+* \param[out] prStaRec       The obtained info is stored in the STA_REC
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+#if (CFG_SUPPORT_TDLS == 1)	/* for test purpose */
+BOOLEAN flgTdlsTestExtCapElm = FALSE;
+UINT8 aucTdlsTestExtCapElm[7];
+#endif /* CFG_SUPPORT_TDLS */
+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec)
+{
+	PUINT_8 pucIE;
+	UINT_16 u2IELength;
+	UINT_16 u2Offset;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+
+	DEBUGFUNC("mqmProcessScanResult");
+
+	ASSERT(prScanResult);
+	ASSERT(prStaRec);
+
+	/* Reset the flag before parsing */
+	prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE;
+
+	if (!prAdapter->rWifiVar.fgSupportQoS)
+		return;
+
+	u2IELength = prScanResult->u2IELength;
+	pucIE = prScanResult->aucIEBuf;
+
+#if (CFG_SUPPORT_TDLS == 1)
+	/* TDLS test purpose */
+	if (flgTdlsTestExtCapElm == TRUE)
+		TdlsexBssExtCapParse(prStaRec, aucTdlsTestExtCapElm);
+#endif /* CFG_SUPPORT_TDLS */
+
+	/* Goal: Determine whether the peer supports WMM/QoS and UAPSDU */
+	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
+		switch (IE_ID(pucIE)) {
+		case ELEM_ID_EXTENDED_CAP:
+#if (CFG_SUPPORT_TDLS == 1)
+			TdlsexBssExtCapParse(prStaRec, pucIE);
+#endif /* CFG_SUPPORT_TDLS */
+			break;
+
+		case ELEM_ID_WMM:
+			if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) &&
+			    (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) {
+
+				switch (WMM_IE_OUI_SUBTYPE(pucIE)) {
+				case VENDOR_OUI_SUBTYPE_WMM_PARAM:
+					if (IE_LEN(pucIE) != 24)
+						break;	/* WMM Param IE with a wrong length */
+
+					prStaRec->fgIsWmmSupported = TRUE;
+					prStaRec->fgIsUapsdSupported =
+					    (((((P_IE_WMM_PARAM_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ?
+					     TRUE : FALSE);
+					break;
+
+				case VENDOR_OUI_SUBTYPE_WMM_INFO:
+					if (IE_LEN(pucIE) != 7)
+						break;	/* WMM Info IE with a wrong length */
+
+					prStaRec->fgIsWmmSupported = TRUE;
+					prStaRec->fgIsUapsdSupported =
+					    (((((P_IE_WMM_INFO_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ?
+					     TRUE : FALSE);
+					break;
+
+				default:
+					/* A WMM QoS IE that doesn't matter. Ignore it. */
+					break;
+				}
+			}
+			/* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */
+
+			break;
+
+		default:
+			/* A WMM IE that doesn't matter. Ignore it. */
+			break;
+		}
+	}
+	DBGLOG(QM, LOUD, "MQM: Scan Result Parsing (WMM=%d, UAPSD=%d)\n",
+			  prStaRec->fgIsWmmSupported, prStaRec->fgIsUapsdSupported);
+
+}
+
+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType)
+{
+	UINT_32 i;
+	P_STA_RECORD_T prTempStaRec;
+
+	prTempStaRec = NULL;
+
+	ASSERT(prAdapter);
+
+	/* 4 <1> DA = BMCAST */
+	if (IS_BMCAST_MAC_ADDR(pucEthDestAddr))
+		return STA_REC_INDEX_BMCAST;
+	/* 4 <2> Check if an AP STA is present */
+	for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) {
+		prTempStaRec = &(prAdapter->arStaRec[i]);
+		if ((prTempStaRec->ucNetTypeIndex == eNetworkType)
+		    && (prTempStaRec->fgIsAp)
+		    && (prTempStaRec->fgIsValid)) {
+			return prTempStaRec->ucIndex;
+		}
+	}
+
+	/* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */
+	for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) {
+		prTempStaRec = &(prAdapter->arStaRec[i]);
+		if (prTempStaRec->fgIsValid) {
+			if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, pucEthDestAddr))
+				return prTempStaRec->ucIndex;
+		}
+	}
+
+	/* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */
+	return STA_REC_INDEX_NOT_FOUND;
+}
+
+UINT_32
+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD,
+			    UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf)
+{
+	P_IE_WMM_INFO_T prIeWmmInfo;
+	UINT_32 ucUapsd[] = {
+		WMM_QOS_INFO_BE_UAPSD,
+		WMM_QOS_INFO_BK_UAPSD,
+		WMM_QOS_INFO_VI_UAPSD,
+		WMM_QOS_INFO_VO_UAPSD
+	};
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+
+	ASSERT(pOutBuf);
+
+	prIeWmmInfo = (P_IE_WMM_INFO_T) pOutBuf;
+
+	prIeWmmInfo->ucId = ELEM_ID_WMM;
+	prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO;
+
+	/* WMM-2.2.1 WMM Information Element Field Values */
+	prIeWmmInfo->aucOui[0] = aucWfaOui[0];
+	prIeWmmInfo->aucOui[1] = aucWfaOui[1];
+	prIeWmmInfo->aucOui[2] = aucWfaOui[2];
+	prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM;
+	prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO;
+
+	prIeWmmInfo->ucVersion = VERSION_WMM;
+	prIeWmmInfo->ucQosInfo = 0;
+
+	/* UAPSD initial queue configurations (delivery and trigger enabled) */
+	if (fgSupportUAPSD) {
+
+		UINT_8 ucQosInfo = 0;
+		UINT_8 i;
+
+		/* Static U-APSD setting */
+		for (i = ACI_BE; i <= ACI_VO; i++) {
+			if (ucBmpDeliveryAC & ucBmpTriggerAC & BIT(i))
+				ucQosInfo |= (UINT_8) ucUapsd[i];
+		}
+
+		if (ucBmpDeliveryAC & ucBmpTriggerAC) {
+			switch (ucUapsdSp) {
+			case WMM_MAX_SP_LENGTH_ALL:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL;
+				break;
+
+			case WMM_MAX_SP_LENGTH_2:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_2;
+				break;
+
+			case WMM_MAX_SP_LENGTH_4:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_4;
+				break;
+
+			case WMM_MAX_SP_LENGTH_6:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_6;
+				break;
+
+			default:
+				DBGLOG(QM, WARN, "MQM: Incorrect SP length\n");
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_2;
+				break;
+			}
+		}
+		prIeWmmInfo->ucQosInfo = ucQosInfo;
+
+	}
+
+	/* Increment the total IE length for the Element ID and Length fields. */
+	return IE_SIZE(prIeWmmInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Generate the WMM Info IE
+*
+* \param[in] prAdapter  Adapter pointer
+* @param prMsduInfo The TX MMPDU
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_IE_WMM_INFO_T prIeWmmInfo;
+	P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo;
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("mqmGenerateWmmInfoIE");
+
+	ASSERT(prMsduInfo);
+
+	/* In case QoS is not turned off, exit directly */
+	if (!prAdapter->rWifiVar.fgSupportQoS)
+		return;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	ASSERT(prStaRec);
+
+	if (prStaRec == NULL)
+		return;
+
+	if (!prStaRec->fgIsWmmSupported)
+		return;
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
+
+	prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
+
+	prIeWmmInfo = (P_IE_WMM_INFO_T)
+	    ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength);
+
+#if 0
+	prIeWmmInfo->ucId = ELEM_ID_WMM;
+	prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO;
+
+	/* WMM-2.2.1 WMM Information Element Field Values */
+	prIeWmmInfo->aucOui[0] = aucWfaOui[0];
+	prIeWmmInfo->aucOui[1] = aucWfaOui[1];
+	prIeWmmInfo->aucOui[2] = aucWfaOui[2];
+	prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM;
+	prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO;
+
+	prIeWmmInfo->ucVersion = VERSION_WMM;
+	prIeWmmInfo->ucQosInfo = 0;
+
+	/* UAPSD initial queue configurations (delivery and trigger enabled) */
+/* if(prAdapter->rWifiVar.fgSupportUAPSD){ */
+	if (prAdapter->rWifiVar.fgSupportUAPSD && prStaRec->fgIsUapsdSupported) {
+
+		UINT_8 ucQosInfo = 0;
+		UINT_8 i;
+
+		/* Static U-APSD setting */
+		for (i = ACI_BE; i <= ACI_VO; i++) {
+			if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC & BIT(i))
+				ucQosInfo |= (UINT_8) ucUapsd[i];
+		}
+
+		if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC) {
+			switch (prPmProfSetupInfo->ucUapsdSp) {
+			case WMM_MAX_SP_LENGTH_ALL:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL;
+				break;
+
+			case WMM_MAX_SP_LENGTH_2:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_2;
+				break;
+
+			case WMM_MAX_SP_LENGTH_4:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_4;
+				break;
+
+			case WMM_MAX_SP_LENGTH_6:
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_6;
+				break;
+
+			default:
+				DBGLOG(QM, INFO, "MQM: Incorrect SP length\n");
+				ucQosInfo |= WMM_QOS_INFO_MAX_SP_2;
+				break;
+			}
+		}
+		prIeWmmInfo->ucQosInfo = ucQosInfo;
+
+	}
+
+	/* Increment the total IE length for the Element ID and Length fields. */
+	prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmInfo);
+#else
+
+	prMsduInfo->u2FrameLength += mqmGenerateWmmInfoIEByParam((prAdapter->rWifiVar.fgSupportUAPSD
+								  && prStaRec->fgIsUapsdSupported),
+								 prPmProfSetupInfo->ucBmpDeliveryAC,
+								 prPmProfSetupInfo->ucBmpTriggerAC,
+								 prPmProfSetupInfo->ucUapsdSp, (UINT_8 *) prIeWmmInfo);
+#endif
+}
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief log2 calculation for CW
+*
+* @param[in] val value
+*
+* @return log2(val)
+*/
+/*----------------------------------------------------------------------------*/
+
+UINT_32 cwlog2(UINT_32 val)
+{
+
+	UINT_32 n;
+
+	n = 0;
+
+	while (val >= 512) {
+		n += 9;
+		val = val >> 9;
+	}
+	while (val >= 16) {
+		n += 4;
+		val >>= 4;
+	}
+	while (val >= 2) {
+		n += 1;
+		val >>= 1;
+	}
+	return n;
+}
+#endif
+
+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter,
+			P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode)
+{
+	P_IE_WMM_PARAM_T prIeWmmParam;
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+	UINT_8 aucACI[] = {
+		WMM_ACI_AC_BE,
+		WMM_ACI_AC_BK,
+		WMM_ACI_AC_VI,
+		WMM_ACI_AC_VO
+	};
+	ENUM_WMM_ACI_T eAci;
+	UCHAR *pucAciAifsn, *pucEcw, *pucTxopLimit;
+
+	ASSERT(pOutBuf);
+
+	prIeWmmParam = (P_IE_WMM_PARAM_T) pOutBuf;
+
+	prIeWmmParam->ucId = ELEM_ID_WMM;
+	prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM;
+
+	/* WMM-2.2.1 WMM Information Element Field Values */
+	prIeWmmParam->aucOui[0] = aucWfaOui[0];
+	prIeWmmParam->aucOui[1] = aucWfaOui[1];
+	prIeWmmParam->aucOui[2] = aucWfaOui[2];
+	prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM;
+	prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM;
+
+	prIeWmmParam->ucVersion = VERSION_WMM;
+	prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT);
+
+	/* UAPSD initial queue configurations (delivery and trigger enabled) */
+	if (prAdapter->rWifiVar.fgSupportUAPSD) {
+		if (ucOpMode == OP_MODE_INFRASTRUCTURE)
+			prIeWmmParam->ucQosInfo = 0xf;
+		else
+			prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD;
+	}
+
+	/* EDCA parameter */
+
+	for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {
+
+		/* DBGLOG(QM, LOUD, */
+		/* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */
+		/* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */
+
+#if 0
+		*(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci]
+											|
+											(prBssInfo->arACQueParmsForBcast
+											 [eAci].fgIsACMSet ?
+											 WMM_ACIAIFSN_ACM : 0)
+											|
+											(prBssInfo->arACQueParmsForBcast
+											 [eAci].u2Aifsn &
+											 (WMM_ACIAIFSN_AIFSN)));
+#else
+		/* avoid compile warnings in Klockwork tool */
+		if (eAci == WMM_AC_BE_INDEX) {
+			pucAciAifsn = &prIeWmmParam->ucAciAifsn_BE;
+			pucEcw = &prIeWmmParam->ucEcw_BE;
+			pucTxopLimit = prIeWmmParam->aucTxopLimit_BE;
+		} else if (eAci == WMM_AC_BK_INDEX) {
+			pucAciAifsn = &prIeWmmParam->ucAciAifsn_BG;
+			pucEcw = &prIeWmmParam->ucEcw_BG;
+			pucTxopLimit = prIeWmmParam->aucTxopLimit_BG;
+		} else if (eAci == WMM_AC_VI_INDEX) {
+			pucAciAifsn = &prIeWmmParam->ucAciAifsn_VI;
+			pucEcw = &prIeWmmParam->ucEcw_VI;
+			pucTxopLimit = prIeWmmParam->aucTxopLimit_VI;
+		} else if (eAci == WMM_AC_VO_INDEX) {
+			pucAciAifsn = &prIeWmmParam->ucAciAifsn_VO;
+			pucEcw = &prIeWmmParam->ucEcw_VO;
+			pucTxopLimit = prIeWmmParam->aucTxopLimit_VO;
+		}
+
+		*pucAciAifsn = (UINT_8) (aucACI[eAci]
+					 | (prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet ? WMM_ACIAIFSN_ACM : 0)
+					 | (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & (WMM_ACIAIFSN_AIFSN)));
+#endif
+
+#if 1
+/* *( ((PUINT_8)(&prIeWmmParam->ucEcw_BE)) + (eAci <<2) ) = (UINT_8) (0 */
+		*pucEcw = (UINT_8) (0 | (((prBssInfo->aucCWminLog2ForBcast[eAci])) & WMM_ECW_WMIN_MASK)
+				    | ((((prBssInfo->aucCWmaxLog2ForBcast[eAci])) << WMM_ECW_WMAX_OFFSET) &
+				       WMM_ECW_WMAX_MASK)
+		    );
+#else
+		*(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0
+										   |
+										   (cwlog2
+										    ((prBssInfo->arACQueParmsForBcast
+										      [eAci].u2CWmin +
+										      1)) & WMM_ECW_WMIN_MASK)
+										   |
+										   ((cwlog2
+										     ((prBssInfo->arACQueParmsForBcast
+										       [eAci].u2CWmax +
+										       1)) << WMM_ECW_WMAX_OFFSET) &
+										    WMM_ECW_WMAX_MASK)
+		    );
+#endif
+
+#if 0
+		WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2)
+				  , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit);
+#else
+		WLAN_SET_FIELD_16(pucTxopLimit, prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit);
+#endif
+	}
+
+	/* Increment the total IE length for the Element ID and Length fields. */
+	return IE_SIZE(prIeWmmParam);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Generate the WMM Param IE
+*
+* \param[in] prAdapter  Adapter pointer
+* @param prMsduInfo The TX MMPDU
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	P_IE_WMM_PARAM_T prIeWmmParam;
+
+#if 0
+	UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
+
+	UINT_8 aucACI[] = {
+		WMM_ACI_AC_BE,
+		WMM_ACI_AC_BK,
+		WMM_ACI_AC_VI,
+		WMM_ACI_AC_VO
+	};
+	ENUM_WMM_ACI_T eAci;
+#endif
+
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+
+	DEBUGFUNC("mqmGenerateWmmParamIE");
+	DBGLOG(QM, LOUD, "\n");
+
+	ASSERT(prMsduInfo);
+
+	/* In case QoS is not turned off, exit directly */
+	if (!prAdapter->rWifiVar.fgSupportQoS)
+		return;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+	if (prStaRec) {
+		if (!prStaRec->fgIsQoS)
+			return;
+	}
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]);
+
+	if (!prBssInfo->fgIsQBSS)
+		return;
+/* 20120220 frog: update beacon content & change OP mode is a separate event for P2P network. */
+#if 0
+	if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT && prBssInfo->eCurrentOPMode != OP_MODE_BOW)
+		return;
+#endif
+
+	prIeWmmParam = (P_IE_WMM_PARAM_T)
+	    ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength);
+
+#if 0
+	prIeWmmParam->ucId = ELEM_ID_WMM;
+	prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM;
+
+	/* WMM-2.2.1 WMM Information Element Field Values */
+	prIeWmmParam->aucOui[0] = aucWfaOui[0];
+	prIeWmmParam->aucOui[1] = aucWfaOui[1];
+	prIeWmmParam->aucOui[2] = aucWfaOui[2];
+	prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM;
+	prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM;
+
+	prIeWmmParam->ucVersion = VERSION_WMM;
+	prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT);
+
+	/* UAPSD initial queue configurations (delivery and trigger enabled) */
+	if (prAdapter->rWifiVar.fgSupportUAPSD)
+		prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD;
+
+	/* EDCA parameter */
+
+	for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {
+
+		/* DBGLOG(QM, LOUD, */
+		/* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */
+		/* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */
+		/* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */
+
+		*(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci]
+											|
+											(prBssInfo->arACQueParmsForBcast
+											 [eAci].fgIsACMSet ?
+											 WMM_ACIAIFSN_ACM : 0)
+											|
+											(prBssInfo->arACQueParmsForBcast
+											 [eAci].u2Aifsn &
+											 (WMM_ACIAIFSN_AIFSN)));
+#if 1
+		*(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0
+										   |
+										   (((prBssInfo->aucCWminLog2ForBcast
+										      [eAci])) & WMM_ECW_WMIN_MASK)
+										   |
+										   ((((prBssInfo->aucCWmaxLog2ForBcast
+										       [eAci])) << WMM_ECW_WMAX_OFFSET)
+										    & WMM_ECW_WMAX_MASK)
+		    );
+#else
+		*(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0
+										   |
+										   (cwlog2
+										    ((prBssInfo->arACQueParmsForBcast
+										      [eAci].u2CWmin +
+										      1)) & WMM_ECW_WMIN_MASK)
+										   |
+										   ((cwlog2
+										     ((prBssInfo->arACQueParmsForBcast
+										       [eAci].u2CWmax +
+										       1)) << WMM_ECW_WMAX_OFFSET) &
+										    WMM_ECW_WMAX_MASK)
+		    );
+#endif
+
+		WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2)
+				  , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit);
+
+	}
+
+	/* Increment the total IE length for the Element ID and Length fields. */
+	prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmParam);
+#else
+
+	prMsduInfo->u2FrameLength += mqmGenerateWmmParamIEByParam(prAdapter,
+				prBssInfo, (UINT_8 *) prIeWmmParam, OP_MODE_ACCESS_POINT);
+#endif
+}
+
+ENUM_FRAME_ACTION_T
+qmGetFrameAction(IN P_ADAPTER_T prAdapter,
+		 IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType,
+		 IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType)
+{
+	P_BSS_INFO_T prBssInfo;
+	P_STA_RECORD_T prStaRec;
+	P_WLAN_MAC_HEADER_T prWlanFrame;
+	UINT_16 u2TxFrameCtrl;
+
+	DEBUGFUNC("qmGetFrameAction");
+
+#if (NIC_TX_BUFF_COUNT_TC4 > 2)
+#define QM_MGMT_QUUEUD_THRESHOLD 2
+#else
+#define QM_MGMT_QUUEUD_THRESHOLD 1
+#endif
+
+	DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD <= (NIC_TX_BUFF_COUNT_TC4));
+	DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD > 0);
+
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkType]);
+	prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx);
+
+	/* XXX Check BOW P2P AIS time ot set active */
+	if (!IS_BSS_ACTIVE(prBssInfo)) {
+		if (eFrameType == FRAME_TYPE_MMPDU) {
+			prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket;
+			u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE;	/* Optimized for ARM */
+			if (((u2TxFrameCtrl == MAC_FRAME_DEAUTH)
+				&& (prMsduInfo->pfTxDoneHandler == NULL))
+				|| (u2TxFrameCtrl == MAC_FRAME_ACTION))		/* whsu */
+				return FRAME_ACTION_TX_PKT;
+		}
+
+		DBGLOG(QM, WARN, "Drop packets Action, eFrameType: %d (Bss Index %u).\n",
+				eFrameType, prBssInfo->ucNetTypeIndex);
+		TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP);
+		return FRAME_ACTION_DROP_PKT;
+	}
+
+	/* TODO Handle disconnect issue */
+
+	/* P2P probe Request frame */
+	do {
+		if (eFrameType == FRAME_TYPE_MMPDU) {
+			prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket;
+			u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE;	/* Optimized for ARM */
+
+			if (u2TxFrameCtrl == MAC_FRAME_BEACON) {
+				if (prBssInfo->fgIsNetAbsent)
+					return FRAME_ACTION_DROP_PKT;
+			} else if (u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) {
+				if (prBssInfo->fgIsNetAbsent)
+					return FRAME_ACTION_DROP_PKT;
+			} else if (u2TxFrameCtrl == MAC_FRAME_DEAUTH) {
+				if (prBssInfo->fgIsNetAbsent)
+					break;
+				DBGLOG(P2P, LOUD, "Sending DEAUTH Frame\n");
+				return FRAME_ACTION_TX_PKT;
+			}
+			/* MMPDU with prStaRec && fgIsInUse not check fgIsNetActive */
+			else if (u2TxFrameCtrl == MAC_FRAME_ASSOC_REQ
+				 || u2TxFrameCtrl == MAC_FRAME_AUTH
+				 || u2TxFrameCtrl == MAC_FRAME_REASSOC_REQ
+				 || u2TxFrameCtrl == MAC_FRAME_PROBE_REQ || u2TxFrameCtrl == MAC_FRAME_ACTION) {
+
+				if ((prStaRec) && (prStaRec->fgIsInPS)) {
+					if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD)
+						return FRAME_ACTION_TX_PKT;
+					else
+						return FRAME_ACTION_QUEUE_PKT;
+				}
+				return FRAME_ACTION_TX_PKT;
+			}
+
+			if (!prStaRec)
+				return FRAME_ACTION_TX_PKT;
+
+			if (!prStaRec->fgIsInUse)
+				return FRAME_ACTION_DROP_PKT;
+
+		} /* FRAME_TYPE_MMPDU */
+		else if (eFrameType == FRAME_TYPE_802_1X) {
+
+			if (!prStaRec)
+				return FRAME_ACTION_TX_PKT;
+
+			if (!prStaRec->fgIsInUse)
+				return FRAME_ACTION_DROP_PKT;
+			if (prStaRec->fgIsInPS) {
+				if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD)
+					return FRAME_ACTION_TX_PKT;
+				else
+					return FRAME_ACTION_QUEUE_PKT;
+			}
+
+		} /* FRAME_TYPE_802_1X */
+		else if ((!IS_BSS_ACTIVE(prBssInfo))
+			 || (!prStaRec)
+			 || (!prStaRec->fgIsInUse)) {
+			return FRAME_ACTION_DROP_PKT;
+		}
+	} while (0);
+
+	if (prBssInfo->fgIsNetAbsent) {
+		DBGLOG(QM, LOUD, "Queue packets (Absent %u).\n", prBssInfo->ucNetTypeIndex);
+		return FRAME_ACTION_QUEUE_PKT;
+	}
+
+	if (prStaRec && prStaRec->fgIsInPS) {
+		DBGLOG(QM, LOUD, "Queue packets (PS %u).\n", prStaRec->fgIsInPS);
+		return FRAME_ACTION_QUEUE_PKT;
+	}
+	switch (eFrameType) {
+	case FRAME_TYPE_802_1X:
+		if (!prStaRec->fgIsValid)
+			return FRAME_ACTION_QUEUE_PKT;
+		break;
+
+	case FRAME_TYPE_MMPDU:
+		break;
+
+	default:
+		ASSERT(0);
+	}
+
+	return FRAME_ACTION_TX_PKT;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Handle BSS change operation Event from the FW
+*
+* \param[in] prAdapter Adapter pointer
+* \param[in] prEvent The event packet from the FW
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
+{
+	P_EVENT_BSS_ABSENCE_PRESENCE_T prEventBssStatus;
+	P_BSS_INFO_T prBssInfo;
+	BOOLEAN fgIsNetAbsentOld;
+
+	prEventBssStatus = (P_EVENT_BSS_ABSENCE_PRESENCE_T) prEvent;
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prEventBssStatus->ucNetTypeIdx]);
+	fgIsNetAbsentOld = prBssInfo->fgIsNetAbsent;
+	prBssInfo->fgIsNetAbsent = prEventBssStatus->fgIsAbsent;
+	prBssInfo->ucBssFreeQuota = prEventBssStatus->ucBssFreeQuota;
+
+	/* DBGLOG(QM, TRACE, ("qmHandleEventBssAbsencePresence (ucNetTypeIdx=%d, fgIsAbsent=%d, FreeQuota=%d)\n", */
+	/* prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota)); */
+
+	DBGLOG(QM, INFO, "NAF=%d,%d,%d\n",
+			   prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota);
+
+	if (!prBssInfo->fgIsNetAbsent) {
+		/* QM_DBG_CNT_27 */
+		QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_27);
+	} else {
+		/* QM_DBG_CNT_28 */
+		QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_28);
+	}
+	/* From Absent to Present */
+	if ((fgIsNetAbsentOld) && (!prBssInfo->fgIsNetAbsent))
+		kalSetEvent(prAdapter->prGlueInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Handle STA change PS mode Event from the FW
+*
+* \param[in] prAdapter Adapter pointer
+* \param[in] prEvent The event packet from the FW
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
+{
+	P_EVENT_STA_CHANGE_PS_MODE_T prEventStaChangePsMode;
+	P_STA_RECORD_T prStaRec;
+	BOOLEAN fgIsInPSOld;
+
+	/* DbgPrint("QM:Event -RxBa\n"); */
+
+	prEventStaChangePsMode = (P_EVENT_STA_CHANGE_PS_MODE_T) prEvent;
+	prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaChangePsMode->ucStaRecIdx);
+	ASSERT(prStaRec);
+
+	if (prStaRec) {
+
+		fgIsInPSOld = prStaRec->fgIsInPS;
+		prStaRec->fgIsInPS = prEventStaChangePsMode->fgIsInPs;
+
+		qmUpdateFreeQuota(prAdapter,
+				  prStaRec,
+				  prEventStaChangePsMode->ucUpdateMode, prEventStaChangePsMode->ucFreeQuota, 0);
+
+		/* DBGLOG(QM, TRACE, ("qmHandleEventStaChangePsMode (ucStaRecIdx=%d, fgIsInPs=%d)\n", */
+		/* prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS)); */
+
+		DBGLOG(QM, TRACE, "PS=%d,%d\n", prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS);
+
+		/* From PS to Awake */
+		if ((fgIsInPSOld) && (!prStaRec->fgIsInPS))
+			kalSetEvent(prAdapter->prGlueInfo);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Update STA free quota Event from FW
+*
+* \param[in] prAdapter Adapter pointer
+* \param[in] prEvent The event packet from the FW
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
+{
+	P_EVENT_STA_UPDATE_FREE_QUOTA_T prEventStaUpdateFreeQuota;
+	P_STA_RECORD_T prStaRec;
+
+	prEventStaUpdateFreeQuota = (P_EVENT_STA_UPDATE_FREE_QUOTA_T) prEvent;
+	prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaUpdateFreeQuota->ucStaRecIdx);
+	ASSERT(prStaRec);
+
+	if (prStaRec) {
+		if (prStaRec->fgIsInPS) {
+			qmUpdateFreeQuota(prAdapter,
+					  prStaRec,
+					  prEventStaUpdateFreeQuota->ucUpdateMode,
+					  prEventStaUpdateFreeQuota->ucFreeQuota,
+					  prEventStaUpdateFreeQuota->aucReserved[0]);
+
+			kalSetEvent(prAdapter->prGlueInfo);
+		}
+#if 0
+		DBGLOG(QM, TRACE,
+		       "qmHandleEventStaUpdateFreeQuota (ucStaRecIdx=%d, ucUpdateMode=%d, ucFreeQuota=%d)\n",
+			prEventStaUpdateFreeQuota->ucStaRecIdx, prEventStaUpdateFreeQuota->ucUpdateMode,
+			prEventStaUpdateFreeQuota->ucFreeQuota);
+#endif
+
+		DBGLOG(QM, TRACE, "UFQ=%d,%d,%d\n",
+				   prEventStaUpdateFreeQuota->ucStaRecIdx,
+				   prEventStaUpdateFreeQuota->ucUpdateMode, prEventStaUpdateFreeQuota->ucFreeQuota);
+
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Update STA free quota
+*
+* \param[in] prStaRec the STA
+* \param[in] ucUpdateMode the method to update free quota
+* \param[in] ucFreeQuota  the value for update
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter,
+		  IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone)
+{
+
+	UINT_8 ucFreeQuotaForNonDelivery;
+	UINT_8 ucFreeQuotaForDelivery;
+	BOOLEAN flgIsUpdateForcedToDelivery;
+
+	ASSERT(prStaRec);
+	DBGLOG(QM, LOUD, "qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n",
+			  prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota);
+
+	if (!prStaRec->fgIsInPS)
+		return;
+
+	flgIsUpdateForcedToDelivery = FALSE;
+
+	if (ucNumOfTxDone > 0) {
+		/*
+		   update free quota by
+		   num of tx done + resident free quota (delivery + non-delivery)
+		 */
+		UINT_8 ucAvailQuota;
+
+		ucAvailQuota = ucNumOfTxDone + prStaRec->ucFreeQuotaForDelivery + prStaRec->ucFreeQuotaForNonDelivery;
+		if (ucAvailQuota > ucFreeQuota)	/* sanity check */
+			ucAvailQuota = ucFreeQuota;
+
+		/* update current free quota */
+		ucFreeQuota = ucAvailQuota;
+
+		/* check if the update is from last packet */
+		if (ucFreeQuota == (prStaRec->ucFreeQuota + 1)) {
+			/* just add the extra quota to delivery queue */
+
+			/*
+			   EX:
+			   1. TDLS peer enters power save
+			   2. When the last 2 VI packets are tx done, we will receive 2 update events
+			   3. 1st update event: ucFreeQuota = 9
+			   4. We will correct new quota for delivey and non-delivery to 7:2
+			   5. 2rd update event: ucFreeQuota = 10
+			   6. We will re-correct new quota for delivery and non-delivery to 5:5
+
+			   But non-delivery queue is not busy.
+			   So in the case, we will have wrong decision, i.e. higher queue always quota 5
+
+			   Solution: skip the 2rd update event and just add the extra quota to delivery.
+			 */
+
+			flgIsUpdateForcedToDelivery = TRUE;
+		}
+	}
+
+	switch (ucUpdateMode) {
+	case FREE_QUOTA_UPDATE_MODE_INIT:
+	case FREE_QUOTA_UPDATE_MODE_OVERWRITE:
+		prStaRec->ucFreeQuota = ucFreeQuota;
+		break;
+	case FREE_QUOTA_UPDATE_MODE_INCREASE:
+		prStaRec->ucFreeQuota += ucFreeQuota;
+		break;
+	case FREE_QUOTA_UPDATE_MODE_DECREASE:
+		prStaRec->ucFreeQuota -= ucFreeQuota;
+		break;
+	default:
+		ASSERT(0);
+	}
+
+	DBGLOG(QM, LOUD, "qmUpdateFreeQuota new ucFreeQuota=%d)\n", prStaRec->ucFreeQuota);
+
+	ucFreeQuota = prStaRec->ucFreeQuota;
+
+	ucFreeQuotaForNonDelivery = 0;
+	ucFreeQuotaForDelivery = 0;
+
+	if (ucFreeQuota > 0) {
+		if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported
+		    /* && prAdapter->rWifiVar.fgSupportQoS
+		       && prAdapter->rWifiVar.fgSupportUAPSD */) {
+			/* XXX We should assign quota to aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES]  */
+
+			if (flgIsUpdateForcedToDelivery == FALSE) {
+				if (prStaRec->ucFreeQuotaForNonDelivery > 0 && prStaRec->ucFreeQuotaForDelivery > 0) {
+					ucFreeQuotaForNonDelivery = ucFreeQuota >> 1;
+					ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery;
+				} else if (prStaRec->ucFreeQuotaForNonDelivery == 0
+					   && prStaRec->ucFreeQuotaForDelivery == 0) {
+					ucFreeQuotaForNonDelivery = ucFreeQuota >> 1;
+					ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery;
+				} else if (prStaRec->ucFreeQuotaForNonDelivery > 0) {
+					/* NonDelivery is not busy */
+					if (ucFreeQuota >= 3) {
+						ucFreeQuotaForNonDelivery = 2;
+						ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery;
+					} else {
+						ucFreeQuotaForDelivery = ucFreeQuota;
+						ucFreeQuotaForNonDelivery = 0;
+					}
+				} else if (prStaRec->ucFreeQuotaForDelivery > 0) {
+					/* Delivery is not busy */
+					if (ucFreeQuota >= 3) {
+						ucFreeQuotaForDelivery = 2;
+						ucFreeQuotaForNonDelivery = ucFreeQuota - ucFreeQuotaForDelivery;
+					} else {
+						ucFreeQuotaForNonDelivery = ucFreeQuota;
+						ucFreeQuotaForDelivery = 0;
+					}
+				}
+			} else {
+				ucFreeQuotaForNonDelivery = 2;
+				ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery;
+			}
+		} else {
+			/* no use ? */
+			/* !prStaRec->fgIsUapsdSupported */
+			ucFreeQuotaForNonDelivery = ucFreeQuota;
+			ucFreeQuotaForDelivery = 0;
+		}
+	}
+	/* ucFreeQuota > 0 */
+	prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery;
+	prStaRec->ucFreeQuotaForNonDelivery = ucFreeQuotaForNonDelivery;
+
+#if (CFG_SUPPORT_TDLS_DBG == 1)
+	if (IS_TDLS_STA(prStaRec))
+		DBGLOG(QM, LOUD, "<tx> quota %d %d %d\n",
+				ucFreeQuota, ucFreeQuotaForDelivery, ucFreeQuotaForNonDelivery);
+#endif
+
+	DBGLOG(QM, LOUD, "new QuotaForDelivery = %d  QuotaForNonDelivery = %d\n",
+			  prStaRec->ucFreeQuotaForDelivery, prStaRec->ucFreeQuotaForNonDelivery);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Return the reorder queued RX packets
+*
+* \param[in] (none)
+*
+* \return The number of queued RX packets
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter)
+{
+	UINT_32 i, u4Total;
+	P_QUE_MGT_T prQM = &prAdapter->rQM;
+
+	u4Total = 0;
+	/* XXX The summation may impact the performance */
+	for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) {
+		u4Total += prQM->arRxBaTable[i].rReOrderQue.u4NumElem;
+#if DBG && 0
+		if (QUEUE_IS_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue)))
+			ASSERT(prQM->arRxBaTable[i].rReOrderQue == 0);
+#endif
+	}
+	ASSERT(u4Total <= (CFG_NUM_OF_QM_RX_PKT_NUM * 2));
+	return u4Total;
+}
+
+#if ARP_MONITER_ENABLE
+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+	struct sk_buff *prSkb = NULL;
+	PUINT_8 pucData = NULL;
+	UINT_16 u2EtherType = 0;
+	int arpOpCode = 0;
+
+	prSkb = (struct sk_buff *)prMsduInfo->prPacket;
+
+	if (!prSkb || (prSkb->len <= ETHER_HEADER_LEN))
+		return;
+
+	pucData = prSkb->data;
+	if (!pucData)
+		return;
+	u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]);
+
+	if (u2EtherType != ETH_P_ARP || (apIp[0] | apIp[1] | apIp[2] | apIp[3]) == 0)
+		return;
+
+	if (strncmp(apIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], sizeof(apIp))) /* dest ip address */
+		return;
+
+	arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]);
+	if (arpOpCode == ARP_PRO_REQ) {
+		arpMoniter++;
+		if (arpMoniter > 20) {
+			DBGLOG(INIT, WARN, "IOT Critical issue, arp no resp, check AP!\n");
+			aisBssBeaconTimeout(prAdapter);
+			arpMoniter = 0;
+			kalMemZero(apIp, sizeof(apIp));
+		}
+	}
+}
+
+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
+{
+	PUINT_8 pucData = NULL;
+	UINT_16 u2EtherType = 0;
+	int arpOpCode = 0;
+	P_BSS_INFO_T prBssInfo = NULL;
+
+	if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN)
+		return;
+
+	pucData = (PUINT_8)prSwRfb->pvHeader;
+	if (!pucData)
+		return;
+	u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]);
+
+	if (u2EtherType != ETH_P_ARP)
+		return;
+
+	arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]);
+	prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
+	if (arpOpCode == ARP_PRO_RSP) {
+		arpMoniter = 0;
+		if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) {
+			if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */
+					prBssInfo->prStaRecOfAP->aucMacAddr)) {
+				strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */
+				DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n",
+					apIp[0], apIp[1], apIp[2], apIp[3]);
+			}
+		}
+	}
+}
+
+VOID qmResetArpDetect(VOID)
+{
+	arpMoniter = 0;
+	kalMemZero(apIp, sizeof(apIp));
+}
+#endif
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c
new file mode 100644
index 0000000000000..6f5c0bcdd90bb
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c
@@ -0,0 +1,1177 @@
+/*
+** Id: @(#) gl_bow.c@@
+*/
+
+/*! \file   gl_bow.c
+    \brief  Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS)
+
+    This file contains the main routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*
+** Log: gl_bow.c
+ *
+ * 02 16 2012 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * [ALPS00235223] [Rose][ICS][Cross Feature][AEE-IPANIC]The device reboot automatically and then the "KE" pops up
+ * after you turn on the "Airplane mode".(once)
+ *
+ * [Root Cause]
+ * PAL operates BOW char dev poll after BOW char dev is registered.
+ *
+ * [Solution]
+ * Rejects PAL char device operation after BOW is unregistered or when wlan GLUE_FLAG_HALT is set.
+ *
+ * This is a workaround for BOW driver robustness, happens only in ICS.
+ *
+ * Root cause should be fixed by CR [ALPS00231570]
+ *
+ * 02 03 2012 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5)
+ *
+ * [Root Cause]
+ * PAL operates BOW char dev poll after BOW char dev is registered.
+ *
+ * [Solution]
+ * Rejects PAL char device operation after BOW is unregistered.
+ *
+ * Happens only in ICS.
+ *
+ * Notified PAL owener to reivew MTKBT/PAL closing BOW char dev procedure.
+ *
+ * [Side Effect]
+ * None.
+ *
+ * 01 16 2012 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support BOW for 5GHz band.
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 10 25 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Modify ampc0 char device for major number 151 for all MT6575 projects.
+ *
+ * 07 28 2011 cp.wu
+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl
+ * unlocked_ioctl returns as long instead of int.
+ *
+ * 07 28 2011 cp.wu
+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl
+ * migrate to unlocked ioctl interface
+ *
+ * 04 12 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add WMM IE for BOW initiator data.
+ *
+ * 04 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes.
+ *
+ * 04 09 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Change Link connection event procedure and change skb length check to 1512 bytes.
+ *
+ * 03 27 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Support multiple physical link.
+ *
+ * 03 06 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Sync BOW Driver to latest person development branch version..
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * support concurrent network
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * replace alloc_netdev to alloc_netdev_mq for BoW
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * modify net device relative functions to support multiple H/W queues
+ *
+ * 02 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Update net register and BOW for concurrent features.
+ *
+ * 02 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix kernel API change issue.
+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is
+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock);
+ * After ALPS 2.3, kfifo_alloc() is changed to
+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask);
+ *
+ * 02 09 2011 cp.wu
+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3
+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031
+ * with BOW and P2P enabled as default
+ *
+ * 02 08 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in.
+ * Update BOW get MAC status, remove returning event for AIS network type.
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
+ * implementation of separate BT_OVER_WIFI data path.
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation
+ * needs such information
+ * fill mac header length information for 802.1x frames.
+ *
+ * 11 11 2010 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix BoW timer assert issue.
+ *
+ * 09 14 2010 chinghwa.yu
+ * NULL
+ * Add bowRunEventAAAComplete.
+ *
+ * 09 14 2010 cp.wu
+ * NULL
+ * correct typo: POLLOUT instead of POLL_OUT
+ *
+ * 09 13 2010 cp.wu
+ * NULL
+ * add waitq for poll() and read().
+ *
+ * 08 24 2010 chinghwa.yu
+ * NULL
+ * Update BOW for the 1st time.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 05 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change variable names for multiple physical link to match with coding convention
+ *
+ * 05 05 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * multiple BoW interfaces need to compare with peer address
+ *
+ * 04 28 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change prefix for data structure used to communicate with 802.11 PAL
+ * to avoid ambiguous naming with firmware interface
+ *
+ * 04 28 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * fix kalIndicateBOWEvent.
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add multiple physical link support
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_os.h"
+#include "debug.h"
+#include "wlan_lib.h"
+#include "gl_wext.h"
+#include "precomp.h"
+#include <linux/poll.h>
+#include "bss.h"
+
+#if CFG_ENABLE_BT_OVER_WIFI
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* @FIXME if there is command/event with payload length > 28 */
+#define MAX_BUFFER_SIZE         (64)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+#if CFG_BOW_TEST
+UINT_32 g_u4PrevSysTime = 0;
+UINT_32 g_u4CurrentSysTime = 0;
+UINT_32 g_arBowRevPalPacketTime[11];
+#endif
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/* forward declarations */
+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos);
+
+static ssize_t
+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos);
+
+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg);
+
+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait);
+
+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp);
+
+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp);
+
+/* character file operations */
+static const struct file_operations mt6620_ampc_fops = {
+	/* .owner              = THIS_MODULE, */
+	.read = mt6620_ampc_read,
+	.write = mt6620_ampc_write,
+	.unlocked_ioctl = mt6620_ampc_ioctl,
+	.poll = mt6620_ampc_poll,
+	.open = mt6620_ampc_open,
+	.release = mt6620_ampc_release,
+};
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Register for character device to communicate with 802.11 PAL
+*
+* \param[in] prGlueInfo      Pointer to glue info
+*
+* \return   TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN glRegisterAmpc(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE)
+		return FALSE;
+
+#if 0
+	/* 1. allocate major number dynamically */
+
+	if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0,	/* first minor number */
+				1,	/* number */
+				GLUE_BOW_DEVICE_NAME) != 0)
+
+		return FALSE;
+#endif
+
+#if 1
+
+#if defined(CONFIG_AMPC_CDEV_NUM)
+	prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0);
+#else
+	prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0);
+#endif
+
+	if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1,	/* number */
+				   GLUE_BOW_DEVICE_NAME) != 0)
+
+		return FALSE;
+#endif
+
+	/* 2. spin-lock initialization */
+	/* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */
+
+	/* 3. initialize kfifo */
+/*        prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH,
+	GFP_KERNEL,
+	&(prGlueInfo->rBowInfo.rSpinLock));*/
+	if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL)))
+		goto fail_kfifo_alloc;
+
+/* if(prGlueInfo->rBowInfo.prKfifo == NULL) */
+	if (&(prGlueInfo->rBowInfo.rKfifo) == NULL)
+		goto fail_kfifo_alloc;
+
+	/* 4. initialize cdev */
+	cdev_init(&(prGlueInfo->rBowInfo.cdev), &mt6620_ampc_fops);
+	/* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */
+	prGlueInfo->rBowInfo.cdev.ops = &mt6620_ampc_fops;
+
+	/* 5. add character device */
+	if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1))
+		goto fail_cdev_add;
+
+	/* 6. in queue initialization */
+	init_waitqueue_head(&(prGlueInfo->rBowInfo.outq));
+
+	/* 7. finish */
+	prGlueInfo->rBowInfo.fgIsRegistered = TRUE;
+	return TRUE;
+
+fail_cdev_add:
+	kfifo_free(&(prGlueInfo->rBowInfo.rKfifo));
+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */
+fail_kfifo_alloc:
+	unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1);
+	return FALSE;
+}				/* end of glRegisterAmpc */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Unregister character device for communicating with 802.11 PAL
+*
+* \param[in] prGlueInfo      Pointer to glue info
+*
+* \return   TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN glUnregisterAmpc(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE)
+		return FALSE;
+
+	prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
+
+	/* 1. free netdev if necessary */
+#if CFG_BOW_SEPARATE_DATA_PATH
+	kalUninitBowDevice(prGlueInfo);
+#endif
+
+	/* 2. removal of character device */
+	cdev_del(&(prGlueInfo->rBowInfo.cdev));
+
+	/* 3. free kfifo */
+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */
+	kfifo_free(&(prGlueInfo->rBowInfo.rKfifo));
+/* prGlueInfo->rBowInfo.prKfifo = NULL; */
+/* prGlueInfo->rBowInfo.rKfifo = NULL; */
+
+	/* 4. free device number */
+	unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1);
+
+	return TRUE;
+}				/* end of glUnregisterAmpc */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief read handler for character device to communicate with 802.11 PAL
+*
+* \param[in]
+* \return
+*           Follows Linux Character Device Interface
+*
+*/
+/*----------------------------------------------------------------------------*/
+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos)
+{
+	UINT_8 aucBuffer[MAX_BUFFER_SIZE];
+	ssize_t retval;
+	P_GLUE_INFO_T prGlueInfo;
+
+	prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
+
+	ASSERT(prGlueInfo);
+
+	if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
+		return -EFAULT;
+	/* size check */
+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */
+	if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size)
+		retval = size;
+	else
+		retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo));
+/* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */
+
+/* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */
+/* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */
+	if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) {
+		retval = -EIO;
+		return retval;
+	}
+
+	if (copy_to_user(buf, aucBuffer, retval))
+		retval = -EIO;
+
+	return retval;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief write handler for character device to communicate with 802.11 PAL
+*
+* \param[in]
+* \return
+*           Follows Linux Character Device Interface
+*
+*/
+/*----------------------------------------------------------------------------*/
+static ssize_t
+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos)
+{
+#if CFG_BOW_TEST
+	UINT_8 i;
+#endif
+
+	UINT_8 aucBuffer[MAX_BUFFER_SIZE];
+	P_AMPC_COMMAND prCmd;
+	P_GLUE_INFO_T prGlueInfo;
+
+	prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
+	ASSERT(prGlueInfo);
+
+	if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
+		return -EFAULT;
+
+	if (size > MAX_BUFFER_SIZE)
+		return -EINVAL;
+	else if (copy_from_user(aucBuffer, buf, size))
+		return -EIO;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size);
+
+	for (i = 0; i < MAX_BUFFER_SIZE; i++)
+		DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]);
+
+	DBGLOG(BOW, EVENT, "BoW CMD write.\n");
+#endif
+
+	prCmd = (P_AMPC_COMMAND) aucBuffer;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength);
+
+	DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(AMPC_COMMAND_HEADER_T));
+#endif
+
+	/* size check */
+	if (prCmd->rHeader.u2PayloadLength + sizeof(AMPC_COMMAND_HEADER_T) != size) {
+#if CFG_BOW_TEST
+		DBGLOG(BOW, EVENT, "Wrong CMD total length.\n");
+#endif
+
+		return -EINVAL;
+	}
+
+	if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS)
+		return size;
+	else
+		return -EINVAL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief ioctl handler for character device to communicate with 802.11 PAL
+*
+* \param[in]
+* \return
+*           Follows Linux Character Device Interface
+*
+*/
+/*----------------------------------------------------------------------------*/
+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg)
+{
+	int err = 0;
+	P_GLUE_INFO_T prGlueInfo;
+
+	prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
+
+	ASSERT(prGlueInfo);
+
+	if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
+		return -EFAULT;
+	/* permission check */
+	if (_IOC_DIR(cmd) & _IOC_READ)
+		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
+	else if (_IOC_DIR(cmd) & _IOC_WRITE)
+		err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
+	if (err)
+		return -EFAULT;
+
+	/* no ioctl is implemented yet */
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief ioctl handler for character device to communicate with 802.11 PAL
+*
+* \param[in]
+* \return
+*           Follows Linux Character Device Interface
+*
+*/
+/*----------------------------------------------------------------------------*/
+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait)
+{
+	unsigned int retval;
+	P_GLUE_INFO_T prGlueInfo;
+
+	prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
+
+	ASSERT(prGlueInfo);
+
+	if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
+		return -EFAULT;
+
+	poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait);
+
+	retval = (POLLOUT | POLLWRNORM);	/* always accepts incoming command packets */
+
+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */
+
+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */
+	if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) {
+		retval |= (POLLIN | POLLRDNORM);
+
+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */
+
+	}
+
+	return retval;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief open handler for character device to communicate with 802.11 PAL
+*
+* \param[in]
+* \return
+*           Follows Linux Character Device Interface
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	P_GL_BOW_INFO prBowInfo;
+
+	prBowInfo = container_of(inodep->i_cdev, GL_BOW_INFO, cdev);
+	ASSERT(prBowInfo);
+
+	prGlueInfo = container_of(prBowInfo, GLUE_INFO_T, rBowInfo);
+	ASSERT(prGlueInfo);
+
+	/* set-up private data */
+	filp->private_data = prGlueInfo;
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief close handler for character device to communicate with 802.11 PAL
+*
+* \param[in]
+* \return
+*           Follows Linux Character Device Interface
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp)
+{
+	P_GLUE_INFO_T prGlueInfo;
+
+	prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
+
+	ASSERT(prGlueInfo);
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to indicate event for Bluetooth over Wi-Fi
+*
+* \param[in]
+*           prGlueInfo
+*           prEvent
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent)
+{
+	size_t u4AvailSize, u4EventSize;
+
+	ASSERT(prGlueInfo);
+	ASSERT(prEvent);
+
+	/* check device */
+	if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
+		return;
+
+/*    u4AvailSize =
+	GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo);*/
+
+	u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo));
+
+	u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(AMPC_EVENT_HEADER_T);
+
+	/* check kfifo availability */
+	if (u4AvailSize < u4EventSize) {
+		DBGLOG(BOW, EVENT, "[bow] no space for event: %zu/%zu\n", u4EventSize, u4AvailSize);
+		return;
+	}
+	/* queue into kfifo */
+/* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */
+/* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */
+	kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (PUINT_8) prEvent, u4EventSize);
+	wake_up_interruptible(&(prGlueInfo->rBowInfo.outq));
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer
+*
+* \param[in]
+*           prGlueInfo
+*           rPeerAddr
+* \return
+*           ENUM_BOW_DEVICE_STATE
+*/
+/*----------------------------------------------------------------------------*/
+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 aucPeerAddress[6])
+{
+	UINT_8 i;
+
+	ASSERT(prGlueInfo);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "kalGetBowState.\n");
+#endif
+
+	for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
+		if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) {
+
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i,
+					    aucPeerAddress[0],
+					    aucPeerAddress[1],
+					    aucPeerAddress[2],
+					    aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]));
+
+			DBGLOG(BOW, EVENT,
+			       "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i,
+				prGlueInfo->rBowInfo.aeState[i]);
+
+#endif
+
+			return prGlueInfo->rBowInfo.aeState[i];
+		}
+	}
+
+	return BOW_DEVICE_STATE_DISCONNECTED;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to set Bluetooth-over-Wi-Fi state in glue layer
+*
+* \param[in]
+*           prGlueInfo
+*           eBowState
+*           rPeerAddr
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, IN UINT_8 aucPeerAddress[6])
+{
+	UINT_8 i;
+
+	ASSERT(prGlueInfo);
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, EVENT, "kalSetBowState.\n");
+
+	DBGLOG(BOW, EVENT, "kalSetBowState, prGlueInfo->rBowInfo.arPeerAddr, %x:%x:%x:%x:%x:%x.\n",
+			    prGlueInfo->rBowInfo.arPeerAddr[0],
+			    prGlueInfo->rBowInfo.arPeerAddr[1],
+			    prGlueInfo->rBowInfo.arPeerAddr[2],
+			    prGlueInfo->rBowInfo.arPeerAddr[3],
+			    prGlueInfo->rBowInfo.arPeerAddr[4], prGlueInfo->rBowInfo.arPeerAddr[5]));
+
+	DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
+			    aucPeerAddress[0],
+			    aucPeerAddress[1],
+			    aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]);
+#endif
+
+	for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
+		if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) {
+			prGlueInfo->rBowInfo.aeState[i] = eBowState;
+
+#if CFG_BOW_TEST
+			DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i,
+					    aucPeerAddress[0],
+					    aucPeerAddress[1],
+					    aucPeerAddress[2],
+					    aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]));
+
+			DBGLOG(BOW, EVENT,
+			       "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i,
+				prGlueInfo->rBowInfo.aeState[i]);
+#endif
+
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Bluetooth-over-Wi-Fi global state
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           BOW_DEVICE_STATE_DISCONNECTED
+*               in case there is no BoW connection or
+*               BoW connection under initialization
+*
+*           BOW_DEVICE_STATE_STARTING
+*               in case there is no BoW connection but
+*               some BoW connection under initialization
+*
+*           BOW_DEVICE_STATE_CONNECTED
+*               in case there is any BoW connection available
+*/
+/*----------------------------------------------------------------------------*/
+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo)
+{
+	UINT_32 i;
+
+	ASSERT(prGlueInfo);
+
+/* Henry, can reduce this logic to indentify state change */
+
+	for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
+		if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED)
+			return BOW_DEVICE_STATE_CONNECTED;
+	}
+
+	for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
+		if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING)
+			return BOW_DEVICE_STATE_STARTING;
+	}
+
+	return BOW_DEVICE_STATE_DISCONNECTED;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Bluetooth-over-Wi-Fi operating frequency
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           in unit of KHz
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->rBowInfo.u4FreqInKHz;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Bluetooth-over-Wi-Fi role
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           0: Responder
+*           1: Initiator
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr)
+{
+	UINT_32 i;
+
+	ASSERT(prGlueInfo);
+
+	for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
+		if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0)
+			return prGlueInfo->rBowInfo.aucRole[i];
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to set Bluetooth-over-Wi-Fi role
+*
+* \param[in]
+*           prGlueInfo
+*           ucRole
+*                   0: Responder
+*                   1: Initiator
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr)
+{
+	UINT_32 i;
+
+	ASSERT(prGlueInfo);
+	ASSERT(ucRole <= 1);
+
+	for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
+		if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0)
+			prGlueInfo->rBowInfo.aucRole[i] = ucRole;	/* Henry, 0 : Responder, 1 : Initiator */
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to get available Bluetooth-over-Wi-Fi physical link number
+*
+* \param[in]
+*           prGlueInfo
+* \return
+*           UINT_32
+*               how many physical links are aviailable
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo)
+{
+	UINT_8 i;
+	UINT_8 ucLinkCount = 0;
+
+	ASSERT(prGlueInfo);
+
+	for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
+		if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED)
+			ucLinkCount++;
+	}
+
+#if 0				/* CFG_BOW_TEST */
+	DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount);
+#endif
+
+	return ucLinkCount;
+}
+
+#if CFG_BOW_SEPARATE_DATA_PATH
+
+/* Net Device Hooks */
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief A function for net_device open (ifup)
+ *
+ * \param[in] prDev      Pointer to struct net_device.
+ *
+ * \retval 0     The execution succeeds.
+ * \retval < 0   The execution failed.
+ */
+/*----------------------------------------------------------------------------*/
+static int bowOpen(IN struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_ADAPTER_T prAdapter = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* 2. carrier on & start TX queue */
+	netif_carrier_on(prDev);
+	netif_tx_start_all_queues(prDev);
+
+	return 0;		/* success */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief A function for net_device stop (ifdown)
+ *
+ * \param[in] prDev      Pointer to struct net_device.
+ *
+ * \retval 0     The execution succeeds.
+ * \retval < 0   The execution failed.
+ */
+/*----------------------------------------------------------------------------*/
+static int bowStop(IN struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_ADAPTER_T prAdapter = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* 1. stop TX queue */
+	netif_tx_stop_all_queues(prDev);
+
+	/* 2. turn of carrier */
+	if (netif_carrier_ok(prDev))
+		netif_carrier_off(prDev);
+
+	return 0;
+};
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief This function is TX entry point of NET DEVICE.
+ *
+ * \param[in] prSkb  Pointer of the sk_buff to be sent
+ * \param[in] prDev  Pointer to struct net_device
+ *
+ * \retval NETDEV_TX_OK - on success.
+ * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
+ */
+/*----------------------------------------------------------------------------*/
+static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+	P_QUE_ENTRY_T prQueueEntry = NULL;
+	P_QUE_T prTxQueue = NULL;
+	UINT_16 u2QueueIdx = 0;
+	UINT_8 ucDSAP, ucSSAP, ucControl;
+	UINT_8 aucOUI[3];
+	PUINT_8 aucLookAheadBuf = NULL;
+
+#if CFG_BOW_TEST
+	UINT_32 i;
+#endif
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prSkb);
+	ASSERT(prDev);
+	ASSERT(prGlueInfo);
+
+	aucLookAheadBuf = prSkb->data;
+
+	ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET];
+	ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1];
+	ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2];
+	aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET];
+	aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1];
+	aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2];
+	prGlueInfo->u8SkbToDriver++;
+
+	if (!(ucDSAP == ETH_LLC_DSAP_SNAP &&
+	      ucSSAP == ETH_LLC_SSAP_SNAP &&
+	      ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION &&
+	      aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 &&
+	      aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) {
+
+#if CFG_BOW_TEST
+		DBGLOG(BOW, TRACE, "Invalid BOW packet, skip tx\n");
+#endif
+
+		dev_kfree_skb(prSkb);
+		prGlueInfo->u8SkbFreed++;
+		return NETDEV_TX_OK;
+	}
+
+	if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
+		DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n");
+		dev_kfree_skb(prSkb);
+		prGlueInfo->u8SkbFreed++;
+		return NETDEV_TX_OK;
+	}
+
+	prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
+	prTxQueue = &prGlueInfo->rTxQueue;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, TRACE, "Tx sk_buff->len: %d\n", prSkb->len);
+	DBGLOG(BOW, TRACE, "Tx sk_buff->data_len: %d\n", prSkb->data_len);
+	DBGLOG(BOW, TRACE, "Tx sk_buff->data:\n");
+
+	for (i = 0; i < prSkb->len; i++) {
+		DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]);
+
+		if ((i + 1) % 16 == 0)
+			DBGLOG(BOW, TRACE, "\n");
+	}
+
+	DBGLOG(BOW, TRACE, "\n";
+#endif
+#if CFG_BOW_TEST
+/* g_u4CurrentSysTime = (OS_SYSTIME)kalGetTimeTick(; */
+	g_u4CurrentSysTime = (OS_SYSTIME) jiffies_to_usecs(jiffies);
+	i = g_u4CurrentSysTime - g_u4PrevSysTime;
+	if ((i >> 10) > 0)
+		i = 10;
+	else
+		i = i >> 7;
+	g_arBowRevPalPacketTime[i]++;
+	g_u4PrevSysTime = g_u4CurrentSysTime;
+#endif
+	if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
+		GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+		QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
+		GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+		GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
+		GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]);
+		if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx] >=
+				CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD)
+			DBGLOG(TX, INFO, "netif_stop_subqueue for BOW, Queue len: %d\n",
+				prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]);
+
+			netif_stop_subqueue(prDev, u2QueueIdx);
+	} else {
+		GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
+	}
+
+	kalSetEvent(prGlueInfo);
+	/* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
+	return NETDEV_TX_OK;
+}
+
+/* callbacks for netdevice */
+static const struct net_device_ops bow_netdev_ops = {
+	.ndo_open = bowOpen, .ndo_stop = bowStop, .ndo_start_xmit = bowHardStartXmit,};
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief initialize net device for Bluetooth-over-Wi-Fi
+*
+* \param[in]
+*           prGlueInfo
+*           prDevName
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName)
+{
+	P_ADAPTER_T prAdapter;
+	P_GL_HIF_INFO_T prHif;
+	PARAM_MAC_ADDRESS rMacAddr;
+
+	ASSERT(prGlueInfo);
+	ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE);
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+	prHif = &prGlueInfo->rHifInfo;
+	ASSERT(prHif);
+	if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) {
+		prGlueInfo->rBowInfo.prDevHandler =
+		alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM);
+		if (!prGlueInfo->rBowInfo.prDevHandler)
+			return FALSE;
+
+		/* 1. setup netdev */
+		/* 1.1 Point to shared glue structure */
+		*((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo;
+		/* 1.2 fill hardware address */
+		COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr);
+		rMacAddr[0] |= 0x2;
+		/* change to local administrated address */
+		ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr);
+		ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->perm_addr,
+			prGlueInfo->rBowInfo.prDevHandler->dev_addr);
+		/* 1.3 register callback functions */
+		prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops;
+#if (MTK_WCN_HIF_SDIO == 0)
+		SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, prHif->Dev);
+#endif
+		register_netdev(prGlueInfo->rBowInfo.prDevHandler);
+		/* 2. net device initialize */
+		netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler);
+		netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler);
+		/* 3. finish */
+		prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE;
+	}
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief uninitialize net device for Bluetooth-over-Wi-Fi
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+	/* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */
+	if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) {
+		prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
+		if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler))
+			netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler);
+
+		netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler);
+		/* netdevice unregistration & free */
+		unregister_netdev(prGlueInfo->rBowInfo.prDevHandler);
+		free_netdev(prGlueInfo->rBowInfo.prDevHandler);
+		prGlueInfo->rBowInfo.prDevHandler = NULL;
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+#endif /* CFG_BOW_SEPARATE_DATA_PATH */
+#endif /* CFG_ENABLE_BT_OVER_WIFI */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c
new file mode 100644
index 0000000000000..1fed65ebc60e6
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c
@@ -0,0 +1,3110 @@
+/*
+** Id: @(#) gl_cfg80211.c@@
+*/
+
+/*! \file   gl_cfg80211.c
+    \brief  Main routines for supporintg MT6620 cfg80211 control interface
+
+    This file contains the support routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*
+** Log: gl_cfg80211.c
+**
+** 09 05 2013 cp.wu
+** correct length to pass to wlanoidSetBssid()
+**
+** 09 04 2013 cp.wu
+** fix typo
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+**
+** 11 23 2012 yuche.tsai
+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely
+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed..
+**
+** 09 12 2012 wcpadmin
+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
+** .
+**
+** 08 30 2012 chinglan.wang
+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
+** .
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_os.h"
+#include "debug.h"
+#include "wlan_lib.h"
+#include "gl_wext.h"
+#include "precomp.h"
+#include <linux/can/netlink.h>
+#include <net/netlink.h>
+#include <net/cfg80211.h>
+#include "gl_cfg80211.h"
+#include "gl_vendor.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor
+to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause
+is that there is no resource in TC4, so del key command was not able to set, and then oid
+timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this
+workaround */
+static UINT_8 gucKeyIndex = 255;
+
+P_SW_RFB_T g_arGscnResultsTempBuffer[MAX_BUFFERED_GSCN_RESULTS];
+UINT_8 g_GscanResultsTempBufferIndex = 0;
+UINT_8 g_arGscanResultsIndicateNumber[MAX_BUFFERED_GSCN_RESULTS] = { 0, 0, 0, 0, 0 };
+
+UINT_8 g_GetResultsBufferedCnt = 0;
+UINT_8 g_GetResultsCmdCnt = 0;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for change STA type between
+ *        1. Infrastructure Client (Non-AP STA)
+ *        2. Ad-Hoc IBSS
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_cfg80211_change_iface(struct wiphy *wiphy,
+			  struct net_device *ndev, enum nl80211_iftype type, /*u32 *flags,*/ struct vif_params *params)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	ENUM_PARAM_OP_MODE_T eOpMode;
+	UINT_32 u4BufLen;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	if (type == NL80211_IFTYPE_STATION)
+		eOpMode = NET_TYPE_INFRA;
+	else if (type == NL80211_IFTYPE_ADHOC)
+		eOpMode = NET_TYPE_IBSS;
+	else
+		return -EINVAL;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetInfrastructureMode,
+			   &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", rStatus);
+
+	/* reset wpa info */
+	prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
+	prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
+	prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
+#if CFG_SUPPORT_802_11W
+	prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
+#endif
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for adding key
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_cfg80211_add_key(struct wiphy *wiphy,
+		     struct net_device *ndev,
+		     u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params)
+{
+	PARAM_KEY_T rKey;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	INT_32 i4Rslt = -EINVAL;
+	UINT_32 u4BufLen = 0;
+	UINT_8 tmp1[8];
+	UINT_8 tmp2[8];
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	kalMemZero(&rKey, sizeof(PARAM_KEY_T));
+
+	rKey.u4KeyIndex = key_index;
+
+	if (mac_addr) {
+		COPY_MAC_ADDR(rKey.arBSSID, mac_addr);
+		if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) &&
+		    (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) {
+			rKey.arBSSID[0] = 0xff;
+			rKey.arBSSID[1] = 0xff;
+			rKey.arBSSID[2] = 0xff;
+			rKey.arBSSID[3] = 0xff;
+			rKey.arBSSID[4] = 0xff;
+			rKey.arBSSID[5] = 0xff;
+		}
+		if (rKey.arBSSID[0] != 0xFF) {
+			rKey.u4KeyIndex |= BIT(31);
+			if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) ||
+			    (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00))
+				rKey.u4KeyIndex |= BIT(30);
+		}
+	} else {
+		rKey.arBSSID[0] = 0xff;
+		rKey.arBSSID[1] = 0xff;
+		rKey.arBSSID[2] = 0xff;
+		rKey.arBSSID[3] = 0xff;
+		rKey.arBSSID[4] = 0xff;
+		rKey.arBSSID[5] = 0xff;
+		/* rKey.u4KeyIndex |= BIT(31);//Enable BIT 31 will make tx use bc key id,should use pairwise key id 0 */
+	}
+
+	if (params->key) {
+		/* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */
+		kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len);
+		if (params->key_len == 32) {
+			kalMemCopy(tmp1, &params->key[16], 8);
+			kalMemCopy(tmp2, &params->key[24], 8);
+			kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8);
+			kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8);
+		}
+	}
+
+	rKey.u4KeyLength = params->key_len;
+	rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength;
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus == WLAN_STATUS_SUCCESS)
+		i4Rslt = 0;
+
+	return i4Rslt;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for getting key for specified STA
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_cfg80211_get_key(struct wiphy *wiphy,
+		     struct net_device *ndev,
+		     u8 key_index,
+		     bool pairwise,
+		     const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *))
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+
+	/* not implemented */
+
+	return -EINVAL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for removing key for specified STA
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	PARAM_REMOVE_KEY_T rRemoveKey;
+	UINT_32 u4BufLen = 0;
+	INT_32 i4Rslt = -EINVAL;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T));
+	if (mac_addr)
+		COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr);
+	else if (key_index <= gucKeyIndex) {	/* new operation, reset gucKeyIndex */
+		gucKeyIndex = 255;
+	} else {			/* bypass the next remove key operation */
+		gucKeyIndex = key_index;
+		return -EBUSY;
+	}
+	rRemoveKey.u4KeyIndex = key_index;
+	rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, WARN, "remove key error:%x\n", rStatus);
+		if (WLAN_STATUS_FAILURE == rStatus && mac_addr) {
+			i4Rslt = -EBUSY;
+			gucKeyIndex = key_index;
+		}
+	} else {
+		gucKeyIndex = 255;
+		i4Rslt = 0;
+	}
+
+	return i4Rslt;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for setting default key on an interface
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+
+	/* not implemented */
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for setting set_default_mgmt_ke on an interface
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index)
+{
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for getting station information such as RSSI
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo)
+{
+#define LINKSPEED_MAX_RANGE_11BGN 3000
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	PARAM_MAC_ADDRESS arBssid;
+	UINT_32 u4BufLen;
+	UINT_32 u4Rate = 0;
+	UINT_32 u8diffTxBad, u8diffRetry;
+	INT_32 i4Rssi = 0;
+	PARAM_802_11_STATISTICS_STRUCT_T rStatistics;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	kalMemZero(arBssid, MAC_ADDR_LEN);
+	wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen);
+
+	/* 1. check BSSID */
+	if (UNEQUAL_MAC_ADDR(arBssid, mac)) {
+		/* wrong MAC address */
+		DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n",
+				   mac, arBssid);
+		return -ENOENT;
+	}
+
+	/* 2. fill TX rate */
+	if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
+		/* not connected */
+		DBGLOG(REQ, WARN, "not yet connected\n");
+	} else {
+		rStatus = kalIoctl(prGlueInfo,
+				wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
+
+		if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) {
+			/* DBGLOG(REQ, WARN, "unable to retrieve link speed\n")); */
+			DBGLOG(REQ, WARN, "last link speed\n");
+			sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache;
+		} else {
+			/* sinfo->filled |= STATION_INFO_TX_BITRATE; */
+			sinfo->txrate.legacy = u4Rate / 1000;	/* convert from 100bps to 100kbps */
+			prGlueInfo->u4LinkSpeedCache = u4Rate / 1000;
+		}
+	}
+
+	/* 3. fill RSSI */
+	if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
+		/* not connected */
+		DBGLOG(REQ, WARN, "not yet connected\n");
+	} else {
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+
+		if (rStatus != WLAN_STATUS_SUCCESS || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM)
+		|| (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) {
+			/* DBGLOG(REQ, WARN, "unable to retrieve link speed\n"); */
+			DBGLOG(REQ, WARN, "last rssi\n");
+			sinfo->signal = prGlueInfo->i4RssiCache;
+		} else {
+			/* in the cfg80211 layer, the signal is a signed char variable. */
+			sinfo->signal = i4Rssi;	/* dBm */
+			prGlueInfo->i4RssiCache = i4Rssi;
+		}
+		sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets;
+
+		/* 4. Fill Tx OK and Tx Bad */
+
+		sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
+		sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
+		{
+			WLAN_STATUS rStatus;
+
+			kalMemZero(&rStatistics, sizeof(rStatistics));
+			/* Get Tx OK/Fail cnt from AIS statistic counter */
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidQueryStatisticsPL,
+					   &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				DBGLOG(REQ, WARN, "unable to retrieive statistic\n");
+			} else {
+				INT_32 i4RssiThreshold = -85;	/* set rssi threshold -85dBm */
+				UINT_32 u4LinkspeedThreshold = 55;	/* set link speed threshold 5.5Mbps */
+				BOOLEAN fgWeighted = 0;
+
+				/* calculate difference */
+				u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0];
+				u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1];
+				/* restore counters */
+				prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart;
+				prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart;
+
+				/* check threshold is valid */
+				if (prGlueInfo->fgPoorlinkValid) {
+					if (prGlueInfo->i4RssiThreshold)
+						i4RssiThreshold = prGlueInfo->i4RssiThreshold;
+					if (prGlueInfo->u4LinkspeedThreshold)
+						u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold;
+				}
+				/* add weighted to fail counter */
+				if (sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold) {
+					prGlueInfo->u8TotalFailCnt += (u8diffTxBad * 16 + u8diffRetry);
+					fgWeighted = 1;
+				} else {
+					prGlueInfo->u8TotalFailCnt += u8diffTxBad;
+				}
+				/* report counters */
+				prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart;
+				prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt;
+
+				sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets;
+				sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors;
+				/* Good Fail Bad Difference retry difference Linkspeed Rate Weighted */
+				DBGLOG(REQ, TRACE,
+					"Poorlink State TxOK(%d) TxFail(%d) Bad(%d) Retry(%d)",
+					sinfo->tx_packets,
+					sinfo->tx_failed,
+					(int)u8diffTxBad,
+					(int)u8diffRetry);
+				DBGLOG(REQ, TRACE,
+					"Rate(%d) Signal(%d) Weight(%d) QuadPart(%d)\n",
+					sinfo->txrate.legacy,
+					sinfo->signal,
+					(int)fgWeighted,
+					(int)rStatistics.rMultipleRetryCount.QuadPart);
+			}
+		}
+
+	}
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for adding a station information
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
+				const u8 *mac, struct station_parameters *params)
+{
+#if (CFG_SUPPORT_TDLS == 1)
+	/*
+	   EX: In supplicant,
+	   (Supplicant) wpa_tdls_process_tpk_m3() ->
+	   (Supplicant) wpa_tdls_enable_link() ->
+	   (Supplicant) wpa_sm_tdls_peer_addset() ->
+	   (Supplicant) ..tdls_peer_addset() ->
+	   (Supplicant) wpa_supplicant_tdls_peer_addset() ->
+	   (Supplicant) wpa_drv_sta_add() ->
+	   (Supplicant) ..sta_add() ->
+	   (Supplicant) wpa_driver_nl80211_sta_add() ->
+	   (NL80211) nl80211_set_station() ->
+	   (Driver) mtk_cfg80211_change_station()
+
+	   if nl80211_set_station fails, supplicant will tear down the link.
+	 */
+	P_GLUE_INFO_T prGlueInfo;
+	TDLS_CMD_PEER_UPDATE_T rCmdUpdate;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen, u4Temp;
+
+	/* sanity check */
+	if ((wiphy == NULL) || (mac == NULL) || (params == NULL))
+		return -EINVAL;
+
+	DBGLOG(TDLS, INFO, "%s: 0x%p 0x%x\n", __func__, params->supported_rates, params->sta_flags_set);
+
+	if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
+		return -EOPNOTSUPP;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	if (prGlueInfo == NULL)
+		return -EINVAL;
+
+	/* TODO: check if we are station mode, not AP mode */
+
+	/* init */
+	kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate));
+	kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6);
+
+	if (params->supported_rates != NULL) {
+		u4Temp = params->supported_rates_len;
+		if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX) {
+			u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX;
+			DBGLOG(TDLS, ERROR, "%s sup rate too long: %d\n", __func__, params->supported_rates_len);
+		}
+		kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp);
+		rCmdUpdate.u2SupRateLen = u4Temp;
+	}
+
+	/*
+	   In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM
+	   So force to support UAPSD here.
+	 */
+	rCmdUpdate.UapsdBitmap = 0x0F;	/*params->uapsd_queues; */
+	rCmdUpdate.UapsdMaxSp = 0;	/*params->max_sp; */
+
+	DBGLOG(TDLS, INFO, "%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n",
+			    __func__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp);
+
+	rCmdUpdate.u2Capability = params->capability;
+
+	if (params->ext_capab != NULL) {
+		u4Temp = params->ext_capab_len;
+		if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN) {
+			u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN;
+			DBGLOG(TDLS, ERROR, "%s ext_capab too long: %d\n", __func__, params->ext_capab_len);
+		}
+		kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp);
+		rCmdUpdate.u2ExtCapLen = u4Temp;
+	}
+
+	if (params->ht_capa != NULL) {
+		DBGLOG(TDLS, INFO, "%s: peer is 11n device\n", __func__);
+
+		rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info;
+		rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info;
+		rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info;
+		rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info;
+		rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info;
+		kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask,
+			   params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask));
+		rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest;
+		rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params;
+		rCmdUpdate.fgIsSupHt = TRUE;
+	}
+
+	/* update a TDLS peer record */
+	rStatus = kalIoctl(prGlueInfo,
+			   TdlsexPeerUpdate,
+			   &rCmdUpdate, sizeof(TDLS_CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s update error:%x\n", __func__, rStatus);
+		return -EINVAL;
+	}
+#endif /* CFG_SUPPORT_TDLS */
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for adding a station information
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev,
+				const u8 *mac, struct station_parameters *params)
+{
+#if (CFG_SUPPORT_TDLS == 1)
+	/* from supplicant -- wpa_supplicant_tdls_peer_addset() */
+	P_GLUE_INFO_T prGlueInfo;
+	TDLS_CMD_PEER_ADD_T rCmdCreate;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+
+	if ((wiphy == NULL) || (mac == NULL) || (params == NULL))
+		return -EINVAL;
+
+	/*
+	   wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
+	   NULL, 0);
+
+	   wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
+	   u16 aid, u16 capability, const u8 *supp_rates,
+	   size_t supp_rates_len,
+	   const struct ieee80211_ht_capabilities *ht_capab,
+	   const struct ieee80211_vht_capabilities *vht_capab,
+	   u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
+
+	   Only MAC address of the peer is valid.
+	 */
+
+	DBGLOG(TDLS, INFO, "%s: 0x%p %d\n", __func__, params->supported_rates, params->supported_rates_len);
+
+	/* sanity check */
+	if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
+		return -EOPNOTSUPP;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	if (prGlueInfo == NULL)
+		return -EINVAL;
+
+	/* TODO: check if we are station mode, not AP mode */
+
+	/* init */
+	kalMemZero(&rCmdCreate, sizeof(rCmdCreate));
+	kalMemCopy(rCmdCreate.aucPeerMac, mac, 6);
+
+#if 0
+	rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
+
+	rCmdCreate.u2CapInfo = params->capability;
+
+	DBGLOG(TDLS, INFO, "<tdls_cmd> %s: capability = 0x%x\n", __func__, rCmdCreate.u2CapInfo);
+
+	if ((params->supported_rates != NULL) && (params->supported_rates_len != 0)) {
+		UINT32 u4Idx;
+
+		DBGLOG(TDLS, INFO, "<tdls_cmd> %s: sup rate = 0x", __func__);
+
+		rIeSup.ucId = ELEM_ID_SUP_RATES;
+		rIeSup.ucLength = params->supported_rates_len;
+		for (u4Idx = 0; u4Idx < rIeSup.ucLength; u4Idx++) {
+			rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx];
+			DBGLOG(TDLS, INFO, "%x ", rIeSup.aucSupportedRates[u4Idx]);
+		}
+		DBGLOG(TDLS, INFO, "\n");
+
+		rateGetRateSetFromIEs(&rIeSup,
+				      NULL,
+				      &rCmdCreate.u2OperationalRateSet,
+				      &rCmdCreate.u2BSSBasicRateSet, &rCmdCreate.fgIsUnknownBssBasicRate);
+	}
+
+	/* phy type */
+#endif
+
+	/* create a TDLS peer record */
+	rStatus = kalIoctl(prGlueInfo,
+			   TdlsexPeerAdd,
+			   &rCmdCreate, sizeof(TDLS_CMD_PEER_ADD_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(TDLS, ERROR, "%s create error:%x\n", __func__, rStatus);
+		return -EINVAL;
+	}
+#endif /* CFG_SUPPORT_TDLS */
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for deleting a station information
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ *
+ * @other
+ *		must implement if you have add_station().
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params)
+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac)
+{
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to do a scan
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+static PARAM_SCAN_REQUEST_EXT_T rScanRequest;
+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+/* PARAM_SCAN_REQUEST_EXT_T rScanRequest; */
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	DBGLOG(REQ, TRACE, "mtk_cfg80211_scan\n");
+	kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T));
+
+	/* check if there is any pending scan not yet finished */
+	if (prGlueInfo->prScanRequest != NULL) {
+		DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n");
+		return -EBUSY;
+	}
+
+	if (request->n_ssids == 0) {
+		rScanRequest.rSsid.u4SsidLen = 0;
+	} else if (request->n_ssids == 1) {
+		COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid,
+			  request->ssids[0].ssid_len);
+	} else {
+		DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", request->n_ssids);
+		return -EINVAL;
+	}
+
+	if (request->ie_len > 0) {
+		rScanRequest.u4IELength = request->ie_len;
+		rScanRequest.pucIE = (PUINT_8) (request->ie);
+	} else {
+		rScanRequest.u4IELength = 0;
+	}
+#if 0
+	prGlueInfo->prScanRequest = request;
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetBssidListScanExt,
+			   &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus);
+		prGlueInfo->prScanRequest = NULL;
+		return -EINVAL;
+	}
+
+	/*prGlueInfo->prScanRequest = request;*/
+#endif
+
+	prGlueInfo->prScanRequest = request;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetBssidListScanExt,
+			   &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		prGlueInfo->prScanRequest = NULL;
+		DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static UINT_8 wepBuf[48];
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to connect to
+ *        the ESS with the specified parameters
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
+	ENUM_PARAM_AUTH_MODE_T eAuthMode;
+	UINT_32 cipher;
+	PARAM_CONNECT_T rNewSsid;
+	BOOLEAN fgCarryWPSIE = FALSE;
+	ENUM_PARAM_OP_MODE_T eOpMode;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	DBGLOG(REQ, TRACE, "[wlan] mtk_cfg80211_connect %p %zu\n", sme->ie, sme->ie_len);
+
+	if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH)
+		eOpMode = NET_TYPE_AUTO_SWITCH;
+	else
+		eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetInfrastructureMode,
+			   &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus);
+		return -EFAULT;
+	}
+
+	/* after set operation mode, key table are cleared */
+
+	/* reset wpa info */
+	prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
+	prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
+	prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
+#if CFG_SUPPORT_802_11W
+	prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
+#endif
+
+	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+		prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA;
+	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
+		prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2;
+	else
+		prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
+
+	switch (sme->auth_type) {
+	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+		prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
+		break;
+	case NL80211_AUTHTYPE_SHARED_KEY:
+		prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY;
+		break;
+	default:
+		prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY;
+		break;
+	}
+
+	if (sme->crypto.n_ciphers_pairwise) {
+		prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] =
+		    sme->crypto.ciphers_pairwise[0];
+		switch (sme->crypto.ciphers_pairwise[0]) {
+		case WLAN_CIPHER_SUITE_WEP40:
+			prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40;
+			break;
+		case WLAN_CIPHER_SUITE_WEP104:
+			prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104;
+			break;
+		case WLAN_CIPHER_SUITE_TKIP:
+			prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP;
+			break;
+		case WLAN_CIPHER_SUITE_CCMP:
+			prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
+			break;
+		case WLAN_CIPHER_SUITE_AES_CMAC:
+			prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
+			break;
+		default:
+			DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]);
+			return -EINVAL;
+		}
+	}
+
+	if (sme->crypto.cipher_group) {
+		prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group;
+		switch (sme->crypto.cipher_group) {
+		case WLAN_CIPHER_SUITE_WEP40:
+			prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40;
+			break;
+		case WLAN_CIPHER_SUITE_WEP104:
+			prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104;
+			break;
+		case WLAN_CIPHER_SUITE_TKIP:
+			prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP;
+			break;
+		case WLAN_CIPHER_SUITE_CCMP:
+			prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
+			break;
+		case WLAN_CIPHER_SUITE_AES_CMAC:
+			prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
+			break;
+		default:
+			DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group);
+			return -EINVAL;
+		}
+	}
+
+	if (sme->crypto.n_akm_suites) {
+		prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] =
+		    sme->crypto.akm_suites[0];
+		if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) {
+			switch (sme->crypto.akm_suites[0]) {
+			case WLAN_AKM_SUITE_8021X:
+				eAuthMode = AUTH_MODE_WPA;
+				break;
+			case WLAN_AKM_SUITE_PSK:
+				eAuthMode = AUTH_MODE_WPA_PSK;
+				break;
+			default:
+				DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group);
+				return -EINVAL;
+			}
+		} else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) {
+			switch (sme->crypto.akm_suites[0]) {
+			case WLAN_AKM_SUITE_8021X:
+				eAuthMode = AUTH_MODE_WPA2;
+				break;
+			case WLAN_AKM_SUITE_PSK:
+				eAuthMode = AUTH_MODE_WPA2_PSK;
+				break;
+			default:
+				DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group);
+				return -EINVAL;
+			}
+		}
+	}
+
+	if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
+		eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
+		    AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
+	}
+
+	prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy;
+
+	prGlueInfo->fgWpsActive = FALSE;
+#if CFG_SUPPORT_HOTSPOT_2_0
+	prGlueInfo->fgConnectHS20AP = FALSE;
+#endif
+
+	if (sme->ie && sme->ie_len > 0) {
+		WLAN_STATUS rStatus;
+		UINT_32 u4BufLen;
+		PUINT_8 prDesiredIE = NULL;
+		PUINT_8 pucIEStart = (PUINT_8)sme->ie;
+
+#if CFG_SUPPORT_WAPI
+		if (wextSrchDesiredWAPIIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetWapiAssocInfo,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS)
+				DBGLOG(SEC, WARN, "[wapi] set wapi assoc info error:%x\n", rStatus);
+		}
+#endif
+
+		DBGLOG(REQ, TRACE, "[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n",
+				   prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode);
+
+#if CFG_SUPPORT_WPS2
+		if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) {
+			prGlueInfo->fgWpsActive = TRUE;
+			fgCarryWPSIE = TRUE;
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetWSCAssocInfo,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+			if (rStatus != WLAN_STATUS_SUCCESS)
+				DBGLOG(SEC, WARN, "WSC] set WSC assoc info error:%x\n", rStatus);
+		}
+#endif
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+		if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetHS20Info,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				/* Do nothing */
+				/* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */
+			}
+		}
+		if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetInterworkingInfo,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				/* Do nothing */
+				/* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */
+			}
+		}
+		if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetRoamingConsortiumIEInfo,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				/* Do nothing */
+				/* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */
+			}
+		}
+#endif
+	}
+
+	/* clear WSC Assoc IE buffer in case WPS IE is not detected */
+	if (fgCarryWPSIE == FALSE) {
+		kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200);
+		prGlueInfo->u2WSCAssocInfoIELen = 0;
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus);
+
+	cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise;
+
+	if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) {
+		if (cipher & IW_AUTH_CIPHER_CCMP) {
+			eEncStatus = ENUM_ENCRYPTION3_ENABLED;
+		} else if (cipher & IW_AUTH_CIPHER_TKIP) {
+			eEncStatus = ENUM_ENCRYPTION2_ENABLED;
+		} else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
+			eEncStatus = ENUM_ENCRYPTION1_ENABLED;
+		} else if (cipher & IW_AUTH_CIPHER_NONE) {
+			if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
+				eEncStatus = ENUM_ENCRYPTION1_ENABLED;
+			else
+				eEncStatus = ENUM_ENCRYPTION_DISABLED;
+		} else {
+			eEncStatus = ENUM_ENCRYPTION_DISABLED;
+		}
+	} else {
+		eEncStatus = ENUM_ENCRYPTION_DISABLED;
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetEncryptionStatus,
+			   &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(REQ, WARN, "set encryption mode error:%x\n", rStatus);
+
+	if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
+		P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
+
+		prWepKey->u4Length = 12 + sme->key_len;
+		prWepKey->u4KeyLength = (UINT_32) sme->key_len;
+		prWepKey->u4KeyIndex = (UINT_32) sme->key_idx;
+		prWepKey->u4KeyIndex |= BIT(31);
+		if (prWepKey->u4KeyLength > 32) {
+			DBGLOG(REQ, ERROR, "Too long key length (%u)\n", prWepKey->u4KeyLength);
+			return -EINVAL;
+		}
+		kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength);
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetAddWep,
+				   prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+		if (rStatus != WLAN_STATUS_SUCCESS) {
+			DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus);
+			return -EFAULT;
+		}
+	}
+
+	if (sme->channel)
+		rNewSsid.u4CenterFreq = sme->channel->center_freq;
+	else
+		rNewSsid.u4CenterFreq = 0;
+	rNewSsid.pucBssid = (UINT_8 *)sme->bssid;
+	rNewSsid.pucSsid = (UINT_8 *)sme->ssid;
+	rNewSsid.u4SsidLen = sme->ssid_len;
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetConnect,
+			   (PVOID)(&rNewSsid), sizeof(PARAM_CONNECT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, ERROR, "set SSID:%x\n", rStatus);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to disconnect from
+ *        currently connected ESS
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to join an IBSS group
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params)
+{
+	PARAM_SSID_T rNewSsid;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_32 u4ChnlFreq;	/* Store channel or frequency information */
+	UINT_32 u4BufLen = 0;
+	WLAN_STATUS rStatus;
+	struct ieee80211_channel *channel = NULL;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	/* set channel */
+	if (params->chandef.chan)
+		channel = params->chandef.chan;
+	if (channel) {
+		u4ChnlFreq = nicChannelNum2Freq(channel->hw_value);
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetFrequency,
+				   &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+		if (rStatus != WLAN_STATUS_SUCCESS)
+			return -EFAULT;
+	}
+
+	/* set SSID */
+	kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len);
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetSsid,
+			   (PVOID)(&rNewSsid), sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus);
+		return -EFAULT;
+	}
+
+	return 0;
+
+	return -EINVAL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to leave from IBSS group
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to configure
+ *        WLAN power managemenet
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	PARAM_POWER_MODE ePowerMode;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	if (enabled) {
+		if (timeout == -1)
+			ePowerMode = Param_PowerModeFast_PSP;
+		else
+			ePowerMode = Param_PowerModeMAX_PSP;
+	} else {
+		ePowerMode = Param_PowerModeCAM;
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSet802dot11PowerSaveProfile,
+			   &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to cache
+ *        a PMKID for a BSSID
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	P_PARAM_PMKID_T prPmkid;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE);
+	if (!prPmkid) {
+		DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n");
+		return -ENOMEM;
+	}
+
+	prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
+	prPmkid->u4BSSIDInfoCount = 1;
+	kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6);
+	kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(REQ, WARN, "add pmkid error:%x\n", rStatus);
+	kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to remove
+ *        a cached PMKID for a BSSID
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa)
+{
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to flush
+ *        all cached PMKID
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	P_PARAM_PMKID_T prPmkid;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE);
+	if (!prPmkid) {
+		DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_FLUSH\n");
+		return -ENOMEM;
+	}
+
+	prPmkid->u4Length = 8;
+	prPmkid->u4BSSIDInfoCount = 0;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(REQ, WARN, "flush pmkid error:%x\n", rStatus);
+	kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
+
+	return 0;
+}
+
+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy,
+				      IN struct wireless_dev *wdev,
+				      IN u16 frame_type, IN bool reg)
+{
+#if 0
+	P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL;
+#endif
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+
+	do {
+
+		DBGLOG(REQ, LOUD, "mtk_cfg80211_mgmt_frame_register\n");
+
+		prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+		switch (frame_type) {
+		case MAC_FRAME_PROBE_REQ:
+			if (reg) {
+				prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ;
+				DBGLOG(REQ, LOUD, "Open packet filer probe request\n");
+			} else {
+				prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ;
+				DBGLOG(REQ, LOUD, "Close packet filer probe request\n");
+			}
+			break;
+		case MAC_FRAME_ACTION:
+			if (reg) {
+				prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME;
+				DBGLOG(REQ, LOUD, "Open packet filer action frame.\n");
+			} else {
+				prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME;
+				DBGLOG(REQ, LOUD, "Close packet filer action frame.\n");
+			}
+			break;
+		default:
+			DBGLOG(REQ, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type);
+			break;
+		}
+
+		if (prGlueInfo->prAdapter != NULL) {
+			/* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */
+			set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag);
+
+			/* wake up main thread */
+			wake_up_interruptible(&prGlueInfo->waitq);
+
+			if (in_interrupt())
+				DBGLOG(REQ, TRACE, "It is in interrupt level\n");
+		}
+#if 0
+
+		prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter,
+										    RAM_TYPE_MSG,
+										    sizeof
+										    (MSG_P2P_MGMT_FRAME_REGISTER_T));
+
+		if (prMgmtFrameRegister == NULL) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER;
+
+		prMgmtFrameRegister->u2FrameType = frame_type;
+		prMgmtFrameRegister->fgIsRegister = reg;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF);
+
+#endif
+
+	} while (FALSE);
+
+}				/* mtk_cfg80211_mgmt_frame_register */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to stay on a
+ *        specified channel
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   struct ieee80211_channel *chan,
+				   unsigned int duration, u64 *cookie)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL))
+			break;
+
+		prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+		ASSERT(prGlueInfo);
+
+#if 1
+		DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+#endif
+
+		*cookie = prGlueInfo->u8Cookie++;
+
+		prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T));
+
+		if (prMsgChnlReq == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+		kalMemZero(prMsgChnlReq, sizeof(MSG_REMAIN_ON_CHANNEL_T));
+
+		prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL;
+		prMsgChnlReq->u8Cookie = *cookie;
+		prMsgChnlReq->u4DurationMs = duration;
+
+		prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000);
+
+		switch (chan->band) {
+		case NL80211_BAND_2GHZ:
+			prMsgChnlReq->eBand = BAND_2G4;
+			break;
+		case NL80211_BAND_5GHZ:
+			prMsgChnlReq->eBand = BAND_5G;
+			break;
+		default:
+			prMsgChnlReq->eBand = BAND_2G4;
+			break;
+		}
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to cancel staying
+ *        on a specified channel
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
+					  struct wireless_dev *wdev,
+					  u64 cookie)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (wdev == NULL))
+			break;
+
+		prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+		ASSERT(prGlueInfo);
+
+#if 1
+		DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+#endif
+
+		prMsgChnlAbort =
+		    cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T));
+
+		if (prMsgChnlAbort == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL;
+		prMsgChnlAbort->u8Cookie = cookie;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to send a management frame
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy,
+		     struct wireless_dev *wdev,
+		     struct cfg80211_mgmt_tx_params *params,
+		     u64 *cookie)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL;
+	P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL;
+	PUINT_8 pucFrameBuf = (PUINT_8) NULL;
+
+	do {
+#if 1
+		DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+#endif
+
+		if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL))
+			break;
+
+		prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+		ASSERT(prGlueInfo);
+
+		*cookie = prGlueInfo->u8Cookie++;
+
+		/* Channel & Channel Type & Wait time are ignored. */
+		prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T));
+
+		if (prMsgTxReq == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prMsgTxReq->fgNoneCckRate = FALSE;
+		prMsgTxReq->fgIsWaitRsp = TRUE;
+
+		prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD));
+		prMsgTxReq->prMgmtMsduInfo = prMgmtFrame;
+		if (prMsgTxReq->prMgmtMsduInfo == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prMsgTxReq->u8Cookie = *cookie;
+		prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX;
+
+		pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD);
+
+		kalMemCopy(pucFrameBuf, params->buf, params->len);
+
+		prMgmtFrame->u2FrameLength = params->len;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	if ((i4Rslt != 0) && (prMsgTxReq != NULL)) {
+		if (prMsgTxReq->prMgmtMsduInfo != NULL)
+			cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo);
+
+		cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq);
+	}
+
+	return i4Rslt;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for requesting to cancel the wait time
+ *        from transmitting a management frame on another channel
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     u64 cookie)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+
+	/* not implemented */
+
+	return -EINVAL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for handling sched_scan start/stop request
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+
+int
+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy,
+			      IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 i, u4BufLen;
+	P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	ASSERT(prGlueInfo);
+
+	/* check if there is any pending scan/sched_scan not yet finished */
+	if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) {
+		DBGLOG(SCN, ERROR, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n");
+		return -EBUSY;
+	} else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) {
+		DBGLOG(SCN, ERROR, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n");
+		/* invalid scheduled scan request */
+		return -EINVAL;
+	} else if (/* !request->n_ssids || */!request->n_match_sets) {
+		/* invalid scheduled scan request */
+		return -EINVAL;
+	}
+
+	prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE);
+	if (prSchedScanRequest == NULL) {
+		DBGLOG(SCN, ERROR, "(prSchedScanRequest == NULL) kalMemAlloc fail\n");
+		return -ENOMEM;
+	}
+
+	kalMemZero(prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST));
+
+	prSchedScanRequest->u4SsidNum = request->n_match_sets;
+	for (i = 0; i < request->n_match_sets; i++) {
+		if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) {
+			prSchedScanRequest->arSsid[i].u4SsidLen = 0;
+		} else {
+			COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid,
+				  prSchedScanRequest->arSsid[i].u4SsidLen,
+				  request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len);
+		}
+	}
+
+	prSchedScanRequest->u4IELength = request->ie_len;
+	if (request->ie_len > 0)
+		prSchedScanRequest->pucIE = (PUINT_8) (request->ie);
+
+	prSchedScanRequest->u2ScanInterval = (UINT_16) (request->scan_plans[0].interval);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetStartSchedScan,
+			   prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST));
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(SCN, ERROR, "scheduled scan error:%x\n", rStatus);
+		return -EINVAL;
+	}
+
+	prGlueInfo->prSchedScanRequest = request;
+
+	return 0;
+}
+
+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev, u64 reqid)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	/* check if there is any pending scan/sched_scan not yet finished */
+	if (prGlueInfo->prSchedScanRequest == NULL) {
+		DBGLOG(SCN, ERROR, "prGlueInfo->prSchedScanRequest == NULL\n");
+		return -EBUSY;
+	}
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(SCN, ERROR, "scheduled scan error, rStatus: %d\n", rStatus);
+		return -EINVAL;
+	}
+
+	/* 1. reset first for newly incoming request */
+	/* GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */
+	if (prGlueInfo->prSchedScanRequest != NULL)
+		prGlueInfo->prSchedScanRequest = NULL;
+	/* GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */
+
+	DBGLOG(SCN, TRACE, "start work queue to send event\n");
+	schedule_delayed_work(&sched_workq, 0);
+	DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n");
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for handling association request
+ *
+ * @param
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	PARAM_MAC_ADDRESS arBssid;
+#if CFG_SUPPORT_HOTSPOT_2_0
+	PUINT_8 prDesiredIE = NULL;
+#endif
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	kalMemZero(arBssid, MAC_ADDR_LEN);
+	wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen);
+
+	/* 1. check BSSID */
+	if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) {
+		/* wrong MAC address */
+		DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n",
+				   req->bss->bssid, arBssid);
+		return -ENOENT;
+	}
+
+	if (req->ie && req->ie_len > 0) {
+#if CFG_SUPPORT_HOTSPOT_2_0
+		if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetHS20Info,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				/* Do nothing */
+				/* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */
+			}
+		}
+
+		if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetInterworkingInfo,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				/* Do nothing */
+				/* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */
+			}
+		}
+
+		if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetRoamingConsortiumIEInfo,
+					   prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				/* Do nothing */
+				/* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */
+			}
+		}
+#endif
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetBssid,
+			   (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+#if CONFIG_NL80211_TESTMODE
+/*
+#define NLA_PUT(skb, attrtype, attrlen, data) \
+do { \
+	if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
+		goto nla_put_failure; \
+} while (0)
+
+#define NLA_PUT_TYPE(skb, type, attrtype, value) \
+do { \
+	type __tmp = value; \
+	NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
+} while (0)
+
+#define NLA_PUT_U8(skb, attrtype, value) \
+	 NLA_PUT_TYPE(skb, u8, attrtype, value)
+
+#define NLA_PUT_U16(skb, attrtype, value) \
+	 NLA_PUT_TYPE(skb, u16, attrtype, value)
+
+#define NLA_PUT_U32(skb, attrtype, value) \
+	 NLA_PUT_TYPE(skb, u32, attrtype, value)
+
+#define NLA_PUT_U64(skb, attrtype, value) \
+	 NLA_PUT_TYPE(skb, u64, attrtype, value)
+*/
+#if CFG_SUPPORT_WAPI
+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL;
+	struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL;
+	WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
+	int fgIsValid = 0;
+	UINT_32 u4BufLen = 0;
+
+	P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
+
+	memset(keyStructBuf, 0, sizeof(keyStructBuf));
+
+	ASSERT(wiphy);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+
+	if (data && len) {
+		prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data;
+	} else {
+		DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_key_ext, data is NULL\n");
+		return -EINVAL;
+	}
+
+	if (prParams)
+		prIWEncExt = (struct iw_encode_exts *)&prParams->ext;
+
+	if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
+		/* KeyID */
+		prWpiKey->ucKeyID = prParams->key_index;
+		prWpiKey->ucKeyID--;
+		if (prWpiKey->ucKeyID > 1) {
+			/* key id is out of range */
+			/* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */
+			return -EINVAL;
+		}
+
+		if (prIWEncExt->key_len != 32) {
+			/* key length not valid */
+			/* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */
+			return -EINVAL;
+		}
+		/* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */
+
+		if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+			prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
+			prWpiKey->eDirection = ENUM_WPI_RX;
+		} else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+			prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
+			prWpiKey->eDirection = ENUM_WPI_RX_TX;
+		}
+/* #if CFG_SUPPORT_WAPI */
+		/* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */
+/* #endif */
+		/* PN */
+		memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE);
+		memcpy(prWpiKey->aucPN + IW_ENCODE_SEQ_MAX_SIZE, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE);
+
+
+		/* BSSID */
+		memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6);
+
+		memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
+		prWpiKey->u4LenWPIEK = 16;
+
+		memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
+		prWpiKey->u4LenWPICK = 16;
+
+		rstatus = kalIoctl(prGlueInfo,
+				   wlanoidSetWapiKey,
+				   prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+		if (rstatus != WLAN_STATUS_SUCCESS) {
+			/* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */
+			fgIsValid = -EFAULT;
+		}
+
+	}
+	return fgIsValid;
+}
+#endif
+
+int
+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	INT_32 i4Status = -EINVAL;
+	UINT_32 u4BufLen;
+	UINT_32 u4LinkScore;
+	UINT_32 u4TotalError;
+	UINT_32 u4TxExceedThresholdCount;
+	UINT_32 u4TxTotalCount;
+
+	P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL;
+	PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics;
+	struct sk_buff *skb;
+
+	ASSERT(wiphy);
+	ASSERT(prGlueInfo);
+
+	if (data && len) {
+		prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data;
+	} else {
+		DBGLOG(QM, ERROR, "mtk_cfg80211_testmode_get_sta_statistics, data is NULL\n");
+		return -EINVAL;
+	}
+/*
+	if (!prParams->aucMacAddr) {
+		DBGLOG(QM, INFO, "%s MAC Address is NULL\n", __func__);
+		return -EINVAL;
+	}
+*/
+	skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
+
+	if (!skb) {
+		DBGLOG(QM, ERROR, "%s allocate skb failed:%x\n", __func__, rStatus);
+		return -ENOMEM;
+	}
+
+	DBGLOG(QM, TRACE, "Get [ %pM ] STA statistics\n", prParams->aucMacAddr);
+
+	kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics));
+	COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryStaStatistics,
+			   &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen);
+
+	/* Calcute Link Score */
+	u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount;
+	u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount;
+	u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount;
+
+	/* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */
+	/* u4LinkScore 0~9    , Drop packet ratio 0~9 and all packets exceed threshold */
+	if (u4TxTotalCount) {
+		if (u4TxExceedThresholdCount <= u4TxTotalCount)
+			u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount));
+		else
+			u4LinkScore = 0;
+	} else {
+		u4LinkScore = 90;
+	}
+
+	u4LinkScore += 10;
+
+	if (u4LinkScore == 10) {
+
+		if (u4TotalError <= u4TxTotalCount)
+			u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount));
+		else
+			u4LinkScore = 0;
+
+	}
+
+	if (u4LinkScore > 100)
+		u4LinkScore = 100;
+
+	/*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/
+	{
+		unsigned char __tmp = 0;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);*/
+	{
+		unsigned char __tmp = NL80211_DRIVER_TESTMODE_VERSION;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(unsigned char), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/* NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); */
+	{
+		unsigned int __tmp = u4LinkScore;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);*/
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, &prParams->aucMacAddr) < 0))
+		goto nla_put_failure;
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4Flag;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+
+	/* FW part STA link status */
+	/*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);*/
+	{
+		unsigned char __tmp = rQueryStaStatistics.ucPer;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(unsigned char), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);*/
+	{
+		unsigned char __tmp = rQueryStaStatistics.ucRcpi;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(unsigned char), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4PhyMode;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);*/
+	{
+		unsigned short __tmp = rQueryStaStatistics.u2LinkSpeed;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE,
+			sizeof(unsigned short), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxFailCount;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxAverageAirTime;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/* Driver part link status */
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxTotalCount;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT,
+		rQueryStaStatistics.u4TxExceedThresholdCount);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxExceedThresholdCount;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME,
+		rQueryStaStatistics.u4TxAverageProcessTime);*/
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxAverageProcessTime;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxMaxTime;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxAverageHifTime;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4TxMaxHifTime;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, rQueryStaStatistics.u4EnqueueCounter);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4EnqueueCounter;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, rQueryStaStatistics.u4DequeueCounter);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4DequeueCounter;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, rQueryStaStatistics.u4EnqueueStaCounter);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4EnqueueStaCounter;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, rQueryStaStatistics.u4DequeueStaCounter);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.u4DequeueStaCounter;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, rQueryStaStatistics.IsrCnt);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.IsrCnt;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, rQueryStaStatistics.IsrPassCnt);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.IsrPassCnt;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, rQueryStaStatistics.TaskIsrCnt);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.TaskIsrCnt;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, rQueryStaStatistics.IsrAbnormalCnt);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.IsrAbnormalCnt;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, rQueryStaStatistics.IsrSoftWareCnt);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.IsrSoftWareCnt;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, rQueryStaStatistics.IsrTxCnt);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.IsrTxCnt;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*
+	 *NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, rQueryStaStatistics.IsrRxCnt);
+	 */
+	{
+		unsigned int __tmp = rQueryStaStatistics.IsrRxCnt;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/* Network counter */
+	/*NLA_PUT(skb,
+		NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount);*/
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), &rQueryStaStatistics.au4TcResourceEmptyCount) < 0))
+		goto nla_put_failure;
+	/*
+	NLA_PUT(skb,
+		NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY,
+		sizeof(rQueryStaStatistics.au4DequeueNoTcResource), rQueryStaStatistics.au4DequeueNoTcResource);
+	 */
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY,
+		sizeof(rQueryStaStatistics.au4DequeueNoTcResource), &rQueryStaStatistics.au4DequeueNoTcResource) < 0))
+		goto nla_put_failure;
+	/*
+	NLA_PUT(skb,
+		NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcResourceBackCount), rQueryStaStatistics.au4TcResourceBackCount);
+	 */
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcResourceBackCount), &rQueryStaStatistics.au4TcResourceBackCount) < 0))
+		goto nla_put_failure;
+
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcResourceUsedCount), &rQueryStaStatistics.au4TcResourceUsedCount) < 0))
+		goto nla_put_failure;
+
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcResourceWantedCount),
+		&rQueryStaStatistics.au4TcResourceWantedCount) < 0))
+		goto nla_put_failure;
+
+	/* Sta queue length */
+	/*NLA_PUT(skb,
+		NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen);*/
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcQueLen), &rQueryStaStatistics.au4TcQueLen) < 0))
+		goto nla_put_failure;
+
+
+	/* Global QM counter */
+	/*NLA_PUT(skb,
+		NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen);*/
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcAverageQueLen), &rQueryStaStatistics.au4TcAverageQueLen) < 0))
+		goto nla_put_failure;
+
+	/*NLA_PUT(skb,
+		NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen);*/
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY,
+		sizeof(rQueryStaStatistics.au4TcCurrentQueLen), &rQueryStaStatistics.au4TcCurrentQueLen) < 0))
+		goto nla_put_failure;
+
+
+	/* Reserved field */
+	/*NLA_PUT(skb,
+		NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY,
+		sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved);*/
+	if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY,
+		sizeof(rQueryStaStatistics.au4Reserved), &rQueryStaStatistics.au4Reserved) < 0))
+		goto nla_put_failure;
+
+	i4Status = cfg80211_testmode_reply(skb);
+	skb = NULL;
+
+nla_put_failure:
+	if (skb != NULL)
+		kfree_skb(skb);
+	return i4Status;
+}
+
+int
+mtk_cfg80211_testmode_get_link_detection(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
+{
+
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	INT_32 i4Status = -EINVAL;
+	UINT_32 u4BufLen;
+
+	PARAM_802_11_STATISTICS_STRUCT_T rStatistics;
+	struct sk_buff *skb;
+
+	ASSERT(wiphy);
+	ASSERT(prGlueInfo);
+
+	skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
+
+	if (!skb) {
+		DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus);
+		return -ENOMEM;
+	}
+
+	kalMemZero(&rStatistics, sizeof(rStatistics));
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryStatistics,
+			   &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
+
+	/*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/
+	{
+		unsigned char __tmp = 0;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);*/
+	{
+		u64 __tmp = rStatistics.rFailedCount.QuadPart;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT,
+			sizeof(u64), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);*/
+	{
+		u64 __tmp = rStatistics.rFailedCount.QuadPart;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT,
+			sizeof(u64), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);*/
+	{
+		u64 __tmp = rStatistics.rMultipleRetryCount.QuadPart;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT,
+			sizeof(u64), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);*/
+	{
+		u64 __tmp = rStatistics.rACKFailureCount.QuadPart;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT,
+			sizeof(u64), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);*/
+	{
+		u64 __tmp = rStatistics.rFCSErrorCount.QuadPart;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT,
+			sizeof(u64), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+
+	i4Status = cfg80211_testmode_reply(skb);
+	skb = NULL;
+
+nla_put_failure:
+	if (skb != NULL)
+		kfree_skb(skb);
+	return i4Status;
+}
+
+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL;
+	WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
+	int fgIsValid = 0;
+	UINT_32 u4SetInfoLen = 0;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+
+	if (data && len)
+		prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data;
+
+	if (prParams) {
+		if (prParams->set == 1) {
+			rstatus = kalIoctl(prGlueInfo,
+					   (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite,
+					   &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+		}
+	}
+
+	if (WLAN_STATUS_SUCCESS != rstatus)
+		fgIsValid = -EFAULT;
+
+	return fgIsValid;
+}
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct wpa_driver_hs20_data_s *prParams = NULL;
+	WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
+	int fgIsValid = 0;
+	UINT_32 u4SetInfoLen = 0;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
+
+	if (data && len) {
+		prParams = (struct wpa_driver_hs20_data_s *)data;
+
+		DBGLOG(REQ, TRACE, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType);
+	}
+
+	if (prParams) {
+		int i;
+
+		switch (prParams->CmdType) {
+		case HS20_CMD_ID_SET_BSSID_POOL:
+			DBGLOG(REQ, TRACE, "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n",
+				prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable,
+				prParams->hs20_set_bssid_pool.ucNumBssidPool);
+			for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) {
+				DBGLOG(REQ, TRACE, "[%d][ %pM ]\n", i,
+					(prParams->hs20_set_bssid_pool.arBssidPool[i]));
+			}
+			rstatus = kalIoctl(prGlueInfo,
+					(PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool,
+					&prParams->hs20_set_bssid_pool,
+					sizeof(struct param_hs20_set_bssid_pool),
+					FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+			break;
+		default:
+			DBGLOG(REQ, TRACE, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType);
+			rstatus = WLAN_STATUS_FAILURE;
+
+		}
+
+	}
+
+	if (WLAN_STATUS_SUCCESS != rstatus)
+		fgIsValid = -EFAULT;
+
+	return fgIsValid;
+}
+
+#endif
+int
+mtk_cfg80211_testmode_set_poorlink_param(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
+{
+	int fgIsValid = 0;
+	P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL;
+
+	ASSERT(wiphy);
+	ASSERT(prGlueInfo);
+
+	if (data && len) {
+		prParams = (P_NL80211_DRIVER_POORLINK_PARAMS) data;
+	} else {
+		DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_poorlink_param, data is NULL\n");
+		return -EINVAL;
+	}
+	if (prParams->ucLinkSpeed)
+		prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed * 10;
+	if (prParams->cRssi)
+		prGlueInfo->i4RssiThreshold = prParams->cRssi;
+	if (!prGlueInfo->fgPoorlinkValid)
+		prGlueInfo->fgPoorlinkValid = 1;
+#if 0
+	DBGLOG(REQ, TRACE, "poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n",
+	       prGlueInfo->fgPoorlinkValid, prGlueInfo->i4RssiThreshold, prGlueInfo->u4LinkspeedThreshold);
+#endif
+
+	return fgIsValid;
+
+}
+
+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL;
+	INT_32 i4Status = -EINVAL;
+#if CFG_SUPPORT_HOTSPOT_2_0
+	BOOLEAN fgIsValid = 0;
+#endif
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	if (data && len) {
+		prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data;
+	} else {
+		DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n");
+		return i4Status;
+	}
+
+	/* Clear the version byte */
+	prParams->index = prParams->index & ~BITS(24, 31);
+
+	if (prParams) {
+		switch (prParams->index) {
+		case TESTMODE_CMD_ID_SW_CMD:	/* SW cmd */
+			i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len);
+			break;
+		case TESTMODE_CMD_ID_WAPI:	/* WAPI */
+#if CFG_SUPPORT_WAPI
+			i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len);
+#endif
+			break;
+		case TESTMODE_CMD_ID_SUSPEND:
+			{
+				P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS) data;
+
+				if (prParams->suspend == 1) {
+					wlanHandleSystemSuspend();
+					if (prGlueInfo->prAdapter->fgIsP2PRegistered)
+						p2pHandleSystemSuspend();
+					i4Status = 0;
+				} else if (prParams->suspend == 0) {
+					wlanHandleSystemResume();
+					if (prGlueInfo->prAdapter->fgIsP2PRegistered)
+						p2pHandleSystemResume();
+					i4Status = 0;
+				}
+				break;
+			}
+		case TESTMODE_CMD_ID_STATISTICS:
+			i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo);
+			break;
+		case TESTMODE_CMD_ID_LINK_DETECT:
+			i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo);
+			break;
+		case TESTMODE_CMD_ID_POORLINK:
+			i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo);
+			break;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+		case TESTMODE_CMD_ID_HS20:
+			if (mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len))
+				fgIsValid = TRUE;
+			break;
+#endif
+		default:
+			i4Status = -EINVAL;
+			break;
+		}
+	}
+
+	return i4Status;
+}
+
+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
+{
+#define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0
+#define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0;
+
+/* P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; */
+	struct sk_buff *skb;
+
+	ASSERT(wiphy);
+	ASSERT(prGlueInfo);
+
+	skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32));
+	READY_TO_BEAM =
+	    (UINT_32) (prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.
+		       fgIsGOInitialDone) &
+	    (!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest);
+	DBGLOG(QM, TRACE,
+	       "NFC:GOInitialDone[%d] and P2PScanning[%d]\n",
+		prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone,
+		prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest);
+
+	if (!skb) {
+		DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus);
+		return -ENOMEM;
+	}
+
+	/*NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);*/
+	{
+		unsigned char __tmp = 0;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, sizeof(unsigned char), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);*/
+	{
+		unsigned int __tmp = READY_TO_BEAM;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+
+	i4Status = cfg80211_testmode_reply(skb);
+	skb = NULL;
+
+nla_put_failure:
+	if (skb != NULL)
+		kfree_skb(skb);
+	return i4Status;
+}
+
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+int
+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
+{
+#define MAXMUN_2_4G_CHA_NUM 14
+#define CHN_DIRTY_WEIGHT_UPPERBOUND 4
+
+	BOOLEAN fgIsReady = FALSE, fgIsFistRecord = TRUE;
+	BOOLEAN fgIsPureAP, fgIsLteSafeChn = FALSE;
+
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucDefaultIdx = 0, ucArrayIdx = 0;
+	UINT_16 u2APNumScore = 0, u2UpThreshold = 0, u2LowThreshold = 0, ucInnerIdx = 0;
+	INT_32 i4Status = -EINVAL;
+	UINT_32 u4BufLen, u4LteSafeChnBitMask_2_4G = 0;
+	UINT32 AcsChnReport[4];
+	/*RF_CHANNEL_INFO_T aucChannelList[MAXMUN_2_4G_CHA_NUM];*/
+
+	struct sk_buff *skb;
+
+	/*PARAM_GET_CHN_LOAD rQueryLTEChn;*/
+	P_PARAM_GET_CHN_LOAD prQueryLTEChn;
+	PARAM_PREFER_CHN_INFO rPreferChannels[2], ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM];
+	P_PARAM_CHN_LOAD_INFO prChnLoad;
+	P_PARAM_GET_CHN_LOAD prGetChnLoad;
+
+	P_DOMAIN_INFO_ENTRY prDomainInfo;
+
+/*
+	 P_PARAM_GET_CHN_LOAD prParams = NULL;
+*/
+	ASSERT(wiphy);
+	ASSERT(prGlueInfo);
+
+	kalMemZero(rPreferChannels, sizeof(rPreferChannels));
+	fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode;
+#if 0
+	if (data && len)
+		prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS) data;
+#endif
+	skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(AcsChnReport) + sizeof(UINT8) + 1);
+	if (!skb) {
+		DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus);
+		return -ENOMEM;
+	}
+
+	DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n");
+	prQueryLTEChn = kalMemAlloc(sizeof(PARAM_GET_CHN_LOAD), VIR_MEM_TYPE);
+	if (prQueryLTEChn == NULL) {
+		DBGLOG(QM, TRACE, "alloc QueryLTEChn fail\n");
+		kalMemFree(skb, VIR_MEM_TYPE, sizeof(struct sk_buff));
+		return -ENOMEM;
+	}
+	kalMemZero(prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD));
+
+	/* Query LTE Safe Channels */
+	prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]
+			= 0xFFFFFFFF;
+
+	prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]
+			= 0xFFFFFFFF;
+
+	prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]
+			= 0xFFFFFFFF;
+
+	prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] =
+	    0xFFFFFFFF;
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidQueryACSChannelList, prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD),
+			TRUE, FALSE, TRUE, TRUE, &u4BufLen);
+#if 0
+	if (fgIsPureAP) {
+
+		AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20;	/* Channel 6 */
+	} else
+#endif
+	{
+		fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit;
+		rPreferChannels[0].u2APNum = 0xFFFF;
+		rPreferChannels[1].u2APNum = 0xFFFF;
+
+		/* 4 In LTE Mode, Hotspot pick up channels from ch4. */
+		ucDefaultIdx = 0;
+		/*
+		   if (fgIsPureAP) {
+		   ucDefaultIdx=3; //SKIP LTE Channels 1~3
+		   }
+		 */
+
+		/* 4 Get the Maximun channel List in 2.4G Bands */
+
+		prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter);
+		ASSERT(prDomainInfo);
+
+		/* 4 ToDo: Enable Step 2 only if we could get Country Code from framework */
+		/* 4 2. Get current domain channel list */
+
+#if 0
+		rlmDomainGetChnlList(prGlueInfo->prAdapter,
+				     BAND_2G4, MAXMUN_2_4G_CHA_NUM, &ucMax_24G_Chn_List, aucChannelList);
+#endif
+
+		prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo);
+		for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
+			DBGLOG(P2P, INFO,
+			       "[Auto Channel] ch[%d]=%d\n", ucIdx,
+				prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx].u2APNum);
+		}
+
+		/*Calculate Each Channel Direty Score */
+		for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
+
+#if 1
+			u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND;
+			u2UpThreshold = u2LowThreshold = 3;
+
+			if (ucIdx < 3) {
+				u2UpThreshold = ucIdx;
+				u2LowThreshold = 3;
+			} else if (ucIdx >= (ucMax_24G_Chn_List - 3)) {
+				u2UpThreshold = 3;
+				u2LowThreshold = ucMax_24G_Chn_List - (ucIdx + 1);
+
+			}
+
+			/*Calculate Lower Channel Dirty Score */
+			for (ucInnerIdx = 0; ucInnerIdx < u2LowThreshold; ucInnerIdx++) {
+				ucArrayIdx = ucIdx + ucInnerIdx + 1;
+				if (ucArrayIdx < MAX_AUTO_CHAL_NUM) {
+					u2APNumScore +=
+					    (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum *
+					     (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx));
+				}
+			}
+
+			/*Calculate Upper Channel Dirty Score */
+			for (ucInnerIdx = 0; ucInnerIdx < u2UpThreshold; ucInnerIdx++) {
+				ucArrayIdx = ucIdx - ucInnerIdx - 1;
+				if (ucArrayIdx < MAX_AUTO_CHAL_NUM) {
+					u2APNumScore +=
+					    (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum *
+					     (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx));
+				}
+			}
+
+			ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
+
+			DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx, u2APNumScore);
+#else
+			if (ucIdx == 0) {
+				/* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum =
+				(prGetChnLoad->rEachChnLoad[ucIdx].u2APNum +
+				prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */
+				u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16)
+											     ((3 *
+											       (prGetChnLoad->
+												rEachChnLoad[ucIdx +
+													     1].
+												u2APNum +
+												prGetChnLoad->
+												rEachChnLoad[ucIdx +
+													     2].
+												u2APNum)) / 4)));
+
+				ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
+				DBGLOG(P2P, INFO,
+				       "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx,
+					ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
+					prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
+					prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum));
+			}
+			if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) {
+				u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16)
+											     ((3 *
+											       (prGetChnLoad->
+												rEachChnLoad[ucIdx +
+													     1].
+												u2APNum +
+												prGetChnLoad->
+												rEachChnLoad[ucIdx -
+													     1].
+												u2APNum)) / 4)));
+
+				ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
+				DBGLOG(P2P, INFO,
+				       "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx,
+					ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
+					prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
+					prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum,
+					prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum));
+			}
+
+			if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) {
+				u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum +
+						((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4)));
+
+				ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
+				DBGLOG(P2P, INFO,
+				       "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx,
+					ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
+					prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
+					prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum));
+			}
+#endif
+
+		}
+
+		u4LteSafeChnBitMask_2_4G =
+		    prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1];
+
+		/*Find out the best channel */
+		for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
+			/* 4 Skip LTE Unsafe Channel */
+			fgIsLteSafeChn = ((u4LteSafeChnBitMask_2_4G & BIT(ucIdx + 1)) >> ucIdx);
+			if (!fgIsLteSafeChn)
+				continue;
+
+			prChnLoad =
+			    (P_PARAM_CHN_LOAD_INFO) &(prGlueInfo->prAdapter->rWifiVar.
+						       rChnLoadInfo.rEachChnLoad[ucIdx]);
+			if (rPreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) {
+				rPreferChannels[1].ucChannel = rPreferChannels[0].ucChannel;
+				rPreferChannels[1].u2APNum = rPreferChannels[0].u2APNum;
+
+				rPreferChannels[0].ucChannel = ucIdx;
+				rPreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum;
+			} else {
+				if (rPreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum
+				    || fgIsFistRecord == 1) {
+					fgIsFistRecord = FALSE;
+					rPreferChannels[1].ucChannel = ucIdx;
+					rPreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum;
+				}
+			}
+		}
+		/* AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] =
+		BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1)); */
+		AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0;
+		AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |= BIT(rPreferChannels[0].ucChannel);
+	}
+
+	/* ToDo: Support 5G Channel Selection */
+	AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344;
+	AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788;
+	AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC;
+
+	/*NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);*/
+	{
+		unsigned char __tmp = 0;
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, sizeof(unsigned char), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1,
+		    AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]);*/
+	{
+		unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1];
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34,
+		    AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]);*/
+	{
+		unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1];
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149,
+		    AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]);*/
+	{
+		unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1];
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+
+	/*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184,
+		    AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]);*/
+	{
+		unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1];
+
+		if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	DBGLOG(P2P, INFO,
+	       "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n", AcsChnReport[0], AcsChnReport[1], AcsChnReport[2],
+		AcsChnReport[3]);
+
+	i4Status = cfg80211_testmode_reply(skb);
+	/*need confirm cfg80211_testmode_reply will free skb*/
+	skb = NULL;
+	/*kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));*/
+
+nla_put_failure:
+	kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));
+	if (skb != NULL)
+		kfree_skb(skb);
+	return i4Status;
+
+}
+#endif
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief cfg80211 suspend callback, will be invoked in wiphy_suspend
+ *
+ * @param wiphy: pointer to wiphy
+ *		wow: pointer to cfg80211_wowlan
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int	mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	if (kalHaltTryLock())
+		return 0;
+
+	if (kalIsHalted() || !wiphy)
+		goto end;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prGlueInfo->prAdapter->ulSuspendFlag);
+	set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prGlueInfo->prAdapter->ulSuspendFlag);
+end:
+	kalHaltUnlock();
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief cfg80211 resume callback, will be invoked in wiphy_resume.
+ *
+ * @param wiphy: pointer to wiphy
+ *
+ * @retval 0:       successful
+ *         others:  failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_cfg80211_resume(struct wiphy *wiphy)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_BSS_DESC_T *pprBssDesc = NULL;
+	P_ADAPTER_T prAdapter = NULL;
+	UINT_8 i = 0;
+
+	if (kalHaltTryLock())
+		return 0;
+
+	if (kalIsHalted() || !wiphy)
+		goto end;
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	prAdapter = prGlueInfo->prAdapter;
+	clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag);
+	pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rNloParam.aprPendingBssDescToInd[0];
+	for (; i < SCN_SSID_MATCH_MAX_NUM; i++) {
+		if (pprBssDesc[i] == NULL)
+			break;
+		if (pprBssDesc[i]->u2RawLength == 0)
+			continue;
+		kalIndicateBssInfo(prGlueInfo,
+						   (PUINT_8) pprBssDesc[i]->aucRawBuf,
+						   pprBssDesc[i]->u2RawLength,
+						   pprBssDesc[i]->ucChannelNum,
+						   RCPI_TO_dBm(pprBssDesc[i]->ucRCPI));
+	}
+	DBGLOG(SCN, INFO, "pending %d sched scan results\n", i);
+	if (i > 0)
+		kalMemZero(&pprBssDesc[0], i * sizeof(P_BSS_DESC_T));
+end:
+	kalHaltUnlock();
+	return 0;
+}
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c
new file mode 100644
index 0000000000000..95ca7546b1bbc
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c
@@ -0,0 +1,3502 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7
+*/
+
+/*! \file   gl_init.c
+    \brief  Main routines of Linux driver
+
+    This file contains the main routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*
+** Log: gl_init.c
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Fix compile error.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Fix compile error for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 05 25 2012 yuche.tsai
+ * NULL
+ * Fix reset KE issue.
+ *
+ * 05 11 2012 cp.wu
+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience
+ * show MAC address & source while initiliazation
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Sync CFG80211 modification from branch 2,2.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Enable CFG80211 Support.
+ *
+ * 12 22 2011 george.huang
+ * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency
+ * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before
+ * TX thread handling
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 14 2011 yuche.tsai
+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
+ * Fix large network type index assert in FW issue.
+ *
+ * 11 14 2011 cm.chang
+ * NULL
+ * Fix compiling warning
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix work thread cancel issue.
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 10 06 2011 eddie.chen
+ * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation
+ * Add rlmDomainGetChnlList symbol.
+ *
+ * 09 22 2011 cm.chang
+ * NULL
+ * Safer writng stype to avoid unitialized regitry structure
+ *
+ * 09 21 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Avoid possible structure alignment problem
+ *
+ * 09 20 2011 chinglan.wang
+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
+ * .
+ *
+ * 09 08 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
+ *
+ * 08 31 2011 cm.chang
+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
+ * .
+ *
+ * 08 11 2011 cp.wu
+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
+ * expose scnQuerySparseChannel() for P2P-FSM.
+ *
+ * 08 11 2011 cp.wu
+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
+ * sparse channel detection:
+ * driver: collect sparse channel information with scan-done event
+ *
+ * 08 02 2011 yuche.tsai
+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting
+ * device issue.
+ * Fix GO send deauth frame issue.
+ *
+ * 07 07 2011 wh.su
+ * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL
+ * Add the dumpMemory8 symbol export for debug mode.
+ *
+ * 07 06 2011 terry.wu
+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
+ * Improve BoW connection establishment speed.
+ *
+ * 07 05 2011 yuche.tsai
+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
+ * Export one symbol for enhancement.
+ *
+ * 06 13 2011 eddie.chen
+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV]  Add tx rx statistics in linux and use netif_rx_ni
+ * Add tx rx statistics and netif_rx_ni.
+ *
+ * 05 27 2011 cp.wu
+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
+ *
+ * 05 18 2011 cp.wu
+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain
+ * pass PHY_PARAM in NVRAM from driver to firmware.
+ *
+ * 05 09 2011 jeffrey.chang
+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
+ * support ARP filter through kernel notifier
+ *
+ * 05 03 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent.
+ *
+ * 04 27 2011 george.huang
+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
+ * Support P2P ARP filter setting on early suspend/ late resume
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW short range mode.
+ *
+ * 04 14 2011 yuche.tsai
+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
+ * Modify some driver connection flow or behavior to pass Sigma test more easier..
+ *
+ * 04 12 2011 cm.chang
+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
+ * .
+ *
+ * 04 11 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * export wlan functions to p2p
+ *
+ * 04 08 2011 pat.lu
+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver
+ *
+ * 04 08 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair.
+ *
+ * 04 08 2011 eddie.chen
+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
+ * Fix for sigma
+ *
+ * 04 06 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI  port
+ * 2. update perm_addr as well for MAC address
+ * 3. not calling check_mem_region() anymore for eHPI
+ * 4. correct MSC_CS macro for 0-based notation
+ *
+ * 03 29 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
+ * RESET_START and RESET_END events
+ * fix typo.
+ *
+ * 03 29 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
+ * RESET_START and RESET_END events
+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism
+ *
+ * 03 23 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * apply multi-queue operation only for linux kernel > 2.6.26
+ *
+ * 03 22 2011 pat.lu
+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability for compatible with linux 2.6.12.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * improve portability for awareness of early version of linux kernel and wireless extension.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability improvement
+ *
+ * 03 18 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * remove early suspend functions
+ *
+ * 03 17 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * reverse order to prevent probing racing.
+ *
+ * 03 16 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * 1. pre-allocate physical continuous buffer while module is being loaded
+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
+ *
+ * The windows part remained the same as before, but added similar APIs to hide the difference.
+ *
+ * 03 15 2011 jeffrey.chang
+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM
+ * refine the queue_select function
+ *
+ * 03 10 2011 cp.wu
+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
+ * deprecate configuration used by MT6620 E2
+ *
+ * 03 10 2011 terry.wu
+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
+ * Remove unnecessary assert and message.
+ *
+ * 03 08 2011 terry.wu
+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
+ * Export nicQmUpdateWmmParms.
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * support concurrent network
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * modify net device relative functions to support multiple H/W queues
+ *
+ * 02 24 2011 george.huang
+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames
+ * Support ARP filter during suspended
+ *
+ * 02 21 2011 cp.wu
+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
+ * simplify logic for checking NVRAM existence only once.
+ *
+ * 02 17 2011 terry.wu
+ * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove
+ * Fix deference a null pointer problem in wlanRemove.
+ *
+ * 02 16 2011 jeffrey.chang
+ * NULL
+ * fix compilig error
+ *
+ * 02 16 2011 jeffrey.chang
+ * NULL
+ * Add query ipv4 and ipv6 address during early suspend and late resume
+ *
+ * 02 15 2011 jeffrey.chang
+ * NULL
+ * to support early suspend in android
+ *
+ * 02 11 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add one more export symbol.
+ *
+ * 02 10 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add RX deauthentication & disassociation process under Hot-Spot mode.
+ *
+ * 02 09 2011 terry.wu
+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
+ * Halt p2p module init and exit until TxThread finished p2p register and unregister.
+ *
+ * 02 08 2011 george.huang
+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
+ * Support querying power mode OID.
+ *
+ * 02 08 2011 yuche.tsai
+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue
+ * Export Deactivation Network.
+ *
+ * 02 01 2011 jeffrey.chang
+ * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded
+ * Unregister the KAL timer during driver unloading
+ *
+ * 01 26 2011 cm.chang
+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
+ * Allocate system RAM if fixed message or mgmt buffer is not available
+ *
+ * 01 19 2011 cp.wu
+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
+ * implementation of separate BT_OVER_WIFI data path.
+ *
+ * 01 10 2011 cp.wu
+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues
+ * due to multiple access
+ * use mutex to protect kalIoctl() for thread safe.
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
+ * physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 12 15 2010 cp.wu
+ * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver
+ * remove set MAC address. MAC address is always loaded from NVRAM instead.
+ *
+ * 12 10 2010 kevin.huang
+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
+ * Add Linux Proc Support
+ *
+ * 11 01 2010 yarco.yang
+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
+ * Add GPIO debug function
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW]
+ * Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 21 2010 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * .
+ *
+ * 10 19 2010 jeffrey.chang
+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK
+ * HIF by default
+ * Refine linux kernel module to the license of MTK and enable MTK HIF
+ *
+ * 10 18 2010 jeffrey.chang
+ * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast  callback in Android
+ * .
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
+ * The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 09 27 2010 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
+ * Update BCM/BoW design and settings.
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
+ * use firmware reported mac address right after wlanAdapterStart() as permanent address
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 08 18 2010 yarco.yang
+ * NULL
+ * 1. Fixed HW checksum offload function not work under Linux issue.
+ * 2. Add debug message.
+ *
+ * 08 16 2010 yarco.yang
+ * NULL
+ * Support Linux x86
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * 1) modify tx service thread to avoid busy looping
+ * 2) add spin lock declartion for linux build
+ *
+ * 07 29 2010 jeffrey.chang
+ * NULL
+ * fix memory leak for module unloading
+ *
+ * 07 28 2010 jeffrey.chang
+ * NULL
+ * 1) remove unused spinlocks
+ * 2) enable encyption ioctls
+ * 3) fix scan ioctl which may cause supplicant to hang
+ *
+ * 07 23 2010 jeffrey.chang
+ *
+ * bug fix: allocate regInfo when disabling firmware download
+ *
+ * 07 23 2010 jeffrey.chang
+ *
+ * use glue layer api to decrease or increase counter atomically
+ *
+ * 07 22 2010 jeffrey.chang
+ *
+ * add new spinlock
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * modify cmd/data path for new design
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) Modify set mac address code
+ * 2) remove power management macro
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement basic wi-fi direct framework
+ *
+ * 05 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * prevent supplicant accessing driver during resume
+ *
+ * 05 07 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic framework for implementating P2P driver hook.
+ *
+ * 04 27 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) fix firmware download bug
+ * 2) remove query statistics for acelerating firmware download
+ *
+ * 04 27 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * follow Linux's firmware framework, and remove unused kal API
+ *
+ * 04 21 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add for private ioctl support
+ *
+ * 04 19 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Query statistics from firmware
+ *
+ * 04 19 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * modify tcp/ip checksum offload flags
+ *
+ * 04 16 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix tcp/ip checksum offload bug
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *    capability
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix spinlock usage
+ *
+ * 04 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Set MAC address from firmware
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  *  *  *  * are done in adapter layer.
+ *
+ * 04 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * (1)improve none-glue code portability
+ *  * (2) disable set Multicast address during atomic context
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * adding debug module
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 30 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * emulate NDIS Pending OID facility
+ *
+ * 03 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix f/w download start and load address by using config.h
+ *
+ * 03 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * adding firmware download support
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090
+**  Fix compile error for Linux EHPI driver
+**  \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090
+**  Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests,
+**  and then stop hw.
+**  \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090
+**  Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input
+**  parameters and pointers.
+**  \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088
+**  remove non-used code
+**  \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088
+**  adding the module parameter for wapi
+**  \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088
+**  adding the code to check the wapi 1x frame
+**  \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090
+**  Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
+**  \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461
+**  Revise the order of increasing u4TxPendingFrameNum because of  CFG_TX_RET_TX_CTRL_EARLY
+**  \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088
+**  set the tid and 1x value at same packet reserved field
+**  \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104
+**  Fix wrong variable name "prDev" in wlanStop()
+**  \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461
+**  add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY
+**  \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461
+**  Update driver for Code review
+**  \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461
+**  Update Driver for Code Review
+**  \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461
+**  Update driver for code review
+**  \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461
+**  Add support for linux statistics
+**  \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461
+**  Fix ASSERT if removing module in BG_SSID_SCAN state
+**  \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461
+**  Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS
+**  \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461
+**  Not use wlanoidSetCurrentAddrForLinux()
+**  \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461
+**  Remove WMM Assoc Flag
+**  \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084
+**  modify wlanISR interface
+**  \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461
+**  Fix Unset Broadcast filter when setMulticast
+**  \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461
+**  Move Query Media Status to GLUE
+**  \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461
+**  Revise set multicast function by using windows oid style for LP own back
+**  \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461
+**  Fix multicast setting in Linux and add comment
+**  \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461
+**  Fix set mac address func in Linux
+**  \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461
+**  Add set MAC Address
+**  \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461
+**  For Linux, set net_device has feature with checksum offload by default
+**  \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461
+**  Fix typo
+**  \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088
+**  add 1x decide code for sw port control
+**  \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461
+**  Rearrange the set off place of GLUE spin lock in HardStartXmit
+**  \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461
+**  Add debug option - Packet Order for Linux and add debug level - Event
+**  \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461
+**  Fix SPIN_LOCK protection
+**  \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425
+**  1. Set Rx multicast packets mode before setting the address list
+**  \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461
+**  Add OS_TIMESTAMP to packet
+**  \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088
+**  fixed the unload module issue
+**  \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461
+**  Fix compile warnning
+**  \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461
+**  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
+**  \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425
+**  1. Refine for multicast list
+**  \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461
+**  Add VOIP SCAN Support  & Refine Roaming
+** Revision 1.4  2007/07/05 07:25:33  MTK01461
+** Add Linux initial code, modify doc, add 11BB, RF init code
+**
+** Revision 1.3  2007/06/27 02:18:50  MTK01461
+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
+**
+** Revision 1.2  2007/06/25 06:16:24  MTK01461
+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_os.h"
+#include "wlan_lib.h"
+#include "gl_wext.h"
+#include "gl_cfg80211.h"
+#include "precomp.h"
+#if CFG_SUPPORT_AGPS_ASSIST
+#include "gl_kal.h"
+#endif
+#if defined(CONFIG_MTK_TC1_FEATURE)
+#include <tc1_partition.h>
+#endif
+#include "gl_vendor.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* #define MAX_IOREQ_NUM   10 */
+
+BOOLEAN fgIsUnderSuspend = false;
+
+
+#if CFG_ENABLE_WIFI_DIRECT
+spinlock_t g_p2p_lock;
+int g_u4P2PEnding = 0;
+int g_u4P2POnOffing = 0;
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Tasklet mechanism is like buttom-half in Linux. We just want to
+ * send a signal to OS for interrupt defer processing. All resources
+ * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty.
+ */
+typedef struct _WLANDEV_INFO_T {
+	struct net_device *prDev;
+} WLANDEV_INFO_T, *P_WLANDEV_INFO_T;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+#define CHAN2G(_channel, _freq, _flags)         \
+{                                           \
+	.band               = NL80211_BAND_2GHZ,  \
+	.center_freq        = (_freq),              \
+	.hw_value           = (_channel),           \
+	.flags              = (_flags),             \
+	.max_antenna_gain   = 0,                    \
+	.max_power          = 30,                   \
+}
+
+static struct ieee80211_channel mtk_2ghz_channels[] = {
+	CHAN2G(1, 2412, 0),
+	CHAN2G(2, 2417, 0),
+	CHAN2G(3, 2422, 0),
+	CHAN2G(4, 2427, 0),
+	CHAN2G(5, 2432, 0),
+	CHAN2G(6, 2437, 0),
+	CHAN2G(7, 2442, 0),
+	CHAN2G(8, 2447, 0),
+	CHAN2G(9, 2452, 0),
+	CHAN2G(10, 2457, 0),
+	CHAN2G(11, 2462, 0),
+	CHAN2G(12, 2467, 0),
+	CHAN2G(13, 2472, 0),
+	CHAN2G(14, 2484, 0),
+};
+
+#define CHAN5G(_channel, _flags)                    \
+{                                               \
+	.band               = NL80211_BAND_5GHZ,      \
+	.center_freq        = 5000 + (5 * (_channel)),  \
+	.hw_value           = (_channel),               \
+	.flags              = (_flags),                 \
+	.max_antenna_gain   = 0,                        \
+	.max_power          = 30,                       \
+}
+
+static struct ieee80211_channel mtk_5ghz_channels[] = {
+	CHAN5G(34, 0), CHAN5G(36, 0),
+	CHAN5G(38, 0), CHAN5G(40, 0),
+	CHAN5G(42, 0), CHAN5G(44, 0),
+	CHAN5G(46, 0), CHAN5G(48, 0),
+	CHAN5G(52, 0), CHAN5G(56, 0),
+	CHAN5G(60, 0), CHAN5G(64, 0),
+	CHAN5G(100, 0), CHAN5G(104, 0),
+	CHAN5G(108, 0), CHAN5G(112, 0),
+	CHAN5G(116, 0), CHAN5G(120, 0),
+	CHAN5G(124, 0), CHAN5G(128, 0),
+	CHAN5G(132, 0), CHAN5G(136, 0),
+	CHAN5G(140, 0), CHAN5G(149, 0),
+	CHAN5G(153, 0), CHAN5G(157, 0),
+	CHAN5G(161, 0), CHAN5G(165, 0),
+	CHAN5G(169, 0), CHAN5G(173, 0),
+	CHAN5G(184, 0), CHAN5G(188, 0),
+	CHAN5G(192, 0), CHAN5G(196, 0),
+	CHAN5G(200, 0), CHAN5G(204, 0),
+	CHAN5G(208, 0), CHAN5G(212, 0),
+	CHAN5G(216, 0),
+};
+
+#define RATETAB_ENT(_rate, _rateid, _flags) \
+{                                           \
+	.bitrate    = (_rate),              \
+	.hw_value   = (_rateid),            \
+	.flags      = (_flags),             \
+}
+
+/* for cfg80211 - rate table */
+static struct ieee80211_rate mtk_rates[] = {
+	RATETAB_ENT(10, 0x1000, 0),
+	RATETAB_ENT(20, 0x1001, 0),
+	RATETAB_ENT(55, 0x1002, 0),
+	RATETAB_ENT(110, 0x1003, 0),	/* 802.11b */
+	RATETAB_ENT(60, 0x2000, 0),
+	RATETAB_ENT(90, 0x2001, 0),
+	RATETAB_ENT(120, 0x2002, 0),
+	RATETAB_ENT(180, 0x2003, 0),
+	RATETAB_ENT(240, 0x2004, 0),
+	RATETAB_ENT(360, 0x2005, 0),
+	RATETAB_ENT(480, 0x2006, 0),
+	RATETAB_ENT(540, 0x2007, 0),	/* 802.11a/g */
+};
+
+#define mtk_a_rates         (mtk_rates + 4)
+#define mtk_a_rates_size    (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4)
+#define mtk_g_rates         (mtk_rates + 0)
+#define mtk_g_rates_size    (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0)
+
+#define WLAN_MCS_INFO                                 \
+{                                                       \
+	.rx_mask        = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\
+	.rx_highest     = 0,                                \
+	.tx_params      = IEEE80211_HT_MCS_TX_DEFINED,      \
+}
+
+#define WLAN_HT_CAP                                   \
+{                                                       \
+	.ht_supported   = true,                             \
+	.cap            = IEEE80211_HT_CAP_SUP_WIDTH_20_40  \
+		    | IEEE80211_HT_CAP_SM_PS            \
+		    | IEEE80211_HT_CAP_GRN_FLD          \
+		    | IEEE80211_HT_CAP_SGI_20           \
+		    | IEEE80211_HT_CAP_SGI_40,          \
+	.ampdu_factor   = IEEE80211_HT_MAX_AMPDU_64K,       \
+	.ampdu_density  = IEEE80211_HT_MPDU_DENSITY_NONE,   \
+	.mcs            = WLAN_MCS_INFO,                  \
+}
+
+/**********************************************************
+* Public for both legacy Wi-Fi and P2P to access
+**********************************************************/
+struct ieee80211_supported_band mtk_band_2ghz = {
+	.band = NL80211_BAND_2GHZ,
+	.channels = mtk_2ghz_channels,
+	.n_channels = ARRAY_SIZE(mtk_2ghz_channels),
+	.bitrates = mtk_g_rates,
+	.n_bitrates = mtk_g_rates_size,
+	.ht_cap = WLAN_HT_CAP,
+};
+
+struct ieee80211_supported_band mtk_band_5ghz = {
+	.band = NL80211_BAND_5GHZ,
+	.channels = mtk_5ghz_channels,
+	.n_channels = ARRAY_SIZE(mtk_5ghz_channels),
+	.bitrates = mtk_a_rates,
+	.n_bitrates = mtk_a_rates_size,
+	.ht_cap = WLAN_HT_CAP,
+};
+
+const UINT_32 mtk_cipher_suites[5] = {
+	/* keep WEP first, it may be removed below */
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+	WLAN_CIPHER_SUITE_CCMP,
+
+	/* keep last -- depends on hw flags! */
+	WLAN_CIPHER_SUITE_AES_CMAC
+};
+
+/*********************************************************/
+
+#define NIC_INF_NAME    "wlan%d"	/* interface name */
+#if CFG_TC1_FEATURE
+#define NIC_INF_NAME_IN_AP_MODE  "legacy%d"
+#endif
+
+/* support to change debug module info dynamically */
+UINT_8 aucDebugModule[DBG_MODULE_NUM];
+UINT_32 u4DebugModule = 0;
+
+/* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */
+static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} };
+
+static UINT_32 u4WlanDevNum;	/* How many NICs coexist now */
+
+/**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/
+struct delayed_work sched_workq;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+#if CFG_ENABLE_WIFI_DIRECT
+static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} };
+#endif
+
+static struct cfg80211_ops mtk_wlan_ops = {
+	.suspend = mtk_cfg80211_suspend,
+	.resume	= mtk_cfg80211_resume,
+	.change_virtual_intf = mtk_cfg80211_change_iface,
+	.add_key = mtk_cfg80211_add_key,
+	.get_key = mtk_cfg80211_get_key,
+	.del_key = mtk_cfg80211_del_key,
+	.set_default_key = mtk_cfg80211_set_default_key,
+	.set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key,
+	.get_station = mtk_cfg80211_get_station,
+	.change_station = mtk_cfg80211_change_station,
+	.add_station = mtk_cfg80211_add_station,
+	.del_station = mtk_cfg80211_del_station,
+	.scan = mtk_cfg80211_scan,
+	.connect = mtk_cfg80211_connect,
+	.disconnect = mtk_cfg80211_disconnect,
+	.join_ibss = mtk_cfg80211_join_ibss,
+	.leave_ibss = mtk_cfg80211_leave_ibss,
+	.set_power_mgmt = mtk_cfg80211_set_power_mgmt,
+	.set_pmksa = mtk_cfg80211_set_pmksa,
+	.del_pmksa = mtk_cfg80211_del_pmksa,
+	.flush_pmksa = mtk_cfg80211_flush_pmksa,
+	.assoc = mtk_cfg80211_assoc,
+	/* Action Frame TX/RX */
+	.remain_on_channel = mtk_cfg80211_remain_on_channel,
+	.cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel,
+	.mgmt_tx = mtk_cfg80211_mgmt_tx,
+/* .mgmt_tx_cancel_wait        = mtk_cfg80211_mgmt_tx_cancel_wait, */
+	.mgmt_frame_register = mtk_cfg80211_mgmt_frame_register,
+#ifdef CONFIG_NL80211_TESTMODE
+	.testmode_cmd = mtk_cfg80211_testmode_cmd,
+#endif
+#if (CFG_SUPPORT_TDLS == 1)
+	.tdls_mgmt = TdlsexCfg80211TdlsMgmt,
+	.tdls_oper = TdlsexCfg80211TdlsOper,
+#endif /* CFG_SUPPORT_TDLS */
+#if 1	/* Remove schedule_scan because we need more verification for NLO */
+	.sched_scan_start = mtk_cfg80211_sched_scan_start,
+	.sched_scan_stop = mtk_cfg80211_sched_scan_stop,
+#endif
+};
+
+static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = {
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_get_channel_list
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_set_country_code
+	},
+	/* GSCAN */
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_GET_CAPABILITIES
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_get_gscan_capabilities
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_SET_CONFIG
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_set_config
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV,
+		.doit = mtk_cfg80211_vendor_set_scan_config
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_ENABLE_GSCAN
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_enable_scan
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_enable_full_scan_results
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_get_scan_results
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_set_significant_change
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = GSCAN_SUBCMD_SET_HOTLIST
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_set_hotlist
+	},
+	/* RTT */
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = RTT_SUBCMD_GETCAPABILITY
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_get_rtt_capabilities
+	},
+	/* Link Layer Statistics */
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = LSTATS_SUBCMD_GET_INFO
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_llstats_get_info
+	},
+
+};
+
+static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = {
+	{
+		.vendor_id = GOOGLE_OUI,
+		.subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS
+	},
+	{
+		.vendor_id = GOOGLE_OUI,
+		.subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND
+	},
+	{
+		.vendor_id = GOOGLE_OUI,
+		.subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE
+	},
+	{
+		.vendor_id = GOOGLE_OUI,
+		.subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS
+	},
+	{
+		.vendor_id = GOOGLE_OUI,
+		.subcmd = RTT_EVENT_COMPLETE
+	},
+	{
+		.vendor_id = GOOGLE_OUI,
+		.subcmd = GSCAN_EVENT_COMPLETE_SCAN
+	},
+	{
+		.vendor_id = GOOGLE_OUI,
+		.subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST
+	},
+};
+
+/* There isn't a lot of sense in it, but you can transmit anything you like */
+static const struct ieee80211_txrx_stypes
+	mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
+	[NL80211_IFTYPE_ADHOC] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4)
+	},
+	[NL80211_IFTYPE_STATION] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+	},
+	[NL80211_IFTYPE_AP] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
+	},
+	[NL80211_IFTYPE_AP_VLAN] = {
+		/* copy AP */
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+		      BIT(IEEE80211_STYPE_AUTH >> 4) |
+		      BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
+	},
+	[NL80211_IFTYPE_P2P_CLIENT] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+	},
+	[NL80211_IFTYPE_P2P_GO] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
+	}
+};
+
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support mtk_wlan_wowlan_support = {
+	.flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY,
+};
+#endif
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Override the implementation of select queue
+*
+* \param[in] dev Pointer to struct net_device
+* \param[in] skb Pointer to struct skb_buff
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+unsigned int _cfg80211_classify8021d(struct sk_buff *skb)
+{
+	unsigned int dscp = 0;
+
+	/* skb->priority values from 256->263 are magic values
+	 * directly indicate a specific 802.1d priority.  This is
+	 * to allow 802.1d priority to be passed directly in from
+	 * tags
+	 */
+
+	if (skb->priority >= 256 && skb->priority <= 263)
+		return skb->priority - 256;
+	switch (skb->protocol) {
+	case htons(ETH_P_IP):
+		dscp = ip_hdr(skb)->tos & 0xfc;
+		break;
+	}
+	return dscp >> 5;
+}
+
+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
+
+static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb,
+				struct net_device *sb_dev,
+				select_queue_fallback_t fallback)
+{
+	skb->priority = _cfg80211_classify8021d(skb);
+
+	return au16Wlan1dToQueueIdx[skb->priority];
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Load NVRAM data and translate it into REG_INFO_T
+*
+* \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
+* \param[out] prRegInfo  Pointer to struct REG_INFO_T
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo)
+{
+	UINT_32 i, j;
+	UINT_8 aucTmp[2];
+	PUINT_8 pucDest;
+
+	ASSERT(prGlueInfo);
+	ASSERT(prRegInfo);
+
+	if ((!prGlueInfo) || (!prRegInfo))
+		return;
+
+	if (kalCfgDataRead16(prGlueInfo, sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16), (PUINT_16) aucTmp) == TRUE) {
+		prGlueInfo->fgNvramAvailable = TRUE;
+
+		/* load MAC Address */
+#if !defined(CONFIG_MTK_TC1_FEATURE)
+		for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) {
+			kalCfgDataRead16(prGlueInfo,
+					 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
+					 (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i));
+		}
+#else
+		TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr);
+#endif
+
+		/* load country code */
+		kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp);
+
+		/* cast to wide characters */
+		prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0];
+		prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1];
+
+		/* load default normal TX power */
+		for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) {
+			kalCfgDataRead16(prGlueInfo,
+					 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i,
+					 (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i));
+		}
+
+		/* load feature flags */
+		kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp);
+		prRegInfo->ucTxPwrValid = aucTmp[0];
+		prRegInfo->ucSupport5GBand = aucTmp[1];
+
+		kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp);
+		prRegInfo->uc2G4BwFixed20M = aucTmp[0];
+		prRegInfo->uc5GBwFixed20M = aucTmp[1];
+
+		kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp);
+		prRegInfo->ucEnable5GBand = aucTmp[0];
+
+		/* load EFUSE overriding part */
+		for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) {
+			kalCfgDataRead16(prGlueInfo,
+					 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i,
+					 (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i));
+		}
+
+		/* load band edge tx power control */
+		kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp);
+		prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0];
+		if (aucTmp[0]) {
+			prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1];
+
+			kalCfgDataRead16(prGlueInfo,
+					 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp);
+			prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0];
+			prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1];
+		}
+
+		/* load regulation subbands */
+		kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp);
+		prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0];
+		prRegInfo->ucRegChannelListIndex = aucTmp[1];
+
+		if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) {
+			for (i = 0; i < MAX_SUBBAND_NUM; i++) {
+				pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i];
+				for (j = 0; j < 6; j += sizeof(UINT_16)) {
+					kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo)
+							 + (i * 6 + j), (PUINT_16) aucTmp);
+
+					*pucDest++ = aucTmp[0];
+					*pucDest++ = aucTmp[1];
+				}
+			}
+		}
+		/* load RSSI compensation */
+		kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp);
+		prRegInfo->uc2GRssiCompensation = aucTmp[0];
+		prRegInfo->uc5GRssiCompensation = aucTmp[1];
+
+		kalCfgDataRead16(prGlueInfo,
+				 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp);
+		prRegInfo->fgRssiCompensationValidbit = aucTmp[0];
+		prRegInfo->ucRxAntennanumber = aucTmp[1];
+	} else {
+		prGlueInfo->fgNvramAvailable = FALSE;
+	}
+
+}
+
+#if CFG_ENABLE_WIFI_DIRECT
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief called by txthread, run sub module init function
+*
+* \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo)
+{
+	/*now, we only have p2p module */
+	if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) {
+		rSubModHandler[P2P_MODULE].subModInit(prGlueInfo);
+		rSubModHandler[P2P_MODULE].fgIsInited = TRUE;
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief called by txthread, run sub module exit function
+*
+* \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo)
+{
+	/*now, we only have p2p module */
+	if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) {
+		rSubModHandler[P2P_MODULE].subModExit(prGlueInfo);
+		rSubModHandler[P2P_MODULE].fgIsInited = FALSE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief set sub module init flag, force TxThread to run sub modle init
+*
+* \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo)
+{
+	/* 4  Mark HALT, notify main thread to finish current job */
+	prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT;
+	/* wake up main thread */
+	wake_up_interruptible(&prGlueInfo->waitq);
+	/* wait main thread  finish sub module INIT */
+	wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
+
+#if 0
+	if (prGlueInfo->prAdapter->fgIsP2PRegistered)
+		p2pNetRegister(prGlueInfo);
+#endif
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief set sub module exit flag, force TxThread to run sub modle exit
+*
+* \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo)
+{
+#if 0
+	if (prGlueInfo->prAdapter->fgIsP2PRegistered)
+		p2pNetUnregister(prGlueInfo);
+#endif
+
+	/* 4  Mark HALT, notify main thread to finish current job */
+	prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT;
+	/* wake up main thread */
+	wake_up_interruptible(&prGlueInfo->waitq);
+	/* wait main thread finish sub module EXIT */
+	wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
+
+	return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief set by sub module, indicate sub module is already inserted
+*
+* \param[in]  rSubModInit, function pointer point to sub module init function
+* \param[in]  rSubModExit,  function pointer point to sub module exit function
+* \param[in]  eSubModIdx,  sub module index
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx)
+{
+	rSubModHandler[eSubModIdx].subModInit = rSubModInit;
+	rSubModHandler[eSubModIdx].subModExit = rSubModExit;
+	rSubModHandler[eSubModIdx].fgIsInited = FALSE;
+}
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief check wlan is launched or not
+*
+* \param[in]  (none)
+*
+* \return TRUE, wlan is already started
+*             FALSE, wlan is not started yet
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wlanIsLaunched(VOID)
+{
+	struct net_device *prDev = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	/* 4 <0> Sanity check */
+	ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
+	if (0 == u4WlanDevNum)
+		return FALSE;
+
+	prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
+
+	ASSERT(prDev);
+	if (NULL == prDev)
+		return FALSE;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+	if (NULL == prGlueInfo)
+		return FALSE;
+
+	return prGlueInfo->prAdapter->fgIsWlanLaunched;
+}
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Export wlan GLUE_INFO_T pointer to p2p module
+*
+* \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
+*
+* \return TRUE: get GlueInfo pointer successfully
+*            FALSE: wlan is not started yet
+*/
+/*---------------------------------------------------------------------------*/
+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr)
+{
+	struct net_device *prDev = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	if (0 == u4WlanDevNum)
+		return FALSE;
+
+	prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
+	if (NULL == prDev)
+		return FALSE;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	if (NULL == prGlueInfo)
+		return FALSE;
+
+	if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched)
+		return FALSE;
+
+	*prGlueInfoExpAddr = prGlueInfo;
+	return TRUE;
+}
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Release prDev from wlandev_array and free tasklet object related to it.
+*
+* \param[in] prDev  Pointer to struct net_device
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static void wlanClearDevIdx(struct net_device *prDev)
+{
+	int i;
+
+	ASSERT(prDev);
+
+	for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
+		if (arWlanDevInfo[i].prDev == prDev) {
+			arWlanDevInfo[i].prDev = NULL;
+			u4WlanDevNum--;
+		}
+	}
+
+}				/* end of wlanClearDevIdx() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Allocate an unique interface index, net_device::ifindex member for this
+*        wlan device. Store the net_device in wlandev_array, and initialize
+*        tasklet object related to it.
+*
+* \param[in] prDev  Pointer to struct net_device
+*
+* \retval >= 0      The device number.
+* \retval -1        Fail to get index.
+*/
+/*----------------------------------------------------------------------------*/
+static int wlanGetDevIdx(struct net_device *prDev)
+{
+	int i;
+
+	ASSERT(prDev);
+
+	for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
+		if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) {
+			/* Reserve 2 bytes space to store one digit of
+			 * device number and NULL terminator.
+			 */
+			arWlanDevInfo[i].prDev = prDev;
+			u4WlanDevNum++;
+			return i;
+		}
+	}
+
+	return -1;
+}				/* end of wlanGetDevIdx() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A method of struct net_device, a primary SOCKET interface to configure
+*        the interface lively. Handle an ioctl call on one of our devices.
+*        Everything Linux ioctl specific is done here. Then we pass the contents
+*        of the ifr->data to the request message handler.
+*
+* \param[in] prDev      Linux kernel netdevice
+*
+* \param[in] prIfReq    Our private ioctl request structure, typed for the generic
+*                       struct ifreq so we can use ptr to function
+*
+* \param[in] cmd        Command ID
+*
+* \retval 0  The IOCTL command is executed successfully.
+* \retval <0 The execution of IOCTL command is failed.
+*/
+/*----------------------------------------------------------------------------*/
+int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	int ret = 0;
+
+	/* Verify input parameters for the following functions */
+	ASSERT(prDev && prIfReq);
+	if (!prDev || !prIfReq) {
+		DBGLOG(INIT, ERROR, "Invalid input data\n");
+		return -EINVAL;
+	}
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	if (!prGlueInfo) {
+		DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n");
+		return -EFAULT;
+	}
+
+	if (prGlueInfo->u4ReadyFlag == 0) {
+		DBGLOG(INIT, ERROR, "Adapter is not ready\n");
+		return -EINVAL;
+	}
+
+	if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) {
+		/* 0x8B00 ~ 0x8BDF, wireless extension region */
+		ret = wext_support_ioctl(prDev, prIfReq, i4Cmd);
+	} else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) {
+		/* 0x8BE0 ~ 0x8BFF, private ioctl region */
+		ret = priv_support_ioctl(prDev, prIfReq, i4Cmd);
+	} else if (i4Cmd == SIOCDEVPRIVATE + 1) {
+		ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd);
+	} else {
+		DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd);
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}				/* end of wlanDoIOCTL() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is to set multicast list and set rx mode.
+*
+* \param[in] prDev  Pointer to struct net_device
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+
+static struct delayed_work workq;
+static struct net_device *gPrDev;
+static BOOLEAN fgIsWorkMcStart = FALSE;
+static BOOLEAN fgIsWorkMcEverInit = FALSE;
+static struct wireless_dev *gprWdev;
+
+static void createWirelessDevice(void)
+{
+	struct wiphy *prWiphy = NULL;
+	struct wireless_dev *prWdev = NULL;
+#if CFG_SUPPORT_PERSIST_NETDEV
+	struct net_device *prNetDev = NULL;
+#endif
+
+	/* <1.1> Create wireless_dev */
+	prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+	if (!prWdev) {
+		DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n");
+		return;
+	}
+
+
+	/* <1.2> Create wiphy */
+	prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T));
+	if (!prWiphy) {
+		DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n");
+		goto free_wdev;
+	}
+
+	/* <1.3> configure wireless_dev & wiphy */
+	prWdev->iftype = NL80211_IFTYPE_STATION;
+	prWiphy->max_scan_ssids   = 1;    /* FIXME: for combo scan */
+	prWiphy->max_scan_ie_len = 512;
+
+	prWiphy->max_sched_scan_ssids	= CFG_SCAN_SSID_MAX_NUM;
+	prWiphy->max_match_sets		= CFG_SCAN_SSID_MATCH_MAX_NUM;
+	prWiphy->max_sched_scan_ie_len	= CFG_CFG80211_IE_BUF_LEN;
+	prWiphy->max_sched_scan_reqs = 1;
+
+	prWiphy->interface_modes	= BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+	prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz;
+	/* always assign 5Ghz bands here, if the chip is not support 5Ghz,
+		bands[IEEE80211_BAND_5GHZ] will be assign to NULL */
+	prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz;
+	prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+	prWiphy->cipher_suites = mtk_cipher_suites;
+	prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites);
+	prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM
+			| WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+	prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG;
+#if CFG_SUPPORT_TDLS
+	TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags);
+#endif /* CFG_SUPPORT_TDLS */
+	prWiphy->max_remain_on_channel_duration = 5000;
+	prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes;
+	prWiphy->vendor_commands = mtk_wlan_vendor_ops;
+	prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command);
+	prWiphy->vendor_events = mtk_wlan_vendor_events;
+	prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events);
+
+	/* <1.4> wowlan support */
+#ifdef CONFIG_PM
+	prWiphy->wowlan = &mtk_wlan_wowlan_support;
+#endif
+#ifdef CONFIG_CFG80211_WEXT
+	 /* <1.5> Use wireless extension to replace IOCTL */
+	prWiphy->wext = &wext_handler_def;
+#endif
+
+	if (wiphy_register(prWiphy) < 0) {
+		DBGLOG(INIT, ERROR, "wiphy_register error\n");
+		goto free_wiphy;
+	}
+	prWdev->wiphy = prWiphy;
+
+#if CFG_SUPPORT_PERSIST_NETDEV
+	/* <2> allocate and register net_device */
+#if CFG_TC1_FEATURE
+	if (wlan_if_changed)
+		prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE,
+									ether_setup, CFG_MAX_TXQ_NUM);
+	else
+#else
+		prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
+									ether_setup, CFG_MAX_TXQ_NUM);
+#endif
+	if (!prNetDev) {
+		DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n");
+		goto unregister_wiphy;
+	}
+
+	*((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy);
+
+	 prNetDev->netdev_ops = &wlan_netdev_ops;
+#ifdef CONFIG_WIRELESS_EXT
+	prNetDev->wireless_handlers = &wext_handler_def;
+#endif
+	netif_carrier_off(prNetDev);
+	netif_tx_stop_all_queues(prNetDev);
+
+	/* <2.1> co-relate with wireless_dev bi-directionally */
+	prNetDev->ieee80211_ptr = prWdev;
+	prWdev->netdev = prNetDev;
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	prNetDev->features = NETIF_F_HW_CSUM;
+#endif
+
+	/* <2.2> co-relate net device & device tree */
+	SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy));
+
+	/* <2.3> register net_device */
+	if (register_netdev(prWdev->netdev) < 0) {
+		DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n");
+		goto unregister_wiphy;
+	}
+#endif /* CFG_SUPPORT_PERSIST_NETDEV */
+	gprWdev = prWdev;
+	DBGLOG(INIT, INFO, "create wireless device success\n");
+	return;
+
+#if CFG_SUPPORT_PERSIST_NETDEV
+unregister_wiphy:
+	wiphy_unregister(prWiphy);
+#endif
+free_wiphy:
+	wiphy_free(prWiphy);
+free_wdev:
+	kfree(prWdev);
+}
+
+static void destroyWirelessDevice(void)
+{
+#if CFG_SUPPORT_PERSIST_NETDEV
+	unregister_netdev(gprWdev->netdev);
+	free_netdev(gprWdev->netdev);
+#endif
+	wiphy_unregister(gprWdev->wiphy);
+	wiphy_free(gprWdev->wiphy);
+	kfree(gprWdev);
+	gprWdev = NULL;
+}
+
+static void wlanSetMulticastList(struct net_device *prDev)
+{
+	gPrDev = prDev;
+	schedule_delayed_work(&workq, 0);
+}
+
+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
+ * another workqueue for sleeping. We don't want to block
+ * tx_thread, so we can't let tx_thread to do this */
+
+static void wlanSetMulticastListWorkQueue(struct work_struct *work)
+{
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_32 u4PacketFilter = 0;
+	UINT_32 u4SetInfoLen;
+	struct net_device *prDev = gPrDev;
+
+	fgIsWorkMcStart = TRUE;
+
+	if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE))
+		return;
+	if (kalIsHalted()) {
+		fgIsWorkMcStart = FALSE;
+		kalHaltUnlock();
+		return;
+	}
+
+	prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
+	ASSERT(prDev);
+	ASSERT(prGlueInfo);
+	if (!prDev || !prGlueInfo) {
+		DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo);
+		fgIsWorkMcStart = FALSE;
+		kalHaltUnlock();
+		return;
+	}
+
+	if (prDev->flags & IFF_PROMISC)
+		u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
+
+	if (prDev->flags & IFF_BROADCAST)
+		u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
+
+	if (prDev->flags & IFF_MULTICAST) {
+		if ((prDev->flags & IFF_ALLMULTI) ||
+		    (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
+
+			u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
+		} else {
+			u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
+		}
+	}
+
+	kalHaltUnlock();
+
+	if (kalIoctl(prGlueInfo,
+		     wlanoidSetCurrentPacketFilter,
+		     &u4PacketFilter,
+		     sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
+		fgIsWorkMcStart = FALSE;
+		DBGLOG(INIT, ERROR, "wlanSetMulticastListWorkQueue kalIoctl u4PacketFilter=%d\n", u4PacketFilter);
+		return;
+	}
+
+	if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
+		/* Prepare multicast address list */
+		struct netdev_hw_addr *ha;
+		PUINT_8 prMCAddrList = NULL;
+		UINT_32 i = 0;
+
+		if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE))
+			return;
+		if (kalIsHalted()) {
+			fgIsWorkMcStart = FALSE;
+			kalHaltUnlock();
+			/*DBGLOG(INIT, WARN, "wlanSetMulticastListWorkQueue g_u4HaltFlag=%d\n", g_u4HaltFlag);*/
+			return;
+		}
+
+		prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE);
+
+		netdev_for_each_mc_addr(ha, prDev) {
+			if (i < MAX_NUM_GROUP_ADDR) {
+				memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN);
+				i++;
+			}
+		}
+
+		kalHaltUnlock();
+
+		kalIoctl(prGlueInfo,
+			 wlanoidSetMulticastList,
+			 prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+
+		kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN);
+	}
+
+	fgIsWorkMcStart = FALSE;
+
+}				/* end of wlanSetMulticastList() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To indicate scheduled scan has been stopped
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           None
+*/
+/*----------------------------------------------------------------------------*/
+VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct net_device *prDev = gPrDev;
+
+	prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
+	if (!prGlueInfo) {
+		DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n");
+		return;
+	}
+
+	/* 2. indication to cfg80211 */
+	/* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */
+	cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo),0);
+	DBGLOG(SCN, INFO,
+		"cfg80211_sched_scan_stopped event send done\n");
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is TX entry point of NET DEVICE.
+*
+* \param[in] prSkb  Pointer of the sk_buff to be sent
+* \param[in] prDev  Pointer to struct net_device
+*
+* \retval NETDEV_TX_OK - on success.
+* \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
+*/
+/*----------------------------------------------------------------------------*/
+int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+	P_QUE_ENTRY_T prQueueEntry = NULL;
+	P_QUE_T prTxQueue = NULL;
+	UINT_16 u2QueueIdx = 0;
+#if (CFG_SUPPORT_TDLS_DBG == 1)
+	UINT16 u2Identifier = 0;
+#endif
+
+#if CFG_BOW_TEST
+	UINT_32 i;
+#endif
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prSkb);
+	ASSERT(prDev);
+	ASSERT(prGlueInfo);
+	prGlueInfo->u8SkbToDriver++;
+
+#if (CFG_SUPPORT_TDLS_DBG == 1)
+	{
+		UINT8 *pkt = prSkb->data;
+
+		if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) {
+			/* ip */
+			u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19));
+			/* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */
+			DBGLOG(INIT, INFO, "<s> %d\n", u2Identifier);
+		}
+	}
+#endif
+	/* check if WiFi is halt */
+	if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
+		DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n");
+		dev_kfree_skb(prSkb);
+		prGlueInfo->u8SkbFreed++;
+		return NETDEV_TX_OK;
+	}
+#if CFG_SUPPORT_HOTSPOT_2_0
+	if (prGlueInfo->fgIsDad) {
+		/* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */
+		dev_kfree_skb(prSkb);
+		prGlueInfo->u8SkbFreed++;
+		return NETDEV_TX_OK;
+	}
+	if (prGlueInfo->fgIs6Dad) {
+		/* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */
+		dev_kfree_skb(prSkb);
+		prGlueInfo->u8SkbFreed++;
+		return NETDEV_TX_OK;
+	}
+#endif
+
+	STATS_TX_TIME_ARRIVE(prSkb);
+	prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
+	prTxQueue = &prGlueInfo->rTxQueue;
+
+#if CFG_BOW_TEST
+	DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len);
+	DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len);
+	DBGLOG(BOW, TRACE, "sk_buff->data:\n");
+
+	for (i = 0; i < prSkb->len; i++) {
+		DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]);
+
+		if ((i + 1) % 16 == 0)
+			DBGLOG(BOW, TRACE, "\n");
+	}
+
+	DBGLOG(BOW, TRACE, "\n");
+#endif
+
+	if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
+
+		/* non-1x packets */
+
+#if CFG_DBG_GPIO_PINS
+		{
+			/* TX request from OS */
+			mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW);
+			kalUdelay(1);
+			mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH);
+		}
+#endif
+
+		u2QueueIdx = skb_get_queue_mapping(prSkb);
+		ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
+
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+		GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick());
+#endif
+		GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
+		if (u2QueueIdx < CFG_MAX_TXQ_NUM)
+			GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]);
+
+		GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+		QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
+		GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+/* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */
+/* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */
+
+		if (u2QueueIdx < CFG_MAX_TXQ_NUM) {
+			if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >=
+			    CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
+				DBGLOG(TX, INFO, "netif_stop_subqueue for wlan0, Queue len: %d\n",
+					prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]);
+
+				netif_stop_subqueue(prDev, u2QueueIdx);
+
+#if (CONF_HIF_LOOPBACK_AUTO == 1)
+			prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01;
+#endif /* CONF_HIF_LOOPBACK_AUTO */
+			}
+		}
+	} else {
+		/* printk("is security frame\n"); */
+
+		GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
+	}
+
+	DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len);
+	prGlueInfo->rNetDevStats.tx_bytes += prSkb->len;
+	prGlueInfo->rNetDevStats.tx_packets++;
+	kalPerMonStart(prGlueInfo);
+
+	/* set GLUE_FLAG_TXREQ_BIT */
+
+	/* pr->u4Flag |= GLUE_FLAG_TXREQ; */
+	/* wake_up_interruptible(&prGlueInfo->waitq); */
+	kalSetEvent(prGlueInfo);
+
+	/* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
+	return NETDEV_TX_OK;
+}				/* end of wlanHardStartXmit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A method of struct net_device, to get the network interface statistical
+*        information.
+*
+* Whenever an application needs to get statistics for the interface, this method
+* is called. This happens, for example, when ifconfig or netstat -i is run.
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \return net_device_stats buffer pointer.
+*/
+/*----------------------------------------------------------------------------*/
+struct net_device_stats *wlanGetStats(IN struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+#if 0
+	WLAN_STATUS rStatus;
+	UINT_32 u4XmitError = 0;
+	UINT_32 u4XmitOk = 0;
+	UINT_32 u4RecvError = 0;
+	UINT_32 u4RecvOk = 0;
+	UINT_32 u4BufLen;
+
+	ASSERT(prDev);
+
+	/* @FIX ME: need a more clear way to do this */
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
+	rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
+	prGlueInfo->rNetDevStats.rx_packets = u4RecvOk;
+	prGlueInfo->rNetDevStats.tx_packets = u4XmitOk;
+	prGlueInfo->rNetDevStats.tx_errors = u4XmitError;
+	prGlueInfo->rNetDevStats.rx_errors = u4RecvError;
+	/* prGlueInfo->rNetDevStats.rx_bytes   = rCustomNetDevStats.u4RxBytes; */
+	/* prGlueInfo->rNetDevStats.tx_bytes   = rCustomNetDevStats.u4TxBytes; */
+	/* prGlueInfo->rNetDevStats.rx_errors  = rCustomNetDevStats.u4RxErrors; */
+	/* prGlueInfo->rNetDevStats.multicast  = rCustomNetDevStats.u4Multicast; */
+#endif
+	/* prGlueInfo->rNetDevStats.rx_packets = 0; */
+	/* prGlueInfo->rNetDevStats.tx_packets = 0; */
+	prGlueInfo->rNetDevStats.tx_errors = 0;
+	prGlueInfo->rNetDevStats.rx_errors = 0;
+	/* prGlueInfo->rNetDevStats.rx_bytes   = 0; */
+	/* prGlueInfo->rNetDevStats.tx_bytes   = 0; */
+	prGlueInfo->rNetDevStats.rx_errors = 0;
+	prGlueInfo->rNetDevStats.multicast = 0;
+
+	return &prGlueInfo->rNetDevStats;
+
+}				/* end of wlanGetStats() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A function for prDev->init
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \retval 0         The execution of wlanInit succeeds.
+* \retval -ENXIO    No such device.
+*/
+/*----------------------------------------------------------------------------*/
+static int wlanInit(struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	if (fgIsWorkMcEverInit == FALSE) {
+		if (!prDev)
+			return -ENXIO;
+
+		prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+		INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue);
+
+		/* 20150205 work queue for sched_scan */
+		INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue);
+
+		fgIsWorkMcEverInit = TRUE;
+	}
+
+	return 0;		/* success */
+}				/* end of wlanInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A function for prDev->uninit
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static void wlanUninit(struct net_device *prDev)
+{
+
+}				/* end of wlanUninit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A function for prDev->open
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \retval 0     The execution of wlanOpen succeeds.
+* \retval < 0   The execution of wlanOpen failed.
+*/
+/*----------------------------------------------------------------------------*/
+static int wlanOpen(struct net_device *prDev)
+{
+	ASSERT(prDev);
+
+	netif_tx_start_all_queues(prDev);
+
+	return 0;		/* success */
+}				/* end of wlanOpen() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A function for prDev->stop
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \retval 0     The execution of wlanStop succeeds.
+* \retval < 0   The execution of wlanStop failed.
+*/
+/*----------------------------------------------------------------------------*/
+static int wlanStop(struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct cfg80211_scan_request *prScanRequest = NULL;
+
+        struct cfg80211_scan_info info = {
+                .aborted = true,
+        };
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+	/* CFG80211 down */
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+	if (prGlueInfo->prScanRequest != NULL) {
+		prScanRequest = prGlueInfo->prScanRequest;
+		prGlueInfo->prScanRequest = NULL;
+	}
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+
+	if (prScanRequest)
+		cfg80211_scan_done(prScanRequest, &info);
+	netif_tx_stop_all_queues(prDev);
+
+	return 0;		/* success */
+}				/* end of wlanStop() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief Update channel table for cfg80211 based on current country domain
+ *
+ * \param[in] prGlueInfo      Pointer to glue info
+ *
+ * \return   none
+ */
+/*----------------------------------------------------------------------------*/
+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo)
+{
+	UINT_8 i, j;
+	UINT_8 ucNumOfChannel;
+	RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)];
+
+	/* 1. Disable all channels */
+	for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) {
+		mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
+		mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) {
+		mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
+		mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED;
+	}
+
+	/* 2. Get current domain channel list */
+	rlmDomainGetChnlList(prGlueInfo->prAdapter,
+			     BAND_NULL, FALSE,
+			     ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels),
+			     &ucNumOfChannel, aucChannelList);
+
+	/* 3. Enable specific channel based on domain channel list */
+	for (i = 0; i < ucNumOfChannel; i++) {
+		switch (aucChannelList[i].eBand) {
+		case BAND_2G4:
+			for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) {
+				if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
+					mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
+					mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED;
+					break;
+				}
+			}
+			break;
+
+		case BAND_5G:
+			for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) {
+				if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
+					mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
+					mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED;
+					break;
+				}
+			}
+			break;
+
+		default:
+			DBGLOG(INIT, WARN, "Unknown band %d\n", aucChannelList[i].eBand);
+			break;
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Register the device to the kernel and return the index.
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \retval 0     The execution of wlanNetRegister succeeds.
+* \retval < 0   The execution of wlanNetRegister failed.
+*/
+/*----------------------------------------------------------------------------*/
+static INT_32 wlanNetRegister(struct wireless_dev *prWdev)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	INT_32 i4DevIdx = -1;
+
+	ASSERT(prWdev);
+
+	do {
+		if (!prWdev)
+			break;
+
+		prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
+		i4DevIdx = wlanGetDevIdx(prWdev->netdev);
+		if (i4DevIdx < 0) {
+			DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n");
+			break;
+		}
+
+#if !CFG_SUPPORT_PERSIST_NETDEV
+		if (register_netdev(prWdev->netdev) < 0) {
+			DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n");
+
+			wiphy_unregister(prWdev->wiphy);
+			wlanClearDevIdx(prWdev->netdev);
+			i4DevIdx = -1;
+		}
+#endif
+		if (i4DevIdx != -1)
+			prGlueInfo->fgIsRegistered = TRUE;
+
+	} while (FALSE);
+
+	return i4DevIdx;	/* success */
+}				/* end of wlanNetRegister() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Unregister the device from the kernel
+*
+* \param[in] prWdev      Pointer to struct net_device.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID wlanNetUnregister(struct wireless_dev *prWdev)
+{
+	P_GLUE_INFO_T prGlueInfo;
+
+	if (!prWdev) {
+		DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n");
+		return;
+	}
+	DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev);
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
+	wlanClearDevIdx(prWdev->netdev);
+#if !CFG_SUPPORT_PERSIST_NETDEV
+	unregister_netdev(prWdev->netdev);
+#endif
+	prGlueInfo->fgIsRegistered = FALSE;
+
+	DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex);
+
+}				/* end of wlanNetUnregister() */
+
+static const struct net_device_ops wlan_netdev_ops = {
+	.ndo_open = wlanOpen,
+	.ndo_stop = wlanStop,
+	.ndo_set_rx_mode = wlanSetMulticastList,
+	.ndo_get_stats = wlanGetStats,
+	.ndo_do_ioctl = wlanDoIOCTL,
+	.ndo_start_xmit = wlanHardStartXmit,
+	.ndo_init = wlanInit,
+	.ndo_uninit = wlanUninit,
+	.ndo_select_queue = wlanSelectQueue,
+};
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A method for creating Linux NET4 struct net_device object and the
+*        private data(prGlueInfo and prAdapter). Setup the IO address to the HIF.
+*        Assign the function pointer to the net_device object
+*
+* \param[in] pvData     Memory address for the device
+*
+* \retval Not null      The wireless_dev object.
+* \retval NULL          Fail to create wireless_dev object
+*/
+/*----------------------------------------------------------------------------*/
+static struct lock_class_key rSpinKey[SPIN_LOCK_NUM];
+static struct wireless_dev *wlanNetCreate(PVOID pvData)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct wireless_dev *prWdev = gprWdev;
+	UINT_32 i;
+	struct device *prDev;
+
+	if (!prWdev) {
+		DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n");
+		return NULL;
+	}
+	/* 4 <1> co-relate wiphy & prDev */
+#if MTK_WCN_HIF_SDIO
+	mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev);
+#else
+/* prDev = &((struct sdio_func *) pvData)->dev; //samp */
+	prDev = pvData;		/* samp */
+#endif
+	if (!prDev)
+		DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n");
+	/* don't set prDev as parent of wiphy->dev, because we have done device_add
+		in driver init. if we set parent here, parent will be not able to know this child,
+		and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent
+		has been freed. */
+	/*set_wiphy_dev(prWdev->wiphy, prDev);*/
+
+#if !CFG_SUPPORT_PERSIST_NETDEV
+	/* 4 <3> Initial Glue structure */
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
+	kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T));
+	/* 4 <3.1> Create net device */
+#if CFG_TC1_FEATURE
+	if (wlan_if_changed) {
+		prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE,
+							NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM);
+	} else {
+		prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
+							ether_setup, CFG_MAX_TXQ_NUM);
+	}
+#else
+	prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
+						ether_setup, CFG_MAX_TXQ_NUM);
+#endif
+	if (!prGlueInfo->prDevHandler) {
+		DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n");
+		return NULL;
+	}
+	DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n",
+			prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex);
+
+	/* 4 <3.1.1> initialize net device varaiables */
+	*((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo;
+
+	prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops;
+#ifdef CONFIG_WIRELESS_EXT
+	prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def;
+#endif
+	netif_carrier_off(prGlueInfo->prDevHandler);
+	netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
+
+	/* 4 <3.1.2> co-relate with wiphy bi-directionally */
+	prGlueInfo->prDevHandler->ieee80211_ptr = prWdev;
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM;
+#endif
+	prWdev->netdev = prGlueInfo->prDevHandler;
+
+	/* 4 <3.1.3> co-relate net device & prDev */
+	/*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/
+	SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev);
+#else /* CFG_SUPPORT_PERSIST_NETDEV */
+	prGlueInfo->prDevHandler = gprWdev->netdev;
+#endif /* CFG_SUPPORT_PERSIST_NETDEV */
+
+	/* 4 <3.2> initiali glue variables */
+	prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
+	prGlueInfo->ePowerState = ParamDeviceStateD0;
+	prGlueInfo->fgIsMacAddrOverride = FALSE;
+	prGlueInfo->fgIsRegistered = FALSE;
+	prGlueInfo->prScanRequest = NULL;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+	/* Init DAD */
+	prGlueInfo->fgIsDad = FALSE;
+	prGlueInfo->fgIs6Dad = FALSE;
+	kalMemZero(prGlueInfo->aucDADipv4, 4);
+	kalMemZero(prGlueInfo->aucDADipv6, 16);
+#endif
+
+	init_completion(&prGlueInfo->rScanComp);
+	init_completion(&prGlueInfo->rHaltComp);
+	init_completion(&prGlueInfo->rPendComp);
+#if CFG_ENABLE_WIFI_DIRECT
+	init_completion(&prGlueInfo->rSubModComp);
+#endif
+
+	/* initialize timer for OID timeout checker */
+	kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler);
+
+	for (i = 0; i < SPIN_LOCK_NUM; i++) {
+		spin_lock_init(&prGlueInfo->rSpinLock[i]);
+		lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]);
+	}
+
+	/* initialize semaphore for ioctl */
+	sema_init(&prGlueInfo->ioctl_sem, 1);
+
+	glSetHifInfo(prGlueInfo, (ULONG) pvData);
+
+	/* 4 <8> Init Queues */
+	init_waitqueue_head(&prGlueInfo->waitq);
+	QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue);
+	QUEUE_INITIALIZE(&prGlueInfo->rTxQueue);
+
+	/* 4 <4> Create Adapter structure */
+	prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo);
+
+	if (!prGlueInfo->prAdapter) {
+		DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n");
+		return NULL;
+	}
+	KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR");
+#if CFG_SUPPORT_PERSIST_NETDEV
+	dev_open(prGlueInfo->prDevHandler);
+	netif_carrier_off(prGlueInfo->prDevHandler);
+	netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
+#endif
+
+	return prWdev;
+}				/* end of wlanNetCreate() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Destroying the struct net_device object and the private data.
+*
+* \param[in] prWdev      Pointer to struct wireless_dev.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID wlanNetDestroy(struct wireless_dev *prWdev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prWdev);
+
+	if (!prWdev) {
+		DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n");
+		return;
+	}
+
+	/* prGlueInfo is allocated with net_device */
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
+	ASSERT(prGlueInfo);
+
+	/* destroy kal OS timer */
+	kalCancelTimer(prGlueInfo);
+
+	glClearHifInfo(prGlueInfo);
+
+	wlanAdapterDestroy(prGlueInfo->prAdapter);
+	prGlueInfo->prAdapter = NULL;
+
+#if CFG_SUPPORT_PERSIST_NETDEV
+	/* take the net_device to down state */
+	dev_close(prGlueInfo->prDevHandler);
+#else
+	/* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */
+	free_netdev(prWdev->netdev);
+#endif
+
+}				/* end of wlanNetDestroy() */
+
+#ifndef CONFIG_X86
+UINT_8 g_aucBufIpAddr[32] = { 0 };
+static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+	UINT_32 u4SetInfoLen;
+
+	rStatus = kalIoctl(prGlueInfo,
+			wlanoidNotifyFwSuspend,
+			(PVOID)&fgSuspend,
+			sizeof(fgSuspend),
+			FALSE,
+			FALSE,
+			TRUE,
+			FALSE,
+			&u4SetInfoLen);
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n");
+}
+
+void wlanHandleSystemSuspend(void)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+	struct net_device *prDev = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_8 ip[4] = { 0 };
+	UINT_32 u4NumIPv4 = 0;
+#ifdef CONFIG_IPV6
+	UINT_8 ip6[16] = { 0 };	/* FIX ME: avoid to allocate large memory in stack */
+	UINT_32 u4NumIPv6 = 0;
+#endif
+	UINT_32 i;
+	P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
+
+	/* <1> Sanity check and acquire the net_device */
+	ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
+	if (u4WlanDevNum == 0) {
+		DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n");
+		return;
+	}
+	prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
+
+	fgIsUnderSuspend = true;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	kalPerMonDisable(prGlueInfo);
+
+	if (!prDev || !(prDev->ip_ptr) ||
+	    !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
+		goto notify_suspend;
+	}
+	kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
+
+	/* todo: traverse between list to find whole sets of IPv4 addresses */
+	if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)))
+		u4NumIPv4++;
+#ifdef CONFIG_IPV6
+	if (!prDev || !(prDev->ip6_ptr) ||
+	    !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
+		goto notify_suspend;
+	}
+	kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
+	DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
+			    ip6[0], ip6[1], ip6[2], ip6[3],
+			    ip6[4], ip6[5], ip6[6], ip6[7],
+			    ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]
+	       );
+
+	/* todo: traverse between list to find whole sets of IPv6 addresses */
+	if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) {
+		/* Do nothing */
+		/* u4NumIPv6++; */
+	}
+#endif
+
+	/* <7> set up the ARP filter */
+	{
+		UINT_32 u4SetInfoLen = 0;
+		UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
+		P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
+		P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
+
+		kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
+
+		prParamNetAddrList->u4AddressCount = u4NumIPv4;
+#ifdef CONFIG_IPV6
+		prParamNetAddrList->u4AddressCount += u4NumIPv6;
+#endif
+		prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+		for (i = 0; i < u4NumIPv4; i++) {
+			prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);	/* 4;; */
+			prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+			prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress;
+			kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
+			prParamNetAddr =
+			    (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
+		}
+#ifdef CONFIG_IPV6
+		for (i = 0; i < u4NumIPv6; i++) {
+			prParamNetAddr->u2AddressLength = 6;
+			prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+			kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
+			prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6));
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
+		}
+#endif
+		ASSERT(u4Len <= sizeof(g_aucBufIpAddr));
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetNetworkAddress,
+				   (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+	}
+
+notify_suspend:
+	DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus);
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		wlanNotifyFwSuspend(prGlueInfo, TRUE);
+}
+
+void wlanHandleSystemResume(void)
+{
+	struct net_device *prDev = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+	UINT_8 ip[4] = { 0 };
+#ifdef CONFIG_IPV6
+	UINT_8 ip6[16] = { 0 };	/* FIX ME: avoid to allocate large memory in stack */
+#endif
+	EVENT_AIS_BSS_INFO_T rParam;
+	UINT_32 u4BufLen = 0;
+
+	/* <1> Sanity check and acquire the net_device */
+	ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
+	if (u4WlanDevNum == 0) {
+		DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n");
+		return;
+	}
+	prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
+	/* ASSERT(prDev); */
+
+	fgIsUnderSuspend = false;
+
+	if (!prDev) {
+		DBGLOG(INIT, INFO, "prDev == NULL!!!\n");
+		return;
+	}
+	/* <3> acquire the prGlueInfo */
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	kalPerMonEnable(prGlueInfo);
+
+	/*
+	   We will receive the event in rx, we will check if the status is the same in driver
+	   and FW, if not the same, trigger disconnetion procedure.
+	 */
+
+	kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T));
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryBSSInfo,
+			   &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus);
+	}
+
+	/* <2> get the IPv4 address */
+	if (!(prDev->ip_ptr) ||
+	    !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
+		goto notify_resume;
+	}
+	/* <4> copy the IPv4 address */
+	kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
+
+#ifdef CONFIG_IPV6
+	/* <5> get the IPv6 address */
+	if (!prDev || !(prDev->ip6_ptr) ||
+	    !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
+		goto notify_resume;
+	}
+	/* <6> copy the IPv6 address */
+	kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
+	DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
+			    ip6[0], ip6[1], ip6[2], ip6[3],
+			    ip6[4], ip6[5], ip6[6], ip6[7],
+			    ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]
+	       );
+#endif
+	/* <7> clear the ARP filter */
+	{
+		UINT_32 u4SetInfoLen = 0;
+/* UINT_8 aucBuf[32] = {0}; */
+		UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
+		P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
+		/* aucBuf; */
+
+		kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
+
+		prParamNetAddrList->u4AddressCount = 0;
+		prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+
+		ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */));
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetNetworkAddress,
+				   (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+	}
+
+notify_resume:
+	DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n",
+		       rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive,
+		       ip[0], ip[1], ip[2], ip[3], rStatus);
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		wlanNotifyFwSuspend(prGlueInfo, FALSE);
+	}
+}
+#endif /* ! CONFIG_X86 */
+
+int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode)
+{
+#if 0
+	P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev));
+	PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P;
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	rSetP2P.u4Enable = p2pmode.u4Enable;
+	rSetP2P.u4Mode = p2pmode.u4Mode;
+
+	if (!rSetP2P.u4Enable)
+		p2pNetUnregister(prGlueInfo, TRUE);
+
+	rWlanStatus = kalIoctl(prGlueInfo,
+			       wlanoidSetP2pMode,
+			       (PVOID) &rSetP2P,
+			       sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+	DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus);
+	if (rSetP2P.u4Enable)
+		p2pNetRegister(prGlueInfo, TRUE);
+
+	return 0;
+
+#else
+
+	P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev));
+	PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P;
+	WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+	BOOLEAN fgIsP2PEnding;
+	UINT_32 u4BufLen = 0;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode);
+
+	/* avoid remove & p2p off command simultaneously */
+	GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+	fgIsP2PEnding = g_u4P2PEnding;
+	g_u4P2POnOffing = 1;
+	GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+
+	if (fgIsP2PEnding == 1) {
+		/* skip the command if we are removing */
+		GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+		g_u4P2POnOffing = 0;
+		GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+		return 0;
+	}
+
+	rSetP2P.u4Enable = p2pmode.u4Enable;
+	rSetP2P.u4Mode = p2pmode.u4Mode;
+
+#if !CFG_SUPPORT_PERSIST_NETDEV
+	if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE))
+		p2pNetUnregister(prGlueInfo, TRUE);
+#endif
+	/* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */
+	/*
+	   Scenario:
+	   1. System enters suspend/resume but not yet enter wlanearlysuspend()
+	   or wlanlateresume();
+
+	   2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl()
+	   and get g_halt_sem then do glRegisterEarlySuspend() or
+	   glUnregisterEarlySuspend();
+
+	   But system suspend/resume procedure is not yet finished so we
+	   suspend;
+
+	   3. System switches back to do suspend/resume procedure and execute
+	   kalIoctl(). But driver does not yet release g_halt_sem so system
+	   suspend in wlanearlysuspend() or wlanlateresume();
+
+	   ==> deadlock occurs.
+	 */
+
+	rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */
+			       sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+#if !CFG_SUPPORT_PERSIST_NETDEV
+	/* Need to check fgIsP2PRegistered, in case of whole chip reset.
+	 * in this case, kalIOCTL return success always,
+	 * and prGlueInfo->prP2pInfo may be NULL */
+	if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE))
+		p2pNetRegister(prGlueInfo, TRUE);
+#endif
+	GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+	g_u4P2POnOffing = 0;
+	GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+	return 0;
+#endif
+}
+
+static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM])
+{
+	kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule));
+	kalPrint("[wlan] change debug level");
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Wlan probe function. This function probes and initializes the device.
+*
+* \param[in] pvData     data passed by bus driver init function
+*                           _HIF_EHPI: NULL
+*                           _HIF_SDIO: sdio bus driver handle
+*
+* \retval 0 Success
+* \retval negative value Failed
+*/
+/*----------------------------------------------------------------------------*/
+static INT_32 wlanProbe(PVOID pvData)
+{
+	struct wireless_dev *prWdev = NULL;
+	enum probe_fail_reason {
+		BUS_INIT_FAIL,
+		NET_CREATE_FAIL,
+		BUS_SET_IRQ_FAIL,
+		ADAPTER_START_FAIL,
+		NET_REGISTER_FAIL,
+		PROC_INIT_FAIL,
+		FAIL_REASON_NUM
+	} eFailReason;
+	P_WLANDEV_INFO_T prWlandevInfo = NULL;
+	INT_32 i4DevIdx = 0;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_ADAPTER_T prAdapter = NULL;
+	INT_32 i4Status = 0;
+	BOOLEAN bRet = FALSE;
+
+	eFailReason = FAIL_REASON_NUM;
+	do {
+		/* 4 <1> Initialize the IO port of the interface */
+		/*  GeorgeKuo: pData has different meaning for _HIF_XXX:
+		 * _HIF_EHPI: pointer to memory base variable, which will be
+		 *      initialized by glBusInit().
+		 * _HIF_SDIO: bus driver handle
+		 */
+
+		bRet = glBusInit(pvData);
+		wlanDebugInit();
+		/* Cannot get IO address from interface */
+		if (FALSE == bRet) {
+			DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n");
+			i4Status = -EIO;
+			eFailReason = BUS_INIT_FAIL;
+			break;
+		}
+		/* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */
+		prWdev = wlanNetCreate(pvData);
+		if (prWdev == NULL) {
+			DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n");
+			i4Status = -ENOMEM;
+			eFailReason = NET_CREATE_FAIL;
+			break;
+		}
+		/* 4 <2.5> Set the ioaddr to HIF Info */
+		prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
+		gPrDev = prGlueInfo->prDevHandler;
+
+		/* 4 <4> Setup IRQ */
+		prWlandevInfo = &arWlanDevInfo[i4DevIdx];
+
+		i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
+
+		if (i4Status != WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n");
+			eFailReason = BUS_SET_IRQ_FAIL;
+			break;
+		}
+
+		prGlueInfo->i4DevIdx = i4DevIdx;
+
+		prAdapter = prGlueInfo->prAdapter;
+
+		prGlueInfo->u4ReadyFlag = 0;
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+		prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP);
+#endif
+#if CFG_SUPPORT_CFG_FILE
+		{
+			PUINT_8 pucConfigBuf;
+			UINT_32 u4ConfigReadLen;
+
+			wlanCfgInit(prAdapter, NULL, 0, 0);
+			pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE);
+			u4ConfigReadLen = 0;
+			DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n");
+			if (pucConfigBuf) {
+				kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE);
+				if (kalReadToFile("/data/misc/wifi.cfg",
+						pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
+					DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n");
+
+				} else if (kalReadToFile("/data/misc/wifi/wifi.cfg",
+						pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
+					DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n");
+				} else if (kalReadToFile("/lib/firmware/mediatek/wifi.cfg",
+						pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
+					DBGLOG(INIT, LOUD, "CFG_FILE: Read /lib/firmware/mediatek/wifi.cfg\n");
+				}
+
+				if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0)
+					wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0);
+				kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE);
+			}	/* pucConfigBuf */
+		}
+#endif
+		/* 4 <5> Start Device */
+		/*  */
+#if CFG_ENABLE_FW_DOWNLOAD
+		DBGLOG(INIT, TRACE, "start to download firmware...\n");
+
+		/* before start adapter, we need to open and load firmware */
+		{
+			UINT_32 u4FwSize = 0;
+			PVOID prFwBuffer = NULL;
+			P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
+
+			/* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */
+			kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T));
+			prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS;
+			prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS;
+
+			/* Load NVRAM content to REG_INFO_T */
+			glLoadNvram(prGlueInfo, prRegInfo);
+#if CFG_SUPPORT_CFG_FILE
+			wlanCfgApply(prAdapter);
+#endif
+
+			/* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */
+
+			prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
+			prRegInfo->fgEnArpFilter = TRUE;
+
+			if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) {
+				i4Status = -EIO;
+				DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n");
+				goto bailout;
+			} else {
+
+				if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer,
+					u4FwSize) != WLAN_STATUS_SUCCESS) {
+					i4Status = -EIO;
+				}
+			}
+
+			kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer);
+
+bailout:
+			/* kfree(prRegInfo); */
+
+			DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status);
+
+			if (i4Status < 0) {
+				GL_HIF_INFO_T *HifInfo;
+				UINT_32 u4FwCnt;
+
+				DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n");
+				HifInfo = &prAdapter->prGlueInfo->rHifInfo;
+				for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++)
+					DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR));
+				/* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */
+
+				/* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */
+				/* dump HIF register may be hung */
+				if (!fgIsBusAccessFailed)
+					HifRegDump(prGlueInfo->prAdapter);
+/* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */
+/* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */
+				eFailReason = ADAPTER_START_FAIL;
+				break;
+			}
+		}
+#else
+		/* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */
+		kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T));
+		P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
+
+		/* Load NVRAM content to REG_INFO_T */
+		glLoadNvram(prGlueInfo, prRegInfo);
+
+		prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
+
+		if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) {
+			i4Status = -EIO;
+			eFailReason = ADAPTER_START_FAIL;
+			break;
+		}
+#endif
+		if (FALSE == prAdapter->fgEnable5GBand)
+			prWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
+
+		prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
+		kalSetHalted(FALSE);
+#if CFG_SUPPORT_ROAMING_ENC
+		/* adjust roaming threshold */
+		{
+			WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+			CMD_ROAMING_INFO_T rRoamingInfo;
+			UINT_32 u4SetInfoLen = 0;
+
+			prAdapter->fgIsRoamingEncEnabled = TRUE;
+
+			/* suggestion from Tsaiyuan.Hsu */
+			kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T));
+			rRoamingInfo.fgIsFastRoamingApplied = TRUE;
+
+			DBGLOG(INIT, TRACE, "Enable roaming enhance function\n");
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetRoamingInfo,
+					   &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS)
+				DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus);
+		}
+#endif /* CFG_SUPPORT_ROAMING_ENC */
+
+#if (CFG_SUPPORT_TXR_ENC == 1)
+		/* adjust tx rate switch threshold */
+		rlmTxRateEnhanceConfig(prGlueInfo->prAdapter);
+#endif /* CFG_SUPPORT_TXR_ENC */
+
+		/* set MAC address */
+		{
+			WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+			struct sockaddr MacAddr;
+			UINT_32 u4SetInfoLen = 0;
+
+			kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data));
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidQueryCurrentAddr,
+					   &MacAddr.sa_data,
+					   PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus);
+				prGlueInfo->u4ReadyFlag = 0;
+			} else {
+				ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data));
+				ether_addr_copy(prGlueInfo->prDevHandler->perm_addr,
+					prGlueInfo->prDevHandler->dev_addr);
+
+				/* card is ready */
+				prGlueInfo->u4ReadyFlag = 1;
+#if CFG_SHOW_MACADDR_SOURCE
+				DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data));
+#endif
+			}
+		}
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+		/* set HW checksum offload */
+		{
+			WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+			UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
+			UINT_32 u4SetInfoLen = 0;
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetCSUMOffload,
+					   (PVOID) &u4CSUMFlags,
+					   sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS)
+				DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus);
+		}
+#endif
+
+		/* 4 <3> Register the card */
+		DBGLOG(INIT, TRACE, "wlanNetRegister...\n");
+		i4DevIdx = wlanNetRegister(prWdev);
+		if (i4DevIdx < 0) {
+			i4Status = -ENXIO;
+			DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n");
+			eFailReason = NET_REGISTER_FAIL;
+			break;
+		}
+
+		wlanRegisterNotifier();
+		/* 4 <6> Initialize /proc filesystem */
+#ifdef WLAN_INCLUDE_PROC
+		DBGLOG(INIT, TRACE, "init procfs...\n");
+		i4Status = procCreateFsEntry(prGlueInfo);
+		if (i4Status < 0) {
+			DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n");
+			eFailReason = PROC_INIT_FAIL;
+			break;
+		}
+#endif /* WLAN_INCLUDE_PROC */
+
+#if CFG_ENABLE_BT_OVER_WIFI
+		prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
+		prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
+		glRegisterAmpc(prGlueInfo);
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+		DBGLOG(INIT, TRACE, "wlanSubModInit...\n");
+
+		/* wlan is launched */
+		prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE;
+		/* if p2p module is inserted, notify tx_thread to init p2p network */
+		if (rSubModHandler[P2P_MODULE].subModInit)
+			wlanSubModInit(prGlueInfo);
+		/* register set_p2p_mode handler to mtk_wmt_wifi */
+		register_set_p2p_mode_handler(set_p2p_mode_handler);
+#endif
+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT
+		if (glIsChipNeedWakelock(prGlueInfo))
+			KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP");
+#endif
+	} while (FALSE);
+
+	if (i4Status != WLAN_STATUS_SUCCESS) {
+		switch (eFailReason) {
+		case PROC_INIT_FAIL:
+			wlanNetUnregister(prWdev);
+			set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
+			/* wake up main thread */
+			wake_up_interruptible(&prGlueInfo->waitq);
+			/* wait main thread stops */
+			wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
+			wlanAdapterStop(prAdapter);
+			glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
+			wlanNetDestroy(prWdev);
+			break;
+		case NET_REGISTER_FAIL:
+			set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
+			/* wake up main thread */
+			wake_up_interruptible(&prGlueInfo->waitq);
+			/* wait main thread stops */
+			wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
+			wlanAdapterStop(prAdapter);
+			glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
+			wlanNetDestroy(prWdev);
+			break;
+		case ADAPTER_START_FAIL:
+			glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
+			wlanNetDestroy(prWdev);
+			break;
+		case BUS_SET_IRQ_FAIL:
+			KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
+			wlanNetDestroy(prWdev);
+			break;
+		case NET_CREATE_FAIL:
+			break;
+		case BUS_INIT_FAIL:
+			break;
+		default:
+			break;
+		}
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	{
+		GLUE_SPIN_LOCK_DECLARATION();
+
+		GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+		g_u4P2PEnding = 0;
+		GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+	}
+#endif
+#if CFG_SUPPORT_AGPS_ASSIST
+	if (i4Status == WLAN_STATUS_SUCCESS)
+		kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0);
+#endif
+#if (CFG_SUPPORT_MET_PROFILING == 1)
+	{
+		int iMetInitRet = WLAN_STATUS_FAILURE;
+
+		if (i4Status == WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, TRACE, "init MET procfs...\n");
+			iMetInitRet = kalMetInitProcfs(prGlueInfo);
+			if (iMetInitRet < 0)
+				DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n");
+		}
+	}
+#endif
+	if (i4Status == WLAN_STATUS_SUCCESS) {
+		/*Init performance monitor structure */
+		kalPerMonInit(prGlueInfo);
+		/* probe ok */
+		DBGLOG(INIT, TRACE, "wlanProbe ok\n");
+	} else {
+		/* we don't care the return value of mtk_wcn_set_connsys_power_off_flag,
+		 * because even this function returns
+		 * error, we can also call core dump but only core dump failed. */
+		if (g_IsNeedDoChipReset)
+			mtk_wcn_set_connsys_power_off_flag(0);
+		/* probe failed */
+		DBGLOG(INIT, ERROR, "wlanProbe failed\n");
+	}
+
+	return i4Status;
+}				/* end of wlanProbe() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A method to stop driver operation and release all resources. Following
+*        this call, no frame should go up or down through this interface.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static VOID wlanRemove(VOID)
+{
+#define KAL_WLAN_REMOVE_TIMEOUT_MSEC			3000
+	struct net_device *prDev = NULL;
+	P_WLANDEV_INFO_T prWlandevInfo = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_ADAPTER_T prAdapter = NULL;
+
+	DBGLOG(INIT, LOUD, "Remove wlan!\n");
+
+	/* 4 <0> Sanity check */
+	ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
+	if (0 == u4WlanDevNum) {
+		DBGLOG(INIT, ERROR, "0 == u4WlanDevNum\n");
+		return;
+	}
+	/* unregister set_p2p_mode handler to mtk_wmt_wifi */
+	register_set_p2p_mode_handler(NULL);
+
+	prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
+	prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1];
+
+	ASSERT(prDev);
+	if (NULL == prDev) {
+		DBGLOG(INIT, ERROR, "NULL == prDev\n");
+		return;
+	}
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+	if (NULL == prGlueInfo) {
+		DBGLOG(INIT, ERROR, "NULL == prGlueInfo\n");
+		free_netdev(prDev);
+		return;
+	}
+
+	kalPerMonDestroy(prGlueInfo);
+#if CFG_ENABLE_WIFI_DIRECT
+	/* avoid remove & p2p off command simultaneously */
+	{
+		BOOLEAN fgIsP2POnOffing;
+
+		GLUE_SPIN_LOCK_DECLARATION();
+
+		GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+		g_u4P2PEnding = 1;
+		fgIsP2POnOffing = g_u4P2POnOffing;
+		GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+
+		DBGLOG(INIT, TRACE, "waiting for fgIsP2POnOffing...\n");
+
+		/* History: cannot use down() here, sometimes we cannot come back here */
+		/* waiting for p2p off command finishes, we cannot skip the remove */
+		while (1) {
+			if (fgIsP2POnOffing == 0)
+				break;
+			GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+			fgIsP2POnOffing = g_u4P2POnOffing;
+			GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+		}
+	}
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	if (prGlueInfo->rBowInfo.fgIsNetRegistered) {
+		bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter);
+		/* wait 300ms for BoW module to send deauth */
+		kalMsleep(300);
+	}
+#endif
+
+	/* 4 <1> Stopping handling interrupt and free IRQ */
+	DBGLOG(INIT, TRACE, "free IRQ...\n");
+	glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev)));
+
+	kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T));
+
+	kalSetHalted(TRUE);	/* before flush_delayed_work() */
+	if (fgIsWorkMcStart == TRUE) {
+		DBGLOG(INIT, TRACE, "flush_delayed_work...\n");
+		flush_delayed_work(&workq);	/* flush_delayed_work_sync is deprecated */
+	}
+
+	flush_delayed_work(&sched_workq);
+
+	DBGLOG(INIT, INFO, "down g_halt_sem...\n");
+	kalHaltLock(KAL_WLAN_REMOVE_TIMEOUT_MSEC);
+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT
+	if (glIsChipNeedWakelock(prGlueInfo))
+		KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock);
+#endif
+
+/* flush_delayed_work_sync(&workq); */
+/* flush_delayed_work(&workq); */ /* flush_delayed_work_sync is deprecated */
+
+	/* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */
+/* prGlueInfo->u4Flag |= GLUE_FLAG_HALT; */
+	set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
+	DBGLOG(INIT, TRACE, "waiting for tx_thread stop...\n");
+
+	/* wake up main thread */
+	wake_up_interruptible(&prGlueInfo->waitq);
+
+	DBGLOG(INIT, TRACE, "wait_for_completion_interruptible\n");
+
+	/* wait main thread stops */
+	wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
+
+	DBGLOG(INIT, TRACE, "mtk_sdiod stopped\n");
+
+	KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rTxThreadWakeLock);
+	KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->rAhbIsrWakeLock);
+
+	/* prGlueInfo->rHifInfo.main_thread = NULL; */
+	prGlueInfo->main_thread = NULL;
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	if (prGlueInfo->rBowInfo.fgIsRegistered)
+		glUnregisterAmpc(prGlueInfo);
+#endif
+
+	/* 4 <3> Remove /proc filesystem. */
+#ifdef WLAN_INCLUDE_PROC
+	procRemoveProcfs();
+#endif /* WLAN_INCLUDE_PROC */
+
+#if (CFG_SUPPORT_MET_PROFILING == 1)
+	kalMetRemoveProcfs();
+#endif
+
+	/* Force to do DMA reset */
+	DBGLOG(INIT, TRACE, "glResetHif\n");
+	glResetHif(prGlueInfo);
+
+	/* 4 <4> wlanAdapterStop */
+	prAdapter = prGlueInfo->prAdapter;
+#if CFG_SUPPORT_AGPS_ASSIST
+	kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, 0);
+#endif
+
+	wlanAdapterStop(prAdapter);
+	DBGLOG(INIT, TRACE, "Number of Stalled Packets = %d\n", prGlueInfo->i4TxPendingFrameNum);
+
+#if CFG_ENABLE_WIFI_DIRECT
+	prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
+	if (prGlueInfo->prAdapter->fgIsP2PRegistered) {
+		DBGLOG(INIT, TRACE, "p2pNetUnregister...\n");
+#if !CFG_SUPPORT_PERSIST_NETDEV
+		p2pNetUnregister(prGlueInfo, FALSE);
+#endif
+		DBGLOG(INIT, INFO, "p2pRemove...\n");
+		p2pRemove(prGlueInfo);
+	}
+#endif
+
+	/* 4 <5> Release the Bus */
+	glBusRelease(prDev);
+
+	kalHaltUnlock();
+	wlanDebugUninit();
+	/* 4 <6> Unregister the card */
+	wlanNetUnregister(prDev->ieee80211_ptr);
+
+	/* 4 <7> Destroy the device */
+	wlanNetDestroy(prDev->ieee80211_ptr);
+	prDev = NULL;
+
+	DBGLOG(INIT, LOUD, "wlanUnregisterNotifier...\n");
+	wlanUnregisterNotifier();
+
+	DBGLOG(INIT, INFO, "wlanRemove ok\n");
+}				/* end of wlanRemove() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Driver entry point when the driver is configured as a Linux Module, and
+*        is called once at module load time, by the user-level modutils
+*        application: insmod or modprobe.
+*
+* \retval 0     Success
+*/
+/*----------------------------------------------------------------------------*/
+/* 1 Module Entry Point */
+static int initWlan(void)
+{
+	int ret = 0, i;
+#if DBG
+	for (i = 0; i < DBG_MODULE_NUM; i++)
+		aucDebugModule[i] = DBG_CLASS_MASK; /* enable all */
+#else
+	/* Initial debug level is D1 */
+	for (i = 0; i < DBG_MODULE_NUM; i++)
+		aucDebugModule[i] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_INFO | DBG_CLASS_STATE;
+#endif /* DBG */
+	DBGLOG(INIT, INFO, "initWlan\n");
+
+	spin_lock_init(&g_p2p_lock);
+
+	/* memory pre-allocation */
+	kalInitIOBuffer();
+	procInitFs();
+	createWirelessDevice();
+	if (gprWdev)
+		glP2pCreateWirelessDevice((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy));
+
+	ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO);
+
+	if (ret == -EIO) {
+		kalUninitIOBuffer();
+		return ret;
+	}
+#if (CFG_CHIP_RESET_SUPPORT)
+	glResetInit();
+#endif
+
+	/* register set_dbg_level handler to mtk_wmt_wifi */
+	register_set_dbg_level_handler(set_dbg_level_handler);
+
+	/* Set the initial DEBUG CLASS of each module */
+	return ret;
+}				/* end of initWlan() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Driver exit point when the driver as a Linux Module is removed. Called
+*        at module unload time, by the user level modutils application: rmmod.
+*        This is our last chance to clean up after ourselves.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+/* 1 Module Leave Point */
+static VOID exitWlan(void)
+{
+	DBGLOG(INIT, INFO, "exitWlan\n");
+
+	/* unregister set_dbg_level handler to mtk_wmt_wifi */
+	register_set_dbg_level_handler(NULL);
+
+#if CFG_CHIP_RESET_SUPPORT
+	glResetUninit();
+#endif
+	destroyWirelessDevice();
+	glP2pDestroyWirelessDevice();
+
+	glUnregisterBus(wlanRemove);
+
+	/* free pre-allocated memory */
+	kalUninitIOBuffer();
+
+	DBGLOG(INIT, INFO, "exitWlan\n");
+	procUninitProcFs();
+
+}				/* end of exitWlan() */
+
+#ifdef MTK_WCN_BUILT_IN_DRIVER
+
+int mtk_wcn_wlan_gen2_init(void)
+{
+	return initWlan();
+}
+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_init);
+
+void mtk_wcn_wlan_gen2_exit(void)
+{
+	return exitWlan();
+}
+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_exit);
+
+#else
+
+module_init(initWlan);
+module_exit(exitWlan);
+
+#endif
+
+MODULE_AUTHOR(NIC_AUTHOR);
+MODULE_DESCRIPTION(NIC_DESC);
+MODULE_SUPPORTED_DEVICE(NIC_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c
new file mode 100644
index 0000000000000..3a257c9f85c4d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c
@@ -0,0 +1,4799 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#3
+*/
+
+/*! \file   gl_kal.c
+    \brief  GLUE Layer will export the required procedures here for internal driver stack.
+
+    This file contains all routines which are exported from GLUE Layer to internal
+    driver stack.
+*/
+
+/*
+** Log: gl_kal.c
+**
+** 08 20 2012 yuche.tsai
+** NULL
+** Fix possible KE issue.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 05 31 2012 terry.wu
+ * NULL
+ * .
+ *
+ * 03 26 2012 cp.wu
+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist
+ * invoke put_cred() after get_current_cred() calls.
+ *
+ * 03 07 2012 yuche.tsai
+ * NULL
+ * Fix compile error when WiFi Direct is off.
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 02 20 2012 cp.wu
+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist
+ * do not need to invoke free() while firmware image file doesn't exist
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 01 02 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
+ *
+ * 11 21 2011 cp.wu
+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing
+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer
+ * add more checking for such cases
+ *
+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered.
+ * add some tweaking to protect such cases because that net device has become invalid.
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 16 2011 yuche.tsai
+ * NULL
+ * Avoid using work thread.
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 23 2011 yuche.tsai
+ * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue
+ * Regulation domain feature check in.
+ *
+ * 08 12 2011 cp.wu
+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC.
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 06 13 2011 eddie.chen
+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV]  Add tx rx statistics in linux and use netif_rx_ni
+ * Add tx rx statistics and netif_rx_ni.
+ *
+ * 04 15 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW short range mode.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated
+ * network type
+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected
+ *
+ * 04 08 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * correct i4TxPendingFrameNum decreasing.
+ *
+ * 03 23 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * apply multi-queue operation only for linux kernel > 2.6.26
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability for compatible with linux 2.6.12.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * improve portability for awareness of early version of linux kernel and wireless extension.
+ *
+ * 03 18 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * refix ...
+ *
+ * 03 18 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * correct compiling warning/error.
+ *
+ * 03 18 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * add more robust fault tolerance design when pre-allocation failed. (rarely happen)
+ *
+ * 03 17 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * use pre-allocated buffer for storing enhanced interrupt response as well
+ *
+ * 03 16 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * 1. pre-allocate physical continuous buffer while module is being loaded
+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
+ *
+ * The windows part remained the same as before, but added similar APIs to hide the difference.
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
+ * memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 14 2011 jeffrey.chang
+ * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message
+ * fix kernel build warning message
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 03 06 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Sync BOW Driver to latest person development branch version..
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * support concurrent network
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * modify net device relative functions to support multiple H/W queues
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after
+ * connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
+ *
+ * 02 21 2011 cp.wu
+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
+ * simplify logic for checking NVRAM existence only once.
+ *
+ * 01 24 2011 cp.wu
+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
+ * 1. add an extra counter for tracking pending forward frames.
+ * 2. notify TX service thread as well when there is pending forward frame
+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
+ *
+ * 01 19 2011 cp.wu
+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
+ * implementation of separate BT_OVER_WIFI data path.
+ *
+ * 01 10 2011 cp.wu
+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues
+ * due to multiple access
+ * use mutex to protect kalIoctl() for thread safe.
+ *
+ * 11 26 2010 cp.wu
+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field
+ * checking
+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used
+ * to indicate user is attached
+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 11 02 2010 jeffrey.chang
+ * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets
+ * .
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 11 01 2010 yarco.yang
+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
+ * Add code to run WlanIST in SDIO callback.
+ *
+ * 10 26 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW]
+ * Support NIC capability query command
+ * 1) update NVRAM content template to ver 1.02
+ * 2) add compile option for querying NIC capability (default: off)
+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
+ * 4) correct auto-rate compiler error under linux (treat warning as error)
+ * 5) simplify usage of NVRAM and REG_INFO_T
+ * 6) add version checking between driver and firmware
+ *
+ * 10 25 2010 jeffrey.chang
+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform
+ * Remove redundant code which cause mismatch of power control release
+ *
+ * 10 25 2010 jeffrey.chang
+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform
+ * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control
+ *
+ * 10 18 2010 jeffrey.chang
+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue
+ * refine the scan ioctl to prevent hanging of Android UI
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
+ * The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * if there is NVRAM, then use MAC address on NVRAM as default MAC address.
+ *
+ * 10 06 2010 cp.wu
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * code reorganization to improve isolation between GLUE and CORE layers.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
+ * associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 30 2010 cp.wu
+ * NULL
+ * API added: nicTxPendingPackets(), for simplifying porting layer
+ *
+ * 08 20 2010 yuche.tsai
+ * NULL
+ * Support second interface indicate when enabling P2P.
+ *
+ * 08 18 2010 yarco.yang
+ * NULL
+ * 1. Fixed HW checksum offload function not work under Linux issue.
+ * 2. Add debug message.
+ *
+ * 08 16 2010 jeffrey.chang
+ * NULL
+ * remove redundant code which cause kernel panic
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * 1) modify tx service thread to avoid busy looping
+ * 2) add spin lock declartion for linux build
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * simplify post-handling after TX_DONE interrupt is handled.
+ *
+ * 07 28 2010 jeffrey.chang
+ * NULL
+ * 1) remove unused spinlocks
+ * 2) enable encyption ioctls
+ * 3) fix scan ioctl which may cause supplicant to hang
+ *
+ * 07 23 2010 cp.wu
+ *
+ * 1) re-enable AIS-FSM beacon timeout handling.
+ * 2) scan done API revised
+ *
+ * 07 23 2010 jeffrey.chang
+ *
+ * add new KAL api
+ *
+ * 07 23 2010 jeffrey.chang
+ *
+ * bug fix: allocate regInfo when disabling firmware download
+ *
+ * 07 23 2010 jeffrey.chang
+ *
+ * use glue layer api to decrease or increase counter atomically
+ *
+ * 07 22 2010 jeffrey.chang
+ *
+ * modify tx thread and remove some spinlock
+ *
+ * 07 22 2010 jeffrey.chang
+ *
+ * use different spin lock for security frame
+ *
+ * 07 22 2010 jeffrey.chang
+ *
+ * add new spinlock
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * add spinlock for pending security frame count
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * adjust the timer unit to microsecond
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * timer should return value greater than zero
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * add kal api for scanning done
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * modify cmd/data path for new design
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * add new kal api
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * for linux driver migration
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 23 2010 yarco.yang
+ * [WPD00003837][MT6620]Data Path Refine
+ * Merge g_arStaRec[] into adapter->arStaRec[]
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change MAC address updating logic.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * remove unused files.
+ *
+ * 05 29 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix private ioctl for rftest
+ *
+ * 05 29 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * workaround for fixing request_firmware() failure on android 2.1
+ *
+ * 05 28 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix kernel panic when debug mode enabled
+ *
+ * 05 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) Modify set mac address code
+ * 2) remove power management macro
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 05 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Disable network interface after disassociation
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * fill network type field while doing frame identification.
+ *
+ * 05 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * prevent supplicant accessing driver during resume
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame
+ *
+ * 04 27 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) fix firmware download bug
+ * 2) remove query statistics for acelerating firmware download
+ *
+ * 04 27 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * follow Linux's firmware framework, and remove unused kal API
+ *
+ * 04 22 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ *
+ * 1) modify rx path code for supporting Wi-Fi direct
+ * 2) modify config.h since Linux dont need to consider retaining packet
+ *
+ * 04 21 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add for private ioctl support
+ *
+ * 04 15 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * change firmware name
+ *
+ * 04 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * flush pending TX packets while unloading driver
+ *
+ * 04 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Set driver own before handling cmd queue
+ *
+ * 04 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used
+ * 2) fix ioctl
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * information buffer for query oid/ioctl is now buffered in prCmdInfo
+ *  *  *  *  *  *  * instead of glue-layer variable to improve multiple oid/ioctl capability
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *    capability
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix spinlock usage
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add spinlock for i4TxPendingFrameNum access
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) add spinlock
+ *  * 2) add KAPI for handling association info
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix spinlock usage
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * adding firmware download KAPI
+ *
+ * 04 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Set MAC address from firmware
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1. free cmdinfo after command is emiited.
+ * 2. for BoW frames, user priority is extracted from sk_buff directly.
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * finish non-glue layer access to glue variables
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * accessing to firmware load/start address, and access to OID handling information
+ *  *  * are now handled in glue layer
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  *  *  *  *  * are done in adapter layer.
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * (1)deliver the kalOidComplete status to upper layer
+ * (2) fix spin lock
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer.
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add timeout check in the kalOidComplete
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) for some OID, never do timeout expiration
+ *  *  * 2) add 2 kal API for later integration
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * raising the priority of processing interrupt
+ *
+ * 04 01 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in
+ *
+ * 03 30 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * emulate NDIS Pending OID facility
+ *
+ * 03 28 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * adding secondary command queue for improving non-glue code portability
+ *
+ * 03 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * adding firmware download kal api
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add Bluetooth-over-Wifi frame header check
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090
+**  Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
+**  \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088
+**  fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding
+**  \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461
+**  Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL
+**  \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088
+**  remove non-used code for code review, add assert check
+**  \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461
+**  \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461
+**  Rename KAL function
+**  \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461
+**  \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084
+**  rename wlanoid
+**  \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084
+**  remove un-used KAL function
+**  \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461
+**  Move Query Media Status to GLUE
+**  \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461
+**  change awake queue threshold and remove code which mark #if 0
+**  \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461
+**  Add iwpriv support for AdHocMode setting
+**  \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084
+**  add KAL function to setting pattern search function enable/ disable
+**  \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461
+**  Add comment
+**  \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461
+**  Add update MAC Address for Linux
+**  \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084
+**  update function for initial value access
+**  \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088
+**  use kal update associate request at linux
+**  \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385
+**   1. add Query Registry Mac address function.
+**  \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084
+**  modify KAL set network address/ checksum offload part
+**  \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461
+**  Add debug option - Packet Order for Linux
+**  \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084
+**  modify the argument of kalQueryPacketInfo()
+**  \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425
+**  1. Revise csum offload
+**  \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425
+**  1. Fix bugs
+**
+**  \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461
+**  Fix Windows RX multiple packet retain problem
+**  \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088
+**  <workaround> CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit
+**  \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425
+**  1. Modify for CSUM offloading with Tx Fragment
+**  \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461
+**  Add Tx Fragmentation Support
+**  \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088
+**  add the WPS code, indicate the mgmt frame to upper layer
+**  \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461
+**  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
+**  \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425
+**  1. Update wlanQueryInformation
+**  \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425
+**  1. Refine multicast list code
+**  2. Refine TCP/IP csum offload code
+**
+** Revision 1.5  2007/07/17 13:01:18  MTK01088
+** add associate req and rsp function
+**
+** Revision 1.4  2007/07/13 05:19:19  MTK01084
+** provide timer set functions
+**
+** Revision 1.3  2007/06/27 02:18:51  MTK01461
+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
+**
+** Revision 1.2  2007/06/25 06:16:24  MTK01461
+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/sched/debug.h>
+#include "gl_os.h"
+#include "gl_wext.h"
+#include "precomp.h"
+#if defined(CONFIG_MTK_TC1_FEATURE)
+#include <tc1_partition.h>
+#endif
+#if CFG_SUPPORT_AGPS_ASSIST
+#include <net/netlink.h>
+#endif
+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG
+#include <mt_sleep.h>
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+#if DBG
+int allocatedMemSize = 0;
+#endif
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+/* #define MTK_DMA_BUF_MEMCPY_SUP */
+static PVOID pvIoBuffer;
+
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+static PVOID pvIoPhyBuf;
+static PVOID pvDmaBuffer;
+static PVOID pvDmaPhyBuf;
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+
+static UINT_32 pvIoBufferSize;
+static UINT_32 pvIoBufferUsage;
+static struct KAL_HALT_CTRL_T rHaltCtrl = {
+	.lock = __SEMAPHORE_INITIALIZER(rHaltCtrl.lock, 1),
+	.owner = NULL,
+	.fgHalt = TRUE,
+	.fgHeldByKalIoctl = FALSE,
+	.u4HoldStart = 0,
+};
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT
+typedef enum _ENUM_WMTHWVER_TYPE_T {
+	WMTHWVER_MT6620_E1 = 0x0,
+	WMTHWVER_MT6620_E2 = 0x1,
+	WMTHWVER_MT6620_E3 = 0x2,
+	WMTHWVER_MT6620_E4 = 0x3,
+	WMTHWVER_MT6620_E5 = 0x4,
+	WMTHWVER_MT6620_E6 = 0x5,
+	WMTHWVER_MT6620_MAX,
+	WMTHWVER_INVALID = 0xff
+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T;
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo)
+{
+	KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &(prGlueInfo->rAhbIsrWakeLock), (HZ / 10));	/* 100ms */
+}
+
+#if CFG_ENABLE_FW_DOWNLOAD
+
+static struct file *filp;
+static uid_t orgfsuid;
+static gid_t orgfsgid;
+static mm_segment_t orgfs;
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is provided by GLUE Layer for internal driver stack to
+*        open firmware image in kernel space
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval WLAN_STATUS_SUCCESS.
+* \retval WLAN_STATUS_FAILURE.
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS kalFirmwareOpen(IN P_GLUE_INFO_T prGlueInfo)
+{
+	UINT_8 aucFilePath[50];
+
+	/* FIX ME: since we don't have hotplug script in the filesystem
+	 * , so the request_firmware() KAPI can not work properly
+	 */
+
+	/* save uid and gid used for filesystem access.
+	 * set user and group to 0(root) */
+	struct cred *cred = (struct cred *)get_current_cred();
+
+	orgfsuid = cred->fsuid.val;
+	orgfsgid = cred->fsgid.val;
+	cred->fsuid.val = cred->fsgid.val = 0;
+
+	ASSERT(prGlueInfo);
+
+	orgfs = get_fs();
+	set_fs(get_ds());
+
+	/* open the fw file */
+#if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT
+	switch (mtk_wcn_wmt_hwver_get()) {
+	case WMTHWVER_MT6620_E1:
+	case WMTHWVER_MT6620_E2:
+	case WMTHWVER_MT6620_E3:
+	case WMTHWVER_MT6620_E4:
+	case WMTHWVER_MT6620_E5:
+		filp = filp_open("/lib/firmware/mediatek/" CFG_FW_FILENAME, O_RDONLY, 0);
+		break;
+
+	case WMTHWVER_MT6620_E6:
+	default:
+		filp = filp_open("/lib/firmware/mediatek/" CFG_FW_FILENAME "_E6", O_RDONLY, 0);
+		break;
+	}
+#elif defined(MT6628)
+/* filp = filp_open("/lib/firmware/mediatek/"CFG_FW_FILENAME"_MT6628", O_RDONLY, 0); */
+/* filp = filp_open("/lib/firmware/mediatek/"CFG_FW_FILENAME"_MT6582", O_RDONLY, 0); */
+#if 0				/* new wifi ram code mechanism, waiting firmware ready, then we can enable these code */
+	kalMemZero(aucFilePath, sizeof(aucFilePath));
+	kalMemCopy(aucFilePath, "/lib/firmware/mediatek/" CFG_FW_FILENAME "_AD", sizeof("/lib/firmware/mediatek/" CFG_FW_FILENAME "_AD"));
+	filp = filp_open(aucFilePath, O_RDONLY, 0);
+	if (!IS_ERR(filp))
+		goto open_success;
+#endif
+	kalMemZero(aucFilePath, sizeof(aucFilePath));
+	kalMemCopy(aucFilePath, "/lib/firmware/mediatek/" CFG_FW_FILENAME "_", strlen("/lib/firmware/mediatek/" CFG_FW_FILENAME "_"));
+	glGetChipInfo(prGlueInfo, &aucFilePath[strlen("/lib/firmware/mediatek/" CFG_FW_FILENAME "_")]);
+
+	DBGLOG(INIT, INFO, "open file: %s\n", aucFilePath);
+
+	filp = filp_open(aucFilePath, O_RDONLY, 0);
+#else
+	filp = filp_open("/lib/firmware/mediatek/" CFG_FW_FILENAME, O_RDONLY, 0);
+#endif
+	if (IS_ERR(filp)) {
+		DBGLOG(INIT, ERROR, "Open FW image: %s failed\n", CFG_FW_FILENAME);
+		goto error_open;
+	}
+#if 0
+open_success:
+#endif
+	DBGLOG(INIT, TRACE, "Open FW image: %s done\n", CFG_FW_FILENAME);
+	return WLAN_STATUS_SUCCESS;
+
+error_open:
+	/* restore */
+	set_fs(orgfs);
+	cred->fsuid.val = orgfsuid;
+	cred->fsgid.val = orgfsgid;
+	put_cred(cred);
+	return WLAN_STATUS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is provided by GLUE Layer for internal driver stack to
+*        release firmware image in kernel space
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval WLAN_STATUS_SUCCESS.
+* \retval WLAN_STATUS_FAILURE.
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS kalFirmwareClose(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	if ((filp != NULL) && !IS_ERR(filp)) {
+		/* close firmware file */
+		filp_close(filp, NULL);
+
+		/* restore */
+		set_fs(orgfs);
+		{
+			struct cred *cred = (struct cred *)get_current_cred();
+
+			cred->fsuid.val = orgfsuid;
+			cred->fsgid.val = orgfsgid;
+			put_cred(cred);
+		}
+		filp = NULL;
+	}
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is provided by GLUE Layer for internal driver stack to
+*        load firmware image in kernel space
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval WLAN_STATUS_SUCCESS.
+* \retval WLAN_STATUS_FAILURE.
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS kalFirmwareLoad(IN P_GLUE_INFO_T prGlueInfo, OUT PVOID prBuf, IN UINT_32 u4Offset, OUT PUINT_32 pu4Size)
+{
+	ASSERT(prGlueInfo);
+	ASSERT(pu4Size);
+	ASSERT(prBuf);
+
+	/* l = filp->f_path.dentry->d_inode->i_size; */
+#if 0
+	/* the object must have a read method */
+	if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) {
+		goto error_read;
+	} else {
+		filp->f_pos = u4Offset;
+		*pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos);
+	}
+#else
+	/* the object must have a read method */
+	if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) ) {
+		goto error_read;
+	} else {
+		filp->f_pos = u4Offset;
+		*pu4Size = vfs_read(filp, prBuf, *pu4Size, &filp->f_pos);
+	}
+#endif
+
+	return WLAN_STATUS_SUCCESS;
+
+error_read:
+	return WLAN_STATUS_FAILURE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is provided by GLUE Layer for internal driver stack to
+*        query firmware image size in kernel space
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval WLAN_STATUS_SUCCESS.
+* \retval WLAN_STATUS_FAILURE.
+*
+*/
+/*----------------------------------------------------------------------------*/
+
+WLAN_STATUS kalFirmwareSize(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_32 pu4Size)
+{
+	ASSERT(prGlueInfo);
+	ASSERT(pu4Size);
+
+	//*pu4Size = filp->f_path.dentry->d_inode->i_size;
+	*pu4Size = filp->f_op->llseek(filp, 0, 2);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to load firmware image
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+* \param ppvMapFileBuf  Pointer of pointer to memory-mapped firmware image
+* \param pu4FileLength  File length and memory mapped length as well
+
+* \retval Map File Handle, used for unammping
+*/
+/*----------------------------------------------------------------------------*/
+
+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength)
+{
+	UINT_32 u4FwSize = 0;
+	PVOID prFwBuffer = NULL;
+
+	DEBUGFUNC("kalFirmwareImageMapping");
+
+	ASSERT(prGlueInfo);
+	ASSERT(ppvMapFileBuf);
+	ASSERT(pu4FileLength);
+
+	do {
+		/* <1> Open firmware */
+		if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) {
+			DBGLOG(INIT, TRACE, "kalFirmwareOpen fail!\n");
+			break;
+		}
+
+		/* <2> Query firmare size */
+		kalFirmwareSize(prGlueInfo, &u4FwSize);
+		printk(KERN_ERR "%s firmware size %d\n", __FUNCTION__, u4FwSize);
+		/* <3> Use vmalloc for allocating large memory trunk */
+		prFwBuffer = vmalloc(ALIGN_4(u4FwSize));
+		/* <4> Load image binary into buffer */
+		if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) {
+			vfree(prFwBuffer);
+			kalFirmwareClose(prGlueInfo);
+			DBGLOG(INIT, TRACE, "kalFirmwareLoad fail!\n");
+			break;
+		}
+		/* <5> write back info */
+		*pu4FileLength = u4FwSize;
+		*ppvMapFileBuf = prFwBuffer;
+
+		return prFwBuffer;
+
+	} while (FALSE);
+
+	return NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to unload firmware image mapped memory
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+* \param pvFwHandle     Pointer to mapping handle
+* \param pvMapFileBuf   Pointer to memory-mapped firmware image
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf)
+{
+	DEBUGFUNC("kalFirmwareImageUnmapping");
+
+	ASSERT(prGlueInfo);
+
+	/* pvMapFileBuf might be NULL when file doesn't exist */
+	if (pvMapFileBuf)
+		vfree(pvMapFileBuf);
+
+	kalFirmwareClose(prGlueInfo);
+}
+
+#endif
+
+#if 0
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to load firmware image
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+* \param ppvMapFileBuf  Pointer of pointer to memory-mapped firmware image
+* \param pu4FileLength  File length and memory mapped length as well
+
+* \retval Map File Handle, used for unammping
+*/
+/*----------------------------------------------------------------------------*/
+
+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength)
+{
+	INT_32 i4Ret = 0;
+
+	DEBUGFUNC("kalFirmwareImageMapping");
+
+	ASSERT(prGlueInfo);
+	ASSERT(ppvMapFileBuf);
+	ASSERT(pu4FileLength);
+
+	do {
+		GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo;
+
+		prGlueInfo->prFw = NULL;
+
+		/* <1> Open firmware */
+		i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, prHifInfo->Dev);
+
+		if (i4Ret) {
+			DBGLOG(INIT, TRACE, "fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret);
+			break;
+		}
+		*pu4FileLength = prGlueInfo->prFw->size;
+		*ppvMapFileBuf = prGlueInfo->prFw->data;
+		return prGlueInfo->prFw->data;
+
+	} while (FALSE);
+
+	return NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to unload firmware image mapped memory
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+* \param pvFwHandle     Pointer to mapping handle
+* \param pvMapFileBuf   Pointer to memory-mapped firmware image
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+
+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf)
+{
+	DEBUGFUNC("kalFirmwareImageUnmapping");
+
+	ASSERT(prGlueInfo);
+	ASSERT(pvMapFileBuf);
+
+	release_firmware(prGlueInfo->prFw);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is provided by GLUE Layer for internal driver stack to acquire
+*        OS SPIN_LOCK.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] rLockCategory  Specify which SPIN_LOCK
+* \param[out] pu4Flags      Pointer of a variable for saving IRQ flags
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags)
+{
+	unsigned long u4Flags = 0;
+
+	ASSERT(prGlueInfo);
+	ASSERT(pu4Flags);
+
+	if (rLockCategory < SPIN_LOCK_NUM) {
+
+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF
+		spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]);
+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
+		spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], u4Flags);
+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
+
+		*pu4Flags = u4Flags;
+/* DBGLOG(INIT, TRACE, ("A+%d\n", rLockCategory)); */
+	}
+
+}				/* end of kalAcquireSpinLock() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is provided by GLUE Layer for internal driver stack to release
+*        OS SPIN_LOCK.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] rLockCategory  Specify which SPIN_LOCK
+* \param[in] u4Flags        Saved IRQ flags
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags)
+{
+	ASSERT(prGlueInfo);
+
+	if (rLockCategory < SPIN_LOCK_NUM) {
+		/* DBGLOG(INIT, TRACE, ("A-%d %d %d\n", rLockCategory, u4MemAllocCnt, u4MemFreeCnt)); */
+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF
+		spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]);
+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
+		spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], u4Flags);
+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
+
+	}
+
+}				/* end of kalReleaseSpinLock() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is provided by GLUE Layer for internal driver stack to update
+*        current MAC address.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] pucMacAddr     Pointer of current MAC address
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr)
+{
+	ASSERT(prGlueInfo);
+	ASSERT(pucMacAddr);
+
+	if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr))
+		memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN);
+
+}
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To query the packet information for offload related parameters.
+*
+* \param[in] pvPacket Pointer to the packet descriptor.
+* \param[in] pucFlag  Points to the offload related parameter.
+*
+* \return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag)
+{
+	struct sk_buff *skb = (struct sk_buff *)pvPacket;
+	UINT_8 ucFlag = 0;
+
+	ASSERT(pvPacket);
+	ASSERT(pucFlag);
+
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+#if DBG
+		/* Kevin: do double check, we can remove this part in Normal Driver.
+		 * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so
+		 * we'll process IP packet only.
+		 */
+		if (skb->protocol != htons(ETH_P_IP)) {
+			/* printk("Wrong skb->protocol( = %08x) for TX Checksum Offload.\n", skb->protocol); */
+		} else
+#endif
+		ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN);
+	}
+
+	*pucFlag = ucFlag;
+
+}				/* kalQueryChksumOffloadParam */
+
+/* 4 2007/10/8, mikewu, this is rewritten by Mike */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To update the checksum offload status to the packet to be indicated to OS.
+*
+* \param[in] pvPacket Pointer to the packet descriptor.
+* \param[in] pucFlag  Points to the offload related parameter.
+*
+* \return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T aeCSUM[])
+{
+	struct sk_buff *skb = (struct sk_buff *)pvPacket;
+
+	ASSERT(pvPacket);
+
+	if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS) &&
+	    ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) {
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	} else {
+		skb->ip_summed = CHECKSUM_NONE;
+#if DBG
+		if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)
+			DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n");
+		else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED)
+			DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n");
+		else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED)
+			DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n");
+		else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED)
+			DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n");
+		else
+			/* Do nothing */
+#endif
+	}
+
+}				/* kalUpdateRxCSUMOffloadParam */
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called to free packet allocated from kalPacketAlloc.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] pvPacket       Pointer of the packet descriptor
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket)
+{
+	dev_kfree_skb((struct sk_buff *)pvPacket);
+	if (prGlueInfo)
+		prGlueInfo->u8SkbFreed++;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Only handles driver own creating packet (coalescing buffer).
+*
+* \param prGlueInfo   Pointer of GLUE Data Structure
+* \param u4Size       Pointer of Packet Handle
+* \param ppucData     Status Code for OS upper layer
+*
+* \return NULL: Failed to allocate skb, Not NULL get skb
+*/
+/*----------------------------------------------------------------------------*/
+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData)
+{
+	struct sk_buff *prSkb = dev_alloc_skb(u4Size);
+
+	if (prSkb)
+		*ppucData = (PUINT_8) (prSkb->data);
+#if DBG
+	{
+		PUINT_32 pu4Head = (PUINT_32) &prSkb->cb[0];
+		*pu4Head = (UINT_32) prSkb->head;
+		DBGLOG(RX, TRACE, "prSkb->head = %#x, prSkb->cb = %#x\n", (UINT_32) prSkb->head, *pu4Head);
+	}
+#endif
+	return (PVOID) prSkb;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Process the received packet for indicating to OS.
+*
+* \param[in] prGlueInfo     Pointer to the Adapter structure.
+* \param[in] pvPacket       Pointer of the packet descriptor
+* \param[in] pucPacketStart The starting address of the buffer of Rx packet.
+* \param[in] u4PacketLen    The packet length.
+* \param[in] pfgIsRetain    Is the packet to be retained.
+* \param[in] aerCSUM        The result of TCP/ IP checksum offload.
+*
+* \retval WLAN_STATUS_SUCCESS.
+* \retval WLAN_STATUS_FAILURE.
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS
+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen,
+		   /* IN PBOOLEAN           pfgIsRetain, */
+		   IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[])
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	struct sk_buff *skb = (struct sk_buff *)pvPacket;
+
+	skb->data = pucPacketStart;
+	skb_reset_tail_pointer(skb);	/* reset tail pointer first, for 64bit kernel,we should call linux kernel API */
+	skb_trim(skb, 0);	/* only if skb->len > len, then skb_trim has effect */
+	skb_put(skb, u4PacketLen);	/* shift tail and skb->len to correct value */
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	kalUpdateRxCSUMOffloadParam(skb, aerCSUM);
+#endif
+
+	return rStatus;
+}
+
+#if (CONF_HIF_LOOPBACK_AUTO == 1)
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Do HIF loopback test.
+*
+* \param[in] GlueInfo   Pointer to the GLUE_INFO_T structure.
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+unsigned int testmode = 0;
+unsigned int testlen = 64;
+
+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo)
+{
+#define HIF_LOOPBK_AUTO_TEST_LEN    1600
+/* GL_HIF_INFO_T *HifInfo; */
+	static unsigned int txcnt;
+	struct sk_buff *MsduInfo;
+	UINT_8 *Pkt;
+	UINT_32 RegVal;
+	UINT_32 PktLen = 16;
+
+	/* Init */
+	if (testmode != 0) {
+		PktLen = kalRandomNumber() % 1520;
+		if (PktLen < 64)
+			PktLen = 64;
+	} else {
+		PktLen = testlen++;
+		if (PktLen > 1520) {
+			testmode = 1;
+			PktLen = 64;
+		}
+	}
+
+/* PktLen = 100; */
+	DBGLOG(INIT, INFO, "kalDevLoopbkAuto> Send a packet to HIF (len = %d) (total = %d)...\n", PktLen, ++txcnt);
+/* HifInfo = &GlueInfo->rHifInfo; */
+
+	/* Allocate a MSDU_INFO_T */
+	MsduInfo = kalPacketAlloc(GlueInfo, HIF_LOOPBK_AUTO_TEST_LEN, &Pkt);
+	if (MsduInfo == NULL) {
+		DBGLOG(INIT, WARN, "No PKT_INFO_T for sending loopback packet!\n");
+		return;
+	}
+
+	/* Init the packet */
+	MsduInfo->dev = GlueInfo->prDevHandler;
+	if (MsduInfo->dev == NULL) {
+		DBGLOG(INIT, WARN, "MsduInfo->dev == NULL!!\n");
+		kalPacketFree(GlueInfo, MsduInfo);
+		return;
+	}
+
+	MsduInfo->len = PktLen;
+	kalMemSet(MsduInfo->data, 0xff, 6);
+	kalMemSet(MsduInfo->data + 6, 0x5a, PktLen - 6);
+
+	/* Simulate OS to send the packet */
+	wlanHardStartXmit(MsduInfo, MsduInfo->dev);
+
+#if 0
+	PktLen += 4;
+	if (PktLen >= 1600)
+		PktLen = 16;
+#endif
+
+	/* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */
+/* HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(1000); */
+/* add_timer(&(HifInfo->HifTmrLoopbkFn)); */
+}
+
+int kalDevLoopbkThread(IN void *data)
+{
+	struct net_device *dev = data;
+	P_GLUE_INFO_T GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
+	GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo;
+	int ret;
+	static int test;
+
+	while (TRUE) {
+		ret = wait_event_interruptible(HifInfo->HifWaitq, (HifInfo->HifLoopbkFlg != 0));
+
+		if (HifInfo->HifLoopbkFlg == 0xFFFFFFFF)
+			break;
+
+		while (TRUE) {
+			/* if ((HifInfo->HifLoopbkFlg & 0x01) == 0) */
+			if (GlueInfo->i4TxPendingFrameNum < 64) {
+				DBGLOG(INIT, INFO, "GlueInfo->i4TxPendingFrameNum = %d\n",
+					GlueInfo->i4TxPendingFrameNum);
+				kalDevLoopbkAuto(GlueInfo);
+
+				if (testmode == 0)
+					kalMsleep(3000);
+			} else
+				kalMsleep(1);
+		}
+	}
+}
+
+void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb)
+{
+	static unsigned int rxcnt;
+	UINT_32 i;
+	UINT_8 *Buf = prSwRfb->pucRecvBuff + sizeof(HIF_TX_HEADER_T);
+	P_HIF_RX_HEADER_T prHifRxHdr = prSwRfb->prHifRxHdr;
+	UINT_32 len = prHifRxHdr->u2PacketLen - sizeof(HIF_TX_HEADER_T);
+
+	if (len > 1600) {
+		while (1)
+			DBGLOG(INIT, ERROR, "HIF> Loopback len > 1600!!! error!!!\n");
+	}
+
+	for (i = 0; i < 6; i++) {
+		if (Buf[i] != 0xff) {
+			while (1) {
+				DBGLOG(INIT, ERROR, "HIF> Loopbk dst addr error (len = %d)!\n", len);
+				dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen);
+			}
+		}
+	}
+
+	for (i = 6; i < len; i++) {
+		if (Buf[i] != 0x5a) {
+			while (1) {
+				DBGLOG(INIT, ERROR, "HIF> Loopbk error (len = %d)!\n", len);
+				dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen);
+			}
+		}
+	}
+
+	DBGLOG(INIT, INFO, "HIF> Loopbk OK (len = %d) (total = %d)!\n", len, ++rxcnt);
+}
+#endif /* CONF_HIF_LOOPBACK_AUTO */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To indicate an array of received packets is available for higher
+*        level protocol uses.
+*
+* \param[in] prGlueInfo Pointer to the Adapter structure.
+* \param[in] apvPkts The packet array to be indicated
+* \param[in] ucPktNum The number of packets to be indicated
+*
+* \retval TRUE Success.
+*
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum)
+{
+	UINT_8 ucIdx = 0;
+	struct net_device *prNetDev = prGlueInfo->prDevHandler;
+	struct sk_buff *prSkb = NULL;
+
+	ASSERT(prGlueInfo);
+	ASSERT(apvPkts);
+
+#if CFG_BOW_TEST
+	UINT_32 i;
+#endif
+
+	for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++) {
+		prSkb = apvPkts[ucIdx];
+#if DBG
+		do {
+			PUINT_8 pu4Head = (PUINT_8) &prSkb->cb[0];
+			UINT_32 u4HeadValue = 0;
+
+			kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue));
+			DBGLOG(RX, TRACE, "prSkb->head = %p, prSkb->cb = 0x%x\n", pu4Head, u4HeadValue);
+		} while (0);
+#endif
+
+		if (GLUE_GET_PKT_IS_P2P(prSkb)) {
+			/* P2P */
+#if CFG_ENABLE_WIFI_DIRECT
+			if (prGlueInfo->prAdapter->fgIsP2PRegistered)
+				prNetDev = kalP2PGetDevHdlr(prGlueInfo);
+			/* prNetDev->stats.rx_bytes += prSkb->len; */
+			/* prNetDev->stats.rx_packets++; */
+			prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len;
+			prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++;
+
+#else
+			prNetDev = prGlueInfo->prDevHandler;
+#endif
+		} else if (GLUE_GET_PKT_IS_PAL(prSkb)) {
+			/* BOW */
+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH
+			if (prGlueInfo->rBowInfo.fgIsNetRegistered)
+				prNetDev = prGlueInfo->rBowInfo.prDevHandler;
+#else
+			prNetDev = prGlueInfo->prDevHandler;
+#endif
+		} else {
+			/* AIS */
+			prNetDev = prGlueInfo->prDevHandler;
+			prGlueInfo->rNetDevStats.rx_bytes += prSkb->len;
+			prGlueInfo->rNetDevStats.rx_packets++;
+
+		}
+
+		/* check if the "unicast" packet is from us */
+		if (kalMemCmp(prSkb->data, prSkb->data + 6, 6) == 0) {
+			/* we will filter broadcast/multicast packet sent from us in hardware */
+			/* source address = destination address ? */
+			DBGLOG(RX, EVENT,
+			       "kalRxIndicatePkts got from us!!! Drop it! ([ %pM ] len %d)\n",
+				prSkb->data, prSkb->len);
+			wlanReturnPacket(prGlueInfo->prAdapter, prSkb);
+			continue;
+		}
+#if (CFG_SUPPORT_TDLS == 1)
+		if (TdlsexRxFrameDrop(prGlueInfo, prSkb->data) == TRUE) {
+			/* drop the received TDLS action frame */
+			DBGLOG(TDLS, WARN,
+			       "<tdls_fme> %s: drop a received packet from %pM %u\n",
+				__func__, prSkb->data,
+				(UINT32) ((P_ADAPTER_T) (prGlueInfo->prAdapter))->rRxCtrl.rFreeSwRfbList.u4NumElem);
+			wlanReturnPacket(prGlueInfo->prAdapter, prSkb);
+			continue;
+		}
+
+		/*
+		   get a TDLS request/response/confirm, we need to parse the HT IE
+		   because older supplicant does not pass HT IE to us
+		 */
+		TdlsexRxFrameHandle(prGlueInfo, prSkb->data, prSkb->len);
+#endif /* CFG_SUPPORT_TDLS */
+
+		STATS_RX_PKT_INFO_DISPLAY(prSkb->data);
+
+		//prNetDev->last_rx = jiffies;
+		prSkb->protocol = eth_type_trans(prSkb, prNetDev);
+		prSkb->dev = prNetDev;
+		/* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */
+		DBGLOG(RX, TRACE, "kalRxIndicatePkts len = %d\n", prSkb->len);
+
+#if CFG_BOW_TEST
+		DBGLOG(BOW, TRACE, "Rx sk_buff->len: %d\n", prSkb->len);
+		DBGLOG(BOW, TRACE, "Rx sk_buff->data_len: %d\n", prSkb->data_len);
+		DBGLOG(BOW, TRACE, "Rx sk_buff->data:\n");
+
+		for (i = 0; i < prSkb->len; i++) {
+			DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]);
+
+			if ((i + 1) % 16 == 0)
+				DBGLOG(BOW, TRACE, "\n");
+		}
+
+		DBGLOG(BOW, TRACE, "\n");
+#endif
+
+		if (!in_interrupt())
+			netif_rx_ni(prSkb);	/* only in non-interrupt context */
+		else
+			netif_rx(prSkb);
+
+		wlanReturnPacket(prGlueInfo->prAdapter, NULL);
+	}
+
+	kalPerMonStart(prGlueInfo);
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Called by driver to indicate event to upper layer, for example, the wpa
+*        supplicant or wireless tools.
+*
+* \param[in] pvAdapter Pointer to the adapter descriptor.
+* \param[in] eStatus Indicated status.
+* \param[in] pvBuf Indicated message buffer.
+* \param[in] u4BufLen Indicated message buffer size.
+*
+* \return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 ScanCnt = 0, ScanDoneFailCnt = 0;
+VOID
+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen)
+{
+	UINT_32 bufLen;
+	P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf;
+	P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus;
+	P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1);
+	PARAM_MAC_ADDRESS arBssid;
+	struct cfg80211_scan_request *prScanRequest = NULL;
+	PARAM_SSID_T ssid;
+	struct ieee80211_channel *prChannel = NULL;
+	struct cfg80211_bss *bss;
+	UINT_8 ucChannelNum;
+	P_BSS_DESC_T prBssDesc = NULL;
+        struct cfg80211_scan_info info = {
+               .aborted = false,
+        };
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	kalMemZero(arBssid, MAC_ADDR_LEN);
+
+	ASSERT(prGlueInfo);
+
+	switch (eStatus) {
+	case WLAN_STATUS_ROAM_OUT_FIND_BEST:
+	case WLAN_STATUS_MEDIA_CONNECT:
+
+		prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED;
+
+		/* indicate assoc event */
+		wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &bufLen);
+		wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen);
+
+		/* switch netif on */
+		netif_carrier_on(prGlueInfo->prDevHandler);
+
+		do {
+			/* print message on console */
+			wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen);
+
+			ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ?
+				     (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen] = '\0';
+			DBGLOG(AIS, INFO, " %s netif_carrier_on [ssid:%s %pM ]\n",
+					    prGlueInfo->prDevHandler->name, ssid.aucSsid, arBssid);
+		} while (0);
+
+		if (prGlueInfo->fgIsRegistered == TRUE) {
+			struct cfg80211_bss *bss_others = NULL;
+			UINT_8 ucLoopCnt = 15; /* only loop 15 times to avoid dead loop */
+
+			/* retrieve channel */
+			ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX);
+			if (ucChannelNum <= 14) {
+				prChannel =
+				    ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
+							  ieee80211_channel_to_frequency(ucChannelNum,
+											 NL80211_BAND_2GHZ));
+			} else {
+				prChannel =
+				    ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
+							  ieee80211_channel_to_frequency(ucChannelNum,
+											 NL80211_BAND_5GHZ));
+			}
+
+			/* ensure BSS exists */
+			bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid,
+					       ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+
+			if (bss == NULL) {
+				/* create BSS on-the-fly */
+				prBssDesc =
+				    wlanGetTargetBssDescByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+				if (prBssDesc != NULL) {
+					bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo), prChannel,
+								CFG80211_BSS_FTYPE_PRESP,
+								arBssid, 0,	/* TSF */
+								WLAN_CAPABILITY_ESS,
+								prBssDesc->u2BeaconInterval,	/* beacon interval */
+								prBssDesc->aucIEBuf,	/* IE */
+								prBssDesc->u2IELength,	/* IE Length */
+								RCPI_TO_dBm(prBssDesc->ucRCPI) * 100,	/* MBM */
+								GFP_KERNEL);
+				}
+			}
+			/* remove all bsses that before and only channel different with the current connected one
+				if without this patch, UI will show channel A is connected even if AP has change channel
+				from A to B */
+			while (ucLoopCnt--) {
+				bss_others = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), NULL, arBssid,
+						ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+				if (bss && bss_others && bss_others != bss) {
+					DBGLOG(SCN, INFO, "remove BSSes that only channel different\n");
+					cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss_others);
+				} else
+					break;
+			}
+
+			/* CFG80211 Indication */
+			if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) {
+				/*cfg80211_roamed_bss(prGlueInfo->prDevHandler,
+						    bss,
+						    prGlueInfo->aucReqIe,
+						    prGlueInfo->u4ReqIeLength,
+						    prGlueInfo->aucRspIe, prGlueInfo->u4RspIeLength, GFP_KERNEL);
+				*/
+				struct cfg80211_roam_info roam_info = {
+							.bss = bss,
+						    .req_ie = prGlueInfo->aucReqIe,
+						    .req_ie_len = prGlueInfo->u4ReqIeLength,
+						    .resp_ie = prGlueInfo->aucRspIe,
+							.resp_ie_len = prGlueInfo->u4RspIeLength
+				};
+				cfg80211_roamed(prGlueInfo->prDevHandler,
+						    &roam_info,
+							GFP_KERNEL);
+			} else {
+				/* to support user space roaming, cfg80211 will change the sme_state to connecting
+				before reassociate */
+				cfg80211_connect_result(prGlueInfo->prDevHandler,
+							arBssid,
+							prGlueInfo->aucReqIe,
+							prGlueInfo->u4ReqIeLength,
+							prGlueInfo->aucRspIe,
+							prGlueInfo->u4RspIeLength, WLAN_STATUS_SUCCESS, GFP_KERNEL);
+			}
+		}
+
+		break;
+
+	case WLAN_STATUS_MEDIA_DISCONNECT:
+	case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY:
+		/* indicate disassoc event */
+		wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0);
+		/* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first,
+		   after associated success, at joinComplete(), do netif_carier_on,
+		   but for unknown reason, the supplicant 1x pkt will not called the driver
+		   hardStartXmit, for template workaround these bugs, add this compiling flag
+		 */
+		/* switch netif off */
+
+		DBGLOG(AIS, INFO, "[wifi] %s netif_carrier_off\n",
+				    prGlueInfo->prDevHandler->name);
+
+		netif_carrier_off(prGlueInfo->prDevHandler);
+
+		if (prGlueInfo->fgIsRegistered == TRUE) {
+			P_WIFI_VAR_T prWifiVar = &prGlueInfo->prAdapter->rWifiVar;
+			UINT_16 u2DeauthReason = prWifiVar->arBssInfo[NETWORK_TYPE_AIS_INDEX].u2DeauthReason;
+			/* CFG80211 Indication */
+			DBGLOG(AIS, INFO, "[wifi] %s cfg80211_disconnected\n", prGlueInfo->prDevHandler->name);
+			cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, false, GFP_KERNEL);
+		}
+
+		prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
+
+		break;
+
+	case WLAN_STATUS_SCAN_COMPLETE:
+		/* indicate scan complete event */
+		wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0);
+
+		/* 1. reset first for newly incoming request */
+		GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+		if (prGlueInfo->prScanRequest != NULL) {
+			prScanRequest = prGlueInfo->prScanRequest;
+			prGlueInfo->prScanRequest = NULL;
+		}
+		GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+
+		/* 2. then CFG80211 Indication */
+		DBGLOG(SCN, TRACE, "[ais] scan complete %p %d %d\n", prScanRequest, ScanCnt, ScanDoneFailCnt);
+
+		if (prScanRequest != NULL)
+			cfg80211_scan_done(prScanRequest, &info);
+		break;
+	case WLAN_STATUS_CONNECT_INDICATION:
+		/* indicate AIS Jion fail  event
+		if (prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) */
+		cfg80211_connect_result(prGlueInfo->prDevHandler,
+					prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc->aucBSSID,
+					prGlueInfo->aucReqIe,
+					prGlueInfo->u4ReqIeLength,
+					prGlueInfo->aucRspIe,
+					prGlueInfo->u4RspIeLength, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL);
+		break;
+
+#if 0
+	case WLAN_STATUS_MSDU_OK:
+		if (netif_running(prGlueInfo->prDevHandler))
+			netif_wake_queue(prGlueInfo->prDevHandler);
+		break;
+#endif
+
+	case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION:
+		if (pStatus) {
+			switch (pStatus->eStatusType) {
+			case ENUM_STATUS_TYPE_AUTHENTICATION:
+				/*
+				   printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [ %pM ] F:%lx\n",
+				   pAuth->Request[0].Length,
+				   pAuth->Request[0].Bssid,
+				   pAuth->Request[0].Flags);
+				 */
+				/* indicate (UC/GC) MIC ERROR event only */
+				if ((pAuth->arRequest[0].u4Flags ==
+				     PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ||
+				    (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR)) {
+					cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL,
+								     (pAuth->arRequest[0].u4Flags ==
+								      PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ?
+								     NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP,
+								     0, NULL, GFP_KERNEL);
+					wext_indicate_wext_event(prGlueInfo, IWEVMICHAELMICFAILURE,
+								 (unsigned char *)&pAuth->arRequest[0],
+								 pAuth->arRequest[0].u4Length);
+				}
+				break;
+
+			case ENUM_STATUS_TYPE_CANDIDATE_LIST:
+				/*
+				   printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n",
+				   pPmkid->u2Version,
+				   pPmkid->u4NumCandidates);
+				   if (pPmkid->u4NumCandidates > 0) {
+				   printk(KERN_NOTICE "candidate[ %pM ] preAuth Flag:%lx\n",
+				   pPmkid->arCandidateList[0].rBSSID,
+				   pPmkid->arCandidateList[0].fgFlags);
+				   }
+				 */
+				{
+					UINT_32 i = 0;
+					/*struct net_device *prDev = prGlueInfo->prDevHandler; */
+					P_PARAM_PMKID_CANDIDATE_T prCand = NULL;
+					/* indicate pmk candidate via cfg80211 to supplicant,
+					   the second parameter is 1000 for
+					   cfg80211_pmksa_candidate_notify, because wpa_supplicant defined it. */
+					for (i = 0; i < pPmkid->u4NumCandidates; i++) {
+						prCand = &pPmkid->arCandidateList[i];
+						cfg80211_pmksa_candidate_notify(prGlueInfo->prDevHandler, 1000,
+										prCand->arBSSID, prCand->u4Flags,
+										GFP_KERNEL);
+
+						wext_indicate_wext_event(prGlueInfo,
+									 IWEVPMKIDCAND,
+									 (unsigned char *)prCand,
+									 pPmkid->u4NumCandidates);
+					}
+				}
+				break;
+
+			default:
+				/* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */
+				/*
+				   printk(KERN_NOTICE "unknown media specific indication type:%x\n",
+				   pStatus->StatusType);
+				 */
+				break;
+			}
+		} else {
+			/*
+			   printk(KERN_WARNING "media specific indication buffer NULL\n");
+			 */
+		}
+		break;
+
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
+	case WLAN_STATUS_BWCS_UPDATE:
+		{
+			wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T));
+		}
+
+		break;
+
+#endif
+
+	default:
+		/*
+		   printk(KERN_WARNING "unknown indication:%lx\n", eStatus);
+		 */
+		break;
+	}
+}				/* kalIndicateStatusAndComplete */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to update the (re)association request
+*        information to the structure used to query and set
+*        OID_802_11_ASSOCIATION_INFORMATION.
+*
+* \param[in] prGlueInfo Pointer to the Glue structure.
+* \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association
+*                         Request frame from the AP.
+* \param[in] u4FrameBodyLen The length of the frame body of the last
+*                           (Re)Association Request frame.
+* \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame.
+*
+* \return (none)
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo,
+			IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest)
+{
+	PUINT_8 cp;
+
+	ASSERT(prGlueInfo);
+
+	/* reset */
+	prGlueInfo->u4ReqIeLength = 0;
+
+	if (fgReassocRequest) {
+		if (u4FrameBodyLen < 15) {
+			/*
+			   printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
+			 */
+			return;
+		}
+	} else {
+		if (u4FrameBodyLen < 9) {
+			/*
+			   printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
+			 */
+			return;
+		}
+	}
+
+	cp = pucFrameBody;
+
+	if (fgReassocRequest) {
+		/* Capability information field 2 */
+		/* Listen interval field 2 */
+		/* Current AP address 6 */
+		cp += 10;
+		u4FrameBodyLen -= 10;
+	} else {
+		/* Capability information field 2 */
+		/* Listen interval field 2 */
+		cp += 4;
+		u4FrameBodyLen -= 4;
+	}
+
+	wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen);
+
+	if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) {
+		prGlueInfo->u4ReqIeLength = u4FrameBodyLen;
+		kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This routine is called to update the (re)association
+*        response information to the structure used to reply with
+*        cfg80211_connect_result
+*
+* @param prGlueInfo      Pointer to adapter descriptor
+* @param pucFrameBody    Pointer to the frame body of the last (Re)Association
+*                         Response frame from the AP
+* @param u4FrameBodyLen  The length of the frame body of the last
+*                          (Re)Association Response frame
+*
+* @return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen)
+{
+	UINT_32 u4IEOffset = 6;	/* cap_info, status_code & assoc_id */
+	UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset;
+
+	ASSERT(prGlueInfo);
+
+	/* reset */
+	prGlueInfo->u4RspIeLength = 0;
+
+	if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) {
+		prGlueInfo->u4RspIeLength = u4IELength;
+		kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength);
+	}
+
+}				/* kalUpdateReAssocRspInfo */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Notify OS with SendComplete event of the specific packet. Linux should
+*        free packets here.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] pvPacket       Pointer of Packet Handle
+* \param[in] status         Status Code for OS upper layer
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket)
+{
+
+	struct net_device *prDev = NULL;
+	struct sk_buff *prSkb = NULL;
+	UINT_16 u2QueueIdx = 0;
+	UINT_8 ucNetworkType = 0;
+	BOOLEAN fgIsValidDevice = TRUE;
+
+	ASSERT(pvPacket);
+	ASSERT(prGlueInfo->i4TxPendingFrameNum);
+
+	prSkb = (struct sk_buff *)pvPacket;
+	u2QueueIdx = skb_get_queue_mapping(prSkb);
+	ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
+
+	if (GLUE_GET_PKT_IS_PAL(prSkb)) {
+		ucNetworkType = NETWORK_TYPE_BOW_INDEX;
+	} else if (GLUE_GET_PKT_IS_P2P(prSkb)) {
+		ucNetworkType = NETWORK_TYPE_P2P_INDEX;
+
+#if CFG_ENABLE_WIFI_DIRECT
+		/* in case packet was sent after P2P device is unregistered */
+		if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE)
+			fgIsValidDevice = FALSE;
+#endif
+	} else {
+		ucNetworkType = NETWORK_TYPE_AIS_INDEX;
+	}
+
+	GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
+	if (u2QueueIdx < CFG_MAX_TXQ_NUM)
+		GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]);
+	prDev = prSkb->dev;
+
+	ASSERT(prDev);
+
+	if ((fgIsValidDevice == TRUE) && (u2QueueIdx < CFG_MAX_TXQ_NUM)) {
+		if (netif_subqueue_stopped(prDev, prSkb) &&
+		    prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <=
+		    CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) {
+			DBGLOG(TX, INFO, "netif_wake_subqueue for bss: %d. Queue len: %d\n",
+				ucNetworkType,
+				prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]);
+			netif_wake_subqueue(prDev, u2QueueIdx);
+
+#if (CONF_HIF_LOOPBACK_AUTO == 1)
+			prGlueInfo->rHifInfo.HifLoopbkFlg &= ~0x01;
+#endif /* CONF_HIF_LOOPBACK_AUTO */
+		}
+	}
+
+	dev_kfree_skb((struct sk_buff *)pvPacket);
+	prGlueInfo->u8SkbFreed++;
+
+	DBGLOG(TX, EVENT, "----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Copy Mac Address setting from registry. It's All Zeros in Linux.
+*
+* \param[in] prAdapter Pointer to the Adapter structure
+*
+* \param[out] paucMacAddr Pointer to the Mac Address buffer
+*
+* \retval WLAN_STATUS_SUCCESS
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalQueryRegistryMacAddr(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_8 paucMacAddr)
+{
+	UINT_8 aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }
+
+	DEBUGFUNC("kalQueryRegistryMacAddr");
+
+	ASSERT(prGlueInfo);
+	ASSERT(paucMacAddr);
+
+	kalMemCopy((PVOID) paucMacAddr, (PVOID) aucZeroMac, MAC_ADDR_LEN);
+
+}				/* end of kalQueryRegistryMacAddr() */
+
+#if CFG_SUPPORT_EXT_CONFIG
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Read external configuration, ex. NVRAM or file
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	/* External data is given from user space by ioctl or /proc, not read by
+	   driver.
+	 */
+	if (0 != prGlueInfo->u4ExtCfgLength)
+		DBGLOG(INIT, TRACE, "Read external configuration data -- OK\n");
+	else
+		DBGLOG(INIT, TRACE, "Read external configuration data -- fail\n");
+
+	return prGlueInfo->u4ExtCfgLength;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This inline function is to extract some packet information, including
+*        user priority, packet length, destination address, 802.1x and BT over Wi-Fi
+*        or not.
+*
+* @param prGlueInfo         Pointer to the glue structure
+* @param prNdisPacket       Packet descriptor
+* @param pucPriorityParam   User priority
+* @param pu4PacketLen       Packet length
+* @param pucEthDestAddr Destination address
+* @param pfgIs1X            802.1x packet or not
+* @param pfgIsPAL           BT over Wi-Fi packet or not
+* @prGenUse		    General used param
+*
+* @retval TRUE      Success to extract information
+* @retval FALSE     Fail to extract correct information
+*/
+/*----------------------------------------------------------------------------*/
+
+BOOLEAN
+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo,
+				   IN P_NATIVE_PACKET prPacket,
+				   OUT PUINT_8 pucPriorityParam,
+				   OUT PUINT_32 pu4PacketLen,
+				   OUT PUINT_8 pucEthDestAddr,
+				   OUT PBOOLEAN pfgIs1X,
+				   OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType,
+				   OUT PVOID prGenUse)
+{
+
+	UINT_32 u4PacketLen;
+
+	UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT;	/* Default */
+	UINT_16 u2EtherTypeLen;
+	struct sk_buff *prSkb = (struct sk_buff *)prPacket;
+	PUINT_8 aucLookAheadBuf = NULL;
+
+	DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo");
+
+	u4PacketLen = prSkb->len;
+
+	if (u4PacketLen < ETH_HLEN) {
+		DBGLOG(TX, WARN, "Invalid Ether packet length: %u\n", (UINT_32) u4PacketLen);
+		return FALSE;
+	}
+
+	aucLookAheadBuf = prSkb->data;
+
+	*pfgIs1X = FALSE;
+	*pfgIsPAL = FALSE;
+
+	/* 4 <3> Obtain the User Priority for WMM */
+	u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]);
+
+	if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) {
+		PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN];
+		UINT_8 ucIpVersion;
+
+		ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
+		if (ucIpVersion == IPVERSION) {
+			UINT_8 ucIpTos;
+			/* Get the DSCP value from the header of IP packet. */
+			ucIpTos = pucIpHdr[1];
+			ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET);
+		}
+
+		/* TODO(Kevin): Add TSPEC classifier here */
+	}  else if (u2EtherTypeLen == ETH_P_1X || u2EtherTypeLen == ETH_P_PRE_1X) {	/* For Port Control */
+		PUINT_8 pucEapol = &aucLookAheadBuf[ETH_HLEN];
+		UINT_8 ucEapolType = pucEapol[1];
+		UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6];
+		/*
+		 * generate a seq number used to trace security frame TX
+		 */
+		if (prGenUse)
+			*(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter);
+
+		switch (ucEapolType) {
+		case 0: /* eap packet */
+			DBGLOG(TX, INFO, "<TX> EAP Packet: code %d, id %d, type %d, seqNo %d\n",
+					pucEapol[4], pucEapol[5], pucEapol[7],
+					prGenUse ? *(UINT_8 *)prGenUse : 0);
+			break;
+		case 1: /* eapol start */
+			DBGLOG(TX, INFO, "<TX> EAPOL: start, seqNo %d\n",
+					prGenUse ? *(UINT_8 *)prGenUse : 0);
+			break;
+		case 3: /* key */
+			DBGLOG(TX, INFO,
+				"<TX> EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x... seqNo %d\n",
+				u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20],
+				pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24],
+				prGenUse ? *(UINT_8 *)prGenUse : 0);
+			break;
+		}
+		*pfgIs1X = TRUE;
+	}
+#if CFG_SUPPORT_WAPI
+	else if (u2EtherTypeLen == ETH_WPI_1X) {
+		PUINT_8 pucEthBody = &aucLookAheadBuf[ETH_HLEN];
+		UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/
+		UINT_16 u2Length = *(PUINT_16)&pucEthBody[6];
+		UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8];
+
+		DBGLOG(TX, INFO, "<TX> WAPI: subType %d, Len %d, Seq %d\n",
+				ucSubType, u2Length, u2Seq);
+		*pfgIs1X = TRUE;
+	}
+#endif
+#if (CFG_SUPPORT_TDLS == 1)
+	else if (u2EtherTypeLen == TDLS_FRM_PROT_TYPE) {
+		/* TDLS case */
+		TDLSEX_UP_ASSIGN(ucUserPriority);
+	}
+#endif /* CFG_SUPPORT_TDLS */
+	else if (u2EtherTypeLen <= 1500) {	/* 802.3 Frame */
+		UINT_8 ucDSAP, ucSSAP, ucControl;
+		UINT_8 aucOUI[3];
+
+		ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET];
+		ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1];
+		ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2];
+
+		aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET];
+		aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1];
+		aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2];
+
+		if (ucDSAP == ETH_LLC_DSAP_SNAP &&
+		    ucSSAP == ETH_LLC_SSAP_SNAP &&
+		    ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION &&
+		    aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 &&
+		    aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) {
+
+			UINT_16 tmp =
+			    ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]);
+
+			*pfgIsPAL = TRUE;
+			ucUserPriority = (UINT_8) prSkb->priority;
+
+			if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) {
+				PUINT_8 pucEapol = &aucLookAheadBuf[ETH_SNAP_OFFSET + 5];
+				UINT_8 ucEapolType = pucEapol[1];
+				UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6];
+				if (prGenUse)
+					*(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter);
+
+				switch (ucEapolType) {
+				case 0: /* eap packet */
+					DBGLOG(TX, INFO, "<TX> EAP Packet: code %d, id %d, type %d, seqNo %d\n",
+							pucEapol[4], pucEapol[5], pucEapol[7],
+							prGenUse ? *(UINT_8 *)prGenUse : 0);
+					break;
+				case 1: /* eapol start */
+					DBGLOG(TX, INFO, "<TX> EAPOL: start, seqNo %d\n",
+							prGenUse ? *(UINT_8 *)prGenUse : 0);
+					break;
+				case 3: /* key */
+					DBGLOG(TX, INFO,
+						"<TX> EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x seqNo %d\n",
+						u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20],
+						pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24],
+						prGenUse ? *(UINT_8 *)prGenUse : 0);
+					break;
+				}
+				*pfgIs1X = TRUE;
+			}
+		}
+	}
+	/* 4 <4> Return the value of Priority Parameter. */
+	*pucPriorityParam = ucUserPriority;
+
+	/* 4 <5> Retrieve Packet Information - DA */
+	/* Packet Length/ Destination Address */
+	*pu4PacketLen = u4PacketLen;
+
+	kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN);
+
+	/* <6> Network type */
+#if CFG_ENABLE_BT_OVER_WIFI
+	if (*pfgIsPAL == TRUE) {
+		*pucNetworkType = NETWORK_TYPE_BOW_INDEX;
+	} else
+#endif
+	{
+#if CFG_ENABLE_WIFI_DIRECT
+		if (prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) {
+			*pucNetworkType = NETWORK_TYPE_P2P_INDEX;
+		} else
+#endif
+		{
+			*pucNetworkType = NETWORK_TYPE_AIS_INDEX;
+		}
+	}
+	return TRUE;
+}				/* end of kalQoSFrameClassifier() */
+
+VOID
+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo,
+	       IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus)
+{
+
+	ASSERT(prGlueInfo);
+	/* remove timeout check timer */
+	wlanoidClearTimeoutCheck(prGlueInfo->prAdapter);
+
+	/* if (prGlueInfo->u4TimeoutFlag != 1) { */
+	prGlueInfo->rPendStatus = rOidStatus;
+	DBGLOG(OID, TEMP, "kalOidComplete, caller: %p\n", __builtin_return_address(0));
+	complete(&prGlueInfo->rPendComp);
+	prGlueInfo->u4OidCompleteFlag = 1;
+	/* } */
+	/* else let it timeout on kalIoctl entry */
+}
+
+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo)
+{
+	/* if (prGlueInfo->u4TimeoutFlag != 1) { */
+	/* clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag); */
+	if (prGlueInfo->u4OidCompleteFlag != 1) {
+		DBGLOG(OID, TEMP, "kalOidClearance, caller: %p\n", __builtin_return_address(0));
+		complete(&prGlueInfo->rPendComp);
+	}
+	/* } */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is used to transfer linux ioctl to OID, and  we
+* need to specify the behavior of the OID by ourself
+*
+* @param prGlueInfo         Pointer to the glue structure
+* @param pvInfoBuf          Data buffer
+* @param u4InfoBufLen       Data buffer length
+* @param fgRead             Is this a read OID
+* @param fgWaitResp         does this OID need to wait for values
+* @param fgCmd              does this OID compose command packet
+* @param pu4QryInfoLen      The data length of the return values
+*
+* @retval TRUE      Success to extract information
+* @retval FALSE     Fail to extract correct information
+*/
+/*----------------------------------------------------------------------------*/
+
+/* todo: enqueue the i/o requests for multiple processes access */
+/*  */
+/* currently, return -1 */
+/*  */
+
+/* static GL_IO_REQ_T OidEntry; */
+
+WLAN_STATUS
+kalIoctl(IN P_GLUE_INFO_T prGlueInfo,
+	 IN PFN_OID_HANDLER_FUNC pfnOidHandler,
+	 IN PVOID pvInfoBuf,
+	 IN UINT_32 u4InfoBufLen,
+	 IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen)
+{
+	P_GL_IO_REQ_T prIoReq = NULL;
+	WLAN_STATUS ret = WLAN_STATUS_SUCCESS;
+
+	if (fgIsResetting == TRUE)
+		return WLAN_STATUS_SUCCESS;
+
+	/* GLUE_SPIN_LOCK_DECLARATION(); */
+	ASSERT(prGlueInfo);
+
+	/* <1> Check if driver is halt */
+	/* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */
+	/* return WLAN_STATUS_ADAPTER_NOT_READY; */
+	/* } */
+
+	/* if wait longer than double OID timeout timer, then will show backtrace who held halt lock.
+		at this case, we will return kalIoctl failure because tx_thread may be hung */
+	if (kalHaltLock(2 * WLAN_OID_TIMEOUT_THRESHOLD))
+		return WLAN_STATUS_FAILURE;
+
+	if (kalIsHalted()) {
+		kalHaltUnlock();
+		return WLAN_STATUS_ADAPTER_NOT_READY;
+	}
+
+	if (down_interruptible(&prGlueInfo->ioctl_sem)) {
+		kalHaltUnlock();
+		return WLAN_STATUS_FAILURE;
+	}
+
+	/* <2> TODO: thread-safe */
+
+	/* <3> point to the OidEntry of Glue layer */
+
+	prIoReq = &(prGlueInfo->OidEntry);
+
+	ASSERT(prIoReq);
+
+	/* <4> Compose the I/O request */
+	prIoReq->prAdapter = prGlueInfo->prAdapter;
+	prIoReq->pfnOidHandler = pfnOidHandler;
+	prIoReq->pvInfoBuf = pvInfoBuf;
+	prIoReq->u4InfoBufLen = u4InfoBufLen;
+	prIoReq->pu4QryInfoLen = pu4QryInfoLen;
+	prIoReq->fgRead = fgRead;
+	prIoReq->fgWaitResp = fgWaitResp;
+	prIoReq->rStatus = WLAN_STATUS_FAILURE;
+#if CFG_ENABLE_WIFI_DIRECT
+	prIoReq->fgIsP2pOid = fgIsP2pOid;
+#endif
+
+	/* <5> Reset the status of pending OID */
+	prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE;
+	/* prGlueInfo->u4TimeoutFlag = 0; */
+	/* prGlueInfo->u4OidCompleteFlag = 0; */
+
+	/* <6> Check if we use the command queue */
+	prIoReq->u4Flag = fgCmd;
+
+	/* <7> schedule the OID bit */
+	set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag);
+
+	/* <8> Wake up tx thread to handle kick start the I/O request */
+	wake_up_interruptible(&prGlueInfo->waitq);
+
+	/* <9> Block and wait for event or timeout, current the timeout is 5 secs */
+	/* if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) { */
+	/* if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) { */
+	DBGLOG(OID, TEMP, "kalIoctl: before wait, caller: %p\n", __builtin_return_address(0));
+	wait_for_completion(&prGlueInfo->rPendComp); {
+		/* Case 1: No timeout. */
+		/* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo  */
+		if (prIoReq->rStatus == WLAN_STATUS_PENDING)
+			ret = prGlueInfo->rPendStatus;
+		else
+			ret = prIoReq->rStatus;
+	}
+#if 0
+	else {
+		/* Case 2: timeout */
+		/* clear pending OID's cmd in CMD queue */
+		if (fgCmd) {
+			prGlueInfo->u4TimeoutFlag = 1;
+			wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
+		}
+		ret = WLAN_STATUS_FAILURE;
+	}
+#endif
+	DBGLOG(OID, TEMP, "kalIoctl: done\n");
+	up(&prGlueInfo->ioctl_sem);
+	kalHaltUnlock();
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to clear all pending security frames
+*
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+
+	/* Clear pending security frames in prGlueInfo->rCmdQueue */
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+	QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+	QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+		prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+		if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
+			prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
+			cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
+		} else {
+			QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+		}
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+
+	QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to clear pending security frames
+*        belongs to dedicated network type
+*
+* \param prGlueInfo         Pointer of GLUE Data Structure
+* \param eNetworkTypeIdx    Network Type Index
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+
+	/* Clear pending security frames in prGlueInfo->rCmdQueue */
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+	QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+	QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+		prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+		if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME && prCmdInfo->eNetworkType == eNetworkTypeIdx) {
+			prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
+			cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
+		} else {
+			QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+		}
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+
+	QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to clear all pending management frames
+*
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+
+	/* Clear pending management frames in prGlueInfo->rCmdQueue */
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+	QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+	QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+		prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+		if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
+			wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo);
+			cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
+		} else {
+			QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+		}
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+
+	QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to clear all pending management frames
+*           belongs to dedicated network type
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+
+	/* Clear pending management frames in prGlueInfo->rCmdQueue */
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+	QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+	QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+		prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+
+		if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME &&
+			prCmdInfo->eNetworkType == eNetworkTypeIdx) {
+			wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo);
+			cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
+		} else {
+			QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+		}
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+
+	QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+}				/* kalClearMgmtFramesByNetType */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief This function is a kernel thread function for handling command packets
+* Tx requests and interrupt events
+*
+* @param data       data pointer to private data of tx_thread
+*
+* @retval           If the function succeeds, the return value is 0.
+* Otherwise, an error code is returned.
+*
+*/
+/*----------------------------------------------------------------------------*/
+
+int tx_thread(void *data)
+{
+	struct net_device *dev = data;
+	P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
+
+	P_QUE_ENTRY_T prQueueEntry = NULL;
+	P_GL_IO_REQ_T prIoReq = NULL;
+	P_QUE_T prTxQueue = NULL;
+	P_QUE_T prCmdQue = NULL;
+
+	int ret = 0;
+
+	BOOLEAN fgNeedHwAccess = FALSE;
+
+	struct sk_buff *prSkb = NULL;
+
+	/* for spin lock acquire and release */
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	prTxQueue = &prGlueInfo->rTxQueue;
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	current->flags |= PF_NOFREEZE;
+
+	DBGLOG(INIT, INFO, "tx_thread starts running...\n");
+
+	while (TRUE) {
+
+#if CFG_ENABLE_WIFI_DIRECT
+		/*run p2p multicast list work. */
+		if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag))
+			p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
+#endif
+
+		if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) {
+			P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL;
+			/* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */
+			prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo);
+			prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter;
+		}
+
+		if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
+			KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock);
+			DBGLOG(INIT, INFO, "tx_thread should stop now...\n");
+			break;
+		}
+
+		/*
+		 * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT
+		 * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT
+		 *
+		 */
+		KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock);
+
+		ret = wait_event_interruptible(prGlueInfo->waitq, (prGlueInfo->ulFlag != 0));
+
+		KAL_WAKE_LOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock);
+
+/* #if (CONF_HIF_LOOPBACK_AUTO == 1) */
+/* if (test_and_clear_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &prGlueInfo->u4Flag)) { */
+/* kalDevLoopbkAuto(prGlueInfo); */
+/* } */
+/* #endif */ /* CONF_HIF_LOOPBACK_AUTO */
+
+#if CFG_DBG_GPIO_PINS
+		/* TX thread Wake up */
+		mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW);
+#endif
+#if CFG_ENABLE_WIFI_DIRECT
+		/*run p2p multicast list work. */
+		if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag))
+			p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
+
+		if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag)) {
+			p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter,
+						       prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter);
+		}
+#endif
+		if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) {
+			P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL;
+			/* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */
+			prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo);
+			prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter;
+		}
+
+		if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
+			KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock);
+			DBGLOG(INIT, INFO, "<1>tx_thread should stop now...\n");
+			break;
+		}
+
+		fgNeedHwAccess = FALSE;
+
+		/* Handle Interrupt */
+		if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) {
+			if (fgNeedHwAccess == FALSE) {
+				fgNeedHwAccess = TRUE;
+
+				wlanAcquirePowerControl(prGlueInfo->prAdapter);
+			}
+
+			/* the Wi-Fi interrupt is already disabled in mmc thread,
+			   so we set the flag only to enable the interrupt later  */
+			prGlueInfo->prAdapter->fgIsIntEnable = FALSE;
+			/* wlanISR(prGlueInfo->prAdapter, TRUE); */
+
+			if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
+				/* Should stop now... skip pending interrupt */
+				DBGLOG(INIT, INFO, "ignore pending interrupt\n");
+			} else {
+				prGlueInfo->TaskIsrCnt++;
+				wlanIST(prGlueInfo->prAdapter);
+			}
+		}
+
+		/* transfer ioctl to OID request */
+#if 0
+		if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
+			DBGLOG(INIT, INFO, "<2>tx_thread should stop now...\n");
+			break;
+		}
+#endif
+
+		do {
+			if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag)) {
+				/* get current prIoReq */
+				prGlueInfo->u4OidCompleteFlag = 0;
+
+				prIoReq = &(prGlueInfo->OidEntry);
+#if CFG_ENABLE_WIFI_DIRECT
+				if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE && prIoReq->fgIsP2pOid == TRUE) {
+					/*    if this Oid belongs to p2p and p2p module is removed
+					 *      do nothing,
+					 */
+				} else
+#endif
+				{
+					if (FALSE == prIoReq->fgRead) {
+						prIoReq->rStatus = wlanSetInformation(prIoReq->prAdapter,
+										      prIoReq->pfnOidHandler,
+										      prIoReq->pvInfoBuf,
+										      prIoReq->u4InfoBufLen,
+										      prIoReq->pu4QryInfoLen);
+					} else {
+						prIoReq->rStatus = wlanQueryInformation(prIoReq->prAdapter,
+											prIoReq->pfnOidHandler,
+											prIoReq->pvInfoBuf,
+											prIoReq->u4InfoBufLen,
+											prIoReq->pu4QryInfoLen);
+					}
+
+					if (prIoReq->rStatus != WLAN_STATUS_PENDING) {
+						DBGLOG(OID, TEMP, "tx_thread, complete\n");
+						complete(&prGlueInfo->rPendComp);
+					} else {
+						wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler);
+					}
+				}
+			}
+
+		} while (FALSE);
+
+		/*
+		 *
+		 * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent
+		 * indicates the following requests occur
+		 *
+		 */
+#if 0
+		if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
+			DBGLOG(INIT, INFO, "<3>tx_thread should stop now...\n");
+			break;
+		}
+#endif
+
+		if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->ulFlag)) {
+			/* Process Mailbox Messages */
+			wlanProcessMboxMessage(prGlueInfo->prAdapter);
+
+			/* Process CMD request */
+			do {
+				if (prCmdQue->u4NumElem > 0) {
+					if (fgNeedHwAccess == FALSE) {
+						fgNeedHwAccess = TRUE;
+
+						wlanAcquirePowerControl(prGlueInfo->prAdapter);
+					}
+					wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue);
+				}
+			} while (FALSE);
+
+			/* Handle Packet Tx */
+			{
+				while (QUEUE_IS_NOT_EMPTY(prTxQueue)) {
+					GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+					QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T);
+					GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+
+					ASSERT(prQueueEntry);
+					if (NULL == prQueueEntry)
+						break;
+
+					prSkb = (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
+					ASSERT(prSkb);
+					if (NULL == prSkb) {
+						DBGLOG(INIT, ERROR, "prSkb == NULL!\n");
+						continue;
+					}
+#if (CFG_SUPPORT_TDLS_DBG == 1)
+					UINT8 *pkt = prSkb->data;
+					UINT16 u2Identifier;
+
+					if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) {
+						/* ip */
+						u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19));
+						DBGLOG(INIT, LOUD, "<TDLS> %d\n", u2Identifier);
+					}
+#endif
+					if (wlanEnqueueTxPacket(prGlueInfo->prAdapter,
+								(P_NATIVE_PACKET) prSkb) == WLAN_STATUS_RESOURCES) {
+						/* no available entry in rFreeMsduInfoList */
+						GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+						QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry);
+						GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+
+						break;
+					}
+				}
+
+				if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) {
+					/* send packets to HIF here */
+					wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess);
+				}
+			}
+
+		}
+
+		/* Process RX, In linux, we don't need to free sk_buff by ourself */
+
+		/* In linux, we don't need to free sk_buff by ourself */
+
+		/* In linux, we don't do reset */
+		if (fgNeedHwAccess == TRUE)
+			wlanReleasePowerControl(prGlueInfo->prAdapter);
+
+		/* handle cnmTimer time out */
+		if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag))
+			wlanTimerTimeoutCheck(prGlueInfo->prAdapter);
+#if CFG_DBG_GPIO_PINS
+		/* TX thread go to sleep */
+		if (!prGlueInfo->ulFlag)
+			mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH);
+#endif
+	}
+
+#if 0
+	if (fgNeedHwAccess == TRUE)
+		wlanReleasePowerControl(prGlueInfo->prAdapter);
+#endif
+
+	/* exit while loop, tx thread is closed so we flush all pending packets */
+	/* flush the pending TX packets */
+	if (prGlueInfo->i4TxPendingFrameNum > 0)
+		kalFlushPendingTxPackets(prGlueInfo);
+
+	/* flush pending security frames */
+	if (prGlueInfo->i4TxPendingSecurityFrameNum > 0)
+		kalClearSecurityFrames(prGlueInfo);
+
+	/* remove pending oid */
+	wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
+
+	/* In linux, we don't need to free sk_buff by ourself */
+
+	DBGLOG(INIT, INFO, "mtk_sdiod stops\n");
+	complete(&prGlueInfo->rHaltComp);
+
+	return 0;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to check if card is removed
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval TRUE:     card is removed
+*         FALSE:    card is still attached
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return FALSE;
+	/* Linux MMC doesn't have removal notification yet */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief This routine is used to send command to firmware for overriding netweork address
+ *
+ * \param pvGlueInfo Pointer of GLUE Data Structure
+
+ * \retval TRUE
+ *         FALSE
+ */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr)
+{
+	ASSERT(prGlueInfo);
+
+	if (prGlueInfo->fgIsMacAddrOverride == FALSE) {
+#if !defined(CONFIG_X86)
+#if !defined(CONFIG_MTK_TC1_FEATURE)
+		UINT_32 i;
+#endif
+		BOOLEAN fgIsReadError = FALSE;
+
+#if !defined(CONFIG_MTK_TC1_FEATURE)
+		for (i = 0; i < MAC_ADDR_LEN; i += 2) {
+			if (kalCfgDataRead16(prGlueInfo,
+					     OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
+					     (PUINT_16) (((PUINT_8) prMacAddr) + i)) == FALSE) {
+				fgIsReadError = TRUE;
+				break;
+			}
+		}
+#else
+		TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prMacAddr);
+#endif
+
+		if (fgIsReadError == TRUE)
+			return FALSE;
+		else
+			return TRUE;
+#else
+		/* x86 Linux doesn't need to override network address so far */
+		return FALSE;
+#endif
+	} else {
+		COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride);
+
+		return TRUE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to flush pending TX packets in glue layer
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo)
+{
+	P_QUE_T prTxQue;
+	P_QUE_ENTRY_T prQueueEntry;
+	PVOID prPacket;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+
+	prTxQue = &(prGlueInfo->rTxQueue);
+
+	if (prGlueInfo->i4TxPendingFrameNum) {
+		while (TRUE) {
+			GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+			QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T);
+			GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+
+			if (prQueueEntry == NULL)
+				break;
+
+			prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
+
+			kalSendComplete(prGlueInfo, prPacket, WLAN_STATUS_NOT_ACCEPTED);
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is get indicated media state
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval
+*/
+/*----------------------------------------------------------------------------*/
+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->eParamMediaStateIndicated;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to set indicated media state
+*
+* \param pvGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate)
+{
+	ASSERT(prGlueInfo);
+
+	prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to clear pending OID staying in command queue
+*
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo)
+{
+	P_QUE_T prCmdQue;
+	QUE_T rTempCmdQue;
+	P_QUE_T prTempCmdQue = &rTempCmdQue;
+	P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
+	P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+	QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
+
+	QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	while (prQueueEntry) {
+
+		if (((P_CMD_INFO_T) prQueueEntry)->fgIsOid) {
+			prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+			break;
+		}
+		QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+
+		QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
+	}
+
+	QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+
+	if (prCmdInfo) {
+		if (prCmdInfo->pfCmdTimeoutHandler)
+			prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
+		else
+			kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_ACCEPTED);
+
+		prGlueInfo->u4OidCompleteFlag = 1;
+		cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to insert command into prCmdQueue
+*
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*        prQueueEntry   Pointer of queue entry to be inserted
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry)
+{
+	P_QUE_T prCmdQue;
+	P_CMD_INFO_T prCmdInfo;
+	P_MSDU_INFO_T prMsduInfo;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+	ASSERT(prQueueEntry);
+
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
+	if (prCmdInfo->prPacket && prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
+		prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket);
+		prMsduInfo->eCmdType = prCmdInfo->eCmdType;
+		prMsduInfo->ucCID = prCmdInfo->ucCID;
+		prMsduInfo->u4InqueTime = kalGetTimeTick();
+	}
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+	QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with
+*        proper information
+*
+* @param pvGlueInfo     Pointer of GLUE Data Structure
+* @param prAssocInfo    Pointer of EVENT_ID_ASSOC_INFO Packet
+*
+* @return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo)
+{
+	/* to do */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to get firmware load address from registry
+*
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->rRegInfo.u4LoadAddress;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to get firmware start address from registry
+*
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->rRegInfo.u4StartAddress;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * * @brief Notify OS with SendComplete event of the specific packet. Linux should
+ * *        free packets here.
+ * *
+ * * @param pvGlueInfo     Pointer of GLUE Data Structure
+ * * @param pvPacket       Pointer of Packet Handle
+ * * @param status         Status Code for OS upper layer
+ * *
+ * * @return none
+ * */
+/*----------------------------------------------------------------------------*/
+
+/* / Todo */
+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus)
+{
+	ASSERT(pvPacket);
+
+	dev_kfree_skb((struct sk_buff *)pvPacket);
+	if (prGlueInfo)
+		prGlueInfo->u8SkbFreed++;
+	GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
+}
+
+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return (UINT_32) (prGlueInfo->i4TxPendingFrameNum);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to retrieve the number of pending commands
+*        (including MMPDU, 802.1X and command packets)
+*
+* \param prGlueInfo     Pointer of GLUE Data Structure
+*
+* \retval
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo)
+{
+	P_QUE_T prCmdQue;
+
+	ASSERT(prGlueInfo);
+	prCmdQue = &prGlueInfo->rCmdQueue;
+
+	return prCmdQue->u4NumElem;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Timer Initialization Procedure
+*
+* \param[in] prGlueInfo     Pointer to GLUE Data Structure
+* \param[in] prTimerHandler Pointer to timer handling function, whose only
+*                           argument is "prAdapter"
+*
+* \retval none
+*
+*/
+/*----------------------------------------------------------------------------*/
+
+/* static struct timer_list tickfn; */
+
+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler)
+{
+
+	ASSERT(prGlueInfo);
+
+	timer_setup(&(prGlueInfo->tickfn), prTimerHandler, 0);
+}
+
+/* Todo */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the time to do the time out check.
+*
+* \param[in] prGlueInfo Pointer to GLUE Data Structure
+* \param[in] rInterval  Time out interval from current time.
+*
+* \retval TRUE Success.
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval)
+{
+	ASSERT(prGlueInfo);
+	del_timer_sync(&(prGlueInfo->tickfn));
+
+	prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC;
+	add_timer(&(prGlueInfo->tickfn));
+
+	return TRUE;		/* success */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to cancel
+*
+* \param[in] prGlueInfo Pointer to GLUE Data Structure
+*
+* \retval TRUE  :   Timer has been canceled
+*         FALAE :   Timer doens't exist
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag);
+
+	if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is a callback function for scanning done
+*
+* \param[in] prGlueInfo Pointer to GLUE Data Structure
+*
+* \retval none
+*
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status)
+{
+	P_AIS_FSM_INFO_T prAisFsmInfo;
+
+	ASSERT(prGlueInfo);
+
+	prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo);
+	/* report all queued beacon/probe response frames  to upper layer */
+	scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL);
+	cnmTimerStopTimer(prGlueInfo->prAdapter, &prAisFsmInfo->rScanDoneTimer);
+
+	/* check for system configuration for generating error message on scan list */
+	wlanCheckSystemConfiguration(prGlueInfo->prAdapter);
+
+	kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is used to generate a random number
+*
+* \param none
+*
+* \retval UINT_32
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalRandomNumber(VOID)
+{
+	UINT_32 number = 0;
+
+	get_random_bytes(&number, 4);
+
+	return number;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief command timeout call-back function
+ *
+ * \param[in] prGlueInfo Pointer to the GLUE data structure.
+ *
+ * \retval (none)
+ */
+/*----------------------------------------------------------------------------*/
+VOID kalTimeoutHandler(struct timer_list *t)
+{
+
+	P_GLUE_INFO_T prGlueInfo = from_timer(prGlueInfo, t, tickfn);
+
+	ASSERT(prGlueInfo);
+
+	/* Notify tx thread  for timeout event */
+	set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag);
+	wake_up_interruptible(&prGlueInfo->waitq);
+
+}
+
+VOID kalSetEvent(P_GLUE_INFO_T pr)
+{
+	set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag);
+	wake_up_interruptible(&pr->waitq);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to check if configuration file (NVRAM/Registry) exists
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo)
+{
+#if !defined(CONFIG_X86)
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->fgNvramAvailable;
+#else
+	/* there is no configuration data for x86-linux */
+	return FALSE;
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Registry information
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           Pointer of REG_INFO_T
+*/
+/*----------------------------------------------------------------------------*/
+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return &(prGlueInfo->rRegInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve version information of corresponding configuration file
+*
+* \param[in]
+*           prGlueInfo
+*
+* \param[out]
+*           pu2Part1CfgOwnVersion
+*           pu2Part1CfgPeerVersion
+*           pu2Part2CfgOwnVersion
+*           pu2Part2CfgPeerVersion
+*
+* \return
+*           NONE
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo,
+			   OUT PUINT_16 pu2Part1CfgOwnVersion,
+			   OUT PUINT_16 pu2Part1CfgPeerVersion,
+			   OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion)
+{
+	ASSERT(prGlueInfo);
+
+	ASSERT(pu2Part1CfgOwnVersion);
+	ASSERT(pu2Part1CfgPeerVersion);
+	ASSERT(pu2Part2CfgOwnVersion);
+	ASSERT(pu2Part2CfgPeerVersion);
+
+	kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion), pu2Part1CfgOwnVersion);
+
+	kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion), pu2Part1CfgPeerVersion);
+
+	kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion), pu2Part2CfgOwnVersion);
+
+	kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion), pu2Part2CfgPeerVersion);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to check if the WPS is active or not
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->fgWpsActive;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief update RSSI and LinkQuality to GLUE layer
+*
+* \param[in]
+*           prGlueInfo
+*           eNetTypeIdx
+*           cRssi
+*           cLinkQuality
+*
+* \return
+*           None
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo,
+	      IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality)
+{
+	struct iw_statistics *pStats = (struct iw_statistics *)NULL;
+
+	ASSERT(prGlueInfo);
+
+	switch (eNetTypeIdx) {
+	case KAL_NETWORK_TYPE_AIS_INDEX:
+		pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats));
+		break;
+#if CFG_ENABLE_WIFI_DIRECT
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+	case KAL_NETWORK_TYPE_P2P_INDEX:
+		pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats));
+		break;
+#endif
+#endif
+	default:
+		break;
+
+	}
+
+	if (pStats) {
+		pStats->qual.qual = cLinkQuality;
+		pStats->qual.noise = 0;
+		pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
+		pStats->qual.level = 0x100 + cRssi;
+		pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Pre-allocate I/O buffer
+*
+* \param[in]
+*           none
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalInitIOBuffer(VOID)
+{
+	UINT_32 u4Size;
+
+	if (CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE)
+		u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
+	else
+		u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
+
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+	pvDmaBuffer = dma_alloc_coherent(NULL, CFG_RX_MAX_PKT_SIZE, &pvDmaPhyBuf, GFP_KERNEL);
+	if (pvDmaBuffer == NULL)
+		return FALSE;
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+
+	pvIoBuffer = kmalloc(u4Size, GFP_KERNEL);
+/* pvIoBuffer = dma_alloc_coherent(NULL, u4Size, &pvIoPhyBuf, GFP_KERNEL); */
+	if (pvIoBuffer) {
+		pvIoBufferSize = u4Size;
+		pvIoBufferUsage = 0;
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Free pre-allocated I/O buffer
+*
+* \param[in]
+*           none
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalUninitIOBuffer(VOID)
+{
+	kfree(pvIoBuffer);
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+	dma_free_coherent(NULL, CFG_RX_MAX_PKT_SIZE, pvDmaBuffer, pvDmaPhyBuf);
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+	/* dma_free_coherent(NULL, pvIoBufferSize, pvIoBuffer, pvIoPhyBuf); */
+
+	pvIoBuffer = (PVOID) NULL;
+	pvIoBufferSize = 0;
+	pvIoBufferUsage = 0;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Dispatch pre-allocated I/O buffer
+*
+* \param[in]
+*           u4AllocSize
+*
+* \return
+*           PVOID for pointer of pre-allocated I/O buffer
+*/
+/*----------------------------------------------------------------------------*/
+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize)
+{
+	PVOID ret = (PVOID) NULL;
+
+	if (pvIoBuffer) {
+		if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) {
+			ret = (PVOID) &(((PUINT_8) (pvIoBuffer))[pvIoBufferUsage]);
+			pvIoBufferUsage += u4AllocSize;
+		}
+	} else {
+		/* fault tolerance */
+		ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE);
+	}
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Release all dispatched I/O buffer
+*
+* \param[in]
+*           none
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size)
+{
+	if (pvIoBuffer) {
+		pvIoBufferUsage -= u4Size;
+	} else {
+		/* fault tolerance */
+		kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo,
+		  IN ENUM_BAND_T eSpecificBand,
+		  IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList)
+{
+	rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum,
+			     pucNumOfChannel, paucChannelList);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo)
+{
+#if CFG_ENABLE_WIFI_DIRECT
+	if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) &&
+	    p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo))
+		return TRUE;
+#endif
+
+	return FALSE;
+}
+
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function gets the physical address for Pre-allocate I/O buffer.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] rLockCategory  Specify which SPIN_LOCK
+* \param[out] pu4Flags      Pointer of a variable for saving IRQ flags
+*
+* \return physical addr
+*/
+/*----------------------------------------------------------------------------*/
+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr)
+{
+	ULONG PhyAddr;
+
+	if ((VirtAddr >= (ULONG) pvIoBuffer) && (VirtAddr <= ((ULONG) (pvIoBuffer) + pvIoBufferSize))) {
+		PhyAddr = (ULONG) pvIoPhyBuf;
+		PhyAddr += (VirtAddr - (ULONG) (pvIoBuffer));
+		return PhyAddr;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function gets the physical address for Pre-allocate I/O buffer.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] rLockCategory  Specify which SPIN_LOCK
+* \param[out] pu4Flags      Pointer of a variable for saving IRQ flags
+*
+* \return physical addr
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr)
+{
+	*VirtAddr = pvDmaBuffer;
+	*PhyAddr = pvDmaPhyBuf;
+}
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+
+#if CFG_SUPPORT_802_11W
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to check if the MFP is active or not
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->rWpaInfo.u4Mfp;
+}
+#endif
+
+struct file *kalFileOpen(const char *path, int flags, int rights)
+{
+	struct file *filp = NULL;
+	mm_segment_t oldfs;
+	int err = 0;
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+	filp = filp_open(path, flags, rights);
+	set_fs(oldfs);
+	if (IS_ERR(filp)) {
+		err = PTR_ERR(filp);
+		return NULL;
+	}
+	return filp;
+}
+
+VOID kalFileClose(struct file *file)
+{
+	filp_close(file, NULL);
+}
+
+UINT_32 kalFileRead(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size)
+{
+	mm_segment_t oldfs;
+	INT_32 ret;
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+
+	ret = vfs_read(file, data, size, &offset);
+
+	set_fs(oldfs);
+	return ret;
+}
+
+UINT_32 kalFileWrite(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size)
+{
+	mm_segment_t oldfs;
+	INT_32 ret;
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+
+	ret = vfs_write(file, data, size, &offset);
+
+	set_fs(oldfs);
+	return ret;
+}
+
+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size)
+{
+	struct file *file = NULL;
+	UINT_32 ret = -1;
+	UINT_32 u4Flags = 0;
+
+	if (fgDoAppend)
+		u4Flags = O_APPEND;
+
+	file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU);
+	if (file) {
+		ret = kalFileWrite(file, 0, pucData, u4Size);
+		kalFileClose(file);
+	}
+
+	return ret;
+}
+
+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize)
+{
+	struct file *file = NULL;
+	INT_32 ret = -1;
+	UINT_32 u4ReadSize = 0;
+
+	DBGLOG(INIT, LOUD, "kalReadToFile() path %s\n", pucPath);
+
+	file = kalFileOpen(pucPath, O_RDONLY, 0);
+
+	if ((file != NULL) && !IS_ERR(file)) {
+		u4ReadSize = kalFileRead(file, 0, pucData, u4Size);
+		kalFileClose(file);
+		if (pu4ReadSize)
+			*pu4ReadSize = u4ReadSize;
+		ret = 0;
+	}
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To indicate BSS-INFO to NL80211 as scanning result
+*
+* \param[in]
+*           prGlueInfo
+*           pucBeaconProbeResp
+*           u4FrameLen
+*
+*
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo,
+		   IN PUINT_8 pucBeaconProbeResp,
+		   IN UINT_32 u4FrameLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength)
+{
+	struct wiphy *wiphy;
+	struct ieee80211_channel *prChannel = NULL;
+
+	ASSERT(prGlueInfo);
+	wiphy = priv_to_wiphy(prGlueInfo);
+
+	/* search through channel entries */
+	if (ucChannelNum <= 14) {
+		prChannel =
+		    ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ));
+	} else {
+		prChannel =
+		    ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ));
+	}
+
+	if (prChannel != NULL && (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)) {
+		struct cfg80211_bss *bss;
+#if CFG_SUPPORT_TSF_USING_BOOTTIME
+		struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt *)pucBeaconProbeResp;
+
+		prMgmtFrame->u.beacon.timestamp = kalGetBootTime();
+#endif
+		ScanCnt++;
+
+		/* indicate to NL80211 subsystem */
+		bss = cfg80211_inform_bss_frame(wiphy,
+						prChannel,
+						(struct ieee80211_mgmt *)pucBeaconProbeResp,
+						u4FrameLen, i4SignalStrength * 100, GFP_KERNEL);
+
+		if (!bss) {
+			ScanDoneFailCnt++;
+			DBGLOG(SCN, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n",
+					ucChannelNum, i4SignalStrength);
+		} else {
+			cfg80211_put_bss(wiphy, bss);
+			DBGLOG(SCN, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n",
+					ucChannelNum, i4SignalStrength);
+		}
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To indicate channel ready
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo,
+		  IN UINT_64 u8Cookie,
+		  IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs)
+{
+	struct ieee80211_channel *prChannel = NULL;
+	enum nl80211_channel_type rChannelType;
+
+	/* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); */
+
+	if (prGlueInfo->fgIsRegistered == TRUE) {
+		if (ucChannelNum <= 14) {
+			prChannel =
+			    ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
+						  ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ));
+		} else {
+			prChannel =
+			    ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
+						  ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ));
+		}
+
+		switch (eSco) {
+		case CHNL_EXT_SCN:
+			rChannelType = NL80211_CHAN_NO_HT;
+			break;
+
+		case CHNL_EXT_SCA:
+			rChannelType = NL80211_CHAN_HT40MINUS;
+			break;
+
+		case CHNL_EXT_SCB:
+			rChannelType = NL80211_CHAN_HT40PLUS;
+			break;
+
+		case CHNL_EXT_RES:
+		default:
+			rChannelType = NL80211_CHAN_HT20;
+			break;
+		}
+
+		cfg80211_ready_on_channel(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, u4DurationMs,
+					  GFP_KERNEL);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To indicate channel expiration
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo,
+			  IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum)
+{
+	struct ieee80211_channel *prChannel = NULL;
+	enum nl80211_channel_type rChannelType;
+
+	ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX);
+
+	if (prGlueInfo->fgIsRegistered == TRUE) {
+		if (ucChannelNum <= 14) {
+			prChannel =
+			    ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
+						  ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ));
+		} else {
+			prChannel =
+			    ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
+						  ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ));
+		}
+
+		switch (eSco) {
+		case CHNL_EXT_SCN:
+			rChannelType = NL80211_CHAN_NO_HT;
+			break;
+
+		case CHNL_EXT_SCA:
+			rChannelType = NL80211_CHAN_HT40MINUS;
+			break;
+
+		case CHNL_EXT_SCB:
+			rChannelType = NL80211_CHAN_HT40PLUS;
+			break;
+
+		case CHNL_EXT_RES:
+		default:
+			rChannelType = NL80211_CHAN_HT20;
+			break;
+		}
+
+		cfg80211_remain_on_channel_expired(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel,
+						   GFP_KERNEL);
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To indicate Mgmt tx status
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo,
+			IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen)
+{
+
+	do {
+		if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) {
+			DBGLOG(AIS, TRACE, "Unexpected pointer PARAM. %p, %p, %u.",
+					    prGlueInfo, pucFrameBuf, u4FrameLen);
+			ASSERT(FALSE);
+			break;
+		}
+
+		cfg80211_mgmt_tx_status(prGlueInfo->prDevHandler->ieee80211_ptr,
+					u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL);
+	} while (FALSE);
+
+}				/* kalIndicateMgmtTxStatus */
+
+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb)
+{
+#define DBG_MGMT_FRAME_INDICATION 1
+	INT_32 i4Freq = 0;
+	UINT_8 ucChnlNum = 0;
+#if DBG_MGMT_FRAME_INDICATION
+	P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL;
+#endif
+
+	do {
+		if ((prGlueInfo == NULL) || (prSwRfb == NULL)) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum;
+
+#if DBG_MGMT_FRAME_INDICATION
+		prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader;
+
+		switch (prWlanHeader->u2FrameCtrl) {
+		case MAC_FRAME_PROBE_REQ:
+			DBGLOG(AIS, TRACE, "RX Probe Req at channel %d ", ucChnlNum);
+			break;
+		case MAC_FRAME_PROBE_RSP:
+			DBGLOG(AIS, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum);
+			break;
+		case MAC_FRAME_ACTION:
+			DBGLOG(AIS, TRACE, "RX Action frame at channel %d ", ucChnlNum);
+			break;
+		default:
+			DBGLOG(AIS, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum);
+			break;
+		}
+
+#endif
+		i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000;
+
+		cfg80211_rx_mgmt(prGlueInfo->prDevHandler->ieee80211_ptr,	/* struct net_device * dev, */
+				 i4Freq,
+				 RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi),
+				 prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_KERNEL);
+	} while (FALSE);
+
+}				/* kalIndicateRxMgmtFrame */
+
+#if CFG_SUPPORT_AGPS_ASSIST
+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen)
+{
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+
+	struct sk_buff *skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy(prGlueInfo),
+								dataLen, GFP_KERNEL);
+	if (!skb) {
+		DBGLOG(AIS, ERROR, "kalIndicateAgpsNotify: alloc skb failed\n");
+		return FALSE;
+	}
+
+	/* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */
+	if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), &cmd) < 0))
+		goto nla_put_failure;
+	if (dataLen > 0 && data && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, data) < 0))
+		goto nla_put_failure;
+	if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, sizeof(UINT_32), &prGlueInfo->prDevHandler->ifindex) < 0))
+		goto nla_put_failure;
+	/* currently, the ifname maybe wlan0, p2p0, so the maximum name length will be 5 bytes */
+	if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, prGlueInfo->prDevHandler->name) < 0))
+		goto nla_put_failure;
+	cfg80211_testmode_event(skb, GFP_KERNEL);
+	return TRUE;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return FALSE;
+}
+#endif
+
+#if (CFG_SUPPORT_MET_PROFILING == 1)
+#define PROC_MET_PROF_CTRL                 "met_ctrl"
+#define PROC_MET_PROF_PORT                 "met_port"
+
+struct proc_dir_entry *pMetProcDir;
+void *pMetGlobalData = NULL;
+static unsigned long __read_mostly tracing_mark_write_addr;
+
+static inline void __mt_update_tracing_mark_write_addr(void)
+{
+	if (unlikely(0 == tracing_mark_write_addr))
+		tracing_mark_write_addr = kallsyms_lookup_name("tracing_mark_write");
+}
+
+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb)
+{
+	UINT_8 ucIpVersion;
+	UINT_16 u2UdpSrcPort;
+	UINT_16 u2RtpSn;
+	PUINT_8 pucEthHdr = prSkb->data;
+	PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr;
+
+	/* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */
+	/* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */
+	/* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */
+	/* printk("MET_PROF: MET enable=%d(HardXmit)\n", prGlueInfo->u8MetProfEnable); */
+	if (prGlueInfo->u8MetProfEnable == 1) {
+		u2UdpSrcPort = prGlueInfo->u16MetUdpPort;
+		if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) {
+			/* IP */
+			pucIpHdr = pucEthHdr + ETH_HLEN;
+			ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
+			if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) {
+				/* UDP */
+				pucUdpHdr = pucIpHdr + IP_HEADER_LEN;
+				/* check UDP port number */
+				if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) {
+					/* RTP */
+					pucRtpHdr = pucUdpHdr + 8;
+					u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3];
+					/* trace_printk("S|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn);
+					//frm_sequence); */
+#ifdef CONFIG_TRACING
+					__mt_update_tracing_mark_write_addr();
+					if (tracing_mark_write_addr != 0) {
+						event_trace_printk(tracing_mark_write_addr, "S|%d|%s|%d\n",
+								   current->tgid, "WIFI-CHIP", u2RtpSn);
+					}
+#endif
+				}
+			}
+		}
+	}
+}
+
+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
+{
+	UINT_8 ucIpVersion;
+	UINT_16 u2UdpSrcPort;
+	UINT_16 u2RtpSn;
+	struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket;
+	PUINT_8 pucEthHdr = prSkb->data;
+	PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr;
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+
+	/* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */
+	/* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */
+	/* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */
+	/* printk("MET_PROF: MET enable=%d(TxMsdu)\n", prGlueInfo->u8MetProfEnable); */
+	if (prGlueInfo->u8MetProfEnable == 1) {
+		u2UdpSrcPort = prGlueInfo->u16MetUdpPort;
+		if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) {
+			/* IP */
+			pucIpHdr = pucEthHdr + ETH_HLEN;
+			ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
+			if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) {
+				/* UDP */
+				pucUdpHdr = pucIpHdr + IP_HEADER_LEN;
+				/* check UDP port number */
+				if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) {
+					/* RTP */
+					pucRtpHdr = pucUdpHdr + 8;
+					u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3];
+					/* trace_printk("F|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn);
+					//frm_sequence); */
+#ifdef CONFIG_TRACING
+					__mt_update_tracing_mark_write_addr();
+					if (tracing_mark_write_addr != 0) {
+						event_trace_printk(tracing_mark_write_addr, "F|%d|%s|%d\n",
+								   current->tgid, "WIFI-CHIP", u2RtpSn);
+					}
+#endif
+				}
+			}
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message.
+*
+* \param[in] file   pointer to file.
+* \param[in] buffer Buffer from user space.
+* \param[in] count  Number of characters to write
+* \param[in] data   Pointer to the private data structure.
+*
+* \return number of characters write from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static ssize_t kalMetCtrlWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off)
+{
+	char acBuf[128 + 1];	/* + 1 for "\0" */
+	UINT_32 u4CopySize;
+	int u8MetProfEnable;
+
+	IN P_GLUE_INFO_T prGlueInfo;
+
+	u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
+	if (copy_from_user(acBuf, buffer, u4CopySize))
+		return -1;
+	acBuf[u4CopySize] = '\0';
+
+	if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1)
+		DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC Enable=%d\n", u8MetProfEnable);
+	if (pMetGlobalData != NULL) {
+		prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData;
+		prGlueInfo->u8MetProfEnable = (UINT_8) u8MetProfEnable;
+	}
+	return count;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message.
+*
+* \param[in] file   pointer to file.
+* \param[in] buffer Buffer from user space.
+* \param[in] count  Number of characters to write
+* \param[in] data   Pointer to the private data structure.
+*
+* \return number of characters write from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static ssize_t kalMetPortWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off)
+{
+	char acBuf[128 + 1];	/* + 1 for "\0" */
+	UINT_32 u4CopySize;
+	int u16MetUdpPort;
+
+	IN P_GLUE_INFO_T prGlueInfo;
+
+	u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
+	if (copy_from_user(acBuf, buffer, u4CopySize))
+		return -1;
+	acBuf[u4CopySize] = '\0';
+
+	if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1)
+		DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC UDP_PORT=%d\n", u16MetUdpPort);
+	if (pMetGlobalData != NULL) {
+		prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData;
+		prGlueInfo->u16MetUdpPort = (UINT_16) u16MetUdpPort;
+	}
+	return count;
+}
+
+const struct file_operations rMetProcCtrlFops = {
+.write = kalMetCtrlWriteProcfs
+};
+
+const struct file_operations rMetProcPortFops = {
+.write = kalMetPortWriteProcfs
+};
+
+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo)
+{
+	/* struct proc_dir_entry *pMetProcDir; */
+	if (init_net.proc_net == (struct proc_dir_entry *)NULL) {
+		DBGLOG(INIT, INFO, "init proc fs fail: proc_net == NULL\n");
+		return -ENOENT;
+	}
+	/*
+	 * Directory: Root (/proc/net/wlan0)
+	 */
+	pMetProcDir = proc_mkdir("wlan0", init_net.proc_net);
+	if (pMetProcDir == NULL)
+		return -ENOENT;
+	/*
+	   /proc/net/wlan0
+	   |-- met_ctrl         (PROC_MET_PROF_CTRL)
+	   |-- met_port         (PROC_MET_PROF_PORT)
+	 */
+	/* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); */
+	proc_create(PROC_MET_PROF_CTRL, 0, pMetProcDir, &rMetProcCtrlFops);
+	proc_create(PROC_MET_PROF_PORT, 0, pMetProcDir, &rMetProcPortFops);
+
+	pMetGlobalData = (void *)prGlueInfo;
+
+	return 0;
+}
+
+int kalMetRemoveProcfs(void)
+{
+
+	if (init_net.proc_net == (struct proc_dir_entry *)NULL) {
+		DBGLOG(INIT, WARN, "remove proc fs fail: proc_net == NULL\n");
+		return -ENOENT;
+	}
+	remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir);
+	remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir);
+	/* remove root directory (proc/net/wlan0) */
+	remove_proc_entry("wlan0", init_net.proc_net);
+	/* clear MetGlobalData */
+	pMetGlobalData = NULL;
+
+	return 0;
+}
+#endif
+UINT_64 kalGetBootTime(void)
+{
+	struct timespec ts;
+	UINT_64 bootTime = 0;
+
+	get_monotonic_boottime(&ts);
+	/* we assign ts.tv_sec to bootTime first, then multiply USEC_PER_SEC
+	   this will prevent multiply result turn to a negative value on 32bit system */
+	bootTime = ts.tv_sec;
+	bootTime *= USEC_PER_SEC;
+	bootTime += ts.tv_nsec / NSEC_PER_USEC;
+	return bootTime;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To indicate scheduled scan results are avilable
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           None
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo),0);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To indicate scheduled scan has been stopped
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           None
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo)
+{
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prGlueInfo);
+
+	/* 1. reset first for newly incoming request */
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+	if (prGlueInfo->prSchedScanRequest != NULL)
+		prGlueInfo->prSchedScanRequest = NULL;
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+	DBGLOG(SCN, INFO, "cfg80211_sched_scan_stopped send event\n");
+
+    /* 2. indication to cfg80211 */
+    /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K thread to send event instead of Tx thread
+		due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds and send event in the same time  */
+	DBGLOG(SCN, TRACE, "start work queue to send event\n");
+	schedule_delayed_work(&sched_workq, 0);
+	DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n");
+
+}
+
+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG
+/* if SPM is not implement this function, we will use this default one */
+wake_reason_t __weak slp_get_wake_reason(VOID)
+{
+	return WR_NONE;
+}
+/* if SPM is not implement this function, we will use this default one */
+UINT_32 __weak spm_get_last_wakeup_src(VOID)
+{
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    To check if device if wake up by wlan
+*
+* \param[in]
+*           prAdapter
+*
+* \return
+*           TRUE: wake up by wlan; otherwise, FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T  prAdapter)
+{
+	/* SUSPEND_FLAG_FOR_WAKEUP_REASON is set means system has suspended, but may be failed
+		duo to some driver suspend failed. so we need help of function slp_get_wake_reason */
+	if (test_and_clear_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prAdapter->ulSuspendFlag) == 0)
+		return FALSE;
+	/* if slp_get_wake_reason or spm_get_last_wakeup_src is NULL, it means SPM module didn't implement
+		it. then we should return FALSE always. otherwise,  if slp_get_wake_reason returns WR_WAKE_SRC,
+		then it means the host is suspend successfully. */
+	if (slp_get_wake_reason() != WR_WAKE_SRC)
+		return FALSE;
+	/* spm_get_last_wakeup_src will returns the last wakeup source,
+		WAKE_SRC_CONN2AP is connsys */
+	return !!(spm_get_last_wakeup_src() & WAKE_SRC_CONN2AP);
+}
+#endif
+
+INT_32 kalHaltLock(UINT_32 waitMs)
+{
+	INT_32 i4Ret = 0;
+
+	if (waitMs) {
+		i4Ret = down_timeout(&rHaltCtrl.lock, MSEC_TO_JIFFIES(waitMs));
+		if (!i4Ret)
+			goto success;
+		if (i4Ret != -ETIME)
+			return i4Ret;
+		if (rHaltCtrl.fgHeldByKalIoctl) {
+			P_GLUE_INFO_T prGlueInfo = NULL;
+
+			wlanExportGlueInfo(&prGlueInfo);
+
+			DBGLOG(INIT, ERROR,
+				"kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n",
+				kalGetTimeTick() - rHaltCtrl.u4HoldStart);
+			if (prGlueInfo)
+				show_stack(prGlueInfo->main_thread, NULL);
+		} else {
+			DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n",
+				rHaltCtrl.owner->comm, rHaltCtrl.owner->pid,
+				kalGetTimeTick() - rHaltCtrl.u4HoldStart);
+			show_stack(rHaltCtrl.owner, NULL);
+		}
+		return i4Ret;
+	}
+	down(&rHaltCtrl.lock);
+success:
+	rHaltCtrl.owner = current;
+	rHaltCtrl.u4HoldStart = kalGetTimeTick();
+	return 0;
+}
+
+INT_32 kalHaltTryLock(VOID)
+{
+	INT_32 i4Ret = 0;
+
+	i4Ret = down_trylock(&rHaltCtrl.lock);
+	if (i4Ret)
+		return i4Ret;
+	rHaltCtrl.owner = current;
+	rHaltCtrl.u4HoldStart = kalGetTimeTick();
+	return 0;
+}
+
+VOID kalHaltUnlock(VOID)
+{
+	if (kalGetTimeTick() - rHaltCtrl.u4HoldStart > WLAN_OID_TIMEOUT_THRESHOLD * 2 &&
+		rHaltCtrl.owner)
+		DBGLOG(INIT, ERROR, "process %s pid %d hold halt lock longer than 4s!\n",
+			rHaltCtrl.owner->comm, rHaltCtrl.owner->pid);
+	rHaltCtrl.owner = NULL;
+	up(&rHaltCtrl.lock);
+}
+
+VOID kalSetHalted(BOOLEAN fgHalt)
+{
+	rHaltCtrl.fgHalt = fgHalt;
+}
+
+BOOLEAN kalIsHalted(VOID)
+{
+	return rHaltCtrl.fgHalt;
+}
+VOID kalPerMonDump(IN P_GLUE_INFO_T prGlueInfo)
+{
+	struct GL_PER_MON_T *prPerMonitor;
+
+	prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor;
+	DBGLOG(SW4, WARN, "ulPerfMonFlag:0x%lx\n", prPerMonitor->ulPerfMonFlag);
+	DBGLOG(SW4, WARN, "ulLastTxBytes:%ld\n", prPerMonitor->ulLastTxBytes);
+	DBGLOG(SW4, WARN, "ulLastRxBytes:%ld\n", prPerMonitor->ulLastRxBytes);
+	DBGLOG(SW4, WARN, "ulP2PLastTxBytes:%ld\n", prPerMonitor->ulP2PLastTxBytes);
+	DBGLOG(SW4, WARN, "ulP2PLastRxBytes:%ld\n", prPerMonitor->ulP2PLastRxBytes);
+	DBGLOG(SW4, WARN, "ulThroughput:%ld\n", prPerMonitor->ulThroughput);
+	DBGLOG(SW4, WARN, "u4UpdatePeriod:%d\n", prPerMonitor->u4UpdatePeriod);
+	DBGLOG(SW4, WARN, "u4TarPerfLevel:%d\n", prPerMonitor->u4TarPerfLevel);
+	DBGLOG(SW4, WARN, "u4CurrPerfLevel:%d\n", prPerMonitor->u4CurrPerfLevel);
+	DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.tx_bytes);
+	DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.rx_bytes);
+	DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes);
+	DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes);
+}
+
+inline INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo)
+{
+	struct GL_PER_MON_T *prPerMonitor;
+
+	prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor;
+	DBGLOG(SW4, INFO, "enter %s\n", __func__);
+	if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag))
+		DBGLOG(SW4, WARN, "abnormal, perf monitory already running\n");
+	KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	prPerMonitor->u4UpdatePeriod = 1000;
+	cnmTimerInitTimer(prGlueInfo->prAdapter,
+		&prPerMonitor->rPerfMonTimer,
+		(PFN_MGMT_TIMEOUT_FUNC) kalPerMonHandler, (ULONG) NULL);
+	DBGLOG(SW4, INFO, "exit %s\n", __func__);
+	return 0;
+}
+
+inline INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo)
+{
+	struct GL_PER_MON_T *prPerMonitor;
+
+	prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor;
+
+	DBGLOG(SW4, INFO, "enter %s\n", __func__);
+	if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) {
+		DBGLOG(SW4, TRACE, "need to stop before disable\n");
+		kalPerMonStop(prGlueInfo);
+	}
+	KAL_SET_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	DBGLOG(SW4, TRACE, "exit %s\n", __func__);
+	return 0;
+}
+
+inline INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo)
+{
+	struct GL_PER_MON_T *prPerMonitor;
+
+	prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor;
+
+	DBGLOG(SW4, INFO, "enter %s\n", __func__);
+	KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	DBGLOG(SW4, TRACE, "exit %s\n", __func__);
+	return 0;
+}
+
+inline INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo)
+{
+	struct GL_PER_MON_T *prPerMonitor;
+
+	prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor;
+	DBGLOG(SW4, TRACE, "enter %s\n", __func__);
+	if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag))
+		return 0;
+	if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) {
+		DBGLOG(SW4, TRACE, "perf monitor already running\n");
+		return 0;
+	}
+	cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod);
+	KAL_SET_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	KAL_CLR_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	DBGLOG(SW4, INFO, "perf monitor started\n");
+	return 0;
+}
+
+inline INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo)
+{
+	struct GL_PER_MON_T *prPerMonitor;
+
+	prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor;
+	DBGLOG(SW4, TRACE, "enter %s\n", __func__);
+
+	if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) {
+		DBGLOG(SW4, TRACE, "perf monitory disabled\n");
+		return 0;
+	}
+
+	if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) {
+		DBGLOG(SW4, TRACE, "perf monitory already stopped\n");
+		return 0;
+	}
+
+	KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+	if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) {
+		cnmTimerStopTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer);
+		KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+		prPerMonitor->ulLastRxBytes = 0;
+		prPerMonitor->ulLastTxBytes = 0;
+		prPerMonitor->ulP2PLastRxBytes = 0;
+		prPerMonitor->ulP2PLastTxBytes = 0;
+		prPerMonitor->ulThroughput = 0;
+		prPerMonitor->u4CurrPerfLevel = 0;
+		prPerMonitor->u4TarPerfLevel = 0;
+		/*Cancel CPU performance mode request*/
+		kalBoostCpu(0);
+	}
+	DBGLOG(SW4, TRACE, "exit %s\n", __func__);
+	return 0;
+}
+
+inline INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo)
+{
+	kalPerMonDisable(prGlueInfo);
+	return 0;
+}
+
+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam)
+{
+	/*Calculate current throughput*/
+	struct GL_PER_MON_T *prPerMonitor;
+
+	LONG latestTxBytes, latestRxBytes, txDiffBytes, rxDiffBytes;
+	LONG p2pLatestTxBytes, p2pLatestRxBytes, p2pTxDiffBytes, p2pRxDiffBytes;
+	P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
+
+	if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) || (!prAdapter->fgIsP2PRegistered))
+		return;
+
+	prPerMonitor = &prAdapter->rPerMonitor;
+	DBGLOG(SW4, TRACE, "enter kalPerMonHandler\n");
+	if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) {
+		KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+		DBGLOG(SW4, WARN, "perf monitory disabled, omit timeout event\n");
+		return;
+	}
+
+	if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) {
+		KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag);
+		DBGLOG(SW4, WARN, "perf monitory stopped, omit timeout event\n");
+		return;
+	}
+	latestTxBytes = prGlueInfo->rNetDevStats.tx_bytes;
+	latestRxBytes = prGlueInfo->rNetDevStats.rx_bytes;
+	p2pLatestTxBytes = prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes;
+	p2pLatestRxBytes = prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes;
+	if (0 == prPerMonitor->ulLastRxBytes &&
+		0 == prPerMonitor->ulLastTxBytes &&
+		0 == prPerMonitor->ulP2PLastRxBytes &&
+		0 == prPerMonitor->ulP2PLastTxBytes) {
+		prPerMonitor->ulThroughput = 0;
+	} else {
+		txDiffBytes = latestTxBytes - prPerMonitor->ulLastTxBytes;
+		rxDiffBytes = latestRxBytes - prPerMonitor->ulLastRxBytes;
+		if (0 > txDiffBytes)
+			txDiffBytes = -(txDiffBytes);
+		if (0 > rxDiffBytes)
+			rxDiffBytes = -(rxDiffBytes);
+
+		p2pTxDiffBytes = p2pLatestTxBytes - prPerMonitor->ulP2PLastTxBytes;
+		p2pRxDiffBytes = p2pLatestRxBytes - prPerMonitor->ulP2PLastRxBytes;
+		if (0 > p2pTxDiffBytes)
+			p2pTxDiffBytes = -(p2pTxDiffBytes);
+		if (0 > p2pRxDiffBytes)
+			p2pRxDiffBytes = -(p2pRxDiffBytes);
+
+		prPerMonitor->ulThroughput = txDiffBytes + rxDiffBytes + p2pTxDiffBytes + p2pRxDiffBytes;
+		prPerMonitor->ulThroughput *= 1000;
+		prPerMonitor->ulThroughput /= prPerMonitor->u4UpdatePeriod;
+		prPerMonitor->ulThroughput <<= 3;
+	}
+	/*start the timer again  to make sure we can cancel performance mode request in the end*/
+	cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod);
+
+	prPerMonitor->ulLastTxBytes = latestTxBytes;
+	prPerMonitor->ulLastRxBytes = latestRxBytes;
+	prPerMonitor->ulP2PLastTxBytes = p2pLatestTxBytes;
+	prPerMonitor->ulP2PLastRxBytes = p2pLatestRxBytes;
+
+	if (prPerMonitor->ulThroughput < THROUGHPUT_L1_THRESHOLD)
+		prPerMonitor->u4TarPerfLevel = 0;
+	else if (prPerMonitor->ulThroughput < THROUGHPUT_L2_THRESHOLD)
+		prPerMonitor->u4TarPerfLevel = 1;
+	else if (prPerMonitor->ulThroughput < THROUGHPUT_L3_THRESHOLD)
+		prPerMonitor->u4TarPerfLevel = 2;
+	else
+		prPerMonitor->u4TarPerfLevel = 3;
+	if (prPerMonitor->u4TarPerfLevel != prPerMonitor->u4CurrPerfLevel) {
+		if (0 == prPerMonitor->u4TarPerfLevel) {
+			/*cancel CPU performance mode request*/
+			kalPerMonStop(prGlueInfo);
+		} else{
+			DBGLOG(SW4, TRACE, "throughput:%ld bps\n", prPerMonitor->ulThroughput);
+			/*adjust CPU core number to prPerMonitor->u4TarPerfLevel+1*/
+			kalBoostCpu(prPerMonitor->u4TarPerfLevel+1);
+			/*start the timer again  to make sure we can cancel performance mode request in the end*/
+			cnmTimerStartTimer(prGlueInfo->prAdapter,
+				&prPerMonitor->rPerfMonTimer,
+				prPerMonitor->u4UpdatePeriod);
+		}
+	}
+	prPerMonitor->u4CurrPerfLevel = prPerMonitor->u4TarPerfLevel;
+	DBGLOG(SW4, TRACE, "exit kalPerMonHandler\n");
+}
+
+INT32 __weak kalBoostCpu(UINT_32 core_num)
+{
+	DBGLOG(SW4, WARN, "enter weak kalBoostCpu, core_num:%d\n", core_num);
+	return 0;
+}
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c
new file mode 100644
index 0000000000000..945a6c03978b8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c
@@ -0,0 +1,4672 @@
+/*
+** Id: @(#) gl_p2p.c@@
+*/
+
+/*! \file   gl_p2p.c
+    \brief  Main routines of Linux driver interface for Wi-Fi Direct
+
+    This file contains the main routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*
+** Log: gl_p2p.c
+**
+** 09 12 2012 wcpadmin
+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
+** .
+**
+** 08 17 2012 yuche.tsai
+** NULL
+** Fix compile warning.
+**
+** 08 16 2012 yuche.tsai
+** NULL
+** Fix compile warning.
+**
+** 08 14 2012 yuche.tsai
+** NULL
+** FPB from ALPS.JB to phase 2 release.
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Fix compile error for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 01 09 2012 terry.wu
+ * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork
+ * cfg80211 integration for p2p network.
+ *
+ * 12 19 2011 terry.wu
+ * [WCXRP00001142] [Wi-Fi] [P2P Driver] XOR local admin bit to generate p2p net device MAC
+ * XOR local administrated bit to generate net device MAC of p2p network.
+ *
+ * 12 02 2011 yuche.tsai
+ * NULL
+ * Fix possible KE when unload p2p.
+ *
+ * 11 24 2011 yuche.tsai
+ * NULL
+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control.
+ *
+ * 11 22 2011 yuche.tsai
+ * NULL
+ * Update RSSI link quality of P2P Network query method. (Bug fix)
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Add RSSI support for P2P network.
+ *
+ * 11 16 2011 yuche.tsai
+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
+ * Avoid using work thread in set p2p multicast address callback.
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix work thread cancel issue.
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix default device name issue.
+ *
+ * 11 08 2011 yuche.tsai
+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service
+ * discovery version check.
+ * Add support for driver version query & p2p supplicant verseion set.
+ * For new service discovery mechanism sync.
+ *
+ * 11 07 2011 yuche.tsai
+ * NULL
+ * [ALPS 00087243] KE in worker thread.
+ * The multicast address list is scheduled in worker thread.
+ * Before the worker thread is excuted, if P2P is unloaded, a KE may occur.
+ *
+ * 10 26 2011 terry.wu
+ * [WCXRP00001066] [MT6620 Wi-Fi] [P2P Driver] Fix P2P Oid Issue
+ * Fix some P2P OID functions didn't raise its flag "fgIsP2pOid" issue.
+ *
+ * 10 25 2011 cm.chang
+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
+ * .
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * Support Channel Query.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * New 2.1 branch
+
+ *
+ * 08 26 2011 yuche.tsai
+ * NULL
+ * Fix bug of parsing secondary device list type issue.
+ *
+ * 08 24 2011 yuche.tsai
+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
+ * Invitation Abort.
+ *
+ * 08 23 2011 yuche.tsai
+ * NULL
+ * Fix multicast address list issue of P2P.
+ *
+ * 08 22 2011 chinglan.wang
+ * NULL
+ * Fix invitation indication bug..
+ *
+ * 08 16 2011 cp.wu
+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence
+ * auto channel decision for 2.4GHz hot spot mode
+ *
+ * 08 16 2011 chinglan.wang
+ * NULL
+ * Add the group id information in the invitation indication.
+ *
+ * 08 09 2011 yuche.tsai
+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
+ * Invitation Feature add on.
+ *
+ * 08 05 2011 yuche.tsai
+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution.
+ * Add Password ID check for quick connection.
+ * Also modify some connection policy.
+ *
+ * 07 18 2011 chinglan.wang
+ * NULL
+ * Add IOC_P2P_GO_WSC_IE (p2p capability).
+ *
+ * 06 14 2011 yuche.tsai
+ * NULL
+ * Add compile flag to disable persistent group support.
+ *
+ * 05 04 2011 chinglan.wang
+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver
+ * .
+ *
+ * 05 02 2011 yuche.tsai
+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout.
+ * Clear formation flag after formation timeout.
+ *
+ * 04 22 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * .
+ *
+ * 04 21 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * 1. Revise P2P power mode setting.
+ * 2. Revise fast-PS for concurrent
+ *
+ * 04 19 2011 wh.su
+ * NULL
+ * Adding length check before doing WPA RSN IE parsing for scan results indicate.
+ *
+ * 04 14 2011 yuche.tsai
+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
+ * Connection flow refine for Sigma test.
+ *
+ * 04 08 2011 yuche.tsai
+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
+ * Add device discoverability support.
+ *
+ * 04 08 2011 george.huang
+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
+ * separate settings of P2P and AIS
+ *
+ * 04 07 2011 terry.wu
+ * [WCXRP00000619] [MT6620 Wi-Fi][Driver] fix kernel panic may occur when removing wlan
+ * Fix kernel panic may occur when removing wlan driver.
+ *
+ * 03 31 2011 wh.su
+ * [WCXRP00000614] [MT6620 Wi-Fi][Driver] P2P: Update beacon content while setting WSC IE
+ * Update the wsc ie to beacon content.
+ *
+ * 03 25 2011 wh.su
+ * NULL
+ * add the sample code for set power mode and get power mode.
+ *
+ * 03 25 2011 yuche.tsai
+ * NULL
+ * Improve some error handleing.
+ *
+ * 03 22 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * link with supplicant commands
+ *
+ * 03 22 2011 yuche.tsai
+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
+ * Modify formation policy.
+ *
+ * 03 22 2011 yuche.tsai
+ * NULL
+ * Modify formation policy setting.
+ *
+ * 03 18 2011 yuche.tsai
+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow
+ * Modify connection flow after Group Formation Complete, or device connect to a GO.
+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN.
+ *
+ * 03 15 2011 wh.su
+ * [WCXRP00000563] [MT6620 Wi-Fi] [P2P] Set local config method while set password Id ready
+ * set lccal config method method while set password Id ready.
+ *
+ * 03 15 2011 yuche.tsai
+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue
+ * Fix some configure method issue.
+ *
+ * 03 15 2011 jeffrey.chang
+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM
+ * refine queue_select function
+ *
+ * 03 13 2011 wh.su
+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
+ * add code for avoid compiling warning.
+ *
+ * 03 10 2011 yuche.tsai
+ * NULL
+ * Add P2P API.
+ *
+ * 03 10 2011 terry.wu
+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
+ * Remove unnecessary assert and message.
+ *
+ * 03 08 2011 wh.su
+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
+ * support the power save related p2p setting.
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * support concurrent network
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * modify P2P's netdevice  functions to support multiple H/W queues
+ *
+ * 03 03 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * for get request, the buffer length to be copied is header + payload.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add code to let the beacon and probe response for Auto GO WSC .
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * add a missed break.
+ *
+ * 03 01 2011 yuche.tsai
+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation
+ * Update channel issue when doing GO formation..
+ *
+ * 02 25 2011 wh.su
+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
+ * add the Operation channel setting.
+ *
+ * 02 23 2011 wh.su
+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
+ * fixed the set int ioctl set index and value map to driver issue.
+ *
+ * 02 22 2011 wh.su
+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters
+ *
+ * 02 21 2011 terry.wu
+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
+ * Clean P2P scan list while removing P2P.
+ *
+ * 02 18 2011 wh.su
+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
+ * fixed the ioctl setting that index not map to spec defined config method.
+ *
+ * 02 17 2011 wh.su
+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
+ * append the WSC IE config method attribute at provision discovery request.
+ *
+ * 02 17 2011 wh.su
+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
+ * modify the structure pointer for set WSC IE.
+ *
+ * 02 16 2011 wh.su
+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
+ * fixed the probe request send out without WSC IE issue (at P2P).
+ *
+ * 02 09 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * fix typo
+ *
+ * 02 09 2011 yuche.tsai
+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
+ * Add Support for MLME deauthentication for Hot-Spot.
+ *
+ * 01 25 2011 terry.wu
+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter
+ * Add a new module parameter to indicate current runnig mode, P2P or AP.
+ *
+ * 01 12 2011 yuche.tsai
+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s.
+ * 2. Call cnmP2pIsPermit() before active P2P network.
+ * 3. Add channel selection support for AP mode.
+ *
+ * 01 05 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * ioctl implementations for P2P Service Discovery
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
+ * physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 12 22 2010 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * 1. header file restructure for more clear module isolation
+ * 2. add function interface definition for implementing Service Discovery callbacks
+ *
+ * 12 15 2010 cp.wu
+ * NULL
+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart()
+ *
+ * 12 08 2010 yuche.tsai
+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in
+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add
+ *
+ * 11 30 2010 yuche.tsai
+ * NULL
+ * Invitation & Provision Discovery Indication.
+ *
+ * 11 17 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] Set the Tx
+ * lowest rate at wlan table for normal operation
+ * fixed some ASSERT check.
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Add the code to support disconnect p2p group
+ *
+ * 10 04 2010 wh.su
+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
+ * add a kal function for set cipher.
+ *
+ * 10 04 2010 wh.su
+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
+ * fixed compiling error while enable p2p.
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 10 2010 george.huang
+ * NULL
+ * update iwpriv LP related
+ *
+ * 09 10 2010 wh.su
+ * NULL
+ * fixed the compiling error at win XP.
+ *
+ * 09 09 2010 cp.wu
+ * NULL
+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result.
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 06 2010 wh.su
+ * NULL
+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
+ *
+ * 08 25 2010 cp.wu
+ * NULL
+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater
+ *
+ * 08 23 2010 cp.wu
+ * NULL
+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
+ *
+ * 08 20 2010 cp.wu
+ * NULL
+ * correct typo.
+ *
+ * 08 20 2010 yuche.tsai
+ * NULL
+ * Invert Connection request provision status parameter.
+ *
+ * 08 19 2010 cp.wu
+ * NULL
+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address.
+ *
+ * 08 18 2010 cp.wu
+ * NULL
+ * modify pwp ioctls attribution by removing FIXED_SIZE.
+ *
+ * 08 18 2010 jeffrey.chang
+ * NULL
+ * support multi-function sdio
+ *
+ * 08 17 2010 cp.wu
+ * NULL
+ * correct p2p net device registration with NULL pointer access issue.
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * add subroutines for P2P to set multicast list.
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * add wext handlers to link P2P set PS profile/ network address function (TBD)
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * revised implementation of Wi-Fi Direct io controls.
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * follow-up with ioctl interface update for Wi-Fi Direct application
+ *
+ * 08 06 2010 cp.wu
+ * NULL
+ * driver hook modifications corresponding to ioctl interface change.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * add basic support for ioctl of getting scan result. (only address and SSID are reporterd though)
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * surpress compilation warning.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * [Wi-Fi Direct] add framework for driver hooks
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 23 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * p2p interface revised to be sync. with HAL
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 01 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl to configure scan mode for p2p connection
+ *
+ * 05 31 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add cfg80211 interface, which is to replace WE, for further extension
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement private io controls for Wi-Fi Direct
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement get scan result.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic handling framework for wireless extension ioctls.
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * 1) add timeout handler mechanism for pending command packets
+ * 2) add p2p add/removal key
+ *
+ * 05 14 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement wireless extension ioctls in iw_handler form.
+ *
+ * 05 14 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * p2p ioctls revised.
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl for controlling p2p scan phase parameters
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement basic wi-fi direct framework
+ *
+ * 05 07 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic framework for implementating P2P driver hook.
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/poll.h>
+#include <linux/kmod.h>
+
+#include "gl_os.h"
+#include "wlan_lib.h"
+#include "gl_wext.h"
+#include "gl_p2p_os.h"
+#include "gl_p2p_ioctl.h"
+#include "gl_vendor.h"
+
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define ARGV_MAX_NUM        (4)
+
+/*For CFG80211 - wiphy parameters*/
+#define MAX_SCAN_LIST_NUM   (1)
+#define MAX_SCAN_IE_LEN     (512)
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+static struct cfg80211_ops mtk_p2p_ops = {
+	.change_virtual_intf = mtk_p2p_cfg80211_change_iface,	/* 1st */
+	.change_bss = mtk_p2p_cfg80211_change_bss,
+	.scan = mtk_p2p_cfg80211_scan,
+	.remain_on_channel = mtk_p2p_cfg80211_remain_on_channel,
+	.cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel,
+	.mgmt_tx = mtk_p2p_cfg80211_mgmt_tx,
+	.connect = mtk_p2p_cfg80211_connect,
+	.disconnect = mtk_p2p_cfg80211_disconnect,
+	.deauth = mtk_p2p_cfg80211_deauth,
+	.disassoc = mtk_p2p_cfg80211_disassoc,
+	.start_ap = mtk_p2p_cfg80211_start_ap,
+	.change_beacon = mtk_p2p_cfg80211_change_beacon,
+	.stop_ap = mtk_p2p_cfg80211_stop_ap,
+	.set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params,
+	.del_station = mtk_p2p_cfg80211_del_station,
+	.set_monitor_channel = mtk_p2p_cfg80211_set_channel,
+	.set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask,
+	.mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register,
+	.get_station = mtk_p2p_cfg80211_get_station,
+	.add_key = mtk_p2p_cfg80211_add_key,
+	.get_key = mtk_p2p_cfg80211_get_key,
+	.del_key = mtk_p2p_cfg80211_del_key,
+	.set_default_key = mtk_p2p_cfg80211_set_default_key,
+	.join_ibss = mtk_p2p_cfg80211_join_ibss,
+	.leave_ibss = mtk_p2p_cfg80211_leave_ibss,
+	.set_tx_power = mtk_p2p_cfg80211_set_txpower,
+	.get_tx_power = mtk_p2p_cfg80211_get_txpower,
+	.set_power_mgmt = mtk_p2p_cfg80211_set_power_mgmt,
+#ifdef CONFIG_NL80211_TESTMODE
+	.testmode_cmd = mtk_p2p_cfg80211_testmode_cmd,
+#endif
+};
+
+static const struct wiphy_vendor_command mtk_p2p_vendor_ops[] = {
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_get_channel_list
+	},
+	{
+		{
+			.vendor_id = GOOGLE_OUI,
+			.subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = mtk_cfg80211_vendor_set_country_code
+	},
+};
+
+/* There isn't a lot of sense in it, but you can transmit anything you like */
+static const struct ieee80211_txrx_stypes
+	mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
+	[NL80211_IFTYPE_ADHOC] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4)
+	},
+	[NL80211_IFTYPE_STATION] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+	},
+	[NL80211_IFTYPE_AP] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
+	},
+	[NL80211_IFTYPE_AP_VLAN] = {
+		/* copy AP */
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+		      BIT(IEEE80211_STYPE_AUTH >> 4) |
+		      BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
+	},
+	[NL80211_IFTYPE_P2P_CLIENT] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+	},
+	[NL80211_IFTYPE_P2P_GO] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
+	}
+};
+
+#endif
+
+/* the legacy wireless extension stuff */
+static const iw_handler rP2PIwStandardHandler[] = {
+	[SIOCGIWPRIV - SIOCIWFIRST] = mtk_p2p_wext_get_priv,
+	[SIOCGIWSCAN - SIOCIWFIRST] = mtk_p2p_wext_discovery_results,
+	[SIOCSIWESSID - SIOCIWFIRST] = mtk_p2p_wext_reconnect,
+	[SIOCSIWAUTH - SIOCIWFIRST] = mtk_p2p_wext_set_auth,
+	[SIOCSIWENCODEEXT - SIOCIWFIRST] = mtk_p2p_wext_set_key,
+	[SIOCSIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_set_powermode,
+	[SIOCGIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_get_powermode,
+	[SIOCSIWTXPOW - SIOCIWFIRST] = mtk_p2p_wext_set_txpow,
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+	[SIOCGIWSTATS - SIOCIWFIRST] = mtk_p2p_wext_get_rssi,
+#endif
+	[SIOCSIWMLME - SIOCIWFIRST] = mtk_p2p_wext_mlme_handler,
+};
+
+static const iw_handler rP2PIwPrivHandler[] = {
+	[IOC_P2P_CFG_DEVICE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_local_dev_info,
+	[IOC_P2P_PROVISION_COMPLETE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_provision_complete,
+	[IOC_P2P_START_STOP_DISCOVERY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_start_stop_discovery,
+	[IOC_P2P_DISCOVERY_RESULTS - SIOCIWFIRSTPRIV] = mtk_p2p_wext_discovery_results,
+	[IOC_P2P_WSC_BEACON_PROBE_RSP_IE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_wsc_ie,
+	[IOC_P2P_CONNECT_DISCONNECT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_connect_disconnect,
+	[IOC_P2P_PASSWORD_READY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_password_ready,
+/* [IOC_P2P_SET_PWR_MGMT_PARAM         - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_set_pm_param, */
+	[IOC_P2P_SET_INT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_int,
+	[IOC_P2P_GET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_get_struct,
+	[IOC_P2P_SET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_struct,
+	[IOC_P2P_GET_REQ_DEVICE_INFO - SIOCIWFIRSTPRIV] = mtk_p2p_wext_request_dev_info,
+};
+
+static const struct iw_priv_args rP2PIwPrivTable[] = {
+	{
+	 .cmd = IOC_P2P_CFG_DEVICE,
+	 .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CFG_DEVICE_TYPE),
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "P2P_CFG_DEVICE"}
+	,
+	{
+	 .cmd = IOC_P2P_START_STOP_DISCOVERY,
+	 .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_REQ_DEVICE_TYPE),
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "P2P_DISCOVERY"}
+	,
+	{
+	 .cmd = IOC_P2P_DISCOVERY_RESULTS,
+	 .set_args = IW_PRIV_TYPE_NONE,
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "P2P_RESULT"}
+	,
+	{
+	 .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE,
+	 .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_HOSTAPD_PARAM),
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "P2P_WSC_IE"}
+	,
+	{
+	 .cmd = IOC_P2P_CONNECT_DISCONNECT,
+	 .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CONNECT_DEVICE),
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "P2P_CONNECT"}
+	,
+	{
+	 .cmd = IOC_P2P_PASSWORD_READY,
+	 .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_PASSWORD_READY),
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "P2P_PASSWD_RDY"}
+	,
+	{
+	 .cmd = IOC_P2P_GET_STRUCT,
+	 .set_args = IW_PRIV_TYPE_NONE,
+	 .get_args = 256,
+	 .name = "P2P_GET_STRUCT"}
+	,
+	{
+	 .cmd = IOC_P2P_SET_STRUCT,
+	 .set_args = 256,
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "P2P_SET_STRUCT"}
+	,
+	{
+	 .cmd = IOC_P2P_GET_REQ_DEVICE_INFO,
+	 .set_args = IW_PRIV_TYPE_NONE,
+	 .get_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_DEVICE_REQ),
+	 .name = "P2P_GET_REQDEV"}
+	,
+	{
+	 /* SET STRUCT sub-ioctls commands */
+	 .cmd = PRIV_CMD_OID,
+	 .set_args = 256,
+	 .get_args = IW_PRIV_TYPE_NONE,
+	 .name = "set_oid"}
+	,
+	{
+	 /* GET STRUCT sub-ioctls commands */
+	 .cmd = PRIV_CMD_OID,
+	 .set_args = IW_PRIV_TYPE_NONE,
+	 .get_args = 256,
+	 .name = "get_oid"}
+};
+
+const struct iw_handler_def mtk_p2p_wext_handler_def = {
+	.num_standard = (__u16) sizeof(rP2PIwStandardHandler) / sizeof(iw_handler),
+	.num_private = (__u16) sizeof(rP2PIwPrivHandler) / sizeof(iw_handler),
+	.num_private_args = (__u16) sizeof(rP2PIwPrivTable) / sizeof(struct iw_priv_args),
+	.standard = rP2PIwStandardHandler,
+	.private = rP2PIwPrivHandler,
+	.private_args = rP2PIwPrivTable,
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+	.get_wireless_stats = mtk_p2p_wext_get_wireless_stats,
+#else
+	.get_wireless_stats = NULL,
+#endif
+};
+
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support p2p_wowlan_support = {
+	.flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY,
+};
+#endif
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/* for IE Searching */
+extern BOOLEAN
+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE);
+
+#if CFG_SUPPORT_WPS
+extern BOOLEAN
+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE);
+#endif
+
+/* Net Device Hooks */
+static int p2pOpen(IN struct net_device *prDev);
+
+static int p2pStop(IN struct net_device *prDev);
+
+static struct net_device_stats *p2pGetStats(IN struct net_device *prDev);
+
+static void p2pSetMulticastList(IN struct net_device *prDev);
+
+static int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev);
+
+static int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd);
+
+static int p2pSetMACAddress(IN struct net_device *prDev, void *addr);
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Override the implementation of select queue
+*
+* \param[in] dev Pointer to struct net_device
+* \param[in] skb Pointer to struct skb_buff
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+
+unsigned int _p2p_cfg80211_classify8021d(struct sk_buff *skb)
+{
+	unsigned int dscp = 0;
+
+	/* skb->priority values from 256->263 are magic values
+	 * directly indicate a specific 802.1d priority.  This is
+	 * to allow 802.1d priority to be passed directly in from
+	 * tags
+	 */
+
+	if (skb->priority >= 256 && skb->priority <= 263)
+		return skb->priority - 256;
+	switch (skb->protocol) {
+	case htons(ETH_P_IP):
+		dscp = ip_hdr(skb)->tos & 0xfc;
+		break;
+	}
+	return dscp >> 5;
+}
+
+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
+
+static UINT_16 p2pSelectQueue(struct net_device *dev, struct sk_buff *skb,
+				struct net_device *sb_dev,
+				select_queue_fallback_t fallback)
+{
+	skb->priority = _p2p_cfg80211_classify8021d(skb);
+
+	return au16Wlan1dToQueueIdx[skb->priority];
+}
+
+static struct net_device *g_P2pPrDev;
+static struct wireless_dev *gprP2pWdev;
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A function for prDev->init
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \retval 0         The execution of wlanInit succeeds.
+* \retval -ENXIO    No such device.
+*/
+/*----------------------------------------------------------------------------*/
+static int p2pInit(struct net_device *prDev)
+{
+/* P_GLUE_INFO_T prGlueInfo; */
+	if (!prDev)
+		return -ENXIO;
+
+	DBGLOG(P2P, INFO, "dev name=%s\n", prDev->name);
+	return 0;		/* success */
+}				/* end of p2pInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A function for prDev->uninit
+*
+* \param[in] prDev      Pointer to struct net_device.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+static void p2pUninit(IN struct net_device *prDev)
+{
+
+}				/* end of p2pUninit() */
+
+static const struct net_device_ops p2p_netdev_ops = {
+	.ndo_open = p2pOpen,
+	.ndo_stop = p2pStop,
+	.ndo_set_mac_address = p2pSetMACAddress,
+	.ndo_set_rx_mode = p2pSetMulticastList,
+	.ndo_get_stats = p2pGetStats,
+	.ndo_do_ioctl = p2pDoIOCTL,
+	.ndo_start_xmit = p2pHardStartXmit,
+	.ndo_select_queue = p2pSelectQueue,
+	.ndo_init = p2pInit,
+	.ndo_uninit = p2pUninit,
+};
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS
+*                                          P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO
+*
+* \param[in] prGlueInfo      Pointer to glue info
+*
+* \return   TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2PAllocInfo(IN P_GLUE_INFO_T prGlueInfo)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_WIFI_VAR_T prWifiVar = NULL;
+
+	if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	prAdapter = prGlueInfo->prAdapter;
+	prWifiVar = &(prAdapter->rWifiVar);
+
+	if (!prWifiVar) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	do {
+		if (prGlueInfo->prP2PInfo == NULL) {
+			/*alloc memory for p2p info */
+			prGlueInfo->prP2PInfo = kalMemAlloc(sizeof(GL_P2P_INFO_T), VIR_MEM_TYPE);
+			prAdapter->prP2pInfo = kalMemAlloc(sizeof(P2P_INFO_T), VIR_MEM_TYPE);
+			prWifiVar->prP2PConnSettings = kalMemAlloc(sizeof(P2P_CONNECTION_SETTINGS_T), VIR_MEM_TYPE);
+			prWifiVar->prP2pFsmInfo = kalMemAlloc(sizeof(P2P_FSM_INFO_T), VIR_MEM_TYPE);
+			prWifiVar->prP2pSpecificBssInfo = kalMemAlloc(sizeof(P2P_SPECIFIC_BSS_INFO_T), VIR_MEM_TYPE);
+		} else {
+			ASSERT(prAdapter->prP2pInfo != NULL);
+			ASSERT(prWifiVar->prP2PConnSettings != NULL);
+			ASSERT(prWifiVar->prP2pFsmInfo != NULL);
+			ASSERT(prWifiVar->prP2pSpecificBssInfo != NULL);
+		}
+		/*MUST set memory to 0 */
+		if (prGlueInfo->prP2PInfo)
+			kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T));
+		if (prAdapter->prP2pInfo)
+			kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T));
+		if (prWifiVar->prP2PConnSettings)
+			kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T));
+		if (prWifiVar->prP2pFsmInfo)
+			kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T));
+		if (prWifiVar->prP2pSpecificBssInfo)
+			kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T));
+
+	} while (FALSE);
+
+	/* chk if alloc successful or not */
+	if (prGlueInfo->prP2PInfo &&
+	    prAdapter->prP2pInfo &&
+	    prWifiVar->prP2PConnSettings && prWifiVar->prP2pFsmInfo && prWifiVar->prP2pSpecificBssInfo) {
+		return TRUE;
+	}
+
+	if (prWifiVar->prP2pSpecificBssInfo) {
+		kalMemFree(prWifiVar->prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T));
+
+		prWifiVar->prP2pSpecificBssInfo = NULL;
+	}
+	if (prWifiVar->prP2pFsmInfo) {
+		kalMemFree(prWifiVar->prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T));
+
+		prWifiVar->prP2pFsmInfo = NULL;
+	}
+	if (prWifiVar->prP2PConnSettings) {
+		kalMemFree(prWifiVar->prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T));
+
+		prWifiVar->prP2PConnSettings = NULL;
+	}
+	if (prGlueInfo->prP2PInfo) {
+		kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T));
+
+		prGlueInfo->prP2PInfo = NULL;
+	}
+	if (prAdapter->prP2pInfo) {
+		kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T));
+
+		prAdapter->prP2pInfo = NULL;
+	}
+	return FALSE;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS
+*                                          P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO
+*
+* \param[in] prGlueInfo      Pointer to glue info
+*
+* \return   TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo)
+{
+
+	if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	/* free memory after p2p module is ALREADY unregistered */
+	if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
+
+		kalMemFree(prGlueInfo->prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T));
+		kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T));
+		kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings, VIR_MEM_TYPE,
+			   sizeof(P2P_CONNECTION_SETTINGS_T));
+		kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T));
+		kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo, VIR_MEM_TYPE,
+			   sizeof(P2P_SPECIFIC_BSS_INFO_T));
+
+		/*Reomve p2p bss scan list */
+		scanRemoveAllP2pBssDesc(prGlueInfo->prAdapter);
+
+		/*reset all pointer to NULL */
+		prGlueInfo->prP2PInfo = NULL;
+		prGlueInfo->prAdapter->prP2pInfo = NULL;
+		prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings = NULL;
+		prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo = NULL;
+		prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo = NULL;
+
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+
+}
+
+#if !CFG_SUPPORT_PERSIST_NETDEV
+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired)
+{
+	BOOLEAN fgDoRegister = FALSE;
+/* BOOLEAN fgRollbackRtnlLock = FALSE; */
+	BOOLEAN ret;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+	if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) {
+		prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERING;
+		fgDoRegister = TRUE;
+	}
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+
+	if (!fgDoRegister)
+		return TRUE;
+
+	/* net device initialize */
+	netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler);
+	netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
+
+	/* register for net device */
+	if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) {
+		DBGLOG(P2P, WARN, "unable to register netdevice for p2p\n");
+
+		free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
+
+		ret = FALSE;
+	} else {
+		prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERED;
+		ret = TRUE;
+	}
+	return ret;
+}
+
+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired)
+{
+	BOOLEAN fgDoUnregister = FALSE;
+/* BOOLEAN fgRollbackRtnlLock = FALSE; */
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+	if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) {
+		prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING;
+		fgDoUnregister = TRUE;
+	}
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+
+	if (!fgDoUnregister)
+		return TRUE;
+
+	/* prepare for removal */
+	if (netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler))
+		netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler);
+
+	netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
+	DBGLOG(P2P, INFO, "P2P unregister_netdev 0x%p\n", prGlueInfo->prP2PInfo->prDevHandler);
+	unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler);
+
+	prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED;
+
+	return TRUE;
+}
+#endif
+
+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo)
+{
+	struct wiphy *prWiphy = NULL;
+	struct wireless_dev *prWdev = NULL;
+#if CFG_SUPPORT_PERSIST_NETDEV
+	struct net_device *prNetDev = NULL;
+#endif
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+	prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+	if (!prWdev) {
+		DBGLOG(P2P, ERROR, "allocate p2p wireless device fail, no memory\n");
+		return FALSE;
+	}
+	/* 1. allocate WIPHY */
+	prWiphy = wiphy_new(&mtk_p2p_ops, sizeof(P_GLUE_INFO_T));
+	if (!prWiphy) {
+		DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n");
+		goto free_wdev;
+	}
+
+	prWiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) |
+						BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_STATION);
+
+	prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz;
+	prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz;
+
+	prWiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes;
+	prWiphy->max_remain_on_channel_duration = 5000;
+	prWiphy->cipher_suites = mtk_cipher_suites;
+	prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites);
+	prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_HAVE_AP_SME;
+	prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG;
+	prWiphy->ap_sme_capa = 1;
+
+	prWiphy->max_scan_ssids = MAX_SCAN_LIST_NUM;
+	prWiphy->max_scan_ie_len = MAX_SCAN_IE_LEN;
+	prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+	prWiphy->vendor_commands = mtk_p2p_vendor_ops;
+	prWiphy->n_vendor_commands = sizeof(mtk_p2p_vendor_ops) / sizeof(struct wiphy_vendor_command);
+
+#ifdef CONFIG_PM
+	prWiphy->wowlan = &p2p_wowlan_support;
+#endif
+
+	/* 2.1 set priv as pointer to glue structure */
+	*((P_GLUE_INFO_T *) wiphy_priv(prWiphy)) = prGlueInfo;
+	 if (wiphy_register(prWiphy) < 0) {
+		DBGLOG(P2P, ERROR, "fail to register wiphy for p2p\n");
+		goto free_wiphy;
+	 }
+	prWdev->wiphy = prWiphy;
+#if CFG_SUPPORT_PERSIST_NETDEV
+	/* 3. allocate netdev */
+	prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), P2P_MODE_INF_NAME, NET_NAME_PREDICTABLE,
+								ether_setup, CFG_MAX_TXQ_NUM);
+	if (!prNetDev) {
+		DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n");
+		goto unregister_wiphy;
+	}
+
+	/* 4. setup netdev */
+	/* 4.1 Point to shared glue structure */
+	*((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = prGlueInfo;
+
+	/* 4.2 fill hardware address */
+	/* COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr);
+	rMacAddr[0] ^= 0x2; // change to local administrated address
+	memcpy(prGlueInfo->prP2PInfo->prDevHandler->dev_addr, rMacAddr, ETH_ALEN);
+	memcpy(prGlueInfo->prP2PInfo->prDevHandler->perm_addr,
+			prGlueInfo->prP2PInfo->prDevHandler->dev_addr, ETH_ALEN);*/
+
+	/* 4.3 register callback functions */
+	prNetDev->netdev_ops = &p2p_netdev_ops;
+	/* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def;*/
+
+	prNetDev->ieee80211_ptr = prWdev;
+	prWdev->netdev = prNetDev;
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	prNetDev->features = NETIF_F_IP_CSUM;
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+	/* net device initialize */
+	netif_carrier_off(prNetDev);
+	netif_tx_stop_all_queues(prNetDev);
+
+	/* register for net device */
+	if (register_netdev(prNetDev) < 0) {
+		DBGLOG(P2P, ERROR, "unable to register netdevice for p2p\n");
+		free_netdev(prNetDev);
+		goto unregister_wiphy;
+	}
+#endif
+	gprP2pWdev = prWdev;
+	return TRUE;
+
+#if CFG_SUPPORT_PERSIST_NETDEV
+unregister_wiphy:
+	wiphy_unregister(prWiphy);
+#endif
+free_wiphy:
+	wiphy_free(prWiphy);
+free_wdev:
+	kfree(prWdev);
+#endif
+	return FALSE;
+}
+
+void glP2pDestroyWirelessDevice(VOID)
+{
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+#if CFG_SUPPORT_PERSIST_NETDEV
+	unregister_netdev(gprP2pWdev->netdev);
+	free_netdev(gprP2pWdev->netdev);
+#endif
+	wiphy_unregister(gprP2pWdev->wiphy);
+	wiphy_free(gprP2pWdev->wiphy);
+	kfree(gprP2pWdev);
+	gprP2pWdev = NULL;
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Register for cfg80211 for Wi-Fi Direct
+*
+* \param[in] prGlueInfo      Pointer to glue info
+*
+* \return   TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GL_HIF_INFO_T prHif = NULL;
+	PARAM_MAC_ADDRESS rMacAddr;
+	struct net_device *prDevHandler = NULL;
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+	struct device *prDev;
+#endif
+
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	prHif = &prGlueInfo->rHifInfo;
+	ASSERT(prHif);
+
+	DBGLOG(P2P, TRACE, "glRegisterP2P\n");
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+	if (!gprP2pWdev) {
+		DBGLOG(P2P, ERROR, "gl_p2p, wireless device is not exist\n");
+		return FALSE;
+	}
+#endif
+	/*0. allocate p2pinfo */
+	if (!p2PAllocInfo(prGlueInfo)) {
+		DBGLOG(P2P, ERROR, "Allocate memory for p2p FAILED\n");
+		ASSERT(0);
+		return FALSE;
+	}
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+	prGlueInfo->prP2PInfo->prWdev = gprP2pWdev;
+	/* 1. fill wiphy parameters */
+#if MTK_WCN_HIF_SDIO
+	mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev);
+	if (!prDev)
+		DBGLOG(P2P, WARN, "unable to get struct dev for p2p\n");
+#else
+	prDev = prHif->Dev;
+#endif
+	/*set_wiphy_dev(gprP2pWdev->wiphy, prDev);*/
+	if (!prGlueInfo->prAdapter->fgEnable5GBand)
+		gprP2pWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
+
+	/* 2 set priv as pointer to glue structure */
+	*(P_GLUE_INFO_T *) wiphy_priv(gprP2pWdev->wiphy) = prGlueInfo;
+
+	if (fgIsApMode) {
+		gprP2pWdev->iftype = NL80211_IFTYPE_AP;
+#if CFG_SUPPORT_PERSIST_NETDEV
+		if (kalStrnCmp(gprP2pWdev->netdev->name, AP_MODE_INF_NAME, 2)) {
+			rtnl_lock();
+			dev_change_name(gprP2pWdev->netdev->name, AP_MODE_INF_NAME);
+			rtnl_unlock();
+		}
+#endif
+	} else {
+#if CFG_SUPPORT_PERSIST_NETDEV
+		if (kalStrnCmp(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME, 3)) {
+			rtnl_lock();
+			dev_change_name(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME);
+			rtnl_unlock();
+		}
+#endif
+		gprP2pWdev->iftype = NL80211_IFTYPE_P2P_CLIENT;
+	}
+#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */
+
+#if CFG_SUPPORT_PERSIST_NETDEV
+		prP2PInfo->prDevHandler = gprP2pWdev->netdev;
+#else /* CFG_SUPPORT_PERSIST_NETDEV */
+	/* 3. allocate netdev */
+	prDevHandler =
+	    alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM);
+	if (!prDevHandler) {
+		DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n");
+		return FALSE;
+	}
+	prGlueInfo->prP2PInfo->prDevHandler = prDevHandler;
+	/* 4. setup netdev */
+	/* 4.1 Point to shared glue structure */
+	*((P_GLUE_INFO_T *) netdev_priv(prDevHandler)) = prGlueInfo;
+
+	/* 4.2 fill hardware address */
+	COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr);
+	rMacAddr[0] ^= 0x2;	/* change to local administrated address */
+	ether_addr_copy(prDevHandler->dev_addr, rMacAddr);
+	ether_addr_copy(prDevHandler->perm_addr, prDevHandler->dev_addr);
+
+	/* 4.3 register callback functions */
+	prDevHandler->netdev_ops = &p2p_netdev_ops;
+	/* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def; */
+
+#if (MTK_WCN_HIF_SDIO == 0)
+	SET_NETDEV_DEV(prDevHandler, prHif->Dev);
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+	prDevHandler->ieee80211_ptr = gprP2pWdev;
+	gprP2pWdev->netdev = prDevHandler;
+#endif
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	prDevHandler->features = NETIF_F_IP_CSUM;
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+#endif /* CFG_SUPPORT_PERSIST_NETDEV */
+
+	/* 5. set p2p net device register state */
+	prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED;
+
+	/* 6. setup running mode */
+	prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode;
+
+	/* 7. finish */
+	p2pFsmInit(prAdapter);
+
+	p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings);
+
+	/* Active network too early would cause HW not able to sleep.
+	 * Defer the network active time.
+	 */
+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */
+
+	return TRUE;
+}				/* end of glRegisterP2P() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Unregister Net Device for Wi-Fi Direct
+*
+* \param[in] prGlueInfo      Pointer to glue info
+*
+* \return   TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+	/* normal flow: this func will called first before wlanRemove, and it can do fsmUninit/deactivateNetwork
+	gracefully. */
+	/* when reset: because tx_thread with fw has stopped, so it can't do these job and the recovery will be
+	dependent on chip system reset. */
+	/* if so, just skip it by flag GLUE_FLAG_HALT(warning: when tx_thread was stop, this flag was not cleared,
+	and NEED TO KEEP IT NOT CLEARED!). */
+	if (!(prGlueInfo->ulFlag & GLUE_FLAG_HALT)) {
+		p2pFsmUninit(prGlueInfo->prAdapter);
+		nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX);
+	}
+#if CFG_SUPPORT_PERSIST_NETDEV
+	dev_close(prGlueInfo->prP2PInfo->prDevHandler);
+#else
+	free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
+	prGlueInfo->prP2PInfo->prDevHandler = NULL;
+#endif
+	/* Free p2p memory */
+	if (!p2PFreeInfo(prGlueInfo)) {
+		DBGLOG(P2P, ERROR, "Free memory for p2p FAILED\n");
+		ASSERT(0);
+		return FALSE;
+	}
+	return TRUE;
+}				/* end of glUnregisterP2P() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief A function for stop p2p fsm immediate
+ *
+ * \param[in] prGlueInfo      Pointer to struct P_GLUE_INFO_T.
+ *
+ * \retval TRUE     The execution succeeds.
+ * \retval FALSE   The execution failed.
+ */
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo)
+{
+/* P_ADAPTER_T prAdapter = NULL; */
+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */
+
+	ASSERT(prGlueInfo);
+
+/* prAdapter = prGlueInfo->prAdapter; */
+/* ASSERT(prAdapter); */
+
+	/* 1. stop TX queue */
+	netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
+
+#if 0
+	/* 2. switch P2P-FSM off */
+	/* 2.1 allocate for message */
+	prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter,
+								 RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T));
+
+	if (!prFuncSwitch) {
+		ASSERT(0);	/* Can't trigger P2P FSM */
+		DBGLOG(P2P, ERROR, "Allocate for p2p mesasage FAILED\n");
+		/* return -ENOMEM; */
+	}
+
+	/* 2.2 fill message */
+	prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
+	prFuncSwitch->fgIsFuncOn = FALSE;
+
+	/* 2.3 send message */
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_UNBUF);
+
+#endif
+
+	/* 3. stop queue and turn off carrier */
+	prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED;
+
+	return TRUE;
+}				/* end of p2pStop() */
+
+/* Net Device Hooks */
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief A function for net_device open (ifup)
+ *
+ * \param[in] prDev      Pointer to struct net_device.
+ *
+ * \retval 0     The execution succeeds.
+ * \retval < 0   The execution failed.
+ */
+/*----------------------------------------------------------------------------*/
+static int p2pOpen(IN struct net_device *prDev)
+{
+/* P_GLUE_INFO_T prGlueInfo = NULL; */
+/* P_ADAPTER_T prAdapter = NULL; */
+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */
+
+	ASSERT(prDev);
+
+#if 0				/* Move after device name set. (mtk_p2p_set_local_dev_info) */
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* 1. switch P2P-FSM on */
+	/* 1.1 allocate for message */
+	prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter,
+								 RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T));
+
+	if (!prFuncSwitch) {
+		ASSERT(0);	/* Can't trigger P2P FSM */
+		return -ENOMEM;
+	}
+
+	/* 1.2 fill message */
+	prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
+	prFuncSwitch->fgIsFuncOn = TRUE;
+
+	/* 1.3 send message */
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF);
+#endif
+
+	/* 2. carrier on & start TX queue */
+	netif_carrier_on(prDev);
+	netif_tx_start_all_queues(prDev);
+
+	return 0;		/* success */
+}				/* end of p2pOpen() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief A function for net_device stop (ifdown)
+ *
+ * \param[in] prDev      Pointer to struct net_device.
+ *
+ * \retval 0     The execution succeeds.
+ * \retval < 0   The execution failed.
+ */
+/*----------------------------------------------------------------------------*/
+static int p2pStop(IN struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	/* P_ADAPTER_T prAdapter = NULL; */
+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+
+        struct cfg80211_scan_info info = {
+               .aborted = true,
+        };
+
+	struct cfg80211_scan_request *prScanRequest = NULL;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prGlueP2pInfo = prGlueInfo->prP2PInfo;
+	ASSERT(prGlueP2pInfo);
+
+	/* CFG80211 down */
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+	if (prGlueP2pInfo->prScanRequest != NULL) {
+		prScanRequest = prGlueP2pInfo->prScanRequest;
+		prGlueP2pInfo->prScanRequest = NULL;
+	}
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+
+	if (prScanRequest)
+		cfg80211_scan_done(prScanRequest, &info);
+#if 0
+
+	/* 1. stop TX queue */
+	netif_tx_stop_all_queues(prDev);
+
+	/* 2. switch P2P-FSM off */
+	/* 2.1 allocate for message */
+	prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter,
+								 RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T));
+
+	if (!prFuncSwitch) {
+		ASSERT(0);	/* Can't trigger P2P FSM */
+		return -ENOMEM;
+	}
+
+	/* 2.2 fill message */
+	prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
+	prFuncSwitch->fgIsFuncOn = FALSE;
+
+	/* 2.3 send message */
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF);
+#endif
+	/* 3. stop queue and turn off carrier */
+	prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED;
+
+	netif_tx_stop_all_queues(prDev);
+	if (netif_carrier_ok(prDev))
+		netif_carrier_off(prDev);
+
+	return 0;
+}				/* end of p2pStop() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief A method of struct net_device, to get the network interface statistical
+ *        information.
+ *
+ * Whenever an application needs to get statistics for the interface, this method
+ * is called. This happens, for example, when ifconfig or netstat -i is run.
+ *
+ * \param[in] prDev      Pointer to struct net_device.
+ *
+ * \return net_device_stats buffer pointer.
+ */
+/*----------------------------------------------------------------------------*/
+struct net_device_stats *p2pGetStats(IN struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+#if CFG_SUPPORT_PERSIST_NETDEV
+	/* @FIXME */
+	/* prDev->stats.rx_packets = 0; */
+	/* prDev->stats.tx_packets = 0; */
+	prDev->stats.tx_errors = 0;
+	prDev->stats.rx_errors = 0;
+	/* prDev->stats.rx_bytes = 0; */
+	/* prDev->stats.tx_bytes = 0; */
+	prDev->stats.multicast = 0;
+
+	return &prDev->stats;
+
+#else
+	/* prGlueInfo->prP2PInfo->rNetDevStats.rx_packets = 0; */
+	/* prGlueInfo->prP2PInfo->rNetDevStats.tx_packets = 0; */
+	prGlueInfo->prP2PInfo->rNetDevStats.tx_errors = 0;
+	prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0;
+	/* prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes   = 0; */
+	/* prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes   = 0; */
+	/* prGlueInfo->prP2PInfo->rNetDevStats.rx_errors  = 0; */
+	prGlueInfo->prP2PInfo->rNetDevStats.multicast = 0;
+
+	return &prGlueInfo->prP2PInfo->rNetDevStats;
+#endif
+}				/* end of p2pGetStats() */
+
+static void p2pSetMulticastList(IN struct net_device *prDev)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+
+	prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
+
+	ASSERT(prDev);
+	ASSERT(prGlueInfo);
+	if (!prDev || !prGlueInfo) {
+		DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo);
+		return;
+	}
+
+	g_P2pPrDev = prDev;
+
+	/* 4  Mark HALT, notify main thread to finish current job */
+/* prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_MULTICAST; */
+	set_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag);
+
+	/* wake up main thread */
+	wake_up_interruptible(&prGlueInfo->waitq);
+
+}				/* p2pSetMulticastList */
+
+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
+ * another workqueue for sleeping. We don't want to block
+ * tx_thread, so we can't let tx_thread to do this */
+
+void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo)
+{
+	if (!prGlueInfo) {
+		DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n");
+		return;
+	}
+#if CFG_ENABLE_WIFI_DIRECT
+	if (prGlueInfo->prAdapter->fgIsP2PRegistered)
+		mtk_p2p_wext_set_Multicastlist(prGlueInfo);
+#endif
+}				/* end of p2pSetMulticastListWorkQueueWrapper() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief This function is to set multicast list and set rx mode.
+ *
+ * \param[in] prDev  Pointer to struct net_device
+ *
+ * \return (none)
+ */
+/*----------------------------------------------------------------------------*/
+void mtk_p2p_wext_set_Multicastlist(P_GLUE_INFO_T prGlueInfo)
+{
+	UINT_32 u4SetInfoLen = 0;
+	struct net_device *prDev = g_P2pPrDev;
+
+	prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
+
+	ASSERT(prDev);
+	ASSERT(prGlueInfo);
+	if (!prDev || !prGlueInfo) {
+		DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo);
+		return;
+	}
+
+	if (prDev->flags & IFF_PROMISC)
+		prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
+
+	if (prDev->flags & IFF_BROADCAST)
+		prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
+
+	if (prDev->flags & IFF_MULTICAST) {
+		if ((prDev->flags & IFF_ALLMULTI) ||
+		    (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
+			prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
+		} else {
+			prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
+		}
+	}
+
+	if (prGlueInfo->prP2PInfo->u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
+		/* Prepare multicast address list */
+		struct netdev_hw_addr *ha;
+		UINT_32 i = 0;
+
+		netdev_for_each_mc_addr(ha, prDev) {
+			if (i < MAX_NUM_GROUP_ADDR) {
+				COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr);
+				i++;
+			}
+		}
+
+		DBGLOG(P2P, TRACE, "SEt Multicast Address List\n");
+
+		if (i >= MAX_NUM_GROUP_ADDR)
+			return;
+		wlanoidSetP2PMulticastList(prGlueInfo->prAdapter,
+					   &(prGlueInfo->prP2PInfo->aucMCAddrList[0]), (i * ETH_ALEN), &u4SetInfoLen);
+
+	}
+
+}				/* end of mtk_p2p_wext_set_Multicastlist */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * * \brief This function is TX entry point of NET DEVICE.
+ * *
+ * * \param[in] prSkb  Pointer of the sk_buff to be sent
+ * * \param[in] prDev  Pointer to struct net_device
+ * *
+ * * \retval NETDEV_TX_OK - on success.
+ * * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
+ * */
+/*----------------------------------------------------------------------------*/
+int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev)
+{
+	P_QUE_ENTRY_T prQueueEntry = NULL;
+	P_QUE_T prTxQueue = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_16 u2QueueIdx = 0;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(prSkb);
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	prGlueInfo->u8SkbToDriver++;
+
+	if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
+		DBGLOG(P2P, ERROR, "GLUE_FLAG_HALT skip tx\n");
+		prGlueInfo->u8SkbFreed++;
+		dev_kfree_skb(prSkb);
+		return NETDEV_TX_OK;
+	}
+#if (CFG_SUPPORT_MET_PROFILING == 1)
+	kalMetProfilingStart(prGlueInfo, prSkb);
+#endif
+
+	/* mark as P2P packets */
+	GLUE_SET_PKT_FLAG_P2P(prSkb);
+#if CFG_ENABLE_PKT_LIFETIME_PROFILE
+	GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick());
+#endif
+
+	STATS_TX_TIME_ARRIVE(prSkb);
+	prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
+	prTxQueue = &prGlueInfo->rTxQueue;
+
+	if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
+
+		u2QueueIdx = skb_get_queue_mapping(prSkb);
+		ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
+
+		if (u2QueueIdx >= CFG_MAX_TXQ_NUM) {
+			DBGLOG(P2P, ERROR, "Incorrect queue index, skip this frame\n");
+			prGlueInfo->u8SkbFreed++;
+			dev_kfree_skb(prSkb);
+			return NETDEV_TX_OK;
+		}
+		GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+		QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
+		GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
+
+		GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
+		GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]);
+
+		if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx] >=
+		    CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
+			DBGLOG(TX, INFO, "netif_stop_subqueue for p2p0, Queue len: %d\n",
+				prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]);
+			netif_stop_subqueue(prDev, u2QueueIdx);
+		}
+	} else {
+		GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
+	}
+
+	kalSetEvent(prGlueInfo);
+
+	/* Statistic usage. */
+	prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes += prSkb->len;
+	prGlueInfo->prP2PInfo->rNetDevStats.tx_packets++;
+	/* prDev->stats.tx_packets++; */
+	kalPerMonStart(prGlueInfo);
+	return NETDEV_TX_OK;
+}				/* end of p2pHardStartXmit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief A method of struct net_device, a primary SOCKET interface to configure
+ *        the interface lively. Handle an ioctl call on one of our devices.
+ *        Everything Linux ioctl specific is done here. Then we pass the contents
+ *        of the ifr->data to the request message handler.
+ *
+ * \param[in] prDev      Linux kernel netdevice
+ *
+ * \param[in] prIfReq    Our private ioctl request structure, typed for the generic
+ *                       struct ifreq so we can use ptr to function
+ *
+ * \param[in] cmd        Command ID
+ *
+ * \retval 0  The IOCTL command is executed successfully.
+ * \retval <0 The execution of IOCTL command is failed.
+ */
+/*----------------------------------------------------------------------------*/
+int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	int ret = 0;
+	char *prExtraBuf = NULL;
+	UINT_32 u4ExtraSize = 0;
+	struct iwreq *prIwReq = (struct iwreq *)prIfReq;
+	struct iw_request_info rIwReqInfo;
+
+	ASSERT(prDev && prIfReq);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	if (!prGlueInfo) {
+		DBGLOG(P2P, ERROR, "prGlueInfo is NULL\n");
+		return -EFAULT;
+	}
+
+	if (prGlueInfo->u4ReadyFlag == 0) {
+		DBGLOG(P2P, ERROR, "Adapter is not ready\n");
+		return -EINVAL;
+	}
+
+	rIwReqInfo.cmd = (__u16) i4Cmd;
+	rIwReqInfo.flags = 0;
+
+	switch (i4Cmd) {
+	case SIOCSIWENCODEEXT:
+		/* Set Encryption Material after 4-way handshaking is done */
+		if (prIwReq->u.encoding.pointer) {
+			u4ExtraSize = prIwReq->u.encoding.length;
+			prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
+
+			if (!prExtraBuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(prExtraBuf, prIwReq->u.encoding.pointer, prIwReq->u.encoding.length))
+				ret = -EFAULT;
+		} else if (prIwReq->u.encoding.length != 0) {
+			ret = -EINVAL;
+			break;
+		}
+
+		if (ret == 0)
+			ret = mtk_p2p_wext_set_key(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf);
+
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
+		prExtraBuf = NULL;
+		break;
+
+	case SIOCSIWMLME:
+		/* IW_MLME_DISASSOC used for disconnection */
+		if (prIwReq->u.data.length != sizeof(struct iw_mlme)) {
+			DBGLOG(P2P, WARN, "MLME buffer strange:%d\n", prIwReq->u.data.length);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!prIwReq->u.data.pointer) {
+			ret = -EINVAL;
+			break;
+		}
+
+		prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE);
+		if (!prExtraBuf) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(prExtraBuf, prIwReq->u.data.pointer, sizeof(struct iw_mlme)))
+			ret = -EFAULT;
+		else
+			ret = mtk_p2p_wext_mlme_handler(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf);
+
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme));
+		prExtraBuf = NULL;
+		break;
+
+	case SIOCGIWPRIV:
+		/* This ioctl is used to list all IW privilege ioctls */
+		ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
+		break;
+
+	case SIOCGIWSCAN:
+		ret = mtk_p2p_wext_discovery_results(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
+		break;
+
+	case SIOCSIWAUTH:
+		ret = mtk_p2p_wext_set_auth(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
+		break;
+
+	case IOC_P2P_CFG_DEVICE:
+	case IOC_P2P_PROVISION_COMPLETE:
+	case IOC_P2P_START_STOP_DISCOVERY:
+	case IOC_P2P_DISCOVERY_RESULTS:
+	case IOC_P2P_WSC_BEACON_PROBE_RSP_IE:
+	case IOC_P2P_CONNECT_DISCONNECT:
+	case IOC_P2P_PASSWORD_READY:
+	case IOC_P2P_GET_STRUCT:
+	case IOC_P2P_SET_STRUCT:
+	case IOC_P2P_GET_REQ_DEVICE_INFO:
+		ret =
+		    rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV] (prDev, &rIwReqInfo, &(prIwReq->u),
+								(char *)&(prIwReq->u));
+		break;
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+	case SIOCGIWSTATS:
+		ret = mtk_p2p_wext_get_rssi(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
+		break;
+#endif
+	case IOC_GET_PRIVATE_IOCTL_CMD:
+		ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd);
+
+		break;
+	default:
+		ret = -ENOTTY;
+	}
+
+	return ret;
+}				/* end of p2pDoIOCTL() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief To report the iw private args table to user space.
+ *
+ * \param[in] prDev Net device requested.
+ * \param[in] info Pointer to iw_request_info.
+ * \param[inout] wrqu Pointer to iwreq_data.
+ * \param[inout] extra
+ *
+ * \retval 0  For success.
+ * \retval -E2BIG For user's buffer size is too small.
+ * \retval -EFAULT For fail.
+ *
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_get_priv(IN struct net_device *prDev,
+		      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	struct iw_point *prData = (struct iw_point *)&wrqu->data;
+	UINT_16 u2BufferSize = prData->length;
+
+	/* Update our private args table size */
+	prData->length = (__u16)sizeof(rP2PIwPrivTable);
+	if (u2BufferSize < prData->length)
+		return -E2BIG;
+
+	if (prData->length) {
+		if (copy_to_user(prData->pointer, rP2PIwPrivTable, sizeof(rP2PIwPrivTable)))
+			return -EFAULT;
+	}
+
+	return 0;
+}				/* end of mtk_p2p_wext_get_priv() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief To indicate P2P-FSM for re-associate to the connecting device
+ *
+ * \param[in] prDev      Net device requested.
+ * \param[inout] wrqu    Pointer to iwreq_data
+ *
+ * \retval 0 For success.
+ * \retval -EFAULT For fail.
+ *
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_reconnect(IN struct net_device *prDev,
+		       IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+#if 0
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_MSG_HDR_T prMsgHdr;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T));
+	if (!prMsgHdr) {
+		ASSERT(0);	/* Can't trigger P2P FSM */
+		return -ENOMEM;
+	}
+
+	/* 1.2 fill message */
+
+	DBGLOG(P2P, TRACE, "mtk_p2p_wext_reconnect: P2P Reconnect\n");
+
+	/* 1.3 send message */
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF);
+#endif
+	return 0;
+}				/* end of mtk_p2p_wext_reconnect() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief MLME command handler
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev,
+			  IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+#if 0
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct iw_mlme *mlme = (struct iw_mlme *)extra;
+	P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt = (P_MSG_P2P_CONNECTION_ABORT_T) NULL;
+	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
+
+	DBGLOG(P2P, TRACE, "mtk_p2p_wext_mlme_handler:\n");
+
+	switch (mlme->cmd) {
+	case IW_MLME_DISASSOC:
+		prMsgP2PConnAbt =
+		    (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T));
+		if (!prMsgP2PConnAbt) {
+			ASSERT(0);	/* Can't trigger P2P FSM */
+			return -ENOMEM;
+		}
+
+		COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, mlme->addr.sa_data);
+
+		prMsgP2PConnAbt->u2ReasonCode = mlme->reason_code;
+
+		if (EQUAL_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prP2pBssInfo->aucOwnMacAddr)) {
+			DBGLOG(P2P, TRACE, "P2P Connection Abort:\n");
+
+			/* 1.2 fill message */
+			prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT;
+		} else {
+			DBGLOG(P2P, TRACE, "P2P Connection Pause:\n");
+
+			/* 1.2 fill message */
+		}
+
+		/* 1.3 send message */
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF);
+
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+#endif
+	return 0;
+}				/* end of mtk_p2p_wext_mlme_handler() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_PROVISION_COMPLETE)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev,
+				    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+#if 0
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct iw_point *prData = (struct iw_point *)&wrqu->data;
+	P_MSG_HDR_T prMsgHdr;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	switch (prData->flags) {
+	case P2P_PROVISIONING_SUCCESS:
+		prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T));
+		if (!prMsgHdr) {
+			ASSERT(0);	/* Can't trigger P2P FSM */
+			return -ENOMEM;
+		}
+
+		/* 1.2 fill message */
+
+		prGlueInfo->prP2PInfo->u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
+
+		/* 1.3 send message */
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF);
+
+		break;
+
+	case P2P_PROVISIONING_FAIL:
+
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+#endif
+
+	return 0;
+}				/* end of mtk_p2p_wext_set_provision_complete() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_START_STOP_DISCOVERY)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev,
+				  IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+#if 0
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct iw_point *prData = (struct iw_point *)&wrqu->data;
+	P_IW_P2P_REQ_DEVICE_TYPE prReqDeviceType = (P_IW_P2P_REQ_DEVICE_TYPE) extra;
+	UINT_8 au4IeBuf[MAX_IE_LENGTH];
+	P_MSG_HDR_T prMsgHdr;
+	P_MSG_P2P_DEVICE_DISCOVER_T prDiscoverMsg;
+	P_P2P_CONNECTION_SETTINGS_T prConnSettings;
+	UINT_8 aucNullAddr[] = NULL_MAC_ADDR;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	prConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+	if (prData->flags == P2P_STOP_DISCOVERY) {
+		prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T));
+
+		if (!prMsgHdr) {
+			ASSERT(0);	/* Can't trigger P2P FSM */
+			return -ENOMEM;
+		}
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF);
+	} else if (prData->flags == P2P_START_DISCOVERY) {
+
+		/* retrieve IE for Probe Response */
+		if (prReqDeviceType->probe_rsp_len > 0) {
+			if (prReqDeviceType->probe_rsp_len <= MAX_IE_LENGTH) {
+				if (copy_from_user
+				    (prGlueInfo->prP2PInfo->aucWSCIE[2], prReqDeviceType->probe_rsp_ie,
+				     prReqDeviceType->probe_rsp_len)) {
+					return -EFAULT;
+				}
+				prGlueInfo->prP2PInfo->u2WSCIELen[2] = prReqDeviceType->probe_rsp_len;
+			} else {
+				return -E2BIG;
+			}
+		}
+
+		/* retrieve IE for Probe Request */
+		if (prReqDeviceType->probe_req_len > 0) {
+			if (prReqDeviceType->probe_req_len <= MAX_IE_LENGTH) {
+				if (copy_from_user
+				    (prGlueInfo->prP2PInfo->aucWSCIE[1], prReqDeviceType->probe_req_ie,
+				     prReqDeviceType->probe_req_len)) {
+					return -EFAULT;
+				}
+				prGlueInfo->prP2PInfo->u2WSCIELen[1] = prReqDeviceType->probe_req_len;
+			} else {
+				return -E2BIG;
+			}
+		}
+		/* update IE for Probe Request */
+
+		if (prReqDeviceType->scan_type == P2P_LISTEN) {
+			/* update listening parameter */
+
+			/* @TODO: update prConnSettings for Probe Response IE */
+		} else {
+			/* indicate P2P-FSM with MID_MNY_P2P_DEVICE_DISCOVERY */
+			prDiscoverMsg = (P_MSG_P2P_DEVICE_DISCOVER_T) cnmMemAlloc(prAdapter,
+										  RAM_TYPE_MSG,
+										  sizeof(MSG_P2P_DEVICE_DISCOVER_T));
+
+			if (!prDiscoverMsg) {
+				ASSERT(0);	/* Can't trigger P2P FSM */
+				return -ENOMEM;
+			}
+
+			prDiscoverMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY;
+			prDiscoverMsg->u4DevDiscoverTime = 0;	/* unlimited */
+			prDiscoverMsg->fgIsSpecificType = TRUE;
+			prDiscoverMsg->rTargetDeviceType.u2CategoryID =
+			    *(PUINT_16) (&(prReqDeviceType->pri_device_type[0]));
+			prDiscoverMsg->rTargetDeviceType.u2SubCategoryID =
+			    *(PUINT_16) (&(prReqDeviceType->pri_device_type[6]));
+			COPY_MAC_ADDR(prDiscoverMsg->aucTargetDeviceID, aucNullAddr);
+
+			/* @FIXME: parameter to be refined, where to pass IE buffer ? */
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDiscoverMsg, MSG_SEND_METHOD_BUF);
+		}
+	} else {
+		return -EINVAL;
+	}
+#endif
+
+	return 0;
+}				/* end of mtk_p2p_wext_start_stop_discovery() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Setting parameters not support.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_invitation_request(IN struct net_device *prDev,
+				IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	int i4Status = 0;
+#if 0
+	P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	struct iw_point *prData = (struct iw_point *)&wrqu->data;
+	P_IW_P2P_IOCTL_INVITATION_STRUCT prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) NULL;
+
+	do {
+		if ((prDev == NULL) || (extra == NULL)) {
+			ASSERT(FALSE);
+			i4Status = -EINVAL;
+			break;
+		}
+
+		prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+		prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) extra;
+
+		if (prGlueInfo == NULL) {
+			i4Status = -EINVAL;
+			break;
+		}
+
+		prAdapter = prGlueInfo->prAdapter;
+
+		if (prAdapter == NULL) {
+			i4Status = -EINVAL;
+			break;
+		}
+
+		if (prIoctlInvitation->ucReinvoke == 1) {
+			/* TODO: Set Group ID */
+			p2pFuncSetGroupID(prAdapter, prIoctlInvitation->aucGroupID, prIoctlInvitation->aucSsid,
+					  prIoctlInvitation->u4SsidLen);
+		}
+
+		else {
+			P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T) NULL;
+
+			/* TODO: Do Invitation. */
+			prMsgP2PInvitationReq =
+			    (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG,
+									 sizeof(MSG_P2P_INVITATION_REQUEST_T));
+			if (!prMsgP2PInvitationReq) {
+				ASSERT(0);	/* Can't trigger P2P FSM */
+				i4Status = -ENOMEM;
+				break;
+			}
+
+			/* 1.2 fill message */
+			kalMemCopy(prMsgP2PInvitationReq->aucDeviceID, prIoctlInvitation->aucDeviceID, MAC_ADDR_LEN);
+
+			DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n");
+
+			/* 1.3 send message */
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationReq, MSG_SEND_METHOD_BUF);
+
+		}
+
+	} while (FALSE);
+#endif
+
+	return i4Status;
+
+}
+
+/* mtk_p2p_wext_invitation_request */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Setting parameters not support.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_invitation_abort(IN struct net_device *prDev,
+			      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	int i4Status = 0;
+#if 0
+	P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	struct iw_point *prData = (struct iw_point *)&wrqu->data;
+	P_IW_P2P_IOCTL_ABORT_INVITATION prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) NULL;
+
+	UINT_8 bssid[MAC_ADDR_LEN];
+
+	do {
+		if ((prDev == NULL) || (extra == NULL)) {
+			ASSERT(FALSE);
+			i4Status = -EINVAL;
+			break;
+		}
+
+		prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+		prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) extra;
+
+		if (prGlueInfo == NULL) {
+			i4Status = -EINVAL;
+			break;
+		}
+
+		prAdapter = prGlueInfo->prAdapter;
+
+		if (prAdapter == NULL) {
+			i4Status = -EINVAL;
+			break;
+		}
+		P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T) NULL;
+
+		prMsgP2PInvitationAbort =
+		    (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG,
+								 sizeof(MSG_P2P_INVITATION_REQUEST_T));
+
+		if (!prMsgP2PInvitationAbort) {
+			ASSERT(0);	/* Can't trigger P2P FSM */
+			i4Status = -ENOMEM;
+			break;
+		}
+
+		/* 1.2 fill message */
+		kalMemCopy(prMsgP2PInvitationAbort->aucDeviceID, prIoctlInvitationAbort->dev_addr,
+			   MAC_ADDR_LEN);
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n");
+
+		/* 1.3 send message */
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationAbort, MSG_SEND_METHOD_BUF);
+
+
+	} while (FALSE);
+#endif
+
+	return i4Status;
+
+}
+
+/* mtk_p2p_wext_invitation_abort */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief To override p2p interface address
+ *
+ * \param[in] prDev Net device requested.
+ * \param[in] addr  Pointer to address
+ *
+ * \retval 0 For success.
+ * \retval -E2BIG For user's buffer size is too small.
+ * \retval -EFAULT For fail.
+ *
+ */
+/*----------------------------------------------------------------------------*/
+int p2pSetMACAddress(IN struct net_device *prDev, void *addr)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* @FIXME */
+	return eth_mac_addr(prDev, addr);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set encryption cipher suite
+*
+* \param[in] prDev Net device requested.
+* \param[out]
+*
+* \retval 0 Success.
+* \retval -EINVAL Invalid parameter
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_auth(IN struct net_device *prDev,
+		      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct iw_param *prAuth = (struct iw_param *)wrqu;
+
+	ASSERT(prDev);
+	ASSERT(prAuth);
+	if (FALSE == GLUE_CHK_PR2(prDev, prAuth))
+		return -EINVAL;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+	/* Save information to glue info and process later when ssid is set. */
+	switch (prAuth->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+		break;
+	case IW_AUTH_CIPHER_PAIRWISE:
+		prGlueInfo->prP2PInfo->u4CipherPairwise = prAuth->value;
+		break;
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_KEY_MGMT:
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+	case IW_AUTH_DROP_UNENCRYPTED:
+	case IW_AUTH_80211_AUTH_ALG:
+	case IW_AUTH_WPA_ENABLED:
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+	case IW_AUTH_ROAMING_CONTROL:
+	case IW_AUTH_PRIVACY_INVOKED:
+	default:
+		/* @TODO */
+		break;
+	}
+
+	return 0;
+}				/* end of mtk_p2p_wext_set_auth() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set encryption cipher and key.
+*
+* \param[in] prDev Net device requested.
+* \param[out] prIfReq Pointer to ifreq structure, content is copied back to
+*                  user space buffer in gl_iwpriv_table.
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note Securiry information is stored in pEnc.
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_key(IN struct net_device *prDev,
+		     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	int ret = 0;
+	struct iw_encode_ext *prIWEncExt;
+	struct iw_point *prEnc;
+	char *prExtraBuf = NULL;
+	UINT_32 u4ExtraSize = 0;
+	UINT_8 keyStructBuf[100];
+	P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf;
+	P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf;
+	P_GLUE_INFO_T prGlueInfo;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+	do {
+		if (wrqu->encoding.pointer) {
+			u4ExtraSize = wrqu->encoding.length;
+			/*need confirm u4ExtraSize > 0 but is not very large*/
+			prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
+
+			if (!prExtraBuf) {
+				ret = -ENOMEM;
+				break;
+			}
+			/* here should set prExtraBuf default value */
+			memset(prExtraBuf, 0, u4ExtraSize);
+			if (copy_from_user(prExtraBuf, wrqu->encoding.pointer, wrqu->encoding.length)) {
+				ret = -EFAULT;
+				break;
+			}
+		} else if (wrqu->encoding.length != 0) {
+			ret = -EINVAL;
+			break;
+		}
+
+		prEnc = &wrqu->encoding;
+		/* here, need confirm (struct iw_encode_ext) < u4ExtraSize */
+		prIWEncExt = (struct iw_encode_ext *)prExtraBuf;
+
+		if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) != TRUE) {
+			ret = -EINVAL;
+			break;
+		}
+
+		memset(keyStructBuf, 0, sizeof(keyStructBuf));
+
+		if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) {	/* Key Removal */
+			prRemoveKey->u4Length = sizeof(*prRemoveKey);
+			memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6);
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetRemoveP2PKey,
+					   prRemoveKey,
+					   prRemoveKey->u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS)
+				ret = -EFAULT;
+		} else {
+			if (prIWEncExt->alg == IW_ENCODE_ALG_CCMP) {
+				/* KeyID */
+				prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
+				    ((prEnc->flags & IW_ENCODE_INDEX) - 1) : 0;
+				if (prKey->u4KeyIndex <= 3) {
+					/* bit(31) and bit(30) are shared by pKey and pRemoveKey */
+					/* Tx Key Bit(31) */
+					if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+						prKey->u4KeyIndex |= 0x1UL << 31;
+
+					/* Pairwise Key Bit(30) */
+					if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+						/* group key */
+					} else {
+						/* pairwise key */
+						prKey->u4KeyIndex |= 0x1UL << 30;
+					}
+
+					/* Rx SC Bit(29) */
+					if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+						prKey->u4KeyIndex |= 0x1UL << 29;
+						memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq,
+						       IW_ENCODE_SEQ_MAX_SIZE);
+					}
+
+					/* BSSID */
+					memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6);
+					memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
+
+					prKey->u4KeyLength = prIWEncExt->key_len;
+					prKey->u4Length =
+					    ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) +
+					    prKey->u4KeyLength;
+
+					rStatus = kalIoctl(prGlueInfo,
+							   wlanoidSetAddP2PKey,
+							   prKey,
+							   prKey->u4Length,
+							   FALSE, FALSE, TRUE, TRUE, &u4BufLen);
+
+					if (rStatus != WLAN_STATUS_SUCCESS)
+						ret = -EFAULT;
+				} else {
+					ret = -EINVAL;
+				}
+			} else {
+				ret = -EINVAL;
+			}
+		}
+
+	} while (FALSE);
+
+	if (prExtraBuf) {
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
+		prExtraBuf = NULL;
+	}
+
+	return ret;
+}				/* end of mtk_p2p_wext_set_key() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief set the p2p gc power mode
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_powermode(IN struct net_device *prNetDev,
+			   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	/* printk("set_powermode = %d, value = %d\n", wrqu->power.disabled, wrqu->power.value); */
+	struct iw_param *prPower = (struct iw_param *)&wrqu->power;
+#if 1
+	PARAM_POWER_MODE ePowerMode;
+	INT_32 i4PowerValue;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prPower);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prPower))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */
+	/* prPower->value, prPower->disabled, prPower->flags); */
+
+	if (prPower->disabled) {
+		ePowerMode = Param_PowerModeCAM;
+	} else {
+		i4PowerValue = prPower->value;
+#if WIRELESS_EXT < 21
+		i4PowerValue /= 1000000;
+#endif
+		if (i4PowerValue == 0) {
+			ePowerMode = Param_PowerModeCAM;
+		} else if (i4PowerValue == 1) {
+			ePowerMode = Param_PowerModeMAX_PSP;
+		} else if (i4PowerValue == 2) {
+			ePowerMode = Param_PowerModeFast_PSP;
+		} else {
+			DBGLOG(P2P, ERROR, "%s(): unsupported power management mode value = %d.\n",
+			       __func__, prPower->value);
+
+			return -EINVAL;
+		}
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetP2pPowerSaveProfile,
+			   &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, TRUE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		/* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */
+		return -EFAULT;
+	}
+#endif
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief get the p2p gc power mode
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_get_powermode(IN struct net_device *prNetDev,
+			   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	/* printk("mtk_p2p_wext_get_powermode\n"); */
+	/* wrqu->power.disabled = 0; */
+	/* wrqu->power.value = 1; */
+
+	struct iw_param *prPower = (struct iw_param *)&wrqu->power;
+	PARAM_POWER_MODE ePowerMode = Param_PowerModeMax;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prPower);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prPower))
+		return -EINVAL;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+	ASSERT(prGlueInfo);
+
+#if 1
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryP2pPowerSaveProfile,
+			   &ePowerMode, sizeof(ePowerMode), TRUE, FALSE, FALSE, TRUE, &u4BufLen);
+#else
+	rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
+				       wlanoidQueryP2pPowerSaveProfile, &ePowerMode, sizeof(ePowerMode), &u4BufLen);
+#endif
+
+	prPower->value = 0;
+	prPower->disabled = 1;
+
+	if (Param_PowerModeCAM == ePowerMode) {
+		prPower->value = 0;
+		prPower->disabled = 1;
+	} else if (Param_PowerModeMAX_PSP == ePowerMode) {
+		prPower->value = 1;
+		prPower->disabled = 0;
+	} else if (Param_PowerModeFast_PSP == ePowerMode) {
+		prPower->value = 2;
+		prPower->disabled = 0;
+	}
+
+	prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE;
+#if WIRELESS_EXT < 21
+	prPower->value *= 1000000;
+#endif
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_CFG_DEVICE)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev,
+				IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_CFG_DEVICE_TYPE prDeviceCfg = (P_IW_P2P_CFG_DEVICE_TYPE) extra;
+	P_P2P_CONNECTION_SETTINGS_T prConnSettings;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL; */
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	prConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+	prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
+
+	/* update connection settings for P2P-FSM */
+	/* 1. update SSID */
+	if (prDeviceCfg->ssid_len > ELEM_MAX_LEN_SSID)
+		prConnSettings->ucSSIDLen = ELEM_MAX_LEN_SSID;
+	else
+		prConnSettings->ucSSIDLen = prDeviceCfg->ssid_len;
+
+	if (copy_from_user(prConnSettings->aucSSID, prDeviceCfg->ssid, prConnSettings->ucSSIDLen))
+		return -EFAULT;
+	/* 2. update device type (WPS IE) */
+	kalMemCopy(&(prConnSettings->rPrimaryDevTypeBE), &(prDeviceCfg->pri_device_type), sizeof(DEVICE_TYPE_T));
+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT
+	kalMemCopy(&(prConnSettings->arSecondaryDevTypeBE[0]), &(prDeviceCfg->snd_device_type), sizeof(DEVICE_TYPE_T));
+#endif
+
+	/* 3. update device name */
+	if (prDeviceCfg->device_name_len > WPS_ATTRI_MAX_LEN_DEVICE_NAME)
+		prConnSettings->ucDevNameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME;
+	else
+		prConnSettings->ucDevNameLen = prDeviceCfg->device_name_len;
+	if (copy_from_user(prConnSettings->aucDevName, prDeviceCfg->device_name, prConnSettings->ucDevNameLen))
+		return -EFAULT;
+	/* 4. update GO intent */
+	prConnSettings->ucGoIntent = prDeviceCfg->intend;
+
+	/* Preferred channel bandwidth */
+	prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M;
+	prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M;
+
+#if 0
+	/* 1. switch P2P-FSM on */
+	/* 1.1 allocate for message */
+	prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter,
+								 RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T));
+
+	if (!prFuncSwitch) {
+		ASSERT(0);	/* Can't trigger P2P FSM */
+		return -ENOMEM;
+	}
+
+	/* 1.2 fill message */
+	prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
+	prFuncSwitch->fgIsFuncOn = TRUE;
+
+	/* 1.3 send message */
+	mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF);
+#endif
+	return 0;
+}				/* end of mtk_p2p_wext_set_local_dev_info() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief I/O Control handler for both
+ *          IOC_P2P_START_STOP_DISCOVERY & SIOCGIWSCAN
+ *
+ * \param[in] prDev      Net device requested.
+ * \param[inout] wrqu    Pointer to iwreq_data
+ *
+ * \retval 0 Success.
+ * \retval -EFAULT Setting parameters to driver fail.
+ * \retval -EOPNOTSUPP Key size not supported.
+ *
+ * \note
+ */
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_discovery_results(IN struct net_device *prDev,
+			       IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	struct iw_event iwe;
+	char *current_ev = extra;
+	UINT_32 i;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_ADAPTER_T prAdapter = NULL;
+	P_P2P_INFO_T prP2PInfo = (P_P2P_INFO_T) NULL;
+	P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL;
+	P_PARAM_VARIABLE_IE_T prDesiredIE = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	prP2PInfo = prAdapter->prP2pInfo;
+
+	for (i = 0; i < prP2PInfo->u4DeviceNum; i++) {
+		prTargetResult = &prP2PInfo->arP2pDiscoverResult[i];
+
+		/* SIOCGIWAP */
+		iwe.cmd = SIOCGIWAP;
+		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+		memcpy(iwe.u.ap_addr.sa_data, prTargetResult->aucInterfaceAddr, 6);
+
+		current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
+
+		/* SIOCGIWESSID */
+		iwe.cmd = SIOCGIWESSID;
+		iwe.u.data.flags = 1;
+		iwe.u.data.length = prTargetResult->u2NameLength;
+
+		current_ev = iwe_stream_add_point(info, current_ev,
+						  extra + IW_SCAN_MAX_DATA, &iwe, prTargetResult->aucName);
+
+		/* IWEVGENIE for WPA IE */
+		if (prTargetResult->u2IELength <= 600 && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf,
+									      prTargetResult->u2IELength,
+									      0xDD, (PUINT_8 *) &prDesiredIE)) {
+
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.flags = 1;
+			iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength;
+
+			current_ev = iwe_stream_add_point(info, current_ev,
+							  extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE);
+		}
+#if CFG_SUPPORT_WPS
+
+		/* IWEVGENIE for WPS IE */
+		if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPSIE(prTargetResult->pucIeBuf,
+										prTargetResult->u2IELength,
+										0xDD, (PUINT_8 *) &prDesiredIE)) {
+
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.flags = 1;
+			iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength;
+
+			current_ev = iwe_stream_add_point(info, current_ev,
+							  extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE);
+		}
+#endif
+
+		/* IWEVGENIE for RSN IE */
+		if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf,
+										prTargetResult->u2IELength,
+										0x30, (PUINT_8 *) &prDesiredIE)) {
+
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.flags = 1;
+			iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength;
+
+			current_ev = iwe_stream_add_point(info, current_ev,
+							  extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE);
+		}
+
+		/* IOC_P2P_GO_WSC_IE */
+#if 1
+		/* device capability */
+		if (1) {
+			UINT_8 data[40];
+
+			iwe.cmd = IWEVCUSTOM;
+			iwe.u.data.flags = 0;
+			iwe.u.data.length = 9 + sizeof("p2p_cap=");
+			if (iwe.u.data.length > 40)
+				iwe.u.data.length = 40;
+
+			snprintf(data, iwe.u.data.length, "p2p_cap=%02x%02x%02x%02x%c",
+				 prTargetResult->ucDeviceCapabilityBitmap, prTargetResult->ucGroupCapabilityBitmap,
+				 (UINT_8) prTargetResult->u2ConfigMethod,
+				 (UINT_8) (prTargetResult->u2ConfigMethod >> 8), '\0');
+			current_ev =
+			    iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data);
+
+			/* printk("%s\n", data); */
+			kalMemZero(data, 40);
+
+			iwe.cmd = IWEVCUSTOM;
+			iwe.u.data.flags = 0;
+			iwe.u.data.length = 13 + sizeof("p2p_dev_type=");
+			if (iwe.u.data.length > 40)
+				iwe.u.data.length = 40;
+
+			snprintf(data, iwe.u.data.length, "p2p_dev_type=%02x%02x%02x%02x%02x%02x%c",
+				 (UINT_8) prTargetResult->rPriDevType.u2CategoryID,
+				 (UINT_8) prTargetResult->rPriDevType.u2SubCategoryID,
+				 (UINT_8) prTargetResult->arSecDevType[0].u2CategoryID,
+				 (UINT_8) prTargetResult->arSecDevType[0].u2SubCategoryID,
+				 (UINT_8) prTargetResult->arSecDevType[1].u2CategoryID,
+				 (UINT_8) prTargetResult->arSecDevType[1].u2SubCategoryID, '\0');
+			current_ev =
+			    iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data);
+			/* printk("%s\n", data); */
+
+			kalMemZero(data, 40);
+
+			iwe.cmd = IWEVCUSTOM;
+			iwe.u.data.flags = 0;
+			iwe.u.data.length = 17 + sizeof("p2p_grp_bssid=");
+			if (iwe.u.data.length > 40)
+				iwe.u.data.length = 40;
+
+			snprintf(data, iwe.u.data.length, "p2p_grp_bssid= %pM %c",
+				 prTargetResult->aucBSSID, '\0');
+			current_ev = iwe_stream_add_point(info, current_ev,
+							  extra + IW_SCAN_MAX_DATA, &iwe, (char *)data);
+			/* printk("%s\n", data); */
+
+		}
+#endif
+	}
+
+	/* Length of data */
+	wrqu->data.length = (current_ev - extra);
+	wrqu->data.flags = 0;
+
+	return 0;
+}				/* end of mtk_p2p_wext_discovery_results() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_WSC_BEACON_PROBE_RSP_IE)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev,
+		    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_HOSTAPD_PARAM prHostapdParam = (P_IW_P2P_HOSTAPD_PARAM) extra;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	if (prHostapdParam->len > 0) {
+		if (prHostapdParam->len <= MAX_WSC_IE_LENGTH) {
+			if (copy_from_user
+			    (prGlueInfo->prP2PInfo->aucWSCIE[0], prHostapdParam->data, prHostapdParam->len)) {
+				return -EFAULT;
+			}
+			if (copy_from_user
+			    (prGlueInfo->prP2PInfo->aucWSCIE[2], prHostapdParam->data, prHostapdParam->len)) {
+				return -EFAULT;
+			}
+		} else {
+			return -E2BIG;
+		}
+	}
+
+	prGlueInfo->prP2PInfo->u2WSCIELen[0] = prHostapdParam->len;
+	prGlueInfo->prP2PInfo->u2WSCIELen[2] = prHostapdParam->len;
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX);
+
+	/* @TODO: send message to P2P-FSM */
+
+	return 0;
+}				/* end of mtk_p2p_wext_wsc_ie() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_CONNECT_DISCONNECT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev,
+				IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct iw_point *prData = (struct iw_point *)&wrqu->data;
+/* P_IW_P2P_CONNECT_DEVICE prConnectDevice = (P_IW_P2P_CONNECT_DEVICE)extra; */
+/* P_MSG_HDR_T prMsgHdr; */
+/* P_MSG_P2P_CONNECTION_REQUEST_T prMsgP2PConnReq; */
+/* P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt; */
+/* UINT_8 aucBCAddr[] = BC_MAC_ADDR; */
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	if (prData->flags == P2P_CONNECT) {
+#if 0
+		/* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_REQ */
+		prMsgP2PConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter,
+									       RAM_TYPE_MSG,
+									       sizeof(MSG_P2P_CONNECTION_REQUEST_T));
+
+		if (!prMsgP2PConnReq) {
+			ASSERT(0);	/* Can't trigger P2P FSM */
+			return -ENOMEM;
+		}
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnReq, MSG_SEND_METHOD_BUF);
+#endif
+	} else if (prData->flags == P2P_DISCONNECT) {
+#if 0
+		/* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_ABORT */
+		prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter,
+							    RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T));
+
+		if (!prMsgP2PConnAbt) {
+			ASSERT(0);	/* Can't trigger P2P FSM */
+			return -ENOMEM;
+		}
+
+		COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prConnectDevice->sta_addr);
+
+		prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT;
+
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF);
+#endif
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}				/* end of mtk_p2p_wext_connect_disconnect() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_PASSWORD_READY)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_password_ready(IN struct net_device *prDev,
+			    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY) extra;
+	P_P2P_CONNECTION_SETTINGS_T prConnSettings;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	prConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
+
+	/* retrieve IE for Probe Request */
+	if (prPasswordReady->probe_req_len > 0) {
+		if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) {
+			if (copy_from_user
+			    (prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie,
+			     prPasswordReady->probe_req_len)) {
+				return -EFAULT;
+			}
+		} else {
+			return -E2BIG;
+		}
+	}
+
+	prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len;
+
+	/* retrieve IE for Probe Response */
+	if (prPasswordReady->probe_rsp_len > 0) {
+		if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) {
+			if (copy_from_user
+			    (prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie,
+			     prPasswordReady->probe_rsp_len)) {
+				return -EFAULT;
+			}
+		} else {
+			return -E2BIG;
+		}
+	}
+
+	prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len;
+
+	switch (prPasswordReady->active_config_method) {
+	case 1:
+		prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_PUSH_BUTTON;
+		break;
+	case 2:
+		prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_KEYPAD;
+		break;
+	case 3:
+		prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_DISPLAY;
+		break;
+	default:
+		break;
+	}
+
+	prConnSettings->fgIsPasswordIDRdy = TRUE;
+	return 0;
+}				/* end of mtk_p2p_wext_password_ready() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_GET_REQ_DEVICE_INFO)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev,
+			      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_DEVICE_REQ prDeviceReq = (P_IW_P2P_DEVICE_REQ) extra;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* specify data length */
+	wrqu->data.length = sizeof(IW_P2P_DEVICE_REQ);
+
+	/* copy to upper-layer supplied buffer */
+	kalMemCopy(prDeviceReq->name, prGlueInfo->prP2PInfo->aucConnReqDevName,
+		   prGlueInfo->prP2PInfo->u4ConnReqNameLength);
+	prDeviceReq->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength;
+	prDeviceReq->name[prDeviceReq->name_len] = '\0';
+	COPY_MAC_ADDR(prDeviceReq->device_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr);
+	prDeviceReq->device_type = prGlueInfo->prP2PInfo->ucConnReqDevType;
+	prDeviceReq->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod;
+	prDeviceReq->active_config_method = prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod;
+
+	return 0;
+}				/* end of mtk_p2p_wext_request_dev_info() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev,
+				 IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_IOCTL_INVITATION_INDICATE prInvIndicate = (P_IW_P2P_IOCTL_INVITATION_INDICATE) extra;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* specify data length */
+	wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_INDICATE);
+
+	/* copy to upper-layer supplied buffer */
+	kalMemCopy(prInvIndicate->dev_name, prGlueInfo->prP2PInfo->aucConnReqDevName,
+		   prGlueInfo->prP2PInfo->u4ConnReqNameLength);
+	kalMemCopy(prInvIndicate->group_bssid, prGlueInfo->prP2PInfo->rConnReqGroupAddr, MAC_ADDR_LEN);
+	prInvIndicate->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength;
+	prInvIndicate->dev_name[prInvIndicate->name_len] = '\0';
+	COPY_MAC_ADDR(prInvIndicate->dev_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr);
+	prInvIndicate->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod;
+	prInvIndicate->operating_channel = prGlueInfo->prP2PInfo->ucOperatingChnl;
+	prInvIndicate->invitation_type = prGlueInfo->prP2PInfo->ucInvitationType;
+
+	return 0;
+}				/* end of mtk_p2p_wext_invitation_indicate() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_invitation_status(IN struct net_device *prDev,
+			       IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_IOCTL_INVITATION_STATUS prInvStatus = (P_IW_P2P_IOCTL_INVITATION_STATUS) extra;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* specify data length */
+	wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_STATUS);
+
+	/* copy to upper-layer supplied buffer */
+	prInvStatus->status_code = prGlueInfo->prP2PInfo->u4InvStatus;
+
+	return 0;
+}				/* end of mtk_p2p_wext_invitation_status() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief indicate an event to supplicant for device found
+*
+* \param[in] prGlueInfo Pointer of GLUE_INFO_T
+*
+* \retval TRUE  Success.
+* \retval FALSE Failure
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	memset(&evt, 0, sizeof(evt));
+
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_FND");
+	evt.data.length = strlen(aucBuffer);
+
+	/* indicate IWEVP2PDVCFND event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+	return FALSE;
+}				/* end of kalP2PIndicateFound() */
+
+int
+mtk_p2p_wext_set_network_address(IN struct net_device *prDev,
+				 IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* @TODO: invoke wlan_p2p functions */
+#if 0
+	rStatus = kalIoctl(prGlueInfo,
+			   (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pNetworkAddress,
+			   prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen);
+#endif
+
+	return 0;
+
+}
+
+int
+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev,
+			    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* @TODO: invoke wlan_p2p functions */
+#if 0
+	rStatus = kalIoctl(prGlueInfo,
+			   (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile,
+			   prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen);
+#endif
+
+	return 0;
+
+}
+
+int
+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev,
+			  IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prAdapter = prGlueInfo->prAdapter;
+	ASSERT(prAdapter);
+
+	/* @TODO: invoke wlan_p2p functions */
+#if 0
+	rStatus = kalIoctl(prGlueInfo,
+			   (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile,
+			   prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen);
+#endif
+
+	return 0;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Setting parameters not support.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_start_formation(IN struct net_device *prDev,
+			     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	int i4Status = 0;
+	P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+/* struct iw_point *prData = (struct iw_point*)&wrqu->data; */
+	P_IW_P2P_IOCTL_START_FORMATION prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) NULL;
+
+	do {
+		if ((prDev == NULL) || (extra == NULL)) {
+			ASSERT(FALSE);
+			i4Status = -EINVAL;
+			break;
+		}
+
+		prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+		prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) extra;
+
+		if (prGlueInfo == NULL) {
+			i4Status = -EINVAL;
+			break;
+		}
+
+		prAdapter = prGlueInfo->prAdapter;
+
+		if (prAdapter == NULL) {
+			i4Status = -EINVAL;
+			break;
+		}
+
+	} while (FALSE);
+
+	return i4Status;
+
+}
+
+/* mtk_p2p_wext_start_formation */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Setting parameters not support.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_int(IN struct net_device *prDev,
+		     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	int status = 0;
+	UINT_32 u4SubCmd = 0;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_32 index;
+	INT_32 value;
+	PUINT_32 pu4IntBuf;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;
+	UINT_32 u4Leng;
+
+	ASSERT(prDev);
+	ASSERT(wrqu);
+
+	/* printk("mtk_p2p_wext_set_int\n"); */
+	pu4IntBuf = (PUINT_32) extra;
+
+	if (FALSE == GLUE_CHK_PR2(prDev, wrqu))
+		return -EINVAL;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo;
+	prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings;
+	prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo;
+
+	u4SubCmd = (UINT_32) wrqu->mode;
+	index = pu4IntBuf[1];
+	value = pu4IntBuf[2];
+
+	DBGLOG(P2P, INFO, "set parameter, u4SubCmd=%d idx=%d value=%d\n", (INT_16) u4SubCmd, (INT_16) index, value);
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_INT_P2P_SET:
+		switch (index) {
+		case 0:	/* Listen CH */
+			{
+				UINT_8 ucSuggestChnl = 0;
+
+				prP2pConnSettings->ucListenChnl = value;
+
+				/* 20110920 - frog: User configurations are placed in ConnSettings. */
+				if (rlmFuncFindAvailableChannel
+				    (prGlueInfo->prAdapter, value, &ucSuggestChnl, TRUE, TRUE)) {
+					prP2pSpecificBssInfo->ucListenChannel = value;
+				} else {
+					prP2pSpecificBssInfo->ucListenChannel = ucSuggestChnl;
+				}
+
+				break;
+			}
+		case 1:	/* P2p mode */
+			break;
+		case 4:	/* Noa duration */
+			prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value;
+			/* only to apply setting when setting NOA count */
+			/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu,
+			(char *)&prP2pSpecificBssInfo->rNoaParam); */
+			break;
+		case 5:	/* Noa interval */
+			prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value;
+			/* only to apply setting when setting NOA count */
+			/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu,
+			(char *)&prP2pSpecificBssInfo->rNoaParam); */
+			break;
+		case 6:	/* Noa count */
+			prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value;
+			status =
+			    mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam);
+			break;
+		case 100:	/* Oper CH */
+			/* 20110920 - frog: User configurations are placed in ConnSettings. */
+			prP2pConnSettings->ucOperatingChnl = value;
+			break;
+		case 101:	/* Local config Method, for P2P SDK */
+			/* prP2pConnSettings->u2LocalConfigMethod; */
+			break;
+		case 102:	/* Sigma P2p reset */
+			kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN);
+			/* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */
+			break;
+		case 103:	/* WPS MODE */
+			kalP2PSetWscMode(prGlueInfo, value);
+			break;
+		case 104:	/* P2p send persence, duration */
+			break;
+		case 105:	/* P2p send persence, interval */
+			break;
+		case 106:	/* P2P set sleep  */
+			value = 1;
+			kalIoctl(prGlueInfo,
+				 wlanoidSetP2pPowerSaveProfile,
+				 &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+			break;
+		case 107:	/* P2P set opps, CTWindowl */
+			prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value;
+			status =
+			    mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rOppPsParam);
+			break;
+		case 108:	/* p2p_set_power_save */
+			kalIoctl(prGlueInfo,
+				 wlanoidSetP2pPowerSaveProfile,
+				 &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+
+			break;
+
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_SET_STRUCT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_struct(IN struct net_device *prDev,
+			IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	int status = 0;
+	UINT_32 u4SubCmd = 0;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL;
+
+	ASSERT(prDev);
+	ASSERT(wrqu);
+
+	if (FALSE == GLUE_CHK_PR2(prDev, wrqu))
+		return -EINVAL;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	u4SubCmd = (UINT_32) wrqu->data.flags;
+
+	kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0], sizeof(prGlueInfo->prP2PInfo->aucOidBuf));
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_OID:
+		if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) {
+			status = -EFAULT;
+			break;
+		}
+
+		if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length))
+			DBGLOG(P2P, INFO, "extra buffer is valid\n");
+		else
+			DBGLOG(P2P, INFO, "extra 0x%p\n", extra);
+
+		prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
+		switch (prP2PReq->u4CmdId) {
+		case P2P_CMD_ID_SEND_SD_RESPONSE:
+			status = mtk_p2p_wext_send_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+
+		case P2P_CMD_ID_SEND_SD_REQUEST:
+			status = mtk_p2p_wext_send_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+
+		case P2P_CMD_ID_TERMINATE_SD_PHASE:
+			status = mtk_p2p_wext_terminate_service_discovery_phase(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+
+		case P2P_CMD_ID_INVITATION:
+			if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_INVITATION_STRUCT)) {
+				/* Do nothing */
+				/* status = mtk_p2p_wext_invitation_request(prDev, info, wrqu,
+					(char *)(prP2PReq->aucBuffer)); */
+			}
+			break;
+
+		case P2P_CMD_ID_INVITATION_ABORT:
+			if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_ABORT_INVITATION)) {
+				/* Do nothing */
+				/* status = mtk_p2p_wext_invitation_abort(prDev, info, wrqu,
+					(char *)(prP2PReq->aucBuffer)); */
+			}
+			break;
+
+		case P2P_CMD_ID_START_FORMATION:
+			if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_START_FORMATION))
+				status = mtk_p2p_wext_start_formation(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
+			break;
+		default:
+			status = -EOPNOTSUPP;
+		}
+
+		break;
+#if CFG_SUPPORT_ANTI_PIRACY
+	case PRIV_SEC_CHECK_OID:
+		if (wrqu->data.length > 256) {
+			status = -EOPNOTSUPP;
+			break;
+		}
+		if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), wrqu->data.pointer, wrqu->data.length)) {
+			status = -EFAULT;
+			break;
+		}
+
+		if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length))
+			DBGLOG(P2P, INFO, "extra buffer is valid\n");
+		else
+			DBGLOG(P2P, INFO, "extra 0x%p\n", extra);
+		prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0]));
+
+		switch (prP2PReq->u4CmdId) {
+		case P2P_CMD_ID_SEC_CHECK:
+			status = mtk_p2p_wext_set_sec_check_request(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+		default:
+			status = -EOPNOTSUPP;
+		}
+		break;
+#endif
+	case PRIV_CMD_P2P_VERSION:
+		if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) {
+			status = -EFAULT;
+			break;
+		}
+
+		if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length))
+			DBGLOG(P2P, INFO, "extra buffer is valid\n");
+		else
+			DBGLOG(P2P, INFO, "extra 0x%p\n", extra);
+
+		prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
+		switch (prP2PReq->u4CmdId) {
+		case P2P_CMD_ID_P2P_VERSION:
+			status = mtk_p2p_wext_set_p2p_version(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+		default:
+			status = -EOPNOTSUPP;
+			break;
+		}
+		break;
+	default:
+		status = -EOPNOTSUPP;
+		break;
+	}
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT)
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_get_struct(IN struct net_device *prDev,
+			IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	int status = 0;
+	UINT_32 u4SubCmd = 0;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL;
+
+	ASSERT(prDev);
+	ASSERT(wrqu);
+
+	if (!prDev || !wrqu) {
+		DBGLOG(P2P, WARN, "%s(): invalid param(0x%p, 0x%p)\n", __func__, prDev, wrqu);
+		return -EINVAL;
+	}
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	u4SubCmd = (UINT_32) wrqu->data.flags;
+
+	kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), sizeof(prGlueInfo->prP2PInfo->aucOidBuf));
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_OID:
+		if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+				   wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) {
+			DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__);
+			return -EFAULT;
+		}
+
+		prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
+
+		switch (prP2PReq->u4CmdId) {
+		case P2P_CMD_ID_GET_SD_REQUEST:
+			status = mtk_p2p_wext_get_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+
+		case P2P_CMD_ID_GET_SD_RESPONSE:
+			status = mtk_p2p_wext_get_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+
+		case P2P_CMD_ID_INVITATION_INDICATE:
+			{
+				status =
+				    mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
+				prP2PReq->outBufferLength = wrqu->data.length;
+				if (copy_to_user(wrqu->data.pointer,
+						 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+						 wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+					DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+					return -EIO;
+				} else {
+					return 0;
+				}
+				break;
+			}
+		case P2P_CMD_ID_INVITATION_STATUS:
+			{
+				status =
+				    mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
+				prP2PReq->outBufferLength = wrqu->data.length;
+				if (copy_to_user(wrqu->data.pointer,
+						 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+						 wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+					DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+					return -EIO;
+				} else {
+					return 0;
+				}
+				break;
+			}
+		case P2P_CMD_ID_GET_CH_LIST:
+			{
+				UINT_16 i;
+				UINT_8 NumOfChannel = 50;
+				RF_CHANNEL_INFO_T aucChannelList[50];
+				UINT_8 ucMaxChannelNum = 50;
+				PUINT_8 pucChnlList = (PUINT_8) prP2PReq->aucBuffer;
+
+				kalGetChnlList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList);
+				if (NumOfChannel > 50)
+					NumOfChannel = 50;
+				prP2PReq->outBufferLength = NumOfChannel;
+				/*here must confirm NumOfChannel < 16, for prP2PReq->aucBuffer 16 byte*/
+				if (NumOfChannel >= 15) {
+					/*DBGLOG(P2P, ERROR, "channel num > 15\n", __func__);*/
+					ASSERT(FALSE);
+				}
+
+				for (i = 0; i < NumOfChannel; i++) {
+#if 0
+					/* 20120208 frog: modify to avoid clockwork warning. */
+					prP2PReq->aucBuffer[i] = aucChannelList[i].ucChannelNum;
+#else
+					*pucChnlList = aucChannelList[i].ucChannelNum;
+					pucChnlList++;
+#endif
+				}
+				if (copy_to_user(wrqu->data.pointer,
+						 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+						 NumOfChannel + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+					DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+					return -EIO;
+				} else {
+					return 0;
+				}
+				break;
+			}
+
+		case P2P_CMD_ID_GET_OP_CH:
+			{
+				prP2PReq->inBufferLength = 4;
+
+				status = wlanoidQueryP2pOpChannel(prGlueInfo->prAdapter,
+								  prP2PReq->aucBuffer,
+								  prP2PReq->inBufferLength, &prP2PReq->outBufferLength);
+
+				if (status == 0) {	/* WLAN_STATUS_SUCCESS */
+					if (copy_to_user(wrqu->data.pointer,
+							 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+							 prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT,
+											       aucBuffer))) {
+						DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+						return -EIO;
+					}
+				} else {
+					if (copy_to_user(wrqu->data.pointer,
+							 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+							 OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+						DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+						return -EIO;
+					}
+				}
+				break;
+			}
+
+		default:
+			status = -EOPNOTSUPP;
+		}
+
+		break;
+#if CFG_SUPPORT_ANTI_PIRACY
+	case PRIV_SEC_CHECK_OID:
+		if (wrqu->data.length > 256) {
+			status = -EOPNOTSUPP;
+			break;
+		}
+		if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]),
+				   wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) {
+			DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__);
+			return -EFAULT;
+		}
+
+		prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0]));
+
+		switch (prP2PReq->u4CmdId) {
+		case P2P_CMD_ID_SEC_CHECK:
+			status = mtk_p2p_wext_get_sec_check_response(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+		default:
+			status = -EOPNOTSUPP;
+		}
+		break;
+#endif
+	case PRIV_CMD_P2P_VERSION:
+		if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+				   wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) {
+			DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__);
+			return -EFAULT;
+		}
+
+		prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
+
+		switch (prP2PReq->u4CmdId) {
+		case P2P_CMD_ID_P2P_VERSION:
+			status = mtk_p2p_wext_get_p2p_version(prDev, info, wrqu, (char *)prP2PReq);
+			break;
+		default:
+			status = -EOPNOTSUPP;
+			break;
+		}
+
+		/* Copy queried data to user. */
+		if (status == 0) {	/* WLAN_STATUS_SUCCESS */
+			if (copy_to_user(wrqu->data.pointer,
+					 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+					 prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+				DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+				return -EIO;
+			}
+		}
+
+		else {
+			if (copy_to_user(wrqu->data.pointer,
+					 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+					 OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+				DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+				return -EIO;
+			}
+		}
+
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*        getting service discovery request frame from driver
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev,
+					   IN struct iw_request_info *info,
+					   IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4QueryInfoLen = 0;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidGetP2PSDRequest,
+			   prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+
+	prP2PReq->outBufferLength = u4QueryInfoLen;
+
+	if (copy_to_user(wrqu->data.pointer,
+			 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+			 u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+		DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+		return -EIO;
+	} else {
+		return 0;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*        getting service discovery response frame from driver
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev,
+					    IN struct iw_request_info *info,
+					    IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4QueryInfoLen = 0;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidGetP2PSDResponse,
+			   prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+
+	prP2PReq->outBufferLength = u4QueryInfoLen;
+
+	if (copy_to_user(wrqu->data.pointer,
+			 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
+			 u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+		DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+		return -EIO;
+	}
+	return 0;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*        sending service discovery request frame
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev,
+					    IN struct iw_request_info *info,
+					    IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4SetInfoLen;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSendP2PSDRequest,
+			   prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*        sending service discovery response frame
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev,
+					     IN struct iw_request_info *info,
+					     IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4SetInfoLen;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSendP2PSDResponse,
+			   prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+#if CFG_SUPPORT_ANTI_PIRACY
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev,
+				   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4SetInfoLen;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetSecCheckRequest,
+			   prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev,
+				    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4QueryInfoLen = 0;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	DBGLOG(P2P, INFO, "mtk_p2p_wext_get_sec_check_response\n");
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidGetSecCheckResponse,
+			   prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+
+	prP2PReq->outBufferLength = u4QueryInfoLen;
+
+	if (copy_to_user(wrqu->data.pointer,
+		 prP2PReq->aucBuffer, u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
+		DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__);
+		return -EIO;
+	}
+	return 0;
+
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*        terminating service discovery phase
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev,
+					       IN struct iw_request_info *info,
+					       IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4SetInfoLen;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetP2PTerminateSDPhase,
+			   prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev,
+			   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4SetInfoLen;
+	/* P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */
+	P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	DBGLOG(P2P, INFO, "mtk_p2p_wext_set_noa_param\n");
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetNoaParam, prNoaParam,	/* prP2PReq->aucBuffer, */
+			   sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T),	/* prP2PReq->inBufferLength, */
+			   FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief P2P Private I/O Control handler for
+*
+* \param[in] prDev      Net device requested.
+* \param[inout] wrqu    Pointer to iwreq_data
+*
+* \retval 0 Success.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int
+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev,
+			     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4SetInfoLen;
+/* P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */
+	P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	DBGLOG(P2P, INFO, "mtk_p2p_wext_set_oppps_param\n");
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetOppPsParam, prOppPsParam,	/* prP2PReq->aucBuffer, */
+			   sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T),	/* prP2PReq->inBufferLength, */
+			   FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+int
+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev,
+			     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	UINT_32 u4SetInfoLen;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetP2pSupplicantVersion,
+			   prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return rStatus;
+
+}
+
+/* mtk_p2p_wext_set_p2p_version */
+
+int
+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev,
+			     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4QueryInfoLen;
+	P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryP2pVersion,
+			   prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return rStatus;
+
+}				/* mtk_p2p_wext_get_p2p_version */
+
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+
+int
+mtk_p2p_wext_get_rssi(IN struct net_device *prDev,
+		      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4QueryInfoLen;
+	struct iw_point *prData = (struct iw_point *)&wrqu->data;
+	UINT_16 u2BufferSize = 0;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Rssi;
+	struct iw_statistics *pStats = NULL;
+
+	ASSERT(prDev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+
+	if (!prGlueInfo) {
+		rStatus = WLAN_STATUS_FAILURE;
+		goto stat_out;
+	}
+
+	pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats));
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &u4QueryInfoLen);
+
+	u2BufferSize = prData->length;
+
+	if (u2BufferSize < sizeof(struct iw_statistics))
+		return -E2BIG;
+
+	if (copy_to_user(prData->pointer, pStats, sizeof(struct iw_statistics)))
+		rStatus = WLAN_STATUS_FAILURE;
+
+stat_out:
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+	else
+		return rStatus;
+
+}				/* mtk_p2p_wext_get_rssi */
+
+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct iw_statistics *pStats = NULL;
+	INT_32 i4Rssi;
+	UINT_32 bufLen = 0;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+	if (!prGlueInfo)
+		goto stat_out;
+
+	pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats));
+
+	if (!prDev || !netif_carrier_ok(prDev)) {
+		/* network not connected */
+		goto stat_out;
+	}
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &bufLen);
+
+stat_out:
+	return pStats;
+}				/* mtk_p2p_wext_get_wireless_stats */
+
+#endif /* CFG_SUPPORT_P2P_RSSI_QUERY */
+
+int
+mtk_p2p_wext_set_txpow(IN struct net_device *prDev,
+		       IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL;
+#if 0
+	P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL;
+#endif
+	int i4Ret = 0;
+
+	ASSERT(prDev);
+	ASSERT(prTxPow);
+
+	do {
+		if ((!prDev) || (!prTxPow)) {
+			i4Ret = -EINVAL;
+			break;
+		}
+
+		prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+		if (!prGlueInfo) {
+			i4Ret = -EINVAL;
+			break;
+		}
+
+		prAdapter = prGlueInfo->prAdapter;
+#if 0
+		prMsgFuncSwitch =
+		    (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG,
+							      sizeof(MSG_P2P_FUNCTION_SWITCH_T));
+		if (!prMsgFuncSwitch) {
+			ASSERT(0);
+			return -ENOMEM;
+		}
+
+		prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
+
+		if (prTxPow->disabled) {
+			/* Dissolve. */
+			prMsgFuncSwitch->fgIsFuncOn = FALSE;
+		} else {
+
+			/* Re-enable function. */
+			prMsgFuncSwitch->fgIsFuncOn = TRUE;
+		}
+
+		/* 1.3 send message */
+		mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF);
+#endif
+
+	} while (FALSE);
+
+	return i4Ret;
+}				/* mtk_p2p_wext_set_txpow */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c
new file mode 100644
index 0000000000000..4d71e0c59b05d
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c
@@ -0,0 +1,1935 @@
+/*
+** Id: @(#) gl_p2p_cfg80211.c@@
+*/
+
+/*! \file   gl_p2p_cfg80211.c
+    \brief  Main routines of Linux driver interface for Wi-Fi Direct
+	    using cfg80211 interface
+
+    This file contains the main routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*
+** Log: gl_p2p_cfg80211.c
+**
+** 01 30 2013 yuche.tsai
+** [ALPS00455459] [GN_WIFI]??wifi direct???????????
+** Fix possible race condition under GO mode.
+**
+** 09 12 2012 wcpadmin
+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
+** .
+**
+** 09 05 2012 wh.su
+** [ALPS00351547] [6577JB][WiFi direct]The 3rd device fail to establish p2p connection with GO sometimes
+** sync with the ICS code.
+**
+** 08 31 2012 yuche.tsai
+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously,
+** one device reboots automatically with KE
+** Fix possible KE when concurrent & disconnect.
+**
+** 08 21 2012 yuche.tsai
+** NULL
+** Fix compile warning.
+**
+** 08 20 2012 yuche.tsai
+** NULL
+** Fix possible KE issue.
+**
+** 08 17 2012 yuche.tsai
+** NULL
+** Fix compile warning.
+**
+** 08 16 2012 yuche.tsai
+** NULL
+** Fix compile warning.
+**
+** 08 14 2012 yuche.tsai
+** NULL
+** Fix p2p bug find on ALPS.JB trunk.
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Fix compile error for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 31 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add cfg80211 interface, which is to replace WE, for further extension
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "config.h"
+
+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#include <linux/can/netlink.h>
+#include <net/netlink.h>
+
+#include "precomp.h"
+#include "gl_cfg80211.h"
+#include "gl_p2p_ioctl.h"
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wformat"
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+BOOLEAN
+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel,
+					   IN enum nl80211_channel_type channel_type,
+					   IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy,
+			     struct net_device *ndev,
+			     u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Rslt = -EINVAL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+	P2P_PARAM_KEY_T rKey;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	kalMemZero(&rKey, sizeof(P2P_PARAM_KEY_T));
+
+	rKey.u4KeyIndex = key_index;
+	if (mac_addr) {
+		ether_addr_copy(rKey.arBSSID, mac_addr);
+		if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) &&
+		    (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) {
+			rKey.arBSSID[0] = 0xff;
+			rKey.arBSSID[1] = 0xff;
+			rKey.arBSSID[2] = 0xff;
+			rKey.arBSSID[3] = 0xff;
+			rKey.arBSSID[4] = 0xff;
+			rKey.arBSSID[5] = 0xff;
+		}
+		if (rKey.arBSSID[0] != 0xFF) {
+			rKey.u4KeyIndex |= BIT(31);
+			if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) ||
+			    (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00))
+				rKey.u4KeyIndex |= BIT(30);
+		} else {
+			rKey.u4KeyIndex |= BIT(31);
+		}
+	} else {
+		rKey.arBSSID[0] = 0xff;
+		rKey.arBSSID[1] = 0xff;
+		rKey.arBSSID[2] = 0xff;
+		rKey.arBSSID[3] = 0xff;
+		rKey.arBSSID[4] = 0xff;
+		rKey.arBSSID[5] = 0xff;
+		rKey.u4KeyIndex |= BIT(31);	/* ???? */
+	}
+	if (params->key) {
+		/* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */
+		kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len);
+	}
+	rKey.u4KeyLength = params->key_len;
+	rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength;
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetAddP2PKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen);
+	if (rStatus == WLAN_STATUS_SUCCESS)
+		i4Rslt = 0;
+
+	return i4Rslt;
+}
+
+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy,
+			     struct net_device *ndev,
+			     u8 key_index,
+			     bool pairwise,
+			     const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)
+)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	/* not implemented yet */
+
+	return -EINVAL;
+}
+
+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy,
+			     struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	PARAM_REMOVE_KEY_T prRemoveKey;
+	INT_32 i4Rslt = -EINVAL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
+		i4Rslt = 0;
+		return i4Rslt;
+	}
+
+	kalMemZero(&prRemoveKey, sizeof(PARAM_REMOVE_KEY_T));
+	if (mac_addr)
+		memcpy(prRemoveKey.arBSSID, mac_addr, PARAM_MAC_ADDR_LEN);
+	prRemoveKey.u4KeyIndex = key_index;
+	prRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetRemoveP2PKey,
+			   &prRemoveKey, prRemoveKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen);
+
+	if (rStatus == WLAN_STATUS_SUCCESS)
+		i4Rslt = 0;
+
+	return i4Rslt;
+}
+
+int
+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy,
+				 struct net_device *netdev, u8 key_index, bool unicast, bool multicast)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	/* not implemented yet */
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
+					const u8 *mac, struct station_info *sinfo)
+{
+	INT_32 i4RetRslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL;
+	P2P_STATION_INFO_T rP2pStaInfo;
+
+	ASSERT(wiphy);
+
+	do {
+		if ((wiphy == NULL) || (ndev == NULL) || (sinfo == NULL) || (mac == NULL))
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_get_station\n");
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+		prP2pGlueInfo = prGlueInfo->prP2PInfo;
+
+		sinfo->filled = 0;
+
+		/* Get station information. */
+		/* 1. Inactive time? */
+		p2pFuncGetStationInfo(prGlueInfo->prAdapter, (PUINT_8)mac, &rP2pStaInfo);
+
+		/* Inactive time. */
+		sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME;
+		sinfo->inactive_time = rP2pStaInfo.u4InactiveTime;
+		sinfo->generation = prP2pGlueInfo->i4Generation;
+
+		i4RetRslt = 0;
+	} while (FALSE);
+
+	return i4RetRslt;
+}
+
+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL;
+	P_MSG_P2P_SCAN_REQUEST_T prMsgScanRequest = (P_MSG_P2P_SCAN_REQUEST_T) NULL;
+	UINT_32 u4MsgSize = 0, u4Idx = 0;
+	INT_32 i4RetRslt = -EINVAL;
+	P_RF_CHANNEL_INFO_T prRfChannelInfo = (P_RF_CHANNEL_INFO_T) NULL;
+	P_P2P_SSID_STRUCT_T prSsidStruct = (P_P2P_SSID_STRUCT_T) NULL;
+	struct ieee80211_channel *prChannel = NULL;
+	struct cfg80211_ssid *prSsid = NULL;
+
+	/* [---------Channel---------] [---------SSID---------][---------IE---------] */
+	DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan\n");
+
+	do {
+		if ((wiphy == NULL) || (request == NULL))
+			break;
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		prP2pGlueInfo = prGlueInfo->prP2PInfo;
+
+		if (prP2pGlueInfo == NULL) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_scan.\n");
+
+		if (prP2pGlueInfo->prScanRequest != NULL) {
+			/* There have been a scan request on-going processing. */
+			DBGLOG(P2P, TRACE, "There have been a scan request on-going processing.\n");
+			break;
+		}
+
+		prP2pGlueInfo->prScanRequest = request;
+
+		/* Should find out why the n_channels so many? */
+		if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) {
+			request->n_channels = MAXIMUM_OPERATION_CHANNEL_LIST;
+			DBGLOG(P2P, TRACE, "Channel list exceed the maximun support.\n");
+		}
+
+		u4MsgSize = sizeof(MSG_P2P_SCAN_REQUEST_T) +
+		    (request->n_channels * sizeof(RF_CHANNEL_INFO_T)) +
+		    (request->n_ssids * sizeof(PARAM_SSID_T)) + request->ie_len;
+
+		prMsgScanRequest = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, u4MsgSize);
+
+		if (prMsgScanRequest == NULL) {
+			ASSERT(FALSE);
+			i4RetRslt = -ENOMEM;
+			prP2pGlueInfo->prScanRequest = NULL;
+			DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan Allocate Mem failed\n");
+			break;
+		}
+
+		DBGLOG(P2P, TRACE, "Generating scan request message.\n");
+
+		prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY;
+
+		DBGLOG(P2P, INFO, "Requesting channel number:%d.\n", request->n_channels);
+
+		for (u4Idx = 0; u4Idx < request->n_channels; u4Idx++) {
+			/* Translate Freq from MHz to channel number. */
+			prRfChannelInfo = &(prMsgScanRequest->arChannelListInfo[u4Idx]);
+			prChannel = request->channels[u4Idx];
+
+			prRfChannelInfo->ucChannelNum = nicFreq2ChannelNum(prChannel->center_freq * 1000);
+			DBGLOG(P2P, TRACE, "Scanning Channel:%d,  freq: %d\n",
+					   prRfChannelInfo->ucChannelNum, prChannel->center_freq);
+			switch (prChannel->band) {
+			case NL80211_BAND_2GHZ:
+				prRfChannelInfo->eBand = BAND_2G4;
+				break;
+			case NL80211_BAND_5GHZ:
+				prRfChannelInfo->eBand = BAND_5G;
+				break;
+			default:
+				DBGLOG(P2P, TRACE, "UNKNOWN Band info from supplicant\n");
+				prRfChannelInfo->eBand = BAND_NULL;
+				break;
+			}
+
+			/* Iteration. */
+			prRfChannelInfo++;
+		}
+		prMsgScanRequest->u4NumChannel = request->n_channels;
+
+		DBGLOG(P2P, TRACE, "Finish channel list.\n");
+
+		/* SSID */
+		prSsid = request->ssids;
+		prSsidStruct = (P_P2P_SSID_STRUCT_T) prRfChannelInfo;
+		if (prSsidStruct) {
+			if (request->n_ssids) {
+				ASSERT((ULONG) prSsidStruct == (ULONG)&(prMsgScanRequest->arChannelListInfo[u4Idx]));
+				prMsgScanRequest->prSSID = prSsidStruct;
+			}
+
+			for (u4Idx = 0; u4Idx < request->n_ssids; u4Idx++) {
+				COPY_SSID(prSsidStruct->aucSsid,
+					  prSsidStruct->ucSsidLen, request->ssids->ssid, request->ssids->ssid_len);
+
+				prSsidStruct++;
+				prSsid++;
+			}
+
+			prMsgScanRequest->i4SsidNum = request->n_ssids;
+
+			DBGLOG(P2P, TRACE, "Finish SSID list:%d.\n", request->n_ssids);
+
+			/* IE BUFFERS */
+			prMsgScanRequest->pucIEBuf = (PUINT_8) prSsidStruct;
+			if (request->ie_len) {
+				kalMemCopy(prMsgScanRequest->pucIEBuf, request->ie, request->ie_len);
+				prMsgScanRequest->u4IELen = request->ie_len;
+			}
+		}
+
+		DBGLOG(P2P, TRACE, "Finish IE Buffer.\n");
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+		prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = FALSE;
+#endif
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgScanRequest, MSG_SEND_METHOD_BUF);
+
+		i4RetRslt = 0;
+	} while (FALSE);
+
+	return i4RetRslt;
+}				/* mtk_p2p_cfg80211_scan */
+
+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+	INT_32 i4Rslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	do {
+		if (wiphy == NULL)
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_wiphy_params\n");
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		if (changed & WIPHY_PARAM_RETRY_SHORT) {
+			/* TODO: */
+			DBGLOG(P2P, TRACE, "The RETRY short param is changed.\n");
+		}
+
+		if (changed & WIPHY_PARAM_RETRY_LONG) {
+			/* TODO: */
+			DBGLOG(P2P, TRACE, "The RETRY long param is changed.\n");
+		}
+
+		if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+			/* TODO: */
+			DBGLOG(P2P, TRACE, "The RETRY fragmentation threshold is changed.\n");
+		}
+
+		if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+			/* TODO: */
+			DBGLOG(P2P, TRACE, "The RETRY RTS threshold is changed.\n");
+		}
+
+		if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
+			/* TODO: */
+			DBGLOG(P2P, TRACE, "The coverage class is changed???\n");
+		}
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_set_wiphy_params */
+
+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	/* not implemented yet */
+
+	return -EINVAL;
+}
+
+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	/* not implemented yet */
+
+	return -EINVAL;
+}
+
+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 enum nl80211_tx_power_setting type, int mbm)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	/* not implemented yet */
+
+	return -EINVAL;
+}
+
+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 int *dbm)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	/* not implemented yet */
+
+	return -EINVAL;
+}
+
+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 value;
+	UINT_32 u4Leng;
+
+	ASSERT(wiphy);
+
+	if (enabled)
+		value = 2;
+	else
+		value = 0;
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+	DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_power_mgmt ps=%d.\n", enabled);
+
+	/* p2p_set_power_save */
+	kalIoctl(prGlueInfo, wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+	return 0;
+}
+
+/* &&&&&&&&&&&&&&&&&&&&&&&&&& Add for ICS Wi-Fi Direct Support. &&&&&&&&&&&&&&&&&&&&&&& */
+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL;
+	P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL;
+	PUINT_8 pucBuffer = (PUINT_8) NULL;
+	/* P_IE_SSID_T prSsidIE = (P_IE_SSID_T)NULL; */
+
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_chan_def *chandef = &wdev->preset_chandef;
+
+	do {
+		if ((wiphy == NULL) || (settings == NULL))
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_start_ap.\n");
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+#if 1
+		mtk_p2p_cfg80211_set_channel(wiphy, chandef);
+#else
+		prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->ucOperatingChnl =
+		    (chandef->chan->center_freq - 2407) / 5;
+		prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->eBand = BAND_2G4;
+#endif
+
+		prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter,
+									    RAM_TYPE_MSG,
+									    (sizeof(MSG_P2P_BEACON_UPDATE_T) +
+									     settings->beacon.head_len +
+									     settings->beacon.tail_len));
+
+		if (prP2pBcnUpdateMsg == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE;
+		pucBuffer = prP2pBcnUpdateMsg->aucBuffer;
+
+		if (settings->beacon.head_len != 0) {
+			kalMemCopy(pucBuffer, settings->beacon.head, settings->beacon.head_len);
+
+			prP2pBcnUpdateMsg->u4BcnHdrLen = settings->beacon.head_len;
+
+			prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer;
+
+			pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) settings->beacon.head_len);
+		} else {
+			prP2pBcnUpdateMsg->u4BcnHdrLen = 0;
+
+			prP2pBcnUpdateMsg->pucBcnHdr = NULL;
+		}
+
+		if (settings->beacon.tail_len != 0) {
+			UINT_32 ucLen = settings->beacon.tail_len;
+
+			prP2pBcnUpdateMsg->pucBcnBody = pucBuffer;
+
+			/*Add TIM IE */
+			/* IEEE 802.11 2007 - 7.3.2.6 */
+			TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM;
+			TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */;
+			/* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */
+			TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */;	/* will be overwrite by FW */
+			TIM_IE(pucBuffer)->ucDTIMPeriod = 1;
+			TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */;
+			/* will be overwrite by FW */
+			ucLen += IE_SIZE(pucBuffer);
+			pucBuffer += IE_SIZE(pucBuffer);
+
+			kalMemCopy(pucBuffer, settings->beacon.tail, settings->beacon.tail_len);
+
+			prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen;
+		} else {
+			prP2pBcnUpdateMsg->u4BcnBodyLen = 0;
+
+			prP2pBcnUpdateMsg->pucBcnBody = NULL;
+		}
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF);
+
+		prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) cnmMemAlloc(prGlueInfo->prAdapter,
+								     RAM_TYPE_MSG, sizeof(MSG_P2P_START_AP_T));
+
+		if (prP2pStartAPMsg == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prP2pStartAPMsg->rMsgHdr.eMsgId = MID_MNY_P2P_START_AP;
+
+		prP2pStartAPMsg->fgIsPrivacy = settings->privacy;
+
+		prP2pStartAPMsg->u4BcnInterval = settings->beacon_interval;
+
+		prP2pStartAPMsg->u4DtimPeriod = settings->dtim_period;
+
+		/* Copy NO SSID. */
+		prP2pStartAPMsg->ucHiddenSsidType = settings->hidden_ssid;
+
+		COPY_SSID(prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen, settings->ssid, settings->ssid_len);
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pStartAPMsg, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT
+		if (glIsChipNeedWakelock(prGlueInfo))
+			KAL_WAKE_LOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock);
+#endif
+
+	} while (FALSE);
+
+	return i4Rslt;
+
+/* /////////////////////// */
+    /**
+	 * struct cfg80211_ap_settings - AP configuration
+	 *
+	 * Used to configure an AP interface.
+	 *
+	 * @beacon: beacon data
+	 * @beacon_interval: beacon interval
+	 * @dtim_period: DTIM period
+	 * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from
+	 *      user space)
+	 * @ssid_len: length of @ssid
+	 * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames
+	 * @crypto: crypto settings
+	 * @privacy: the BSS uses privacy
+	 * @auth_type: Authentication type (algorithm)
+	 * @inactivity_timeout: time in seconds to determine station's inactivity.
+	 */
+/* struct cfg80211_ap_settings { */
+/* struct cfg80211_beacon_data beacon; */
+/*  */
+/* int beacon_interval, dtim_period; */
+/* const u8 *ssid; */
+/* size_t ssid_len; */
+/* enum nl80211_hidden_ssid hidden_ssid; */
+/* struct cfg80211_crypto_settings crypto; */
+/* bool privacy; */
+/* enum nl80211_auth_type auth_type; */
+/* int inactivity_timeout; */
+/* }; */
+/* ////////////////// */
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_start_ap */
+
+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL;
+	PUINT_8 pucBuffer = (PUINT_8) NULL;
+
+	do {
+		if ((wiphy == NULL) || (info == NULL))
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_beacon.\n");
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter,
+									    RAM_TYPE_MSG,
+									    (sizeof(MSG_P2P_BEACON_UPDATE_T) +
+									     info->head_len + info->tail_len));
+
+		if (prP2pBcnUpdateMsg == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE;
+		pucBuffer = prP2pBcnUpdateMsg->aucBuffer;
+
+		if (info->head_len != 0) {
+			kalMemCopy(pucBuffer, info->head, info->head_len);
+
+			prP2pBcnUpdateMsg->u4BcnHdrLen = info->head_len;
+
+			prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer;
+
+			pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) info->head_len);
+		} else {
+			prP2pBcnUpdateMsg->u4BcnHdrLen = 0;
+
+			prP2pBcnUpdateMsg->pucBcnHdr = NULL;
+		}
+
+		if (info->tail_len != 0) {
+			UINT_32 ucLen = info->tail_len;
+
+			prP2pBcnUpdateMsg->pucBcnBody = pucBuffer;
+
+			/*Add TIM IE */
+			/* IEEE 802.11 2007 - 7.3.2.6 */
+			TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM;
+			TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */;
+			/* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */
+			TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */;	/* will be overwrite by FW */
+			TIM_IE(pucBuffer)->ucDTIMPeriod = 1;
+			TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */;
+			/* will be overwrite by FW */
+			ucLen += IE_SIZE(pucBuffer);
+			pucBuffer += IE_SIZE(pucBuffer);
+
+			kalMemCopy(pucBuffer, info->tail, info->tail_len);
+
+			prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen;
+		} else {
+			prP2pBcnUpdateMsg->u4BcnBodyLen = 0;
+
+			prP2pBcnUpdateMsg->pucBcnBody = NULL;
+		}
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF);
+
+/* ////////////////////////// */
+/**
+ * struct cfg80211_beacon_data - beacon data
+ * @head: head portion of beacon (before TIM IE)
+ *     or %NULL if not changed
+ * @tail: tail portion of beacon (after TIM IE)
+ *     or %NULL if not changed
+ * @head_len: length of @head
+ * @tail_len: length of @tail
+ * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL
+ * @beacon_ies_len: length of beacon_ies in octets
+ * @proberesp_ies: extra information element(s) to add into Probe Response
+ *      frames or %NULL
+ * @proberesp_ies_len: length of proberesp_ies in octets
+ * @assocresp_ies: extra information element(s) to add into (Re)Association
+ *      Response frames or %NULL
+ * @assocresp_ies_len: length of assocresp_ies in octets
+ * @probe_resp_len: length of probe response template (@probe_resp)
+ * @probe_resp: probe response template (AP mode only)
+ */
+/* struct cfg80211_beacon_data { */
+/* const u8 *head, *tail; */
+/* const u8 *beacon_ies; */
+/* const u8 *proberesp_ies; */
+/* const u8 *assocresp_ies; */
+/* const u8 *probe_resp; */
+
+/* size_t head_len, tail_len; */
+/* size_t beacon_ies_len; */
+/* size_t proberesp_ies_len; */
+/* size_t assocresp_ies_len; */
+/* size_t probe_resp_len; */
+/* }; */
+
+/* ////////////////////////// */
+
+	} while (FALSE);
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_change_beacon */
+
+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_P2P_SWITCH_OP_MODE_T prP2pSwitchMode = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL;
+
+	do {
+		if (wiphy == NULL)
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_stop_ap.\n");
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		/* Switch OP MOde. */
+		prP2pSwitchMode = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_SWITCH_OP_MODE_T));
+
+		if (prP2pSwitchMode == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prP2pSwitchMode->rMsgHdr.eMsgId = MID_MNY_P2P_STOP_AP;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pSwitchMode, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT
+		if (glIsChipNeedWakelock(prGlueInfo))
+			KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock);
+#endif
+	} while (FALSE);
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_stop_ap */
+
+/* TODO: */
+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	/* not implemented yet */
+	DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_deauth.\n");
+
+	return -EINVAL;
+}				/* mtk_p2p_cfg80211_deauth */
+
+/* TODO: */
+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_disassoc.\n");
+
+	/* not implemented yet */
+
+	return -EINVAL;
+}				/* mtk_p2p_cfg80211_disassoc */
+
+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy,
+				       struct wireless_dev *wdev,
+				       struct ieee80211_channel *chan,
+				       unsigned int duration, u64 *cookie)
+{
+	INT_32 i4Rslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+	P_MSG_P2P_CHNL_REQUEST_T prMsgChnlReq = (P_MSG_P2P_CHNL_REQUEST_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL))
+			break;
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		*cookie = prGlueP2pInfo->u8Cookie++;
+
+		prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_REQUEST_T));
+
+		if (prMsgChnlReq == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_remain_on_channel\n");
+
+		prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ;
+		prMsgChnlReq->u8Cookie = *cookie;
+		prMsgChnlReq->u4Duration = duration;
+
+		mtk_p2p_cfg80211func_channel_format_switch(chan, NL80211_CHAN_HT20,	/* 4 KH Need Check */
+							   &prMsgChnlReq->rChannelInfo, &prMsgChnlReq->eChnlSco);
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}
+
+/* mtk_p2p_cfg80211_remain_on_channel */
+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      u64 cookie)
+{
+	INT_32 i4Rslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	P_MSG_P2P_CHNL_ABORT_T prMsgChnlAbort = (P_MSG_P2P_CHNL_ABORT_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (wdev == NULL))
+			break;
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_ABORT_T));
+
+		if (prMsgChnlAbort == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_cancel_remain_on_channel\n");
+
+		prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT;
+		prMsgChnlAbort->u8Cookie = cookie;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_cancel_remain_on_channel */
+
+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy,
+			     struct wireless_dev *wdev,
+			     struct cfg80211_mgmt_tx_params *params,
+			     u64 *cookie)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+	INT_32 i4Rslt = -EINVAL;
+	struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prMsgExtListenReq = NULL;
+	P_MSG_P2P_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL;
+	P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL;
+	PUINT_8 pucFrameBuf = (PUINT_8) NULL;
+
+	do {
+		if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL))
+			break;
+		/* DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_mgmt_tx\n")); */
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		*cookie = prGlueP2pInfo->u8Cookie++;
+
+		/* Channel & Channel Type & Wait time are ignored. */
+		prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_MGMT_TX_REQUEST_T));
+
+		if (prMsgTxReq == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		/* Here need to extend the listen interval */
+		prMsgExtListenReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG,
+			sizeof(struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T));
+		if (prMsgExtListenReq) {
+			prMsgExtListenReq->rMsgHdr.eMsgId = MID_MNY_P2P_EXTEND_LISTEN_INTERVAL;
+			prMsgExtListenReq->wait = params->wait;
+			DBGLOG(P2P, INFO, "ext listen, wait: %d\n", prMsgExtListenReq->wait);
+			mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T)prMsgExtListenReq,
+				MSG_SEND_METHOD_BUF);
+		}
+
+		prMsgTxReq->fgNoneCckRate = FALSE;
+		prMsgTxReq->fgIsWaitRsp = TRUE;
+
+		prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD));
+
+		prMsgTxReq->prMgmtMsduInfo = prMgmtFrame;
+		if (prMsgTxReq->prMgmtMsduInfo == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prMsgTxReq->u8Cookie = *cookie;
+		prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX;
+
+		pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD);
+
+		kalMemCopy(pucFrameBuf, params->buf, params->len);
+
+		prMgmtFrame->u2FrameLength = params->len;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	if ((i4Rslt != 0) && (prMsgTxReq != NULL)) {
+		if (prMsgTxReq->prMgmtMsduInfo != NULL)
+			cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo);
+
+		cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq);
+	}
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_mgmt_tx */
+
+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	INT_32 i4Rslt = -EINVAL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	switch (params->use_cts_prot) {
+	case -1:
+		DBGLOG(P2P, TRACE, "CTS protection no change\n");
+		break;
+	case 0:
+		DBGLOG(P2P, TRACE, "CTS protection disable.\n");
+		break;
+	case 1:
+		DBGLOG(P2P, TRACE, "CTS protection enable\n");
+		break;
+	default:
+		DBGLOG(P2P, TRACE, "CTS protection unknown\n");
+		break;
+	}
+
+	switch (params->use_short_preamble) {
+	case -1:
+		DBGLOG(P2P, TRACE, "Short prreamble no change\n");
+		break;
+	case 0:
+		DBGLOG(P2P, TRACE, "Short prreamble disable.\n");
+		break;
+	case 1:
+		DBGLOG(P2P, TRACE, "Short prreamble enable\n");
+		break;
+	default:
+		DBGLOG(P2P, TRACE, "Short prreamble unknown\n");
+		break;
+	}
+
+#if 0
+	/* not implemented yet */
+	p2pFuncChangeBssParam(prGlueInfo->prAdapter,
+			      prBssInfo->fgIsProtection,
+			      prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortSlotTime,
+			      /* Basic rates */
+			      /* basic rates len */
+			      /* ap isolate */
+			      /* ht opmode. */
+	    );
+#else
+	i4Rslt = 0;
+#endif
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_change_bss */
+
+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params)
+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_P2P_CONNECTION_ABORT_T prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL;
+	UINT_8 aucBcMac[] = BC_MAC_ADDR;
+	const UINT_8 *mac = NULL;
+
+	do {
+		if ((wiphy == NULL) || (dev == NULL))
+			break;
+
+		if (params->mac == NULL)
+			mac = aucBcMac;
+                else
+                        mac = params->mac;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_del_station.\n");
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		/* prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(MSG_P2P_CONNECTION_ABORT_T),
+		VIR_MEM_TYPE); */
+		prDisconnectMsg =
+		    (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG,
+							       sizeof(MSG_P2P_CONNECTION_ABORT_T));
+
+		if (prDisconnectMsg == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT;
+		COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac);
+		prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnectMsg, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+
+}				/* mtk_p2p_cfg80211_del_station */
+
+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+	INT_32 i4Rslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (dev == NULL) || (sme == NULL))
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_connect.\n");
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		prConnReqMsg =
+		    (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG,
+								 (sizeof(MSG_P2P_CONNECTION_REQUEST_T) + sme->ie_len));
+
+		if (prConnReqMsg == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prConnReqMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ;
+
+		COPY_SSID(prConnReqMsg->rSsid.aucSsid, prConnReqMsg->rSsid.ucSsidLen, sme->ssid, sme->ssid_len);
+
+		COPY_MAC_ADDR(prConnReqMsg->aucBssid, sme->bssid);
+		DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_connect to %pM, IE len: %d\n",
+				prConnReqMsg->aucBssid, sme->ie_len);
+
+		DBGLOG(P2P, TRACE, "Assoc Req IE Buffer Length:%d\n", sme->ie_len);
+		kalMemCopy(prConnReqMsg->aucIEBuf, sme->ie, sme->ie_len);
+		prConnReqMsg->u4IELen = sme->ie_len;
+
+		mtk_p2p_cfg80211func_channel_format_switch(sme->channel,
+							   NL80211_CHAN_NO_HT,
+							   &prConnReqMsg->rChannelInfo, &prConnReqMsg->eChnlSco);
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prConnReqMsg, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_connect */
+
+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
+{
+	INT_32 i4Rslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL;
+	UINT_8 aucBCAddr[] = BC_MAC_ADDR;
+
+	do {
+		if ((wiphy == NULL) || (dev == NULL))
+			break;
+
+		DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.\n");
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+/* prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(P_MSG_P2P_CONNECTION_ABORT_T), VIR_MEM_TYPE); */
+		prDisconnMsg =
+		    (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG,
+							       sizeof(MSG_P2P_CONNECTION_ABORT_T));
+
+		if (prDisconnMsg == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.Allocate Memory Failed.\n");
+			break;
+		}
+
+		prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT;
+		prDisconnMsg->u2ReasonCode = reason_code;
+		prDisconnMsg->fgSendDeauth = TRUE;
+		COPY_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCAddr);
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnMsg, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_disconnect */
+
+int
+mtk_p2p_cfg80211_change_iface(IN struct wiphy *wiphy,
+			      IN struct net_device *ndev,
+			      IN enum nl80211_iftype type,/* IN u32 *flags,*/ IN struct vif_params *params)
+{
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	INT_32 i4Rslt = -EINVAL;
+	P_MSG_P2P_SWITCH_OP_MODE_T prSwitchModeMsg = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (ndev == NULL))
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_iface.\n");
+
+		if (ndev->ieee80211_ptr)
+			ndev->ieee80211_ptr->iftype = type;
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		/* Switch OP MOde. */
+		prSwitchModeMsg =
+		    (P_MSG_P2P_SWITCH_OP_MODE_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG,
+							     sizeof(MSG_P2P_SWITCH_OP_MODE_T));
+
+		if (prSwitchModeMsg == NULL) {
+			ASSERT(FALSE);
+			i4Rslt = -ENOMEM;
+			break;
+		}
+
+		prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
+
+		switch (type) {
+		case NL80211_IFTYPE_P2P_CLIENT:
+			DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n");
+		case NL80211_IFTYPE_STATION:
+			if (type == NL80211_IFTYPE_STATION)
+				DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n");
+			prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE;
+			break;
+		case NL80211_IFTYPE_AP:
+			DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n");
+		case NL80211_IFTYPE_P2P_GO:
+			if (type == NL80211_IFTYPE_P2P_GO)
+				DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_GO not AP.\n");
+			prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT;
+			break;
+		default:
+			DBGLOG(P2P, TRACE, "Other type :%d .\n", type);
+			prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE;
+			break;
+		}
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSwitchModeMsg, MSG_SEND_METHOD_BUF);
+
+		i4Rslt = 0;
+
+	} while (FALSE);
+
+	return i4Rslt;
+
+}				/* mtk_p2p_cfg80211_change_iface */
+
+int mtk_p2p_cfg80211_set_channel(IN struct wiphy *wiphy,
+				 struct cfg80211_chan_def *chandef)
+{
+	INT_32 i4Rslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+	RF_CHANNEL_INFO_T rRfChnlInfo;
+
+	do {
+		if (wiphy == NULL)
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_channel.\n");
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+		mtk_p2p_cfg80211func_channel_format_switch(chandef->chan, chandef->width, &rRfChnlInfo, NULL);
+		p2pFuncSetChannel(prGlueInfo->prAdapter, &rRfChnlInfo);
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+
+}
+
+/* mtk_p2p_cfg80211_set_channel */
+
+int
+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy,
+				  IN struct net_device *dev,
+				  IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask)
+{
+	INT_32 i4Rslt = -EINVAL;
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (dev == NULL) || (mask == NULL))
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_bitrate_mask\n");
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		/* TODO: Set bitrate mask of the peer? */
+
+		i4Rslt = 0;
+	} while (FALSE);
+
+	return i4Rslt;
+}				/* mtk_p2p_cfg80211_set_bitrate_mask */
+
+void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy,
+					  struct wireless_dev *wdev,
+					  IN u16 frame_type, IN bool reg)
+{
+#if 0
+	P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL;
+#endif
+	P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
+
+	do {
+		if ((wiphy == NULL) || (wdev == NULL))
+			break;
+
+		DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_mgmt_frame_register\n");
+
+		prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+		switch (frame_type) {
+		case MAC_FRAME_PROBE_REQ:
+			if (reg) {
+				prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ;
+				DBGLOG(P2P, TRACE, "Open packet filer probe request\n");
+			} else {
+				prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ;
+				DBGLOG(P2P, TRACE, "Close packet filer probe request\n");
+			}
+			break;
+		case MAC_FRAME_ACTION:
+			if (reg) {
+				prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME;
+				DBGLOG(P2P, TRACE, "Open packet filer action frame.\n");
+			} else {
+				prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME;
+				DBGLOG(P2P, TRACE, "Close packet filer action frame.\n");
+			}
+			break;
+		default:
+			DBGLOG(P2P, ERROR, "Ask frog to add code for mgmt:%x\n", frame_type);
+			break;
+		}
+
+		if ((prGlueInfo->prAdapter != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) {
+
+			/* prGlueInfo->u4Flag |= GLUE_FLAG_FRAME_FILTER; */
+			set_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag);
+
+			/* wake up main thread */
+			wake_up_interruptible(&prGlueInfo->waitq);
+
+			if (in_interrupt())
+				DBGLOG(P2P, TRACE, "It is in interrupt level\n");
+		}
+#if 0
+
+		prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter,
+										    RAM_TYPE_MSG,
+										    sizeof
+										    (MSG_P2P_MGMT_FRAME_REGISTER_T));
+
+		if (prMgmtFrameRegister == NULL) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER;
+
+		prMgmtFrameRegister->u2FrameType = frame_type;
+		prMgmtFrameRegister->fgIsRegister = reg;
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF);
+
+#endif
+
+	} while (FALSE);
+
+}				/* mtk_p2p_cfg80211_mgmt_frame_register */
+
+BOOLEAN
+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel,
+					   IN enum nl80211_channel_type channel_type,
+					   IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco)
+{
+	BOOLEAN fgIsValid = FALSE;
+
+	do {
+		if (channel == NULL)
+			break;
+
+		if (prRfChnlInfo) {
+			prRfChnlInfo->ucChannelNum = nicFreq2ChannelNum(channel->center_freq * 1000);
+
+			switch (channel->band) {
+			case NL80211_BAND_2GHZ:
+				prRfChnlInfo->eBand = BAND_2G4;
+				break;
+			case NL80211_BAND_5GHZ:
+				prRfChnlInfo->eBand = BAND_5G;
+				break;
+			default:
+				prRfChnlInfo->eBand = BAND_2G4;
+				break;
+			}
+
+		}
+
+		if (prChnlSco) {
+
+			switch (channel_type) {
+			case NL80211_CHAN_NO_HT:
+				*prChnlSco = CHNL_EXT_SCN;
+				break;
+			case NL80211_CHAN_HT20:
+				*prChnlSco = CHNL_EXT_SCN;
+				break;
+			case NL80211_CHAN_HT40MINUS:
+				*prChnlSco = CHNL_EXT_SCA;
+				break;
+			case NL80211_CHAN_HT40PLUS:
+				*prChnlSco = CHNL_EXT_SCB;
+				break;
+			default:
+				ASSERT(FALSE);
+				*prChnlSco = CHNL_EXT_SCN;
+				break;
+			}
+		}
+
+		fgIsValid = TRUE;
+	} while (FALSE);
+
+	return fgIsValid;
+}
+
+/* mtk_p2p_cfg80211func_channel_format_switch */
+
+#if CONFIG_NL80211_TESTMODE
+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_TEST_PARAMS prParams = (P_NL80211_DRIVER_TEST_PARAMS) NULL;
+	INT_32 i4Status = -EINVAL;
+	P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = NULL;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_cmd\n");
+
+	if (data && len) {
+		prParams = (P_NL80211_DRIVER_TEST_PARAMS) data;
+	} else {
+		DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_cmd, data is NULL\n");
+		return i4Status;
+	}
+
+	if (prParams->index >> 24 == 0x01) {
+		/* New version */
+	} else {
+		/* Old version */
+		mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len);
+		i4Status = 0;
+		return i4Status;
+	}
+
+	/* Clear the version byte */
+	prParams->index = prParams->index & ~BITS(24, 31);
+
+	if (prParams) {
+		switch (prParams->index) {
+		case 1:	/* P2P Simga */
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+			{
+				P_NL80211_DRIVER_SW_CMD_PARAMS prParamsCmd;
+
+				prParamsCmd = (P_NL80211_DRIVER_SW_CMD_PARAMS) data;
+
+				if ((prParamsCmd->adr & 0xffff0000) == 0xffff0000) {
+					i4Status = mtk_p2p_cfg80211_testmode_sw_cmd(wiphy, data, len);
+					break;
+				}
+			}
+#endif
+			i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(wiphy, data, len);
+			break;
+#if CFG_SUPPORT_WFD
+		case 2:	/* WFD */
+			i4Status = mtk_p2p_cfg80211_testmode_wfd_update_cmd(wiphy, data, len);
+			break;
+#endif
+		case 3:	/* Hotspot Client Management */
+			i4Status = mtk_p2p_cfg80211_testmode_hotspot_block_cmd(wiphy, data, len);
+			break;
+		case 0x10:
+			i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo);
+			break;
+#if 1
+		case 0x11:	/*NFC Beam + Indication */
+			prChnlReqInfo = &prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo;
+			if (data && len) {
+				P_NL80211_DRIVER_SET_NFC_PARAMS prParams = (P_NL80211_DRIVER_SET_NFC_PARAMS) data;
+
+				prChnlReqInfo->NFC_BEAM = prParams->NFC_Enable;
+				DBGLOG(P2P, INFO, "NFC: BEAM[%d]\n", prChnlReqInfo->NFC_BEAM);
+			}
+			break;
+		case 0x12:	/*NFC Beam + Indication */
+			DBGLOG(P2P, INFO, "NFC: Polling\n");
+			i4Status = mtk_cfg80211_testmode_get_scan_done(wiphy, data, len, prGlueInfo);
+			break;
+#endif
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+		case 0x30:
+			i4Status = mtk_cfg80211_testmode_get_lte_channel(wiphy, data, len, prGlueInfo);
+			break;
+#endif
+
+		default:
+			i4Status = -EINVAL;
+			break;
+		}
+	}
+
+	return i4Status;
+}
+
+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	NL80211_DRIVER_TEST_PRE_PARAMS rParams;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	UINT_32 index_mode;
+	UINT_32 index;
+	INT_32 value;
+	int status = 0;
+	UINT_32 u4Leng;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	kalMemZero(&rParams, sizeof(NL80211_DRIVER_TEST_PRE_PARAMS));
+
+	prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo;
+	prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings;
+
+	DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd\n");
+
+	if (data && len)
+		memcpy(&rParams, data, len);
+
+	DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA,idx_mode=%d idx=%d value=%u\n",
+			    (INT_16) rParams.idx_mode, (INT_16) rParams.idx, rParams.value);
+
+	index_mode = rParams.idx_mode;
+	index = rParams.idx;
+	value = rParams.value;
+
+	switch (index) {
+	case 0:		/* Listen CH */
+		break;
+	case 1:		/* P2p mode */
+		break;
+	case 4:		/* Noa duration */
+		prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value;
+		/* only to apply setting when setting NOA count */
+		/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */
+		break;
+	case 5:		/* Noa interval */
+		prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value;
+		/* only to apply setting when setting NOA count */
+		/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */
+		break;
+	case 6:		/* Noa count */
+		prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value;
+		/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */
+		break;
+	case 100:		/* Oper CH */
+		/* 20110920 - frog: User configurations are placed in ConnSettings. */
+		/* prP2pConnSettings->ucOperatingChnl = value; */
+		break;
+	case 101:		/* Local config Method, for P2P SDK */
+		prP2pConnSettings->u2LocalConfigMethod = value;
+		break;
+	case 102:		/* Sigma P2p reset */
+		/* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */
+		/* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */
+		p2pFsmUninit(prGlueInfo->prAdapter);
+		p2pFsmInit(prGlueInfo->prAdapter);
+		break;
+	case 103:		/* WPS MODE */
+		kalP2PSetWscMode(prGlueInfo, value);
+		break;
+	case 104:		/* P2p send persence, duration */
+		break;
+	case 105:		/* P2p send persence, interval */
+		break;
+	case 106:		/* P2P set sleep  */
+		value = 1;
+		kalIoctl(prGlueInfo,
+			 wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+		break;
+	case 107:		/* P2P set opps, CTWindowl */
+		prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value;
+		/* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */
+		break;
+	case 108:		/* p2p_set_power_save */
+		kalIoctl(prGlueInfo,
+			 wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+
+		break;
+	default:
+		break;
+	}
+
+	return status;
+
+}
+
+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_P2P_SIGMA_PARAMS prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+	UINT_32 index;
+	INT_32 value;
+	int status = 0;
+	UINT_32 u4Leng;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo;
+	prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings;
+
+	DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd\n");
+
+	if (data && len) {
+		prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) data;
+	} else {
+		DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd, data is NULL or len is 0\n");
+		return -EINVAL;
+	}
+
+	index = (INT_32) prParams->idx;
+	value = (INT_32) prParams->value;
+
+	DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA, idx=%d value=%d\n",
+			    (INT_32) prParams->idx, (INT_32) prParams->value);
+
+	switch (index) {
+	case 0:		/* Listen CH */
+		break;
+	case 1:		/* P2p mode */
+		break;
+	case 4:		/* Noa duration */
+		prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value;
+		/* only to apply setting when setting NOA count */
+		/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */
+		break;
+	case 5:		/* Noa interval */
+		prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value;
+		/* only to apply setting when setting NOA count */
+		/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */
+		break;
+	case 6:		/* Noa count */
+		prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value;
+		/* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */
+		break;
+	case 100:		/* Oper CH */
+		/* 20110920 - frog: User configurations are placed in ConnSettings. */
+		/* prP2pConnSettings->ucOperatingChnl = value; */
+		break;
+	case 101:		/* Local config Method, for P2P SDK */
+		prP2pConnSettings->u2LocalConfigMethod = value;
+		break;
+	case 102:		/* Sigma P2p reset */
+		/* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */
+		/* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */
+		break;
+	case 103:		/* WPS MODE */
+		kalP2PSetWscMode(prGlueInfo, value);
+		break;
+	case 104:		/* P2p send persence, duration */
+		break;
+	case 105:		/* P2p send persence, interval */
+		break;
+	case 106:		/* P2P set sleep  */
+		value = 1;
+		kalIoctl(prGlueInfo,
+			 wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+		break;
+	case 107:		/* P2P set opps, CTWindowl */
+		prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value;
+		/* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */
+		break;
+	case 108:		/* p2p_set_power_save */
+		kalIoctl(prGlueInfo,
+			 wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+
+		break;
+	case 109:		/* Max Clients */
+		kalP2PSetMaxClients(prGlueInfo, value);
+		break;
+	case 110:		/* Hotspot WPS mode */
+		kalIoctl(prGlueInfo, wlanoidSetP2pWPSmode, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng);
+		break;
+	default:
+		break;
+	}
+
+	return status;
+
+}
+
+#if CFG_SUPPORT_WFD
+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_WFD_PARAMS prParams = (P_NL80211_DRIVER_WFD_PARAMS) NULL;
+	int status = 0;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+	P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL;
+	static UINT_8 prevWfdEnable;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	prParams = (P_NL80211_DRIVER_WFD_PARAMS) data;
+
+	DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_wfd_update_cmd\n");
+
+	/* to reduce log, print when state changed */
+	if (prevWfdEnable != prParams->WfdEnable) {
+		prevWfdEnable = prParams->WfdEnable;
+		DBGLOG(P2P, INFO, "WFD Enable:%x\n", prParams->WfdEnable);
+		DBGLOG(P2P, INFO, "WFD Session Available:%x\n", prParams->WfdSessionAvailable);
+		DBGLOG(P2P, INFO, "WFD Couple Sink Status:%x\n", prParams->WfdCoupleSinkStatus);
+		/* aucReserved0[2] */
+		DBGLOG(P2P, INFO, "WFD Device Info:%x\n", prParams->WfdDevInfo);
+		DBGLOG(P2P, INFO, "WFD Control Port:%x\n", prParams->WfdControlPort);
+		DBGLOG(P2P, INFO, "WFD Maximum Throughput:%x\n", prParams->WfdMaximumTp);
+		DBGLOG(P2P, INFO, "WFD Extend Capability:%x\n", prParams->WfdExtendCap);
+		DBGLOG(P2P, INFO, "WFD Couple Sink Addr %pM\n", prParams->WfdCoupleSinkAddress);
+		DBGLOG(P2P, INFO, "WFD Associated BSSID %pM\n", prParams->WfdAssociatedBssid);
+		/* UINT_8 aucVideolp[4]; */
+		/* UINT_8 aucAudiolp[4]; */
+		DBGLOG(P2P, INFO, "WFD Video Port:%x\n", prParams->WfdVideoPort);
+		DBGLOG(P2P, INFO, "WFD Audio Port:%x\n", prParams->WfdAudioPort);
+		DBGLOG(P2P, INFO, "WFD Flag:%x\n", prParams->WfdFlag);
+		DBGLOG(P2P, INFO, "WFD Policy:%x\n", prParams->WfdPolicy);
+		DBGLOG(P2P, INFO, "WFD State:%x\n", prParams->WfdState);
+		/* UINT_8 aucWfdSessionInformationIE[24*8]; */
+		DBGLOG(P2P, INFO, "WFD Session Info Length:%x\n", prParams->WfdSessionInformationIELen);
+		/* UINT_8 aucReserved1[2]; */
+		DBGLOG(P2P, INFO, "WFD Primary Sink Addr %pM\n", prParams->aucWfdPrimarySinkMac);
+		DBGLOG(P2P, INFO, "WFD Secondary Sink Addr %pM\n", prParams->aucWfdSecondarySinkMac);
+		DBGLOG(P2P, INFO, "WFD Advanced Flag:%x\n", prParams->WfdAdvanceFlag);
+		DBGLOG(P2P, INFO, "WFD Sigma mode:%x\n", prParams->WfdSigmaMode);
+		/* UINT_8 aucReserved2[64]; */
+		/* UINT_8 aucReserved3[64]; */
+		/* UINT_8 aucReserved4[64]; */
+	}
+
+	prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+
+	kalMemCopy(&prWfdCfgSettings->u4WfdCmdType, &prParams->WfdCmdType, sizeof(WFD_CFG_SETTINGS_T));
+
+	prMsgWfdCfgUpdate = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T));
+
+	if (prMsgWfdCfgUpdate == NULL) {
+		ASSERT(FALSE);
+		return status;
+	}
+
+	prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE;
+	prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings;
+
+	mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF);
+#if 0				/* Test Only */
+/* prWfdCfgSettings->ucWfdEnable = 1; */
+/* prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; */
+	prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID;
+	prWfdCfgSettings->u2WfdDevInfo = 123;
+	prWfdCfgSettings->u2WfdControlPort = 456;
+	prWfdCfgSettings->u2WfdMaximumTp = 789;
+
+	prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_SINK_INFO_VALID;
+	prWfdCfgSettings->ucWfdCoupleSinkStatus = 0xAB;
+	{
+		UINT_8 aucTestAddr[MAC_ADDR_LEN] = { 0x77, 0x66, 0x55, 0x44, 0x33, 0x22 };
+
+		COPY_MAC_ADDR(prWfdCfgSettings->aucWfdCoupleSinkAddress, aucTestAddr);
+	}
+
+	prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_EXT_CAPABILITY_VALID;
+	prWfdCfgSettings->u2WfdExtendCap = 0xCDE;
+
+#endif
+
+	return status;
+
+}
+#endif /*  CFG_SUPPORT_WFD */
+
+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) NULL;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+	if (data && len) {
+		prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) data;
+	} else {
+		DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd, data is NULL or len is 0\n");
+		return -EINVAL;
+	}
+
+	DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd\n");
+
+	return kalP2PSetBlackList(prGlueInfo, prParams->aucBssid, prParams->ucblocked);
+}
+
+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL;
+	WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
+	int fgIsValid = 0;
+	UINT_32 u4SetInfoLen = 0;
+
+	ASSERT(wiphy);
+
+	prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+
+#if 1
+	DBGLOG(P2P, TRACE, "--> %s()\n", __func__);
+#endif
+
+	if (data && len)
+		prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data;
+
+	if (prParams) {
+		if (prParams->set == 1) {
+			rstatus = kalIoctl(prGlueInfo,
+					   (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite,
+					   &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+		}
+	}
+
+	if (WLAN_STATUS_SUCCESS != rstatus)
+		fgIsValid = -EFAULT;
+
+	return fgIsValid;
+}
+
+#endif
+
+#endif /* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c
new file mode 100644
index 0000000000000..d0f2d25a4529f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c
@@ -0,0 +1,433 @@
+/*
+* Copyright (C) 2011-2014 MediaTek Inc.
+*
+* This program is free software: you can redistribute it and/or modify it under the terms of the
+* GNU General Public License version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program.
+* If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+** Id: @(#) gl_p2p_init.c@@
+*/
+
+/*! \file   gl_p2p_init.c
+    \brief  init and exit routines of Linux driver interface for Wi-Fi Direct
+
+    This file contains the main routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define P2P_MODE_INF_NAME "p2p%d"
+#if CFG_TC1_FEATURE
+#define AP_MODE_INF_NAME "wlan%d"
+#else
+#define AP_MODE_INF_NAME "ap%d"
+#endif
+/* #define MAX_INF_NAME_LEN 15 */
+/* #define MIN_INF_NAME_LEN 1 */
+
+#define RUNNING_P2P_MODE 0
+#define RUNNING_AP_MODE 1
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*  Get interface name and running mode from module insertion parameter
+*       Usage: insmod p2p.ko mode=1
+*       default: interface name is p2p%d
+*                   running mode is P2P
+*/
+static PUCHAR ifname = P2P_MODE_INF_NAME;
+static UINT_16 mode = RUNNING_P2P_MODE;
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief    check interface name parameter is valid or not
+*             if invalid, set ifname to P2P_MODE_INF_NAME
+*
+*
+* \retval
+*/
+/*----------------------------------------------------------------------------*/
+VOID p2pCheckInterfaceName(VOID)
+{
+
+	if (mode) {
+		mode = RUNNING_AP_MODE;
+		ifname = AP_MODE_INF_NAME;
+	}
+#if 0
+	UINT_32 ifLen = 0;
+
+	if (ifname) {
+		ifLen = strlen(ifname);
+
+		if (ifLen > MAX_INF_NAME_LEN)
+			ifname[MAX_INF_NAME_LEN] = '\0';
+		else if (ifLen < MIN_INF_NAME_LEN)
+			ifname = P2P_MODE_INF_NAME;
+	} else {
+		ifname = P2P_MODE_INF_NAME;
+	}
+#endif
+}
+
+void p2pHandleSystemSuspend(void)
+{
+	struct net_device *prDev = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_8 ip[4] = { 0 };
+	UINT_32 u4NumIPv4 = 0;
+#ifdef CONFIG_IPV6
+	UINT_8 ip6[16] = { 0 };	/* FIX ME: avoid to allocate large memory in stack */
+	UINT_32 u4NumIPv6 = 0;
+#endif
+	UINT_32 i;
+	P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
+
+
+	if (!wlanExportGlueInfo(&prGlueInfo)) {
+		DBGLOG(P2P, INFO, "No glue info\n");
+		return;
+	}
+
+	ASSERT(prGlueInfo);
+	/* <1> Sanity check and acquire the net_device */
+	prDev = prGlueInfo->prP2PInfo->prDevHandler;
+	ASSERT(prDev);
+
+	/* <3> get the IPv4 address */
+	if (!prDev || !(prDev->ip_ptr) ||
+	    !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
+		DBGLOG(P2P, INFO, "ip is not available.\n");
+		return;
+	}
+	/* <4> copy the IPv4 address */
+	kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
+
+	/* todo: traverse between list to find whole sets of IPv4 addresses */
+	if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)))
+		u4NumIPv4++;
+#ifdef CONFIG_IPV6
+	/* <5> get the IPv6 address */
+	if (!prDev || !(prDev->ip6_ptr) ||
+	    !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
+		DBGLOG(P2P, INFO, "ipv6 is not available.\n");
+		return;
+	}
+	/* <6> copy the IPv6 address */
+	kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
+	DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
+	       ip6[0], ip6[1], ip6[2], ip6[3],
+	       ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]);
+	/* todo: traverse between list to find whole sets of IPv6 addresses */
+
+	if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0)))
+		; /* Do nothing */
+#endif
+	/* <7> set up the ARP filter */
+	{
+		WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+		UINT_32 u4SetInfoLen = 0;
+/* UINT_8 aucBuf[32] = {0}; */
+		UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
+		P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
+		/* aucBuf; */
+		P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
+
+		kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
+
+		prParamNetAddrList->u4AddressCount = u4NumIPv4;
+#ifdef CONFIG_IPV6
+		prParamNetAddrList->u4AddressCount += u4NumIPv6;
+#endif
+
+		prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+		for (i = 0; i < u4NumIPv4; i++) {
+			prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);	/* 4;; */
+			prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+#if 0
+			kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
+			prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr + sizeof(ip));
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
+#else
+			prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress;
+			kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
+
+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
+// TODO: frog. The pointer is not right. */
+
+			prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr +
+								    (ULONG) (prParamNetAddr->u2AddressLength +
+									     OFFSET_OF(PARAM_NETWORK_ADDRESS,
+										       aucAddress)));
+
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
+#endif
+		}
+#ifdef CONFIG_IPV6
+		for (i = 0; i < u4NumIPv6; i++) {
+			prParamNetAddr->u2AddressLength = 6;
+			prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+			kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6)); */
+
+			prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr +
+								    (ULONG) (prParamNetAddr->u2AddressLength +
+									     OFFSET_OF(PARAM_NETWORK_ADDRESS,
+										       aucAddress)));
+
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
+		}
+#endif
+		ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */));
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetP2pSetNetworkAddress,
+				   (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+		DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus);
+	}
+}
+
+void p2pHandleSystemResume(void)
+{
+	struct net_device *prDev = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_8 ip[4] = { 0 };
+#ifdef CONFIG_IPV6
+	UINT_8 ip6[16] = { 0 };	/* FIX ME: avoid to allocate large memory in stack */
+#endif
+
+	if (!wlanExportGlueInfo(&prGlueInfo)) {
+		DBGLOG(P2P, WARN, "no glue info\n");
+		return;
+	}
+
+	ASSERT(prGlueInfo);
+	/* <1> Sanity check and acquire the net_device */
+	prDev = prGlueInfo->prP2PInfo->prDevHandler;
+	ASSERT(prDev);
+
+	/* <3> get the IPv4 address */
+	if (!prDev || !(prDev->ip_ptr) ||
+	    !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
+		DBGLOG(P2P, INFO, "ip is not available.\n");
+		return;
+	}
+	/* <4> copy the IPv4 address */
+	kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
+
+#ifdef CONFIG_IPV6
+	/* <5> get the IPv6 address */
+	if (!prDev || !(prDev->ip6_ptr) ||
+	    !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
+		DBGLOG(P2P, INFO, "ipv6 is not available.\n");
+		return;
+	}
+	/* <6> copy the IPv6 address */
+	kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
+	DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
+	       ip6[0], ip6[1], ip6[2], ip6[3],
+	       ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]);
+#endif
+	/* <7> clear the ARP filter */
+	{
+		WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+		UINT_32 u4SetInfoLen = 0;
+/* UINT_8 aucBuf[32] = {0}; */
+		UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
+		P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
+		/* aucBuf; */
+
+		kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
+
+		prParamNetAddrList->u4AddressCount = 0;
+		prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+
+		ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */));
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetP2pSetNetworkAddress,
+				   (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
+
+		DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*       run p2p init procedure, include register pointer to wlan
+*                                                     glue register p2p
+*                                                     set p2p registered flag
+* \retval 1     Success
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo)
+{
+
+	DBGLOG(P2P, TRACE, "p2pLaunch\n");
+
+	if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
+		DBGLOG(P2P, INFO, "p2p already registered\n");
+		return FALSE;
+	} else if (glRegisterP2P(prGlueInfo, ifname, (BOOLEAN) mode)) {
+		prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
+
+		DBGLOG(P2P, TRACE, "Launch success, fgIsP2PRegistered TRUE.\n");
+		return TRUE;
+	}
+	DBGLOG(P2P, ERROR, "Launch Fail\n");
+
+	return FALSE;
+}
+
+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde)
+{
+	if (fgIsAPMOde) {
+		mode = RUNNING_AP_MODE;
+		ifname = AP_MODE_INF_NAME;
+	} else {
+		mode = RUNNING_P2P_MODE;
+		ifname = P2P_MODE_INF_NAME;
+	}
+
+}				/* p2pSetMode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*       run p2p exit procedure, include unregister pointer to wlan
+*                                                     glue unregister p2p
+*                                                     set p2p registered flag
+
+* \retval 1     Success
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo)
+{
+	if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
+		DBGLOG(P2P, INFO, "p2p is not Registered.\n");
+		return FALSE;
+	}
+	/*Check p2p fsm is stop or not. If not then stop now */
+	if (IS_P2P_ACTIVE(prGlueInfo->prAdapter))
+		p2pStopImmediate(prGlueInfo);
+	prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
+	glUnregisterP2P(prGlueInfo);
+	/*p2p is removed successfully */
+	return TRUE;
+
+}
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Driver entry point when the driver is configured as a Linux Module, and
+*        is called once at module load time, by the user-level modutils
+*        application: insmod or modprobe.
+*
+* \retval 0     Success
+*/
+/*----------------------------------------------------------------------------*/
+static int initP2P(void)
+{
+	P_GLUE_INFO_T prGlueInfo;
+
+	/*check interface name validation */
+	p2pCheckInterfaceName();
+
+	DBGLOG(P2P, INFO, "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP" : "P2P");
+
+	/*register p2p init & exit function to wlan sub module handler */
+	wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
+
+	/*if wlan is not start yet, do nothing
+	 * p2pLaunch will be called by txthread while wlan start
+	 */
+	/*if wlan is not started yet, return FALSE */
+	if (wlanExportGlueInfo(&prGlueInfo)) {
+		wlanSubModInit(prGlueInfo);
+		return prGlueInfo->prAdapter->fgIsP2PRegistered ? 0 : -EIO;
+	}
+
+	return 0;
+}				/* end of initP2P() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Driver exit point when the driver as a Linux Module is removed. Called
+*        at module unload time, by the user level modutils application: rmmod.
+*        This is our last chance to clean up after ourselves.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+/* 1 Module Leave Point */
+static VOID __exit exitP2P(void)
+{
+	P_GLUE_INFO_T prGlueInfo;
+
+	DBGLOG(P2P, INFO, KERN_INFO DRV_NAME "ExitP2P\n");
+
+	/*if wlan is not started yet, return FALSE */
+	if (wlanExportGlueInfo(&prGlueInfo))
+		wlanSubModExit(prGlueInfo);
+	/*UNregister p2p init & exit function to wlan sub module handler */
+	wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
+}				/* end of exitP2P() */
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c
new file mode 100644
index 0000000000000..11a417e4c74c9
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c
@@ -0,0 +1,1314 @@
+/*
+** Id: @(#) gl_p2p_cfg80211.c@@
+*/
+
+/*! \file   gl_p2p_kal.c
+    \brief
+
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "net/cfg80211.h"
+#include "precomp.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Wi-Fi Direct state from glue layer
+*
+* \param[in]
+*           prGlueInfo
+*           rPeerAddr
+* \return
+*           ENUM_BOW_DEVICE_STATE
+*/
+/*----------------------------------------------------------------------------*/
+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->prP2PInfo->eState;
+}				/* end of kalP2PGetState() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to update the assoc req to p2p
+*
+* \param[in]
+*           prGlueInfo
+*           pucFrameBody
+*           u4FrameBodyLen
+*           fgReassocRequest
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo,
+		      IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest)
+{
+	union iwreq_data wrqu;
+	unsigned char *pucExtraInfo = NULL;
+	unsigned char *pucDesiredIE = NULL;
+/* unsigned char aucExtraInfoBuf[200]; */
+	PUINT_8 cp;
+
+	memset(&wrqu, 0, sizeof(wrqu));
+
+	if (fgReassocRequest) {
+		if (u4FrameBodyLen < 15) {
+			/*
+			   printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
+			 */
+			return;
+		}
+	} else {
+		if (u4FrameBodyLen < 9) {
+			/*
+			   printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
+			 */
+			return;
+		}
+	}
+
+	cp = pucFrameBody;
+
+	if (fgReassocRequest) {
+		/* Capability information field 2 */
+		/* Listen interval field 2 */
+		/* Current AP address 6 */
+		cp += 10;
+		u4FrameBodyLen -= 10;
+	} else {
+		/* Capability information field 2 */
+		/* Listen interval field 2 */
+		cp += 4;
+		u4FrameBodyLen -= 4;
+	}
+
+	/* do supplicant a favor, parse to the start of WPA/RSN IE */
+	if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) {
+		/* printk("wextSrchDesiredWPSIE!!\n"); */
+		/* WPS IE found */
+	} else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0x30, &pucDesiredIE)) {
+		/* printk("wextSrchDesiredWPAIE!!\n"); */
+		/* RSN IE found */
+	} else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) {
+		/* printk("wextSrchDesiredWPAIE!!\n"); */
+		/* WPA IE found */
+	} else {
+		/* no WPA/RSN IE found, skip this event */
+		goto skip_indicate_event;
+	}
+
+	/* IWEVASSOCREQIE, indicate binary string */
+	pucExtraInfo = pucDesiredIE;
+	wrqu.data.length = pucDesiredIE[1] + 2;
+
+	/* Send event to user space */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVASSOCREQIE, &wrqu, pucExtraInfo);
+
+skip_indicate_event:
+	return;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to set Wi-Fi Direct state in glue layer
+*
+* \param[in]
+*           prGlueInfo
+*           eBowState
+*           rPeerAddr
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo,
+	       IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	memset(&evt, 0, sizeof(evt));
+
+	if (eState == PARAM_MEDIA_STATE_CONNECTED) {
+		prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_CONNECTED;
+
+		snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_CONNECT=%pM ", rPeerAddr);
+		evt.data.length = strlen(aucBuffer);
+
+		/* indicate in IWECUSTOM event */
+		wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+	} else if (eState == PARAM_MEDIA_STATE_DISCONNECTED) {
+		snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_DISCONNECT=%pM ", rPeerAddr);
+		evt.data.length = strlen(aucBuffer);
+
+		/* indicate in IWECUSTOM event */
+		wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+	} else {
+		ASSERT(0);
+	}
+
+}				/* end of kalP2PSetState() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Wi-Fi Direct operating frequency
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           in unit of KHz
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->prP2PInfo->u4FreqInKHz;
+}				/* end of kalP2PGetFreqInKHz() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to retrieve Bluetooth-over-Wi-Fi role
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           0: P2P Device
+*           1: Group Client
+*           2: Group Owner
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo)
+{
+	ASSERT(prGlueInfo);
+
+	return prGlueInfo->prP2PInfo->ucRole;
+}				/* end of kalP2PGetRole() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to set Wi-Fi Direct role
+*
+* \param[in]
+*           prGlueInfo
+*           ucResult
+*                   0: successful
+*                   1: error
+*           ucRole
+*                   0: P2P Device
+*                   1: Group Client
+*                   2: Group Owner
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo,
+	      IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+	ASSERT(ucRole <= 2);
+
+	memset(&evt, 0, sizeof(evt));
+
+	if (ucResult == 0)
+		prGlueInfo->prP2PInfo->ucRole = ucRole;
+
+	if (pucSSID)
+		snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole,
+			 1 /* persistence or not */ , pucSSID[7], pucSSID[8]);
+	else
+		snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole,
+			 1 /* persistence or not */ , '0', '0');
+
+	evt.data.length = strlen(aucBuffer);
+
+	/* if (pucSSID) */
+	/* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */
+
+	/* indicate in IWECUSTOM event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+}				/* end of kalP2PSetRole() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to set the cipher for p2p
+*
+* \param[in]
+*           prGlueInfo
+*           u4Cipher
+*
+* \return
+*           none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	prGlueInfo->prP2PInfo->u4CipherPairwise = u4Cipher;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to get the cipher, return for cipher is ccmp
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           TRUE: cipher is ccmp
+*           FALSE: cipher is none
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP)
+		return TRUE;
+
+	if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP)
+		return TRUE;
+
+	return FALSE;
+}
+
+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP)
+		return TRUE;
+
+	if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP)
+		return FALSE;
+
+	return FALSE;
+}
+
+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP)
+		return FALSE;
+
+	if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP)
+		return TRUE;
+
+	return FALSE;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to set the status of WSC
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	prGlueInfo->prP2PInfo->ucWSCRunning = ucWscMode;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to get the status of WSC
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return 0;
+	}
+
+	return prGlueInfo->prP2PInfo->ucWSCRunning;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to get the wsc ie length
+*
+* \param[in]
+*           prGlueInfo
+*           ucType : 0 for beacon, 1 for probe req, 2 for probe resp
+*
+* \return
+*           The WSC IE length
+*/
+/*----------------------------------------------------------------------------*/
+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType)
+{
+	ASSERT(prGlueInfo);
+
+	ASSERT(ucType < 3);
+
+	return prGlueInfo->prP2PInfo->u2WSCIELen[ucType];
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to copy the wsc ie setting from p2p supplicant
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*           The WPS IE length
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer)
+{
+	P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL;
+
+	do {
+		if ((prGlueInfo == NULL) || (ucType >= 3) || (pucBuffer == NULL))
+			break;
+
+		prGlP2pInfo = prGlueInfo->prP2PInfo;
+
+		kalMemCopy(pucBuffer, prGlP2pInfo->aucWSCIE[ucType], prGlP2pInfo->u2WSCIELen[ucType]);
+
+	} while (FALSE);
+
+}
+
+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength)
+{
+	P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL;
+
+	do {
+		if ((prGlueInfo == NULL) || (ucType >= 3) || ((u2BufferLength > 0) && (pucBuffer == NULL)))
+			break;
+
+		if (u2BufferLength > 400) {
+			DBGLOG(P2P, ERROR,
+			       "Buffer length is not enough, GLUE only 400 bytes but %d received\n", u2BufferLength);
+			ASSERT(FALSE);
+			break;
+		}
+
+		prGlP2pInfo = prGlueInfo->prP2PInfo;
+
+		kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], pucBuffer, u2BufferLength);
+
+		prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength;
+
+	} while (FALSE);
+
+}				/* kalP2PUpdateWSC_IE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief indicate an event to supplicant for device connection request
+*
+* \param[in] prGlueInfo Pointer of GLUE_INFO_T
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength,
+			   IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType,	/* 0: P2P Device / 1: GC / 2: GO */
+			   IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	/* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */
+	prGlueInfo->prP2PInfo->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength;
+	kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, pucDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength);
+	COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, rPeerAddr);
+	prGlueInfo->prP2PInfo->ucConnReqDevType = ucDevType;
+	prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = i4ConfigMethod;
+	prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod;
+
+	/* prepare event structure */
+	memset(&evt, 0, sizeof(evt));
+
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ");
+	evt.data.length = strlen(aucBuffer);
+
+	/* indicate in IWEVCUSTOM event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+}				/* end of kalP2PIndicateConnReq() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Indicate an event to supplicant for device connection request from other device.
+*
+* \param[in] prGlueInfo Pointer of GLUE_INFO_T
+* \param[in] pucGroupBssid  Only valid when invitation Type equals to 0.
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo,
+			   IN P_P2P_DEVICE_DESC_T prP2pDevDesc,
+			   IN PUINT_8 pucSsid,
+			   IN UINT_8 ucSsidLen,
+			   IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid)
+{
+#if 1
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	/* buffer peer information for later IOC_P2P_GET_STRUCT access */
+	prGlueInfo->prP2PInfo->u4ConnReqNameLength =
+	    (UINT_32) ((prP2pDevDesc->u2NameLength > 32) ? 32 : prP2pDevDesc->u2NameLength);
+	kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, prP2pDevDesc->aucName,
+		   prGlueInfo->prP2PInfo->u4ConnReqNameLength);
+	COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, prP2pDevDesc->aucDeviceAddr);
+	COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqGroupAddr, pucGroupBssid);
+	prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = (INT_32) (prP2pDevDesc->u2ConfigMethod);
+	prGlueInfo->prP2PInfo->ucOperatingChnl = ucOperatingChnl;
+	prGlueInfo->prP2PInfo->ucInvitationType = ucInvitationType;
+
+	/* prepare event structure */
+	memset(&evt, 0, sizeof(evt));
+
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE");
+	evt.data.length = strlen(aucBuffer);
+
+	/* indicate in IWEVCUSTOM event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+	return;
+
+#else
+	P_MSG_P2P_CONNECTION_REQUEST_T prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL;
+	P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+	P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
+
+	do {
+		ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL));
+
+		/* Not a real solution */
+
+		prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo;
+		prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings;
+
+		prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter,
+									    RAM_TYPE_MSG,
+									    sizeof(MSG_P2P_CONNECTION_REQUEST_T));
+
+		if (prP2pConnReq == NULL)
+			break;
+
+		kalMemZero(prP2pConnReq, sizeof(MSG_P2P_CONNECTION_REQUEST_T));
+
+		prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ;
+
+		prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO;
+
+		COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, prP2pDevDesc->aucDeviceAddr);
+
+		prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod;
+
+		if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) {
+			prP2pConnReq->fgIsPersistentGroup = FALSE;
+			prP2pConnReq->fgIsTobeGO = FALSE;
+
+		}
+
+		else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) {
+			DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n");
+			prP2pConnReq->fgIsPersistentGroup = TRUE;
+			prP2pConnReq->fgIsTobeGO = (prGlueInfo->prP2PInfo->ucRole == 2) ? TRUE : FALSE;
+
+		}
+
+		p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL);
+
+		if (ucOperatingChnl != 0)
+			prP2pSpecificBssInfo->ucPreferredChannel = ucOperatingChnl;
+
+		if ((ucSsidLen < 32) && (pucSsid != NULL))
+			COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, pucSsid, ucSsidLen);
+
+		mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pConnReq, MSG_SEND_METHOD_BUF);
+
+	} while (FALSE);
+
+	/* frog add. */
+	/* TODO: Invitation Indication */
+
+	return;
+#endif
+
+}				/* kalP2PInvitationIndication */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Indicate an status to supplicant for device invitation status.
+*
+* \param[in] prGlueInfo Pointer of GLUE_INFO_T
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	/* buffer peer information for later IOC_P2P_GET_STRUCT access */
+	prGlueInfo->prP2PInfo->u4InvStatus = u4InvStatus;
+
+	/* prepare event structure */
+	memset(&evt, 0, sizeof(evt));
+
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS");
+	evt.data.length = strlen(aucBuffer);
+
+	/* indicate in IWEVCUSTOM event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+}				/* kalP2PInvitationStatus */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Indicate an event to supplicant for Service Discovery request from other device.
+*
+* \param[in] prGlueInfo Pointer of GLUE_INFO_T
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	memset(&evt, 0, sizeof(evt));
+
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_REQ %d", ucSeqNum);
+	evt.data.length = strlen(aucBuffer);
+
+	/* indicate IWEVP2PSDREQ event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+}				/* end of kalP2PIndicateSDRequest() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Indicate an event to supplicant for Service Discovery response
+*         from other device.
+*
+* \param[in] prGlueInfo Pointer of GLUE_INFO_T
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	memset(&evt, 0, sizeof(evt));
+
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_RESP %d", ucSeqNum);
+	evt.data.length = strlen(aucBuffer);
+
+	/* indicate IWEVP2PSDREQ event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+}				/* end of kalP2PIndicateSDResponse() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Indicate an event to supplicant for Service Discovery TX Done
+*         from other device.
+*
+* \param[in] prGlueInfo Pointer of GLUE_INFO_T
+* \param[in] ucSeqNum   Sequence number of the frame
+* \param[in] ucStatus   Status code for TX
+*
+* \retval none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	memset(&evt, 0, sizeof(evt));
+
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus);
+	evt.data.length = strlen(aucBuffer);
+
+	/* indicate IWEVP2PSDREQ event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+
+}				/* end of kalP2PIndicateSDResponse() */
+
+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return NULL;
+	}
+
+	return prGlueInfo->prP2PInfo->prDevHandler;
+}
+
+#if CFG_SUPPORT_ANTI_PIRACY
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen)
+{
+	union iwreq_data evt;
+	UINT_8 aucBuffer[IW_CUSTOM_MAX];
+
+	ASSERT(prGlueInfo);
+
+	memset(&evt, 0, sizeof(evt));
+	snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP=");
+
+	kalMemCopy(prGlueInfo->prP2PInfo->aucSecCheckRsp, pucRsp, u2RspLen);
+	evt.data.length = strlen(aucBuffer);
+
+#if DBG
+	DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u2RspLen);
+#endif
+	/* indicate in IWECUSTOM event */
+	wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer);
+}				/* p2pFsmRunEventRxDisassociation */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param[in] prAdapter  Pointer of ADAPTER_T
+*
+* \return none
+*/
+/*----------------------------------------------------------------------------*/
+VOID
+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo,
+	       IN ENUM_BAND_T eSpecificBand,
+	       IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList)
+{
+	rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum,
+			     pucNumOfChannel, paucChannelList);
+}				/* kalGetChnlList */
+
+/* ////////////////////////////////////ICS SUPPORT////////////////////////////////////// */
+
+VOID
+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo,
+			   IN UINT_64 u8SeqNum,
+			   IN UINT_32 u4ChannelNum,
+			   IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration)
+{
+	struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL;
+	RF_CHANNEL_INFO_T rChannelInfo;
+	enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT;
+
+	do {
+		if (prGlueInfo == NULL)
+			break;
+
+		kalMemZero(&rChannelInfo, sizeof(RF_CHANNEL_INFO_T));
+
+		rChannelInfo.ucChannelNum = u4ChannelNum;
+		rChannelInfo.eBand = eBand;
+
+		prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo, &rChannelInfo);
+
+		kalP2pFuncGetChannelType(eSco, &eChnlType);
+
+		cfg80211_ready_on_channel(prGlueInfo->prP2PInfo->prWdev,	/* struct wireless_dev, */
+					  u8SeqNum,	/* u64 cookie, */
+					  prIEEE80211ChnlStruct,	/* struct ieee80211_channel * chan, */
+					  u4Duration,	/* unsigned int duration, */
+					  GFP_KERNEL);	/* gfp_t gfp */    /* allocation flags */
+	} while (FALSE);
+
+}				/* kalP2PIndicateChannelReady */
+
+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo)
+{
+
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+	struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL;
+	enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT;
+	RF_CHANNEL_INFO_T rRfChannelInfo;
+
+	do {
+		if ((prGlueInfo == NULL) || (prChnlReqInfo == NULL)) {
+
+			ASSERT(FALSE);
+			break;
+		}
+
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		if (prGlueP2pInfo == NULL) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n");
+
+		rRfChannelInfo.eBand = prChnlReqInfo->eBand;
+		rRfChannelInfo.ucChannelNum = prChnlReqInfo->ucReqChnlNum;
+
+		prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueP2pInfo, &rRfChannelInfo);
+
+		kalP2pFuncGetChannelType(prChnlReqInfo->eChnlSco, &eChnlType);
+
+		cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev,	/* struct wireless_dev, */
+						   prChnlReqInfo->u8Cookie, prIEEE80211ChnlStruct, GFP_KERNEL);
+	} while (FALSE);
+
+}				/* kalP2PIndicateChannelExpired */
+
+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort)
+{
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+	struct cfg80211_scan_request *prScanRequest = NULL;
+        struct cfg80211_scan_info info = {
+                .aborted = true,
+        };
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	do {
+		if (prGlueInfo == NULL) {
+
+			ASSERT(FALSE);
+			break;
+		}
+
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		if (prGlueP2pInfo == NULL) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		DBGLOG(INIT, TRACE, "[p2p] scan complete %p\n", prGlueP2pInfo->prScanRequest);
+
+		GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+		if (prGlueP2pInfo->prScanRequest != NULL) {
+			prScanRequest = prGlueP2pInfo->prScanRequest;
+			prGlueP2pInfo->prScanRequest = NULL;
+		}
+		GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+
+		/* 2. then CFG80211 Indication */
+
+		if (prScanRequest != NULL) {
+
+			/* report all queued beacon/probe response frames  to upper layer */
+			scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL);
+
+			info.aborted = fgIsAbort;
+			DBGLOG(INIT, TRACE, "DBG:p2p_cfg_scan_done\n");
+			cfg80211_scan_done(prScanRequest, &info);
+		}
+
+	} while (FALSE);
+
+}				/* kalP2PIndicateScanDone */
+
+VOID
+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo,
+		      IN PUINT_8 pucFrameBuf,
+		      IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength)
+{
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+	struct ieee80211_channel *prChannelEntry = (struct ieee80211_channel *)NULL;
+	struct ieee80211_mgmt *prBcnProbeRspFrame = (struct ieee80211_mgmt *)pucFrameBuf;
+	struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL;
+
+	do {
+		if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (prChannelInfo == NULL)) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		if (prGlueP2pInfo == NULL) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		prChannelEntry = kalP2pFuncGetChannelEntry(prGlueP2pInfo, prChannelInfo);
+
+		if (prChannelEntry == NULL) {
+			DBGLOG(P2P, WARN, "Unknown channel info\n");
+			break;
+		}
+		/* rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; */
+
+		prCfg80211Bss = cfg80211_inform_bss_frame(prGlueP2pInfo->prWdev->wiphy,	/* struct wiphy * wiphy, */
+							  prChannelEntry,
+							  prBcnProbeRspFrame, u4BufLen, i4SignalStrength, GFP_KERNEL);
+
+		/* Return this structure. */
+		if (!prCfg80211Bss) {
+			DBGLOG(P2P, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n",
+					prChannelInfo->ucChannelNum, i4SignalStrength);
+		} else {
+			cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, prCfg80211Bss);
+			DBGLOG(P2P, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n",
+					prChannelInfo->ucChannelNum, i4SignalStrength);
+		}
+	} while (FALSE);
+
+}				/* kalP2PIndicateBssInfo */
+
+VOID
+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo,
+			   IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen)
+{
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+
+	do {
+		if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) {
+			DBGLOG(P2P, TRACE, "Unexpected pointer PARAM. %p, %p, %u.",
+					    prGlueInfo, pucFrameBuf, u4FrameLen);
+			ASSERT(FALSE);
+			break;
+		}
+
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		cfg80211_mgmt_tx_status(prGlueP2pInfo->prWdev,	/* struct net_device * dev, */
+					u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL);
+
+	} while (FALSE);
+
+}				/* kalP2PIndicateMgmtTxStatus */
+
+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb)
+{
+#define DBG_P2P_MGMT_FRAME_INDICATION 0
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+	INT_32 i4Freq = 0;
+	UINT_8 ucChnlNum = 0;
+#if DBG_P2P_MGMT_FRAME_INDICATION
+	P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL;
+#endif
+
+	do {
+		if ((prGlueInfo == NULL) || (prSwRfb == NULL)) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum;
+
+#if DBG_P2P_MGMT_FRAME_INDICATION
+
+		prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader;
+
+		switch (prWlanHeader->u2FrameCtrl) {
+		case MAC_FRAME_PROBE_REQ:
+			DBGLOG(P2P, TRACE, "RX Probe Req at channel %d ", ucChnlNum);
+			break;
+		case MAC_FRAME_PROBE_RSP:
+			DBGLOG(P2P, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum);
+			break;
+		case MAC_FRAME_ACTION:
+			DBGLOG(P2P, TRACE, "RX Action frame at channel %d ", ucChnlNum);
+			break;
+		default:
+			DBGLOG(P2P, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum);
+			break;
+		}
+
+		DBGLOG(P2P, TRACE, "from: %pM\n", prWlanHeader->aucAddr2);
+#endif
+		i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000;
+
+		cfg80211_rx_mgmt(prGlueP2pInfo->prWdev,	/* struct net_device * dev, */
+				 i4Freq,
+				 RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi),
+				 prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_ATOMIC);
+	} while (FALSE);
+
+}				/* kalP2PIndicateRxMgmtFrame */
+
+VOID
+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo,
+				 IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo,
+				 IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason,
+				 IN WLAN_STATUS eStatus)
+{
+	P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL;
+
+	do {
+		if (prGlueInfo == NULL) {
+			ASSERT(FALSE);
+			break;
+		}
+
+		prGlueP2pInfo = prGlueInfo->prP2PInfo;
+
+		if (prP2pConnInfo) {
+			cfg80211_connect_result(prGlueP2pInfo->prDevHandler,	/* struct net_device * dev, */
+						prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf,
+						prP2pConnInfo->u4BufLength,
+						pucRxIEBuf, u2RxIELen, u2StatusReason, GFP_KERNEL);
+						/* gfp_t gfp */   /* allocation flags */
+			prP2pConnInfo->fgIsConnRequest = FALSE;
+		} else {
+			/* Disconnect, what if u2StatusReason == 0? */
+			cfg80211_disconnected(prGlueP2pInfo->prDevHandler,	/* struct net_device * dev, */
+					      u2StatusReason, pucRxIEBuf, u2RxIELen, 
+					      eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ? true : false,
+					      GFP_KERNEL);
+		}
+
+	} while (FALSE);
+
+}				/* kalP2PGCIndicateConnectionStatus */
+
+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew)
+{
+	P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL;
+	struct station_info rStationInfo;
+
+	memset(&rStationInfo, 0, sizeof(struct station_info));
+
+	do {
+		if ((prGlueInfo == NULL) || (prCliStaRec == NULL))
+			break;
+
+		prP2pGlueInfo = prGlueInfo->prP2PInfo;
+
+		if (fgIsNew) {
+			//rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES;
+			rStationInfo.generation = ++prP2pGlueInfo->i4Generation;
+
+			rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe;
+			rStationInfo.assoc_req_ies_len = prCliStaRec->u2AssocReqIeLen;
+/* rStationInfo.filled |= STATION_INFO_ASSOC_REQ_IES; */
+
+			cfg80211_new_sta(prGlueInfo->prP2PInfo->prDevHandler,	/* struct net_device * dev, */
+					 prCliStaRec->aucMacAddr, &rStationInfo, GFP_KERNEL);
+		} else {
+			++prP2pGlueInfo->i4Generation;
+
+			cfg80211_del_sta(prGlueInfo->prP2PInfo->prDevHandler,	/* struct net_device * dev, */
+					 prCliStaRec->aucMacAddr, GFP_KERNEL);
+		}
+
+	} while (FALSE);
+
+	return;
+
+}				/* kalP2PGOStationUpdate */
+
+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type)
+{
+	BOOLEAN fgIsValid = FALSE;
+
+	do {
+		if (channel_type) {
+
+			switch (rChnlSco) {
+			case CHNL_EXT_SCN:
+				*channel_type = NL80211_CHAN_NO_HT;
+				break;
+			case CHNL_EXT_SCA:
+				*channel_type = NL80211_CHAN_HT40MINUS;
+				break;
+			case CHNL_EXT_SCB:
+				*channel_type = NL80211_CHAN_HT40PLUS;
+				break;
+			default:
+				ASSERT(FALSE);
+				*channel_type = NL80211_CHAN_NO_HT;
+				break;
+			}
+
+		}
+
+		fgIsValid = TRUE;
+	} while (FALSE);
+
+	return fgIsValid;
+}				/* kalP2pFuncGetChannelType */
+
+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo)
+{
+	struct ieee80211_channel *prTargetChannelEntry = (struct ieee80211_channel *)NULL;
+	UINT_32 u4TblSize = 0, u4Idx = 0;
+	struct ieee80211_supported_band **bands;
+
+	do {
+		if ((prP2pInfo == NULL) || (prChannelInfo == NULL))
+			break;
+		bands = &prP2pInfo->prWdev->wiphy->bands[0];
+		switch (prChannelInfo->eBand) {
+		case BAND_2G4:
+			prTargetChannelEntry = bands[NL80211_BAND_2GHZ]->channels;
+			u4TblSize = bands[NL80211_BAND_2GHZ]->n_channels;
+			break;
+		case BAND_5G:
+			prTargetChannelEntry = bands[NL80211_BAND_5GHZ]->channels;
+			u4TblSize = bands[NL80211_BAND_5GHZ]->n_channels;
+			break;
+		default:
+			break;
+		}
+
+		if (prTargetChannelEntry == NULL)
+			break;
+
+		for (u4Idx = 0; u4Idx < u4TblSize; u4Idx++, prTargetChannelEntry++) {
+			if (prTargetChannelEntry->hw_value == prChannelInfo->ucChannelNum)
+				break;
+		}
+
+		if (u4Idx == u4TblSize) {
+			prTargetChannelEntry = NULL;
+			break;
+		}
+
+	} while (FALSE);
+
+	return prTargetChannelEntry;
+}				/* kalP2pFuncGetChannelEntry */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to set the block list of Hotspot
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock)
+{
+	UINT_8 aucNullAddr[] = NULL_MAC_ADDR;
+	UINT_32 i;
+
+	ASSERT(prGlueInfo);
+	ASSERT(prGlueInfo->prP2PInfo);
+
+	if (EQUAL_MAC_ADDR(rbssid, aucNullAddr))
+		return -EINVAL;
+
+	if (fgIsblock) {
+		for (i = 0; i < 8; i++) {
+			if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) {
+				break;
+			} else if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr)) {
+				COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid);
+				break;
+			}
+		}
+		if (i >= 8) {
+			DBGLOG(P2P, ERROR, "AP black list is full, cannot block more STA!!\n");
+			return -ENOBUFS;
+		}
+	} else {
+		for (i = 0; i < 8; i++) {
+			if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) {
+				COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr);
+				break;
+			}
+		}
+		if (i >= 8)
+			DBGLOG(P2P, ERROR, "The STA is not found in black list!!\n");
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to compare the black list of Hotspot
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid)
+{
+	UINT_8 aucNullAddr[] = NULL_MAC_ADDR;
+	BOOLEAN fgIsExsit = FALSE;
+	UINT_32 i;
+
+	ASSERT(prGlueInfo);
+	ASSERT(prGlueInfo->prP2PInfo);
+
+	for (i = 0; i < 8; i++) {
+		if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) {
+			if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) {
+				fgIsExsit = TRUE;
+				return fgIsExsit;
+			}
+		}
+	}
+
+	return fgIsExsit;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to return the max clients of Hotspot
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return;
+	}
+
+	if (u4MaxClient == 0 || prGlueInfo->prP2PInfo->ucMaxClients >= P2P_MAXIMUM_CLIENT_COUNT)
+		prGlueInfo->prP2PInfo->ucMaxClients = P2P_MAXIMUM_CLIENT_COUNT;
+	else
+		prGlueInfo->prP2PInfo->ucMaxClients = u4MaxClient;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief to return the max clients of Hotspot
+*
+* \param[in]
+*           prGlueInfo
+*
+* \return
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient)
+{
+	if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) {
+		ASSERT(FALSE);
+		return FALSE;
+	}
+
+	if (prGlueInfo->prP2PInfo->ucMaxClients) {
+		if ((UINT_8) u4NumClient > prGlueInfo->prP2PInfo->ucMaxClients)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return FALSE;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c
new file mode 100644
index 0000000000000..075045f547b7c
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c
@@ -0,0 +1,1020 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_proc.c#1
+*/
+
+/*! \file   "gl_proc.c"
+    \brief  This file defines the interface which can interact with users in /proc fs.
+
+    Detail description.
+*/
+
+/*
+** Log: gl_proc.c
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 12 10 2010 kevin.huang
+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
+ * Add Linux Proc Support
+**  \main\maintrunk.MT5921\19 2008-09-02 21:08:37 GMT mtk01461
+**  Fix the compile error of SPRINTF()
+**  \main\maintrunk.MT5921\18 2008-08-10 18:48:28 GMT mtk01461
+**  Update for Driver Review
+**  \main\maintrunk.MT5921\17 2008-08-04 16:52:01 GMT mtk01461
+**  Add proc dbg print message of DOMAIN_INDEX level
+**  \main\maintrunk.MT5921\16 2008-07-10 00:45:16 GMT mtk01461
+**  Remove the check of MCR offset, we may use the MCR address which is not align to DW boundary or proprietary usage.
+**  \main\maintrunk.MT5921\15 2008-06-03 20:49:44 GMT mtk01461
+**  \main\maintrunk.MT5921\14 2008-06-02 22:56:00 GMT mtk01461
+**  Rename some functions for linux proc
+**  \main\maintrunk.MT5921\13 2008-06-02 20:23:18 GMT mtk01461
+**  Revise PROC mcr read / write for supporting TELNET
+**  \main\maintrunk.MT5921\12 2008-03-28 10:40:25 GMT mtk01461
+**  Remove temporary set desired rate in linux proc
+**  \main\maintrunk.MT5921\11 2008-01-07 15:07:29 GMT mtk01461
+**  Add User Update Desired Rate Set for QA in Linux
+**  \main\maintrunk.MT5921\10 2007-12-11 00:11:14 GMT mtk01461
+**  Fix SPIN_LOCK protection
+**  \main\maintrunk.MT5921\9 2007-12-04 18:07:57 GMT mtk01461
+**  Add additional debug category to proc
+**  \main\maintrunk.MT5921\8 2007-11-02 01:03:23 GMT mtk01461
+**  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
+**  \main\maintrunk.MT5921\7 2007-10-25 18:08:14 GMT mtk01461
+**  Add VOIP SCAN Support  & Refine Roaming
+** Revision 1.3  2007/07/05 07:25:33  MTK01461
+** Add Linux initial code, modify doc, add 11BB, RF init code
+**
+** Revision 1.2  2007/06/27 02:18:51  MTK01461
+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "precomp.h"
+
+/* #include "wlan_lib.h" */
+/* #include "debug.h" */
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#define PROC_WLAN_THERMO                        "wlanThermo"
+#define PROC_DRV_STATUS                         "status"
+#define PROC_RX_STATISTICS                      "rx_statistics"
+#define PROC_TX_STATISTICS                      "tx_statistics"
+#define PROC_DBG_LEVEL_NAME						"dbgLevel"
+#define PROC_NEED_TX_DONE						"TxDoneCfg"
+#define PROC_AUTO_PER_CFG						"autoPerCfg"
+#define PROC_ROOT_NAME			"wlan"
+#define PROC_CMD_DEBUG_NAME		"cmdDebug"
+
+#define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN      20
+#define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN   10
+#define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN   10
+#define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN       (20*10)
+#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN      8
+
+#define PROC_UID_SHELL							2000
+#define PROC_GID_WIFI							1010
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+/* static UINT_32 u4McrOffset; */
+#if CFG_SUPPORT_THERMO_THROTTLING
+static P_GLUE_INFO_T g_prGlueInfo_proc;
+#endif
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for reading MCR register to User Space, the offset of
+*        the MCR is specified in u4McrOffset.
+*
+* \param[in] page       Buffer provided by kernel.
+* \param[in out] start  Start Address to read(3 methods).
+* \param[in] off        Offset.
+* \param[in] count      Allowable number to read.
+* \param[out] eof       End of File indication.
+* \param[in] data       Pointer to the private data structure.
+*
+* \return number of characters print to the buffer from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+#if 0
+static int procMCRRead(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo;
+	UINT_32 u4BufLen;
+	char *p = page;
+	UINT_32 u4Count;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(data);
+
+	/* Kevin: Apply PROC read method 1. */
+	if (off != 0)
+		return 0;	/* To indicate end of file. */
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data));
+
+	rMcrInfo.u4McrOffset = u4McrOffset;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryMcrRead,
+			   (PVOID)&rMcrInfo, sizeof(rMcrInfo), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
+
+	/* SPRINTF(p, ("MCR (0x%08lxh): 0x%08lx\n", */
+	/* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData)); */
+
+	u4Count = (UINT_32) (p - page);
+
+	*eof = 1;
+
+	return (int)u4Count;
+
+}				/* end of procMCRRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for writing MCR register to HW or update u4McrOffset
+*        for reading MCR later.
+*
+* \param[in] file   pointer to file.
+* \param[in] buffer Buffer from user space.
+* \param[in] count  Number of characters to write
+* \param[in] data   Pointer to the private data structure.
+*
+* \return number of characters write from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static int procMCRWrite(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1];	/* + 1 for "\0" */
+	int i4CopySize;
+	PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo;
+	UINT_32 u4BufLen;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(data);
+
+	i4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
+	if (copy_from_user(acBuf, buffer, i4CopySize))
+		return 0;
+	acBuf[i4CopySize] = '\0';
+
+	if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 2) {
+		/* NOTE: Sometimes we want to test if bus will still be ok, after accessing
+		 * the MCR which is not align to DW boundary.
+		 */
+		/* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */
+		prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data));
+
+		u4McrOffset = rMcrInfo.u4McrOffset;
+
+		/* printk("Write 0x%lx to MCR 0x%04lx\n", */
+		/* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData); */
+
+		rStatus = kalIoctl(prGlueInfo,
+				wlanoidSetMcrWrite,
+				(PVOID)&rMcrInfo, sizeof(rMcrInfo), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+	}
+
+	if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 1) {
+		/* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */
+		u4McrOffset = rMcrInfo.u4McrOffset;
+	}
+
+	return count;
+
+}				/* end of procMCRWrite() */
+#endif
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for reading Driver Status to User Space.
+*
+* \param[in] page       Buffer provided by kernel.
+* \param[in out] start  Start Address to read(3 methods).
+* \param[in] off        Offset.
+* \param[in] count      Allowable number to read.
+* \param[out] eof       End of File indication.
+* \param[in] data       Pointer to the private data structure.
+*
+* \return number of characters print to the buffer from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static int procDrvStatusRead(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
+	char *p = page;
+	UINT_32 u4Count;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(data);
+
+	/* Kevin: Apply PROC read method 1. */
+	if (off != 0)
+		return 0;	/* To indicate end of file. */
+
+	SPRINTF(p, ("GLUE LAYER STATUS:"));
+	SPRINTF(p, ("\n=================="));
+
+	SPRINTF(p, ("\n* Number of Pending Frames: %ld\n", prGlueInfo->u4TxPendingFrameNum));
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+	wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count);
+
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+	u4Count += (UINT_32) (p - page);
+
+	*eof = 1;
+
+	return (int)u4Count;
+
+}				/* end of procDrvStatusRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for reading Driver RX Statistic Counters to User Space.
+*
+* \param[in] page       Buffer provided by kernel.
+* \param[in out] start  Start Address to read(3 methods).
+* \param[in] off        Offset.
+* \param[in] count      Allowable number to read.
+* \param[out] eof       End of File indication.
+* \param[in] data       Pointer to the private data structure.
+*
+* \return number of characters print to the buffer from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static int procRxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
+	char *p = page;
+	UINT_32 u4Count;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(data);
+
+	/* Kevin: Apply PROC read method 1. */
+	if (off != 0)
+		return 0;	/* To indicate end of file. */
+
+	SPRINTF(p, ("RX STATISTICS (Write 1 to clear):"));
+	SPRINTF(p, ("\n=================================\n"));
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+	wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count);
+
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+	u4Count += (UINT_32) (p - page);
+
+	*eof = 1;
+
+	return (int)u4Count;
+
+}				/* end of procRxStatisticsRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for reset Driver RX Statistic Counters.
+*
+* \param[in] file   pointer to file.
+* \param[in] buffer Buffer from user space.
+* \param[in] count  Number of characters to write
+* \param[in] data   Pointer to the private data structure.
+*
+* \return number of characters write from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static int procRxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
+	char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1];	/* + 1 for "\0" */
+	UINT_32 u4CopySize;
+	UINT_32 u4ClearCounter;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(data);
+
+	u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
+	copy_from_user(acBuf, buffer, u4CopySize);
+	acBuf[u4CopySize] = '\0';
+
+	if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) {
+		if (u4ClearCounter == 1) {
+			GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+			wlanoidSetRxStatisticsForLinuxProc(prGlueInfo->prAdapter);
+
+			GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+		}
+	}
+
+	return count;
+
+}				/* end of procRxStatisticsWrite() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for reading Driver TX Statistic Counters to User Space.
+*
+* \param[in] page       Buffer provided by kernel.
+* \param[in out] start  Start Address to read(3 methods).
+* \param[in] off        Offset.
+* \param[in] count      Allowable number to read.
+* \param[out] eof       End of File indication.
+* \param[in] data       Pointer to the private data structure.
+*
+* \return number of characters print to the buffer from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static int procTxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
+	char *p = page;
+	UINT_32 u4Count;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(data);
+
+	/* Kevin: Apply PROC read method 1. */
+	if (off != 0)
+		return 0;	/* To indicate end of file. */
+
+	SPRINTF(p, ("TX STATISTICS (Write 1 to clear):"));
+	SPRINTF(p, ("\n=================================\n"));
+
+	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+	wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count);
+
+	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+	u4Count += (UINT_32) (p - page);
+
+	*eof = 1;
+
+	return (int)u4Count;
+
+}				/* end of procTxStatisticsRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The PROC function for reset Driver TX Statistic Counters.
+*
+* \param[in] file   pointer to file.
+* \param[in] buffer Buffer from user space.
+* \param[in] count  Number of characters to write
+* \param[in] data   Pointer to the private data structure.
+*
+* \return number of characters write from User Space.
+*/
+/*----------------------------------------------------------------------------*/
+static int procTxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
+	char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1];	/* + 1 for "\0" */
+	UINT_32 u4CopySize;
+	UINT_32 u4ClearCounter;
+
+	GLUE_SPIN_LOCK_DECLARATION();
+
+	ASSERT(data);
+
+	u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
+	copy_from_user(acBuf, buffer, u4CopySize);
+	acBuf[u4CopySize] = '\0';
+
+	if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) {
+		if (u4ClearCounter == 1) {
+			GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+
+			wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter);
+
+			GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
+		}
+	}
+
+	return count;
+
+}				/* end of procTxStatisticsWrite() */
+#endif
+static struct proc_dir_entry *gprProcRoot;
+static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = {
+	"INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", "SW1", "SW2",
+	"SW3", "SW4", "HEM", "AIS", "RLM", "MEM", "CNM", "RSN", "BSS", "SCN",
+	"SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "OID",
+	"NIC"
+};
+static UINT_8 aucProcBuf[1536];
+static ssize_t procDbgLevelRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	UINT_8 *temp = &aucProcBuf[0];
+	UINT_32 u4CopySize = 0;
+	UINT_16 i;
+	UINT_16 u2ModuleNum = 0;
+
+	/* if *f_ops>0, we should return 0 to make cat command exit */
+	if (*f_pos > 0)
+		return 0;
+
+	kalStrCpy(temp, "\nTEMP |LOUD |INFO |TRACE|EVENT|STATE|WARN |ERROR\n"
+			"bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0\n\n"
+			"Debug Module\tIndex\tLevel\tDebug Module\tIndex\tLevel\n\n");
+	temp += kalStrLen(temp);
+
+	u2ModuleNum = (sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0xfe;
+	for (i = 0; i < u2ModuleNum; i += 2)
+		SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\tDBG_%s_IDX\t(0x%02x):\t0x%02x\n",
+				&aucDbModuleName[i][0], i, aucDebugModule[i],
+				&aucDbModuleName[i+1][0], i+1, aucDebugModule[i+1]));
+
+	if ((sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0x1)
+		SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\n",
+				&aucDbModuleName[u2ModuleNum][0], u2ModuleNum, aucDebugModule[u2ModuleNum]));
+
+	u4CopySize = kalStrLen(aucProcBuf);
+	if (u4CopySize > count)
+		u4CopySize = count;
+	if (copy_to_user(buf, aucProcBuf, u4CopySize)) {
+		kalPrint("copy to user failed\n");
+		return -EFAULT;
+	}
+
+	*f_pos += u4CopySize;
+	return (ssize_t)u4CopySize;
+}
+
+static ssize_t procDbgLevelWrite(struct file *file, const char *buffer, size_t count, loff_t *data)
+{
+	UINT_32 u4NewDbgModule, u4NewDbgLevel;
+	UINT_8 i = 0;
+	UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf);
+	UINT_8 *temp = &aucProcBuf[0];
+
+	if (u4CopySize >= count + 1)
+		u4CopySize = count;
+
+	kalMemSet(aucProcBuf, 0, u4CopySize);
+
+	if (copy_from_user(aucProcBuf, buffer, u4CopySize)) {
+		kalPrint("error of copy from user\n");
+		return -EFAULT;
+	}
+	aucProcBuf[u4CopySize] = '\0';
+
+	while (temp) {
+		if (sscanf(temp, "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2)  {
+			kalPrint("debug module and debug level should be one byte in length\n");
+			break;
+		}
+		if (u4NewDbgModule == 0xFF) {
+			for (i = 0; i < DBG_MODULE_NUM; i++)
+				aucDebugModule[i] = u4NewDbgLevel & DBG_CLASS_MASK;
+
+			break;
+		} else if (u4NewDbgModule >= DBG_MODULE_NUM) {
+			kalPrint("debug module index should less than %d\n", DBG_MODULE_NUM);
+			break;
+		}
+		aucDebugModule[u4NewDbgModule] =  u4NewDbgLevel & DBG_CLASS_MASK;
+		temp = kalStrChr(temp, ',');
+		if (!temp)
+			break;
+		temp++; /* skip ',' */
+	}
+	return count;
+}
+
+
+static const struct file_operations dbglevel_ops = {
+	.owner = THIS_MODULE,
+	.read = procDbgLevelRead,
+	.write = procDbgLevelWrite,
+};
+
+static ssize_t procTxDoneCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	UINT_8 *temp = &aucProcBuf[0];
+	UINT_32 u4CopySize = 0;
+	UINT_16 u2TxDoneCfg = 0;
+
+	/* if *f_ops>0, we should return 0 to make cat command exit */
+	if (*f_pos > 0)
+		return 0;
+
+	u2TxDoneCfg = StatsGetCfgTxDone();
+	SPRINTF(temp, ("Tx Done Configure:\nARP %d\tDNS %d\nTCP %d\tUDP %d\nEAPOL %d\tDHCP %d\nICMP %d\n",
+			!!(u2TxDoneCfg & CFG_ARP), !!(u2TxDoneCfg & CFG_DNS), !!(u2TxDoneCfg & CFG_TCP),
+			!!(u2TxDoneCfg & CFG_UDP), !!(u2TxDoneCfg & CFG_EAPOL), !!(u2TxDoneCfg & CFG_DHCP),
+			!!(u2TxDoneCfg & CFG_ICMP)));
+
+	u4CopySize = kalStrLen(aucProcBuf);
+	if (u4CopySize > count)
+		u4CopySize = count;
+	if (copy_to_user(buf, aucProcBuf, u4CopySize)) {
+		kalPrint("copy to user failed\n");
+		return -EFAULT;
+	}
+
+	*f_pos += u4CopySize;
+	return (ssize_t)u4CopySize;
+}
+
+static ssize_t procTxDoneCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data)
+{
+#define MODULE_NAME_LENGTH 6
+
+	UINT_8 i = 0;
+	UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf);
+	UINT_8 *temp = &aucProcBuf[0];
+	UINT_16 u2SetTxDoneCfg = 0;
+	UINT_16 u2ClsTxDoneCfg = 0;
+	UINT_8 aucModule[MODULE_NAME_LENGTH];
+	UINT_32 u4Enabled;
+	UINT_8 aucModuleArray[][MODULE_NAME_LENGTH] = {"ARP", "DNS", "TCP", "UDP", "EAPOL", "DHCP", "ICMP"};
+
+	if (u4CopySize >= count + 1)
+		u4CopySize = count;
+
+	kalMemSet(aucProcBuf, 0, u4CopySize);
+	if (copy_from_user(aucProcBuf, buffer, u4CopySize)) {
+		kalPrint("error of copy from user\n");
+		return -EFAULT;
+	}
+	aucProcBuf[u4CopySize] = '\0';
+	temp = &aucProcBuf[0];
+	while (temp) {
+		/* pick up a string and teminated after meet : */
+		if (sscanf(temp, "%s %d", aucModule, &u4Enabled) != 2)  {
+			kalPrint("read param fail, aucModule=%s\n", aucModule);
+			break;
+		}
+		for (i = 0; i < sizeof(aucModuleArray)/MODULE_NAME_LENGTH; i++) {
+			if (kalStrniCmp(aucModule, aucModuleArray[i], MODULE_NAME_LENGTH) == 0) {
+				if (u4Enabled)
+					u2SetTxDoneCfg |= 1 << i;
+				else
+					u2ClsTxDoneCfg |= 1 << i;
+				break;
+			}
+		}
+		temp = kalStrChr(temp, ',');
+		if (!temp)
+			break;
+		temp++; /* skip ',' */
+	}
+	if (u2SetTxDoneCfg)
+		StatsSetCfgTxDone(u2SetTxDoneCfg, TRUE);
+
+	if (u2ClsTxDoneCfg)
+		StatsSetCfgTxDone(u2ClsTxDoneCfg, FALSE);
+	return count;
+}
+
+static const struct file_operations proc_txdone_ops = {
+	.owner = THIS_MODULE,
+	.read = procTxDoneCfgRead,
+	.write = procTxDoneCfgWrite,
+};
+
+static ssize_t procAutoPerCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	UINT_8 *temp = &aucProcBuf[0];
+	UINT_32 u4CopySize = 0;
+
+	/* if *f_ops>0, we should return 0 to make cat command exit */
+	if (*f_pos > 0)
+		return 0;
+
+	SPRINTF(temp, ("Auto Performance Configure:\nperiod\tL1\nL2\tL3\n"));
+
+	u4CopySize = kalStrLen(aucProcBuf);
+	if (u4CopySize > count)
+		u4CopySize = count;
+	if (copy_to_user(buf, aucProcBuf, u4CopySize)) {
+		kalPrint("copy to user failed\n");
+		return -EFAULT;
+	}
+
+	*f_pos += u4CopySize;
+	return (ssize_t)u4CopySize;
+}
+
+static ssize_t procAutoPerCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data)
+{
+	DBGLOG(INIT, WARN, "%s\n", __func__);
+	return 0;
+}
+
+static const struct file_operations auto_per_ops = {
+	.owner = THIS_MODULE,
+	.read = procAutoPerCfgRead,
+	.write = procAutoPerCfgWrite,
+};
+
+
+static ssize_t procCmdDebug(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	UINT_32 u4CopySize = 0;
+
+	/* if *f_ops>0, we should return 0 to make cat command exit */
+	if (*f_pos > 0)
+		return 0;
+
+	wlanDumpTcResAndTxedCmd(aucProcBuf, sizeof(aucProcBuf));
+
+	u4CopySize = kalStrLen(aucProcBuf);
+	if (u4CopySize > count)
+		u4CopySize = count;
+	if (copy_to_user(buf, aucProcBuf, u4CopySize)) {
+		kalPrint("copy to user failed\n");
+		return -EFAULT;
+	}
+
+	*f_pos += u4CopySize;
+	return (ssize_t)u4CopySize;
+}
+
+static const struct file_operations proc_CmdDebug_ops = {
+	.owner = THIS_MODULE,
+	.read = procCmdDebug,
+};
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function create a PROC fs in linux /proc/net subdirectory.
+*
+* \param[in] prDev      Pointer to the struct net_device.
+* \param[in] pucDevName Pointer to the name of net_device.
+*
+* \return N/A
+*/
+/*----------------------------------------------------------------------------*/
+
+#if CFG_SUPPORT_THERMO_THROTTLING
+
+/**
+ * This function is called then the /proc file is read
+ *
+ */
+typedef struct _COEX_BUF1 {
+	UINT8 buffer[128];
+	INT32 availSize;
+} COEX_BUF1, *P_COEX_BUF1;
+
+COEX_BUF1 gCoexBuf1;
+
+static ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+
+	INT32 retval = 0;
+	INT32 i_ret = 0;
+	CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n";
+
+	if (*f_pos > 0) {
+		retval = 0;
+	} else {
+		/*len = sprintf(page, "%d\n", g_psm_enable); */
+#if 1
+		if (gCoexBuf1.availSize <= 0) {
+			DBGLOG(INIT, WARN, "no data available\n");
+			retval = strlen(warn_msg) + 1;
+			if (count < retval)
+				retval = count;
+			i_ret = copy_to_user(buf, warn_msg, retval);
+			if (i_ret) {
+				DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval);
+				retval = -EFAULT;
+				goto err_exit;
+			}
+			*f_pos += retval;
+		} else
+#endif
+		{
+			INT32 i = 0;
+			INT32 len = 0;
+			CHAR msg_info[128];
+			INT32 max_num = 0;
+			/*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page
+			buffer is not enough, a bomb is placed here on unexpected condition */
+
+			DBGLOG(INIT, TRACE, "%d bytes available\n", gCoexBuf1.availSize);
+			max_num = ((sizeof(msg_info) > count ? sizeof(msg_info) : count) - 1) / 5;
+
+			if (max_num > gCoexBuf1.availSize)
+				max_num = gCoexBuf1.availSize;
+			else
+				DBGLOG(INIT, TRACE,
+				"round to %d bytes due to local buffer size limitation\n", max_num);
+
+			for (i = 0; i < max_num; i++)
+				len += sprintf(msg_info + len, "%d", gCoexBuf1.buffer[i]);
+
+			len += sprintf(msg_info + len, "\n");
+			retval = len;
+
+			i_ret = copy_to_user(buf, msg_info, retval);
+			if (i_ret) {
+				DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval);
+				retval = -EFAULT;
+				goto err_exit;
+			}
+			*f_pos += retval;
+		}
+	}
+	gCoexBuf1.availSize = 0;
+err_exit:
+
+	return retval;
+}
+
+#if 1
+typedef INT32 (*WLAN_DEV_DBG_FUNC)(void);
+static INT32 wlan_get_thermo_power(void);
+static INT32 wlan_get_link_mode(void);
+
+static const WLAN_DEV_DBG_FUNC wlan_dev_dbg_func[] = {
+	[0] = wlan_get_thermo_power,
+	[1] = wlan_get_link_mode,
+
+};
+
+INT32 wlan_get_thermo_power(void)
+{
+	P_ADAPTER_T prAdapter;
+
+	prAdapter = g_prGlueInfo_proc->prAdapter;
+
+	if (prAdapter->u4AirDelayTotal > 100)
+		gCoexBuf1.buffer[0] = 100;
+	else
+		gCoexBuf1.buffer[0] = prAdapter->u4AirDelayTotal;
+	gCoexBuf1.availSize = 1;
+	DBGLOG(RLM, TRACE, "PROC %s thrmo_power(%d)\n", __func__, gCoexBuf1.buffer[0]);
+
+	return 0;
+}
+
+INT32 wlan_get_link_mode(void)
+{
+	UINT_8 ucLinkMode = 0;
+	P_ADAPTER_T prAdapter;
+	BOOLEAN fgIsAPmode;
+
+	prAdapter = g_prGlueInfo_proc->prAdapter;
+	fgIsAPmode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo);
+
+	DBGLOG(RLM, TRACE, "PROC %s AIS(%d)P2P(%d)AP(%d)\n",
+			   __func__,
+			   prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState,
+			   prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState, fgIsAPmode);
+
+#if 1
+
+	if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED)
+		ucLinkMode |= BIT(0);
+	if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED)
+		ucLinkMode |= BIT(1);
+	if (fgIsAPmode)
+		ucLinkMode |= BIT(2);
+
+#endif
+	gCoexBuf1.buffer[0] = ucLinkMode;
+	gCoexBuf1.availSize = 1;
+
+	return 0;
+}
+
+static ssize_t procfile_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
+{
+	char buf[256];
+	char *pBuf;
+	ULONG len = count;
+	INT32 x = 0, y = 0, z = 0;
+	char *pToken = NULL;
+	char *pDelimiter = " \t";
+	INT32 i4Ret = 0;
+
+	if (copy_from_user(gCoexBuf1.buffer, buffer, count))
+		return -EFAULT;
+	/* gCoexBuf1.availSize = count; */
+
+	/* return gCoexBuf1.availSize; */
+#if 1
+	DBGLOG(INIT, TRACE, "write parameter len = %d\n\r", (INT32) len);
+	if (len >= sizeof(buf)) {
+		DBGLOG(INIT, ERROR, "input handling fail!\n");
+		len = sizeof(buf) - 1;
+		return -1;
+	}
+
+	if (copy_from_user(buf, buffer, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	DBGLOG(INIT, TRACE, "write parameter data = %s\n\r", buf);
+
+	pBuf = buf;
+	pToken = strsep(&pBuf, pDelimiter);
+
+	if (pToken) /* x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; */
+		i4Ret = kalkStrtos32(pToken, 16, &x);
+	if (!i4Ret)
+		DBGLOG(INIT, TRACE, "x = 0x%x\n", x);
+
+#if 1
+	pToken = strsep(&pBuf, "\t\n ");
+	if (pToken != NULL) {
+		i4Ret = kalkStrtos32(pToken, 16, &y); /* y = simple_strtol(pToken, NULL, 16); */
+		if (!i4Ret)
+			DBGLOG(INIT, TRACE, "y = 0x%08x\n\r", y);
+	} else {
+		y = 3000;
+		/*efuse, register read write default value */
+		if (0x11 == x || 0x12 == x || 0x13 == x)
+			y = 0x80000000;
+	}
+
+	pToken = strsep(&pBuf, "\t\n ");
+	if (pToken != NULL) {
+		i4Ret = kalkStrtos32(pToken, 16, &z); /* z = simple_strtol(pToken, NULL, 16); */
+		if (!i4Ret)
+			DBGLOG(INIT, TRACE, "z = 0x%08x\n\r", z);
+	} else {
+		z = 10;
+		/*efuse, register read write default value */
+		if (0x11 == x || 0x12 == x || 0x13 == x)
+			z = 0xffffffff;
+	}
+
+	DBGLOG(INIT, TRACE, " x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);
+#endif
+
+	if (((sizeof(wlan_dev_dbg_func) / sizeof(wlan_dev_dbg_func[0])) > x) && NULL != wlan_dev_dbg_func[x])
+		(*wlan_dev_dbg_func[x]) ();
+	else
+		DBGLOG(INIT, ERROR, "no handler defined for command id(0x%08x)\n\r", x);
+#endif
+
+	/* len = gCoexBuf1.availSize; */
+	return len;
+}
+#endif
+	static const struct file_operations proc_fops = {
+		.owner = THIS_MODULE,
+		.read = procfile_read,
+		.write = procfile_write,
+	};
+#endif
+
+INT_32 procInitFs(VOID)
+{
+	struct proc_dir_entry *prEntry;
+
+	if (init_net.proc_net == (struct proc_dir_entry *)NULL) {
+		kalPrint("init proc fs fail: proc_net == NULL\n");
+		return -ENOENT;
+	}
+
+	/*
+	 * Directory: Root (/proc/net/wlan0)
+	 */
+
+	gprProcRoot = proc_mkdir(PROC_ROOT_NAME, init_net.proc_net);
+	if (!gprProcRoot) {
+		kalPrint("gprProcRoot == NULL\n");
+		return -ENOENT;
+	}
+	proc_set_user(gprProcRoot, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI));
+
+	prEntry = proc_create(PROC_DBG_LEVEL_NAME, 0664, gprProcRoot, &dbglevel_ops);
+	if (prEntry == NULL) {
+		kalPrint("Unable to create /proc entry dbgLevel\n\r");
+		return -1;
+	}
+	proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI));
+
+	prEntry = proc_create(PROC_NEED_TX_DONE, 0664, gprProcRoot, &proc_txdone_ops);
+	if (prEntry == NULL) {
+		kalPrint("Unable to create /proc entry dbgLevel\n\r");
+		return -1;
+	}
+	proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI));
+
+	prEntry = proc_create(PROC_AUTO_PER_CFG, 0664, gprProcRoot, &auto_per_ops);
+	if (prEntry == NULL) {
+		kalPrint("Unable to create /proc entry autoPerCfg\n\r");
+		return -1;
+	}
+	proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI));
+
+	return 0;
+}				/* end of procInitProcfs() */
+
+INT_32 procUninitProcFs(VOID)
+{
+	remove_proc_entry(PROC_DBG_LEVEL_NAME, gprProcRoot);
+	remove_proc_subtree(PROC_ROOT_NAME, init_net.proc_net);
+	remove_proc_entry(PROC_AUTO_PER_CFG, gprProcRoot);
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function clean up a PROC fs created by procInitProcfs().
+*
+* \param[in] prDev      Pointer to the struct net_device.
+* \param[in] pucDevName Pointer to the name of net_device.
+*
+* \return N/A
+*/
+/*----------------------------------------------------------------------------*/
+INT_32 procRemoveProcfs(VOID)
+{
+	/* remove root directory (proc/net/wlan0) */
+	/* remove_proc_entry(pucDevName, init_net.proc_net); */
+	remove_proc_entry(PROC_WLAN_THERMO, gprProcRoot);
+	remove_proc_entry(PROC_CMD_DEBUG_NAME, gprProcRoot);
+#if CFG_SUPPORT_THERMO_THROTTLING
+	g_prGlueInfo_proc = NULL;
+#endif
+	return 0;
+}				/* end of procRemoveProcfs() */
+
+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo)
+{
+	struct proc_dir_entry *prEntry;
+
+	DBGLOG(INIT, TRACE, "[%s]\n", __func__);
+
+#if CFG_SUPPORT_THERMO_THROTTLING
+	g_prGlueInfo_proc = prGlueInfo;
+#endif
+
+	prGlueInfo->pProcRoot = gprProcRoot;
+
+	prEntry = proc_create(PROC_WLAN_THERMO, 0664, gprProcRoot, &proc_fops);
+	if (prEntry == NULL) {
+		DBGLOG(INIT, ERROR, "Unable to create /proc entry\n\r");
+		return -1;
+	}
+
+	prEntry = proc_create(PROC_CMD_DEBUG_NAME, 0444, gprProcRoot, &proc_CmdDebug_ops);
+	if (prEntry == NULL) {
+		kalPrint("Unable to create /proc entry dbgLevel\n\r");
+		return -1;
+	}
+	proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI));
+	return 0;
+}
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c
new file mode 100644
index 0000000000000..f97db8a69fd21
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c
@@ -0,0 +1,228 @@
+/*
+** Id: @(#) gl_rst.c@@
+*/
+
+/*! \file   gl_rst.c
+    \brief  Main routines for supporintg MT6620 whole-chip reset mechanism
+
+    This file contains the support routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*
+** Log: gl_rst.c
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 04 22 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
+ * RESET_START and RESET_END events
+ * skip power-off handshaking when RESET indication is received.
+ *
+ * 04 14 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
+ * RESET_START and RESET_END events
+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
+ * 2. add dummy function for both Win32 and Linux part.
+ *
+ * 03 30 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
+ * RESET_START and RESET_END events
+ * use netlink unicast instead of broadcast
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
+
+#include "precomp.h"
+#include "gl_rst.h"
+
+#if CFG_CHIP_RESET_SUPPORT
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+BOOLEAN fgIsResetting = FALSE;
+UINT_32 g_IsNeedDoChipReset = 0;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+static RESET_STRUCT_T wifi_rst;
+
+static void mtk_wifi_reset(struct work_struct *work);
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType,
+			     ENUM_WMTDRV_TYPE_T eDstType,
+			     ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for
+ *        1. register wifi reset callback
+ *        2. initialize wifi reset work
+ *
+ * @param none
+ *
+ * @retval none
+ */
+/*----------------------------------------------------------------------------*/
+VOID glResetInit(VOID)
+{
+#if (MTK_WCN_SINGLE_MODULE == 0)
+	/* 1. Register reset callback */
+	mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB) glResetCallback);
+#endif /* MTK_WCN_SINGLE_MODULE */
+
+	/* 2. Initialize reset work */
+	INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for
+ *        1. deregister wifi reset callback
+ *
+ * @param none
+ *
+ * @retval none
+ */
+/*----------------------------------------------------------------------------*/
+VOID glResetUninit(VOID)
+{
+#if (MTK_WCN_SINGLE_MODULE == 0)
+	/* 1. Deregister reset callback */
+	mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI);
+#endif /* MTK_WCN_SINGLE_MODULE */
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is invoked when there is reset messages indicated
+ *
+ * @param   eSrcType
+ *          eDstType
+ *          eMsgType
+ *          prMsgBody
+ *          u4MsgLength
+ *
+ * @retval
+ */
+/*----------------------------------------------------------------------------*/
+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType,
+			     ENUM_WMTDRV_TYPE_T eDstType,
+			     ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength)
+{
+	switch (eMsgType) {
+	case WMTMSG_TYPE_RESET:
+		if (u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
+			P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody;
+
+			switch (*prRstMsg) {
+			case WMTRSTMSG_RESET_START:
+				DBGLOG(INIT, WARN, "Whole chip reset start!\n");
+				fgIsResetting = TRUE;
+				wifi_reset_start();
+				break;
+
+			case WMTRSTMSG_RESET_END:
+				DBGLOG(INIT, WARN, "Whole chip reset end!\n");
+				fgIsResetting = FALSE;
+				wifi_rst.rst_data = RESET_SUCCESS;
+				schedule_work(&(wifi_rst.rst_work));
+				break;
+
+			case WMTRSTMSG_RESET_END_FAIL:
+				DBGLOG(INIT, WARN, "Whole chip reset fail!\n");
+				fgIsResetting = FALSE;
+				wifi_rst.rst_data = RESET_FAIL;
+				schedule_work(&(wifi_rst.rst_work));
+				break;
+
+			default:
+				break;
+			}
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is called for wifi reset
+ *
+ * @param   skb
+ *          info
+ *
+ * @retval  0
+ *          nonzero
+ */
+/*----------------------------------------------------------------------------*/
+static void mtk_wifi_reset(struct work_struct *work)
+{
+	RESET_STRUCT_T *rst = container_of(work, RESET_STRUCT_T, rst_work);
+
+	wifi_reset_end(rst->rst_data);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is called for generating reset request to WMT
+ *
+ * @param   None
+ *
+ * @retval  None
+ */
+/*----------------------------------------------------------------------------*/
+VOID glSendResetRequest(VOID)
+{
+	/* WMT thread would trigger whole chip reset itself */
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is called for checking if connectivity chip is resetting
+ *
+ * @param   None
+ *
+ * @retval  TRUE
+ *          FALSE
+ */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalIsResetting(VOID)
+{
+	return fgIsResetting;
+}
+
+#endif /* CFG_CHIP_RESET_SUPPORT */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c
new file mode 100644
index 0000000000000..862d011a43df3
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c
@@ -0,0 +1,1220 @@
+/*
+** Id: @(#) gl_cfg80211.c@@
+*/
+
+/*! \file   gl_cfg80211.c
+    \brief  Main routines for supporintg MT6620 cfg80211 control interface
+
+    This file contains the support routines of Linux driver for MediaTek Inc. 802.11
+    Wireless LAN Adapters.
+*/
+
+/*
+** Log: gl_cfg80211.c
+**
+** 09 05 2013 cp.wu
+** correct length to pass to wlanoidSetBssid()
+**
+** 09 04 2013 cp.wu
+** fix typo
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+**
+** 11 23 2012 yuche.tsai
+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely
+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed..
+**
+** 09 12 2012 wcpadmin
+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
+** .
+**
+** 08 30 2012 chinglan.wang
+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
+** .
+ *
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/can/netlink.h>
+#include <net/netlink.h>
+#include <net/cfg80211.h>
+
+#include "gl_os.h"
+#include "wlan_lib.h"
+#include "gl_wext.h"
+#include "precomp.h"
+#include "gl_cfg80211.h"
+#include "gl_vendor.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+static struct nla_policy nla_parse_policy[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1] = {
+	[GSCAN_ATTRIBUTE_NUM_BUCKETS] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BASE_PERIOD] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BUCKETS_BAND] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BUCKET_ID] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BUCKET_PERIOD] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BUCKET_CHANNELS] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_REPORT_THRESHOLD] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_REPORT_EVENTS] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BSSID] = {.type = NLA_UNSPEC},
+	[GSCAN_ATTRIBUTE_RSSI_LOW] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_RSSI_HIGH] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE] = {.type = NLA_U16},
+	[GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_MIN_BREACHING] = {.type = NLA_U16},
+	[GSCAN_ATTRIBUTE_NUM_AP] = {.type = NLA_U16},
+	[GSCAN_ATTRIBUTE_HOTLIST_FLUSH] = {.type = NLA_U8},
+	[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH] = {.type = NLA_U8},
+};
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	struct nlattr *attr;
+	UINT_32 band = 0;
+	UINT_8 ucNumOfChannel, i, j;
+	RF_CHANNEL_INFO_T aucChannelList[64];
+	UINT_32 num_channels;
+	wifi_channel channels[64];
+	struct sk_buff *skb;
+
+	ASSERT(wiphy && wdev);
+	if ((data == NULL) || !data_len)
+		return -EINVAL;
+
+	DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len);
+
+	attr = (struct nlattr *)data;
+	if (attr->nla_type == WIFI_ATTRIBUTE_BAND)
+		band = nla_get_u32(attr);
+
+	DBGLOG(REQ, INFO, "Get channel list for band: %d\n", band);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	if (!prGlueInfo)
+		return -EFAULT;
+
+	if (band == 0) { /* 2.4G band */
+		rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE,
+			     64, &ucNumOfChannel, aucChannelList);
+	} else { /* 5G band */
+		rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE,
+			     64, &ucNumOfChannel, aucChannelList);
+	}
+
+	kalMemZero(channels, sizeof(channels));
+	for (i = 0, j = 0; i < ucNumOfChannel; i++) {
+		/* We need to report frequency list to HAL */
+		channels[j] = nicChannelNum2Freq(aucChannelList[i].ucChannelNum) / 1000;
+		if (channels[j] == 0)
+			continue;
+		else if ((prGlueInfo->prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_TW) &&
+			(channels[j] >= 5180 && channels[j] <= 5260)) {
+			/* Taiwan NCC has resolution to follow FCC spec to support 5G Band 1/2/3/4
+			 * (CH36~CH48, CH52~CH64, CH100~CH140, CH149~CH165)
+			 * Filter CH36~CH52 for compatible with some old devices.
+			 */
+			continue;
+		} else {
+			DBGLOG(REQ, INFO, "channels[%d] = %d\n", j, channels[j]);
+			j++;
+		}
+	}
+	num_channels = j;
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(channels));
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "Allocate skb failed\n");
+		return -ENOMEM;
+	}
+
+	if (unlikely(nla_put_u32(skb, WIFI_ATTRIBUTE_NUM_CHANNELS, num_channels) < 0))
+		goto nla_put_failure;
+
+	if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_CHANNEL_LIST,
+		(sizeof(wifi_channel) * num_channels), channels) < 0))
+		goto nla_put_failure;
+
+	return cfg80211_vendor_cmd_reply(skb);
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EFAULT;
+}
+
+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	struct nlattr *attr;
+	UINT_8 country[2] = {0, 0};
+
+	ASSERT(wiphy && wdev);
+	if ((data == NULL) || (data_len == 0))
+		return -EINVAL;
+
+	DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len);
+
+	attr = (struct nlattr *)data;
+	if (attr->nla_type == WIFI_ATTRIBUTE_COUNTRY_CODE) {
+		country[0] = *((PUINT_8)nla_data(attr));
+		country[1] = *((PUINT_8)nla_data(attr) + 1);
+	}
+
+	DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], country[1]);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	if (!prGlueInfo)
+		return -EFAULT;
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, country, 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Status = -EINVAL;
+	PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T rGscanCapabilities;
+	struct sk_buff *skb;
+	/* UINT_32 u4BufLen; */
+
+	DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__);
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rGscanCapabilities));
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status);
+		return -ENOMEM;
+	}
+
+	kalMemZero(&rGscanCapabilities, sizeof(rGscanCapabilities));
+
+	/*rStatus = kalIoctl(prGlueInfo,
+	   wlanoidQueryStatistics,
+	   &rGscanCapabilities,
+	   sizeof(rGscanCapabilities),
+	   TRUE,
+	   TRUE,
+	   TRUE,
+	   FALSE,
+	   &u4BufLen); */
+	rGscanCapabilities.max_scan_cache_size = PSCAN_MAX_SCAN_CACHE_SIZE;
+	rGscanCapabilities.max_scan_buckets = GSCAN_MAX_BUCKETS;
+	rGscanCapabilities.max_ap_cache_per_scan = PSCAN_MAX_AP_CACHE_PER_SCAN;
+	rGscanCapabilities.max_rssi_sample_size = 10;
+	rGscanCapabilities.max_scan_reporting_threshold = GSCAN_MAX_REPORT_THRESHOLD;
+	rGscanCapabilities.max_hotlist_aps = MAX_HOTLIST_APS;
+	rGscanCapabilities.max_significant_wifi_change_aps = MAX_SIGNIFICANT_CHANGE_APS;
+	rGscanCapabilities.max_bssid_history_entries = PSCAN_MAX_AP_CACHE_PER_SCAN * PSCAN_MAX_SCAN_CACHE_SIZE;
+
+	/* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); */
+	/* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_ID, GOOGLE_OUI); */
+	/* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_GET_CAPABILITIES); */
+	/*NLA_PUT(skb, GSCAN_ATTRIBUTE_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities);*/
+	if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CAPABILITIES,
+		sizeof(rGscanCapabilities), &rGscanCapabilities) < 0))
+		goto nla_put_failure;
+
+	i4Status = cfg80211_vendor_cmd_reply(skb);
+	return i4Status;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	/* CMD_GSCN_REQ_T rCmdGscnParam; */
+
+	/* INT_32 i4Status = -EINVAL; */
+	P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL;
+	struct nlattr *attr[GSCAN_ATTRIBUTE_REPORT_EVENTS + 1];
+	struct nlattr *pbucket, *pchannel;
+	UINT_32 len_basic, len_bucket, len_channel;
+	int i, j, k;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	if ((data == NULL) || !data_len)
+		goto nla_put_failure;
+
+	prWifiScanCmd = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE);
+	if (!prWifiScanCmd) {
+		DBGLOG(REQ, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n");
+		return -ENOMEM;
+	}
+
+	DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len);
+	kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS));
+	kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_REPORT_EVENTS + 1));
+
+	nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL);
+	len_basic = 0;
+	for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) {
+		if (attr[k]) {
+			switch (k) {
+			case GSCAN_ATTRIBUTE_BASE_PERIOD:
+				prWifiScanCmd->base_period = nla_get_u32(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				break;
+			case GSCAN_ATTRIBUTE_NUM_BUCKETS:
+				prWifiScanCmd->num_buckets = nla_get_u32(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				DBGLOG(REQ, TRACE, "attr=0x%x, num_buckets=%d nla_len=%d, \r\n",
+				       *(UINT_32 *) attr[k], prWifiScanCmd->num_buckets, attr[k]->nla_len);
+				break;
+			}
+		}
+	}
+	pbucket = (struct nlattr *)((UINT_8 *) data + len_basic);
+	DBGLOG(REQ, TRACE, "+++basic attribute size=%d pbucket=%p\r\n", len_basic, pbucket);
+
+	for (i = 0; i < prWifiScanCmd->num_buckets; i++) {
+		if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)pbucket,
+			nla_parse_policy,NULL) < 0)
+			goto nla_put_failure;
+		len_bucket = 0;
+		for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) {
+			if (attr[k]) {
+				switch (k) {
+				case GSCAN_ATTRIBUTE_BUCKETS_BAND:
+					prWifiScanCmd->buckets[i].band = nla_get_u32(attr[k]);
+					len_bucket += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_BUCKET_ID:
+					prWifiScanCmd->buckets[i].bucket = nla_get_u32(attr[k]);
+					len_bucket += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_BUCKET_PERIOD:
+					prWifiScanCmd->buckets[i].period = nla_get_u32(attr[k]);
+					len_bucket += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_REPORT_EVENTS:
+					prWifiScanCmd->buckets[i].report_events = nla_get_u32(attr[k]);
+					len_bucket += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS:
+					prWifiScanCmd->buckets[i].num_channels = nla_get_u32(attr[k]);
+					len_bucket += NLA_ALIGN(attr[k]->nla_len);
+					DBGLOG(REQ, TRACE, "bucket%d: attr=0x%x, num_channels=%d nla_len = %d, \r\n",
+					       i, *(UINT_32 *) attr[k], nla_get_u32(attr[k]), attr[k]->nla_len);
+					break;
+				}
+			}
+		}
+		pbucket = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN);
+		/* request.attr_start(i) as nested attribute */
+		DBGLOG(REQ, TRACE, "+++pure bucket size=%d pbucket=%p \r\n", len_bucket, pbucket);
+		pbucket = (struct nlattr *)((UINT_8 *) pbucket + len_bucket);
+		/* pure bucket payload, not include channels */
+
+		/*don't need to use nla_parse_nested to parse channels */
+		/* the header of channel in bucket i */
+		pchannel = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN);
+		for (j = 0; j < prWifiScanCmd->buckets[i].num_channels; j++) {
+			prWifiScanCmd->buckets[i].channels[j].channel = nla_get_u32(pchannel);
+			len_channel = NLA_ALIGN(pchannel->nla_len);
+			DBGLOG(REQ, TRACE,
+				"attr=0x%x, channel=%d, \r\n", *(UINT_32 *) pchannel, nla_get_u32(pchannel));
+
+			pchannel = (struct nlattr *)((UINT_8 *) pchannel + len_channel);
+		}
+		pbucket = pchannel;
+	}
+
+	DBGLOG(REQ, TRACE, "base_period=%d, num_buckets=%d, bucket0: %d %d %d %d",
+		prWifiScanCmd->base_period, prWifiScanCmd->num_buckets,
+		prWifiScanCmd->buckets[0].bucket, prWifiScanCmd->buckets[0].period,
+		prWifiScanCmd->buckets[0].band, prWifiScanCmd->buckets[0].report_events);
+
+	DBGLOG(REQ, TRACE, "num_channels=%d, channel0=%d, channel1=%d; num_channels=%d, channel0=%d, channel1=%d",
+		prWifiScanCmd->buckets[0].num_channels,
+		prWifiScanCmd->buckets[0].channels[0].channel, prWifiScanCmd->buckets[0].channels[1].channel,
+		prWifiScanCmd->buckets[1].num_channels,
+		prWifiScanCmd->buckets[1].channels[0].channel, prWifiScanCmd->buckets[1].channels[1].channel);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetGSCNAParam,
+			   prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+	kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS));
+	return 0;
+
+nla_put_failure:
+	if (prWifiScanCmd != NULL)
+		kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS));
+	return -1;
+}
+
+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	INT_32 i4Status = -EINVAL;
+	/*PARAM_WIFI_GSCAN_CMD_PARAMS rWifiScanCmd;*/
+	P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL;
+	struct nlattr *attr[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1];
+	/* UINT_32 num_scans = 0; */	/* another attribute */
+	int k;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	if ((data == NULL) || !data_len)
+		goto nla_put_failure;
+	DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len);
+	/*kalMemZero(&rWifiScanCmd, sizeof(rWifiScanCmd));*/
+	prWifiScanCmd = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE);
+	if (prWifiScanCmd == NULL)
+		goto nla_put_failure;
+	kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS));
+	kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1));
+
+	if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
+		(struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0)
+		goto nla_put_failure;
+	for (k = GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN; k <= GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE; k++) {
+		if (attr[k]) {
+			switch (k) {
+			case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN:
+				prWifiScanCmd->max_ap_per_scan = nla_get_u32(attr[k]);
+				break;
+			case GSCAN_ATTRIBUTE_REPORT_THRESHOLD:
+				prWifiScanCmd->report_threshold = nla_get_u32(attr[k]);
+				break;
+			case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE:
+				prWifiScanCmd->num_scans = nla_get_u32(attr[k]);
+				break;
+			}
+		}
+	}
+	DBGLOG(REQ, TRACE, "attr=0x%x, attr2=0x%x ", *(UINT_32 *) attr[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN],
+	       *(UINT_32 *) attr[GSCAN_ATTRIBUTE_REPORT_THRESHOLD]);
+
+	DBGLOG(REQ, TRACE, "max_ap_per_scan=%d, report_threshold=%d num_scans=%d \r\n",
+	       prWifiScanCmd->max_ap_per_scan, prWifiScanCmd->report_threshold, prWifiScanCmd->num_scans);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetGSCNAConfig,
+			   prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+	kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS));
+	return 0;
+
+nla_put_failure:
+	if (prWifiScanCmd != NULL)
+		kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS));
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev,
+					       const void *data, int data_len)
+{
+	INT_32 i4Status = -EINVAL;
+	P_PARAM_WIFI_SIGNIFICANT_CHANGE prWifiChangeCmd = NULL;
+	UINT_8 flush = 0;
+	/* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */
+	struct nlattr **attr = NULL;
+	struct nlattr *paplist;
+	int i, k;
+	UINT_32 len_basic, len_aplist;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	if ((data == NULL) || !data_len)
+		goto nla_put_failure;
+	DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len);
+	for (i = 0; i < 6; i++)
+		DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n",
+			*((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1),
+			*((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3));
+	prWifiChangeCmd = kalMemAlloc(sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE), VIR_MEM_TYPE);
+	if (prWifiChangeCmd == NULL)
+		goto nla_put_failure;
+	kalMemZero(prWifiChangeCmd, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE));
+	attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE);
+	if (attr == NULL)
+		goto nla_put_failure;
+	kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1));
+
+	if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH,
+		(struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0)
+		goto nla_put_failure;
+	len_basic = 0;
+	for (k = GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE; k <= GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH; k++) {
+		if (attr[k]) {
+			switch (k) {
+			case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE:
+				prWifiChangeCmd->rssi_sample_size = nla_get_u16(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				break;
+			case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE:
+				prWifiChangeCmd->lost_ap_sample_size = nla_get_u16(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				break;
+			case GSCAN_ATTRIBUTE_MIN_BREACHING:
+				prWifiChangeCmd->min_breaching = nla_get_u16(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				break;
+			case GSCAN_ATTRIBUTE_NUM_AP:
+				prWifiChangeCmd->num_ap = nla_get_u16(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n",
+				       *(UINT_32 *) attr[k], prWifiChangeCmd->num_ap, attr[k]->nla_len);
+				break;
+			case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH:
+				flush = nla_get_u8(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				break;
+			}
+		}
+	}
+	paplist = (struct nlattr *)((UINT_8 *) data + len_basic);
+	DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush);
+
+	if (paplist->nla_type == GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS)
+		paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN);
+
+	for (i = 0; i < prWifiChangeCmd->num_ap; i++) {
+		if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0)
+			goto nla_put_failure;
+		paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN);
+		/* request.attr_start(i) as nested attribute */
+		len_aplist = 0;
+		for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) {
+			if (attr[k]) {
+				switch (k) {
+				case GSCAN_ATTRIBUTE_BSSID:
+					kalMemCopy(prWifiChangeCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr));
+					len_aplist += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_RSSI_LOW:
+					prWifiChangeCmd->ap[i].low = nla_get_u32(attr[k]);
+					len_aplist += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_RSSI_HIGH:
+					prWifiChangeCmd->ap[i].high = nla_get_u32(attr[k]);
+					len_aplist += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				}
+			}
+		}
+		if (((i + 1) % 4 == 0) || (i == prWifiChangeCmd->num_ap - 1))
+			DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist);
+		else
+			DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist);
+		paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist);
+	}
+
+	DBGLOG(REQ, TRACE,
+		"flush=%d, rssi_sample_size=%d lost_ap_sample_size=%d min_breaching=%d",
+		flush, prWifiChangeCmd->rssi_sample_size, prWifiChangeCmd->lost_ap_sample_size,
+		prWifiChangeCmd->min_breaching);
+	DBGLOG(REQ, TRACE,
+		"ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d",
+		prWifiChangeCmd->ap[0].channel, prWifiChangeCmd->ap[0].low, prWifiChangeCmd->ap[0].high,
+		prWifiChangeCmd->ap[1].channel, prWifiChangeCmd->ap[1].low, prWifiChangeCmd->ap[1].high);
+	kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE));
+	kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1));
+	return 0;
+
+nla_put_failure:
+	if (prWifiChangeCmd)
+		kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE));
+	if (attr)
+		kalMemFree(attr, VIR_MEM_TYPE,
+			sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1));
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	/*WLAN_STATUS rStatus;*/
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist;
+
+	INT_32 i4Status = -EINVAL;
+	P_PARAM_WIFI_BSSID_HOTLIST prWifiHotlistCmd = NULL;
+	UINT_8 flush = 0;
+	/* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */
+	struct nlattr **attr = NULL;
+	struct nlattr *paplist;
+	int i, k;
+	UINT_32 len_basic, len_aplist;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	if ((data == NULL) || !data_len)
+		goto nla_put_failure;
+	DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len);
+	for (i = 0; i < 5; i++)
+		DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n",
+			*((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1),
+			*((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3));
+	prWifiHotlistCmd = kalMemAlloc(sizeof(PARAM_WIFI_BSSID_HOTLIST), VIR_MEM_TYPE);
+	if (prWifiHotlistCmd == NULL)
+		goto nla_put_failure;
+	kalMemZero(prWifiHotlistCmd, sizeof(PARAM_WIFI_BSSID_HOTLIST));
+	attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE);
+	if (attr == NULL)
+		goto nla_put_failure;
+	kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1));
+
+	if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_AP, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0)
+		goto nla_put_failure;
+	len_basic = 0;
+	for (k = GSCAN_ATTRIBUTE_HOTLIST_FLUSH; k <= GSCAN_ATTRIBUTE_NUM_AP; k++) {
+		if (attr[k]) {
+			switch (k) {
+			case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE:
+				prWifiHotlistCmd->lost_ap_sample_size = nla_get_u32(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				break;
+			case GSCAN_ATTRIBUTE_NUM_AP:
+				prWifiHotlistCmd->num_ap = nla_get_u16(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n",
+				       *(UINT_32 *) attr[k], prWifiHotlistCmd->num_ap, attr[k]->nla_len);
+				break;
+			case GSCAN_ATTRIBUTE_HOTLIST_FLUSH:
+				flush = nla_get_u8(attr[k]);
+				len_basic += NLA_ALIGN(attr[k]->nla_len);
+				break;
+			}
+		}
+	}
+	paplist = (struct nlattr *)((UINT_8 *) data + len_basic);
+	DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush);
+
+	if (paplist->nla_type == GSCAN_ATTRIBUTE_HOTLIST_BSSIDS)
+		paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN);
+
+	for (i = 0; i < prWifiHotlistCmd->num_ap; i++) {
+		if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0)
+			goto nla_put_failure;
+		paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN);
+		/* request.attr_start(i) as nested attribute */
+		len_aplist = 0;
+		for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) {
+			if (attr[k]) {
+				switch (k) {
+				case GSCAN_ATTRIBUTE_BSSID:
+					kalMemCopy(prWifiHotlistCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr));
+					len_aplist += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_RSSI_LOW:
+					prWifiHotlistCmd->ap[i].low = nla_get_u32(attr[k]);
+					len_aplist += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				case GSCAN_ATTRIBUTE_RSSI_HIGH:
+					prWifiHotlistCmd->ap[i].high = nla_get_u32(attr[k]);
+					len_aplist += NLA_ALIGN(attr[k]->nla_len);
+					break;
+				}
+			}
+		}
+		if (((i + 1) % 4 == 0) || (i == prWifiHotlistCmd->num_ap - 1))
+			DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist);
+		else
+			DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist);
+		paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist);
+	}
+
+	DBGLOG(REQ, TRACE,
+	"flush=%d, lost_ap_sample_size=%d, Hotlist:ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d",
+		flush, prWifiHotlistCmd->lost_ap_sample_size,
+		prWifiHotlistCmd->ap[0].channel, prWifiHotlistCmd->ap[0].low, prWifiHotlistCmd->ap[0].high,
+		prWifiHotlistCmd->ap[1].channel, prWifiHotlistCmd->ap[1].low, prWifiHotlistCmd->ap[1].high);
+
+	memcpy(&(rCmdPscnAddHotlist.aucMacAddr), &(prWifiHotlistCmd->ap[0].bssid), 6 * sizeof(UINT_8));
+	rCmdPscnAddHotlist.ucFlags = (UINT_8) TRUE;
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST));
+	kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1));
+	return 0;
+
+nla_put_failure:
+	if (prWifiHotlistCmd)
+		kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST));
+	if (attr)
+		kalMemFree(attr, VIR_MEM_TYPE,
+			sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1));
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS rWifiScanActionCmd;
+
+	INT_32 i4Status = -EINVAL;
+	struct nlattr *attr;
+	UINT_8 gGScanEn = 0;
+
+	static UINT_8 k; /* only for test */
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	if ((data == NULL) || !data_len)
+		goto nla_put_failure;
+	DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n",
+	       __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1));
+
+	attr = (struct nlattr *)data;
+	if (attr->nla_type == GSCAN_ATTRIBUTE_ENABLE_FEATURE)
+		gGScanEn = nla_get_u32(attr);
+	DBGLOG(REQ, INFO, "gGScanEn=%d, \r\n", gGScanEn);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+	if (gGScanEn == TRUE)
+		rWifiScanActionCmd.ucPscanAct = ENABLE;
+	else
+		rWifiScanActionCmd.ucPscanAct = DISABLE;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetGSCNAction,
+			   &rWifiScanActionCmd,
+			   sizeof(PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	/* mtk_cfg80211_vendor_get_scan_results(wiphy, wdev, data, data_len ); */
+
+	return 0;
+
+	/* only for test */
+	if (k % 3 == 1) {
+		mtk_cfg80211_vendor_event_significant_change_results(wiphy, wdev, NULL, 0);
+		mtk_cfg80211_vendor_event_hotlist_ap_found(wiphy, wdev, NULL, 0);
+		mtk_cfg80211_vendor_event_hotlist_ap_lost(wiphy, wdev, NULL, 0);
+	}
+	k++;
+
+	return 0;
+
+nla_put_failure:
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev,
+						 const void *data, int data_len)
+{
+	INT_32 i4Status = -EINVAL;
+	struct nlattr *attr;
+	UINT_8 gFullScanResultsEn = 0;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	if ((data == NULL) || !data_len)
+		goto nla_put_failure;
+	DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n",
+	       __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1));
+
+	attr = (struct nlattr *)data;
+	if (attr->nla_type == GSCAN_ENABLE_FULL_SCAN_RESULTS)
+		gFullScanResultsEn = nla_get_u32(attr);
+	DBGLOG(REQ, INFO, "gFullScanResultsEn=%d, \r\n", gFullScanResultsEn);
+
+	return 0;
+
+	/* only for test */
+	mtk_cfg80211_vendor_event_complete_scan(wiphy, wdev, WIFI_SCAN_COMPLETE);
+	mtk_cfg80211_vendor_event_scan_results_available(wiphy, wdev, 4);
+	if (gFullScanResultsEn == TRUE)
+		mtk_cfg80211_vendor_event_full_scan_results(wiphy, wdev, NULL, 0);
+
+	return 0;
+
+nla_put_failure:
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	/*WLAN_STATUS rStatus;*/
+	UINT_32 u4BufLen;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	PARAM_WIFI_GSCAN_GET_RESULT_PARAMS rGSscnResultParm;
+
+	INT_32 i4Status = -EINVAL;
+	struct nlattr *attr;
+	UINT_32 get_num = 0, real_num = 0;
+	UINT_8 flush = 0;
+	/*PARAM_WIFI_GSCAN_RESULT result[4], *pResult;
+	struct sk_buff *skb;*/
+	int i; /*int j;*/
+	/*UINT_32 scan_id;*/
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	if ((data == NULL) || !data_len)
+		goto nla_put_failure;
+	DBGLOG(REQ, TRACE, "%s for vendor command: data_len=%d \r\n", __func__, data_len);
+	for (i = 0; i < 2; i++)
+		DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4),
+			*((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2),
+			*((UINT_32 *) data + i * 4 + 3));
+
+	attr = (struct nlattr *)data;
+	if (attr->nla_type == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) {
+		get_num = nla_get_u32(attr);
+		attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len);
+	}
+	if (attr->nla_type == GSCAN_ATTRIBUTE_FLUSH_RESULTS) {
+		flush = nla_get_u8(attr);
+		attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len);
+	}
+	DBGLOG(REQ, TRACE, "number=%d, flush=%d \r\n", get_num, flush);
+
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+	ASSERT(prGlueInfo);
+
+	real_num = (get_num < PSCAN_MAX_SCAN_CACHE_SIZE) ? get_num : PSCAN_MAX_SCAN_CACHE_SIZE;
+	get_num = real_num;
+
+#if 0	/* driver buffer FW results and reports by buffer workaround for FW mismatch with hal results numbers */
+	g_GetResultsCmdCnt++;
+	DBGLOG(REQ, INFO,
+	       "(g_GetResultsCmdCnt [%d], g_GetResultsBufferedCnt [%d]\n", g_GetResultsCmdCnt,
+		g_GetResultsBufferedCnt);
+
+	BOOLEAN fgIsGetResultFromBuffer = FALSE;
+	UINT_8 BufferedResultReportIndex = 0;
+
+	if (g_GetResultsBufferedCnt > 0) {
+
+		DBGLOG(REQ, INFO,
+		       "(g_GetResultsBufferedCnt > 0), report buffered results instead of ask from FW\n");
+
+		/* reply the results to wifi_hal  */
+		for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) {
+
+			if (g_arGscanResultsIndicateNumber[i] > 0) {
+				real_num = g_arGscanResultsIndicateNumber[i];
+				get_num = real_num;
+				g_arGscanResultsIndicateNumber[i] = 0;
+				fgIsGetResultFromBuffer = TRUE;
+				BufferedResultReportIndex = i;
+				break;
+			}
+		}
+		if (i == MAX_BUFFERED_GSCN_RESULTS)
+			DBGLOG(REQ, TRACE, "all buffered results are invalid, unexpected case \r\n");
+		DBGLOG(REQ, TRACE, "BufferedResultReportIndex[%d] i = %d real_num[%d] get_num[%d] \r\n",
+			BufferedResultReportIndex, i, real_num, get_num);
+	}
+#endif
+
+	rGSscnResultParm.get_num = get_num;
+	rGSscnResultParm.flush = flush;
+#if 0/* //driver buffer FW results and reports by buffer workaround for FW results mismatch with hal results number */
+	if (fgIsGetResultFromBuffer) {
+		nicRxProcessGSCNEvent(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]);
+		g_GetResultsBufferedCnt--;
+		g_GetResultsCmdCnt--;
+		nicRxReturnRFB(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]);
+	} else
+#endif
+	{
+		kalIoctl(prGlueInfo,
+			 wlanoidGetGSCNResult,
+			 &rGSscnResultParm,
+			 sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+	}
+	return 0;
+
+nla_put_failure:
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Status = -EINVAL;
+	PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities;
+	struct sk_buff *skb;
+
+	DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__);
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rRttCapabilities));
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status);
+		return -ENOMEM;
+	}
+
+	kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities));
+
+	/*rStatus = kalIoctl(prGlueInfo,
+	   wlanoidQueryStatistics,
+	   &rRttCapabilities,
+	   sizeof(rRttCapabilities),
+	   TRUE,
+	   TRUE,
+	   TRUE,
+	   FALSE,
+	   &u4BufLen); */
+	rRttCapabilities.rtt_one_sided_supported = 0;
+	rRttCapabilities.rtt_ftm_supported = 0;
+	rRttCapabilities.lci_support = 0;
+	rRttCapabilities.lcr_support = 0;
+	rRttCapabilities.preamble_support = 0;
+	rRttCapabilities.bw_support = 0;
+
+	if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES,
+		sizeof(rRttCapabilities), &rRttCapabilities) < 0))
+		goto nla_put_failure;
+
+	i4Status = cfg80211_vendor_cmd_reply(skb);
+	return i4Status;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len)
+{
+	INT_32 i4Status = -EINVAL;
+	WIFI_RADIO_STAT *pRadioStat;
+	struct sk_buff *skb;
+	UINT_32 u4BufLen;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+
+	u4BufLen = sizeof(WIFI_RADIO_STAT) + sizeof(WIFI_IFACE_STAT);
+	pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE);
+	if (!pRadioStat) {
+		DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", __func__);
+		return -ENOMEM;
+	}
+	kalMemZero(pRadioStat, u4BufLen);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen);
+	if (!skb) {
+		DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status);
+		return -ENOMEM;
+	}
+
+	/*rStatus = kalIoctl(prGlueInfo,
+	   wlanoidQueryStatistics,
+	   &rRadioStat,
+	   sizeof(rRadioStat),
+	   TRUE,
+	   TRUE,
+	   TRUE,
+	   FALSE,
+	   &u4BufLen); */
+	/* only for test */
+	pRadioStat->radio = 10;
+	pRadioStat->on_time = 11;
+	pRadioStat->tx_time = 12;
+	pRadioStat->num_channels = 4;
+
+	/*NLA_PUT(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat);*/
+	if (unlikely(nla_put(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat) < 0))
+		goto nla_put_failure;
+
+	i4Status = cfg80211_vendor_cmd_reply(skb);
+	kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen);
+	return -1; /* not support LLS now*/
+	/* return i4Status; */
+
+nla_put_failure:
+	kfree_skb(skb);
+	return i4Status;
+}
+
+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete)
+{
+	struct sk_buff *skb;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	/* WIFI_SCAN_EVENT complete_scan; */
+
+	DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__);
+
+	skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(complete), GSCAN_EVENT_COMPLETE_SCAN, GFP_KERNEL);
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__);
+		return -ENOMEM;
+	}
+	/* complete_scan = WIFI_SCAN_COMPLETE; */
+	/*NLA_PUT_U32(skb, GSCAN_EVENT_COMPLETE_SCAN, complete);*/
+	{
+		unsigned int __tmp = complete;
+
+		if (unlikely(nla_put(skb, GSCAN_EVENT_COMPLETE_SCAN,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num)
+{
+	struct sk_buff *skb;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	/* UINT_32 scan_result; */
+
+	DBGLOG(REQ, INFO, "%s for vendor command %d  \r\n", __func__, num);
+
+	skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(num), GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, GFP_KERNEL);
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__);
+		return -ENOMEM;
+	}
+	/* scan_result = 2; */
+	/*NLA_PUT_U32(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, num);*/
+	{
+		unsigned int __tmp = num;
+
+		if (unlikely(nla_put(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE,
+			sizeof(unsigned int), &__tmp) < 0))
+			goto nla_put_failure;
+	}
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev,
+						P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len)
+{
+	struct sk_buff *skb;
+	PARAM_WIFI_GSCAN_RESULT result;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__);
+
+	skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(result), GSCAN_EVENT_FULL_SCAN_RESULTS, GFP_KERNEL);
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	kalMemZero(&result, sizeof(result));
+	kalMemCopy(result.ssid, "Gscan_full_test", sizeof("Gscan_full_test"));
+	result.channel = 2437;
+
+	/* kalMemCopy(&result, pdata, sizeof(PARAM_WIFI_GSCAN_RESULT); */
+	/*NLA_PUT(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, sizeof(result), &result);*/
+	if (unlikely(nla_put(skb, GSCAN_EVENT_FULL_SCAN_RESULTS,
+		sizeof(result), &result) < 0))
+		goto nla_put_failure;
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev,
+							 P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len)
+{
+	struct sk_buff *skb;
+	PARAM_WIFI_CHANGE_RESULT result[2], *presult;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__);
+
+	skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_CHANGE_RESULT),
+					  GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, GFP_KERNEL);
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	presult = result;
+	kalMemZero(presult, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2));
+	/* only for test */
+	kalMemCopy(presult->bssid, "213123", sizeof(mac_addr));
+	presult->channel = 2437;
+	presult->rssi[0] = -45;
+	presult->rssi[1] = -46;
+	presult++;
+	presult->channel = 2439;
+	presult->rssi[0] = -47;
+	presult->rssi[1] = -48;
+	/*NLA_PUT(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result);*/
+	if (unlikely(nla_put(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS,
+		(sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result) < 0))
+		goto nla_put_failure;
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev,
+					       P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len)
+{
+	struct sk_buff *skb;
+	PARAM_WIFI_GSCAN_RESULT result[2], *presult;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__);
+
+	skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT),
+					  GSCAN_EVENT_HOTLIST_RESULTS_FOUND, GFP_KERNEL);
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	presult = result;
+	kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2));
+	/* only for test */
+	kalMemCopy(presult->bssid, "123123", sizeof(mac_addr));
+	presult->channel = 2441;
+	presult->rssi = -45;
+	presult++;
+	presult->channel = 2443;
+	presult->rssi = -47;
+	/*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/
+	if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND,
+		(sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0))
+		goto nla_put_failure;
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev,
+					      P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len)
+{
+	struct sk_buff *skb;
+	PARAM_WIFI_GSCAN_RESULT result[2], *presult;
+
+	ASSERT(wiphy);
+	ASSERT(wdev);
+	DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__);
+
+	skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT),
+					  GSCAN_EVENT_HOTLIST_RESULTS_LOST, GFP_KERNEL);
+	if (!skb) {
+		DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	presult = result;
+	kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2));
+	/* only for test */
+	kalMemCopy(presult->bssid, "321321", sizeof(mac_addr));
+	presult->channel = 2445;
+	presult->rssi = -46;
+	presult++;
+	presult->channel = 2447;
+	presult->rssi = -48;
+	/*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/
+	if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST,
+		(sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0))
+		goto nla_put_failure;
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -1;
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c
new file mode 100644
index 0000000000000..1793742e98022
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c
@@ -0,0 +1,4158 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3
+*/
+
+/*! \file gl_wext.c
+    \brief  ioctl() (mostly Linux Wireless Extensions) routines for STA driver.
+*/
+
+/*
+** Log: gl_wext.c
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 01 16 2012 wh.su
+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl
+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6)..
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 01 02 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 23 2011 tsaiyuan.hsu
+ * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state
+ * avoid entering D3 state after deep sleep.
+ *
+ * 07 28 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS cmd and event.
+ *
+ * 07 27 2011 wh.su
+ * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query
+ * the ap address
+ * Remove the netif check while query bssid and ssid
+ *
+ * 07 26 2011 chinglan.wang
+ * NULL
+ * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection..
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 05 17 2011 eddie.chen
+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
+ * Initialize the vairlabes.
+ *
+ * 05 11 2011 jeffrey.chang
+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
+ * modify set_tx_pow ioctl
+ *
+ * 03 29 2011 terry.wu
+ * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring
+ * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of
+ * essid storage array.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * improve portability for awareness of early version of linux kernel and wireless extension.
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 02 21 2011 wh.su
+ * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get
+ * essid
+ * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running.
+ *
+ * 02 08 2011 george.huang
+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
+ * Support querying power mode OID.
+ *
+ * 01 29 2011 wh.su
+ * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0
+ * not doing mem alloc. while set ie length already 0
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Remove debug text.
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Adjust OID order.
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Add Oid for sw control debug command
+ *
+ * 01 11 2011 chinglan.wang
+ * NULL
+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP.  Connection establish
+ * successfully.
+ * Use the WPS function to connect AP, the privacy bit always is set to 1. .
+ *
+ * 01 07 2011 cm.chang
+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
+ * Add a new compiling option to control if MCR read/write is permitted
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
+ * physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous types
+ * to ease slab system pressure
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
+ * physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 12 31 2010 cm.chang
+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
+ * Add some iwpriv commands to support test mode operation
+ *
+ * 12 15 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * Support set PS profile and set WMM-PS related iwpriv.
+ *
+ * 12 15 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * Allow change PS profile function (through wext_set_power()).
+ *
+ * 12 14 2010 jeffrey.chang
+ * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID
+ * handle hidden SSID
+ *
+ * 12 13 2010 chinglan.wang
+ * NULL
+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function.
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * Fix compiling error
+ *
+ * 12 07 2010 cm.chang
+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
+ * 1. Country code is from NVRAM or supplicant
+ * 2. Change band definition in CMD/EVENT.
+ *
+ * 11 30 2010 cp.wu
+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1
+ * .
+ *
+ * 11 08 2010 wh.su
+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
+ * add the message check code from mt5921.
+ *
+ * 10 19 2010 jeffrey.chang
+ * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power
+ * saving
+ * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving
+ *
+ * 10 18 2010 jeffrey.chang
+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue
+ * refine the scan ioctl to prevent hanging of Android UI
+ *
+ * 10 01 2010 wh.su
+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
+ * add the scan result with wapi ie.
+ *
+ * 09 30 2010 wh.su
+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
+ * fixed the wapi ie assigned issue.
+ *
+ * 09 27 2010 wh.su
+ * NULL
+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function.
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 09 2010 cp.wu
+ * NULL
+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result.
+ *
+ * 09 06 2010 cp.wu
+ * NULL
+ * Androi/Linux: return current operating channel information
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * enable remove key ioctl
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * 1) modify tx service thread to avoid busy looping
+ * 2) add spin lock declartion for linux build
+ *
+ * 07 28 2010 jeffrey.chang
+ * NULL
+ * 1) enable encyption ioctls
+ * 2) temporarily disable remove keys ioctl to prevent  TX1 busy
+ *
+ * 07 28 2010 jeffrey.chang
+ * NULL
+ * 1) remove unused spinlocks
+ * 2) enable encyption ioctls
+ * 3) fix scan ioctl which may cause supplicant to hang
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * add kal api for scanning done
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * for linux driver migration
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 28 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * remove unused macro and debug messages
+ *
+ * 05 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Add dissassoication support for wpa supplicant
+ *
+ * 04 22 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ *
+ * 1) modify rx path code for supporting Wi-Fi direct
+ * 2) modify config.h since Linux dont need to consider retaining packet
+ *
+ * 04 21 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add for private ioctl support
+ *
+ * 04 19 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Add ioctl of power management
+ *
+ * 04 19 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * remove debug message
+ *
+ * 04 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used
+ *  * 2) fix ioctl
+ *
+ * 04 12 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * remove debug messages for pre-release
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  *  *  *  *  *  * are done in adapter layer.
+ *
+ * 04 02 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix ioctl type
+ *
+ * 04 01 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * enable pmksa cache operation
+ *
+ * 03 31 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix ioctl which may cause cmdinfo memory leak
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 30 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * emulate NDIS Pending OID facility
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090
+**  Avoid accessing private data of net_device directly. Replace with netdev_priv().
+**  Add more checking for input parameters and pointers.
+**  \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090
+**  Remove unused variables
+**  \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088
+**  adding the wapi ioctl support
+**  \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089
+**  fix compiling warning
+**  \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089
+**  Add mandatory and private IO control for Linux BWCS
+**  \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088
+**  fixed the compiling error
+**  \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088
+**  add the privacy setting from linux supplicant ap selection
+**  \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088
+**  fixed the compling error
+**  \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088
+**  rename some variable with pre-fix to avoid the misunderstanding
+**  \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088
+**  fixed compiling error
+**  \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088
+**  adjust the code for meet the coding style, and add assert check
+**  \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461
+**  Update after wlanoidSetPowerMode changed
+**  \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084
+**  rename wlanoid
+**  \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461
+**  Add set desired rate in Linux STD IOCTL
+**  \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088
+**  add pmkid ioctl and indicate
+**  \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461
+**  \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461
+**  Refine WPS related priv ioctl for unified interface
+**
+**  \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088
+**  move the configuration code from set essid function,
+**  remove the non-used code
+**  \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461
+**  Fix CR[489]
+**  \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461
+**  Add Set Frequency & Channel oid support for Linux
+**  \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461
+**  \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461
+**  Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter
+**  \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425
+**  1. Branch Test
+**  \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461
+**  fix typo
+**  \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425
+**  1. Fix compiling erros
+**
+**  \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425
+**  1. Add WMM-PS setting
+**  \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088
+**  fixed the compiler error
+**  \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088
+**  add WPS code
+**  \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425
+**  1. Update wlanQueryInformation
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#include "gl_os.h"
+
+#include "config.h"
+#include "wlan_oid.h"
+
+#include "gl_wext.h"
+#include "gl_wext_priv.h"
+
+#include "precomp.h"
+
+#if CFG_SUPPORT_WAPI
+#include "gl_sec.h"
+#endif
+
+/* compatibility to wireless extensions */
+#ifdef WIRELESS_EXT
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+const long channel_freq[] = {
+	2412, 2417, 2422, 2427, 2432, 2437, 2442,
+	2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+
+
+#define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0]))
+
+#define MAX_SSID_LEN    32
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+/* NOTE: name in iwpriv_args only have 16 bytes */
+static const struct iw_priv_args rIwPrivTable[] = {
+	{IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""},
+	{IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""},
+	{IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""},
+	{IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""},
+	{IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""},
+
+	{IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""},
+	{IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""},
+
+	{IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""},
+	{IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""},
+	{IOCTL_GET_INT, 0, IW_PRIV_TYPE_CHAR | 16, ""},
+
+	{IOCTL_SET_STRING, IW_PRIV_TYPE_CHAR | 256, 0, ""},
+
+	/* added for set_oid and get_oid */
+	{IOCTL_SET_STRUCT, 256, 0, ""},
+	{IOCTL_GET_STRUCT, 0, 256, ""},
+
+	/* sub-ioctl definitions */
+#if 0
+	{PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain"},
+	{PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain"},
+#endif
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	{PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum"},
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+	{PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode"},
+	{PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode"},
+
+	{PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps"},
+
+	{PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode"},
+	{PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd"},
+	{PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_test_result"},
+#if CFG_SUPPORT_PRIV_MCR_RW
+	{PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr"},
+	{PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_mcr"},
+#endif
+	{PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl"},
+	{PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_sw_ctrl"},
+
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
+	{PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"},
+	/* GET STRUCT sub-ioctls commands */
+	{PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_bwcs"},
+#endif
+
+	/* SET STRUCT sub-ioctls commands */
+	{PRIV_CMD_OID, 256, 0, "set_oid"},
+	/* GET STRUCT sub-ioctls commands */
+	{PRIV_CMD_OID, 0, 256, "get_oid"},
+
+	{PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band"},
+	{PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band"},
+
+	{PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower"},
+	{PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list"},
+	{PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_mem"},
+
+#if CFG_ENABLE_WIFI_DIRECT
+	{PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode"},
+#endif
+	{PRIV_CMD_GET_BUILD_DATE_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_date_code"},
+	{PRIV_CMD_GET_DEBUG_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_dbg_code"},
+	/* handle any command with many input parameters */
+	{PRIV_CMD_OTHER, IW_PRIV_TYPE_CHAR | 256, 0, "set_str_cmd"},
+
+	{PRIV_CMD_WFD_DEBUG_CODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_wfd_dbg_code"},
+};
+
+static const iw_handler rIwPrivHandler[] = {
+	[IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int,
+	[IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int,
+	[IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL,
+	[IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL,
+	[IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL,
+	[IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL,
+	[IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL,
+	[IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL,
+	[IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct,
+	[IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct,
+	[IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct,
+	[IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints,
+	[IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints,
+	[IOCTL_SET_STRING - SIOCIWFIRSTPRIV] = priv_set_string,
+};
+
+const struct iw_handler_def wext_handler_def = {
+	.num_standard = 0,
+	.num_private = (__u16) sizeof(rIwPrivHandler) / sizeof(iw_handler),
+	.num_private_args = (__u16) sizeof(rIwPrivTable) / sizeof(struct iw_priv_args),
+	.standard = (iw_handler *) NULL,
+	.private = rIwPrivHandler,
+	.private_args = rIwPrivTable,
+	.get_wireless_stats = wext_get_wireless_stats,
+};
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Find the desired WPA/RSN Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucIEStart);
+	ASSERT(ppucDesiredIE);
+
+	while (i4TotalIeLen >= 2) {
+		i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
+
+		if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) {
+			if (ucDesiredElemId != 0xDD) {
+				/* Non 0xDD, OK! */
+				*ppucDesiredIE = &pucIEStart[0];
+				return TRUE;
+			}
+			/* EID == 0xDD, check WPA IE */
+			if (pucIEStart[1] >= 4) {
+				if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) {
+					*ppucDesiredIE = &pucIEStart[0];
+					return TRUE;
+				}
+			}	/* check WPA IE length */
+			/* check EID == 0xDD */
+		}
+
+		/* check desired EID */
+		/* Select next information element. */
+		i4TotalIeLen -= i4InfoElemLen;
+		pucIEStart += i4InfoElemLen;
+	}
+
+	return FALSE;
+}				/* parseSearchDesiredWPAIE */
+
+#if CFG_SUPPORT_WAPI
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Find the desired WAPI Information Element .
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucIEStart);
+	ASSERT(ppucDesiredIE);
+
+	while (i4TotalIeLen >= 2) {
+		i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
+
+		if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) {
+			*ppucDesiredIE = &pucIEStart[0];
+			return TRUE;
+		}
+
+		/* check desired EID */
+		/* Select next information element. */
+		i4TotalIeLen -= i4InfoElemLen;
+		pucIEStart += i4InfoElemLen;
+	}
+
+	return FALSE;
+}				/* wextSrchDesiredWAPIIE */
+#endif
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Check if exist the desired HS2.0 Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextIsDesiredHS20IE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucCurIE);
+
+	i4InfoElemLen = (INT_32) pucCurIE[1] + 2;
+
+	if (pucCurIE[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) {
+		if (pucCurIE[1] >= ELEM_MIN_LEN_HS20_INDICATION) {
+			if (memcmp(&pucCurIE[2], "\x50\x6f\x9a\x10", 4) == 0)
+				return TRUE;
+		}
+	}
+	/* check desired EID */
+	return FALSE;
+}				/* wextIsDesiredHS20IE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Check if exist the desired interworking Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextIsDesiredInterworkingIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucCurIE);
+
+	i4InfoElemLen = (INT_32) pucCurIE[1] + 2;
+
+	if (pucCurIE[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) {
+		switch (pucCurIE[1]) {
+		case IW_IE_LENGTH_ANO:
+		case IW_IE_LENGTH_ANO_HESSID:
+		case IW_IE_LENGTH_ANO_VENUE:
+		case IW_IE_LENGTH_ANO_VENUE_HESSID:
+			return TRUE;
+
+		default:
+			break;
+		}
+
+	}
+	/* check desired EID */
+	return FALSE;
+}				/* wextIsDesiredInterworkingIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextIsDesiredAdvProtocolIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucCurIE);
+
+	i4InfoElemLen = (INT_32) pucCurIE[1] + 2;
+
+	if (pucCurIE[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen)
+		return TRUE;
+	/* check desired EID */
+	return FALSE;
+}				/* wextIsDesiredAdvProtocolIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextIsDesiredRoamingConsortiumIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucCurIE);
+
+	i4InfoElemLen = (INT_32) pucCurIE[1] + 2;
+
+	if (pucCurIE[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen)
+		return TRUE;
+	/* check desired EID */
+	return FALSE;
+}				/* wextIsDesiredRoamingConsortiumIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Find the desired HS2.0 Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucIEStart);
+	ASSERT(ppucDesiredIE);
+
+	while (i4TotalIeLen >= 2) {
+		i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
+
+		if (pucIEStart[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) {
+			if (pucIEStart[1] >= ELEM_MIN_LEN_HS20_INDICATION) {
+				if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x10", 4) == 0) {
+					*ppucDesiredIE = &pucIEStart[0];
+					return TRUE;
+				}
+			}
+		}
+
+		/* check desired EID */
+		/* Select next information element. */
+		i4TotalIeLen -= i4InfoElemLen;
+		pucIEStart += i4InfoElemLen;
+	}
+
+	return FALSE;
+}				/* wextSrchDesiredHS20IE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Find the desired interworking Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucIEStart);
+	ASSERT(ppucDesiredIE);
+
+	while (i4TotalIeLen >= 2) {
+		i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
+
+		if (pucIEStart[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) {
+			*ppucDesiredIE = &pucIEStart[0];
+			return TRUE;
+		}
+
+		/* check desired EID */
+		/* Select next information element. */
+		i4TotalIeLen -= i4InfoElemLen;
+		pucIEStart += i4InfoElemLen;
+	}
+
+	return FALSE;
+}				/* wextSrchDesiredInterworkingIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Find the desired Adv Protocol Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucIEStart);
+	ASSERT(ppucDesiredIE);
+
+	while (i4TotalIeLen >= 2) {
+		i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
+
+		if (pucIEStart[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) {
+			*ppucDesiredIE = &pucIEStart[0];
+			return TRUE;
+		}
+
+		/* check desired EID */
+		/* Select next information element. */
+		i4TotalIeLen -= i4InfoElemLen;
+		pucIEStart += i4InfoElemLen;
+	}
+
+	return FALSE;
+}				/* wextSrchDesiredAdvProtocolIE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Find the desired Roaming Consortium Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucIEStart);
+	ASSERT(ppucDesiredIE);
+
+	while (i4TotalIeLen >= 2) {
+		i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
+
+		if (pucIEStart[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) {
+			*ppucDesiredIE = &pucIEStart[0];
+			return TRUE;
+		}
+
+		/* check desired EID */
+		/* Select next information element. */
+		i4TotalIeLen -= i4InfoElemLen;
+		pucIEStart += i4InfoElemLen;
+	}
+
+	return FALSE;
+}				/* wextSrchDesiredRoamingConsortiumIE */
+#endif
+
+#if CFG_SUPPORT_WPS
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Find the desired WPS Information Element according to desiredElemID.
+*
+* \param[in] pucIEStart IE starting address.
+* \param[in] i4TotalIeLen Total length of all the IE.
+* \param[in] ucDesiredElemId Desired element ID.
+* \param[out] ppucDesiredIE Pointer to the desired IE.
+*
+* \retval TRUE Find the desired IE.
+* \retval FALSE Desired IE not found.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE)
+{
+	INT_32 i4InfoElemLen;
+
+	ASSERT(pucIEStart);
+	ASSERT(ppucDesiredIE);
+
+	while (i4TotalIeLen >= 2) {
+		i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
+
+		if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) {
+			if (ucDesiredElemId != 0xDD) {
+				/* Non 0xDD, OK! */
+				*ppucDesiredIE = &pucIEStart[0];
+				return TRUE;
+			}
+			/* EID == 0xDD, check WPS IE */
+			if (pucIEStart[1] >= 4) {
+				if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) {
+					*ppucDesiredIE = &pucIEStart[0];
+					return TRUE;
+				}
+			}	/* check WPS IE length */
+			/* check EID == 0xDD */
+		}
+
+		/* check desired EID */
+		/* Select next information element. */
+		i4TotalIeLen -= i4InfoElemLen;
+		pucIEStart += i4InfoElemLen;
+	}
+
+	return FALSE;
+}				/* parseSearchDesiredWPSIE */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Get the name of the protocol used on the air.
+*
+* \param[in]  prDev Net device requested.
+* \param[in]  prIwrInfo NULL.
+* \param[out] pcName Buffer to store protocol name string
+* \param[in]  pcExtra NULL.
+*
+* \retval 0 For success.
+*
+* \note If netif_carrier_ok, protocol name is returned;
+*       otherwise, "disconnected" is returned.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_name(IN struct net_device *prNetDev, IN struct iw_request_info *prIwrInfo, OUT char *pcName, IN char *pcExtra)
+{
+	ENUM_PARAM_NETWORK_TYPE_T eNetWorkType = PARAM_NETWORK_TYPE_NUM;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(pcName);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pcName))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	if (netif_carrier_ok(prNetDev)) {
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidQueryNetworkTypeInUse,
+				   &eNetWorkType, sizeof(eNetWorkType), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		switch (eNetWorkType) {
+		case PARAM_NETWORK_TYPE_DS:
+			strcpy(pcName, "IEEE 802.11b");
+			break;
+		case PARAM_NETWORK_TYPE_OFDM24:
+			strcpy(pcName, "IEEE 802.11bgn");
+			break;
+		case PARAM_NETWORK_TYPE_AUTOMODE:
+		case PARAM_NETWORK_TYPE_OFDM5:
+			strcpy(pcName, "IEEE 802.11abgn");
+			break;
+		case PARAM_NETWORK_TYPE_FH:
+		default:
+			strcpy(pcName, "IEEE 802.11");
+			break;
+		}
+	} else {
+		strcpy(pcName, "Disconnected");
+	}
+
+	return 0;
+}				/* wext_get_name */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set the operating channel in the wireless device.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL
+* \param[in] prFreq Buffer to store frequency information
+* \param[in] pcExtra NULL
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS.
+* \retval -EINVAL Invalid channel frequency.
+*
+* \note If infrastructure mode is IBSS, new channel frequency is set to device.
+*      The range of channel number depends on different regulatory domain.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_freq(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN struct iw_freq *prIwFreq, IN char *pcExtra)
+{
+
+#if 0
+	UINT_32 u4ChnlFreq;	/* Store channel or frequency information */
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prIwFreq);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/*
+	   printk("set m:%d, e:%d, i:%d, flags:%d\n",
+	   prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags);
+	 */
+
+	/* If setting by frequency, convert to a channel */
+	if ((prIwFreq->e == 1) && (prIwFreq->m >= (int)2.412e8) && (prIwFreq->m <= (int)2.484e8)) {
+
+		/* Change to KHz format */
+		u4ChnlFreq = (UINT_32) (prIwFreq->m / (KILO / 10));
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetFrequency,
+				   &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen);
+
+		if (WLAN_STATUS_SUCCESS != rStatus)
+			return -EINVAL;
+	}
+	/* Setting by channel number */
+	else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0))
+		return -EOPNOTSUPP;
+
+	/* Change to channel number format */
+	u4ChnlFreq = (UINT_32) prIwFreq->m;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetChannel, &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (WLAN_STATUS_SUCCESS != rStatus)
+		return -EINVAL;
+
+#endif
+
+	return 0;
+
+}				/* wext_set_freq */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get the operating channel in the wireless device.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prFreq Buffer to store frequency information.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 If netif_carrier_ok.
+* \retval -ENOTCONN Otherwise
+*
+* \note If netif_carrier_ok, channel frequency information is stored in pFreq.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_freq(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwrInfo, OUT struct iw_freq *prIwFreq, IN char *pcExtra)
+{
+	UINT_32 u4Channel = 0;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prIwFreq);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* GeorgeKuo: TODO skip checking in IBSS mode */
+	if (!netif_carrier_ok(prNetDev))
+		return -ENOTCONN;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryFrequency, &u4Channel, sizeof(u4Channel), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	prIwFreq->m = (int)u4Channel;	/* freq in KHz */
+	prIwFreq->e = 3;
+
+	return 0;
+
+}				/* wext_get_freq */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set operating mode.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] pu4Mode Pointer to new operation mode.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP If new mode is not supported.
+*
+* \note Device will run in new operation mode if it is valid.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_mode(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN unsigned int *pu4Mode, IN char *pcExtra)
+{
+	ENUM_PARAM_OP_MODE_T eOpMode;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(pu4Mode);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	switch (*pu4Mode) {
+	case IW_MODE_AUTO:
+		eOpMode = NET_TYPE_AUTO_SWITCH;
+		break;
+
+	case IW_MODE_ADHOC:
+		eOpMode = NET_TYPE_IBSS;
+		break;
+
+	case IW_MODE_INFRA:
+		eOpMode = NET_TYPE_INFRA;
+		break;
+
+	default:
+		DBGLOG(REQ, ERROR, "%s(): Set UNSUPPORTED Mode = %d.\n", __func__, *pu4Mode);
+		return -EOPNOTSUPP;
+	}
+
+	/* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetInfrastructureMode,
+			   &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	/* after set operation mode, key table are cleared */
+
+	/* reset wpa info */
+	prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
+	prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
+	prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
+#if CFG_SUPPORT_802_11W
+	prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
+#endif
+
+	return 0;
+}				/* wext_set_mode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get operating mode.
+*
+* \param[in] prNetDev Net device requested.
+* \param[in] prIwReqInfo NULL.
+* \param[out] pu4Mode Buffer to store operating mode information.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 If data is valid.
+* \retval -EINVAL Otherwise.
+*
+* \note If netif_carrier_ok, operating mode information is stored in pu4Mode.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_mode(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, OUT unsigned int *pu4Mode, IN char *pcExtra)
+{
+	ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_NUM;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(pu4Mode);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryInfrastructureMode,
+			   &eOpMode, sizeof(eOpMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	switch (eOpMode) {
+	case NET_TYPE_IBSS:
+		*pu4Mode = IW_MODE_ADHOC;
+		break;
+
+	case NET_TYPE_INFRA:
+		*pu4Mode = IW_MODE_INFRA;
+		break;
+
+	case NET_TYPE_AUTO_SWITCH:
+		*pu4Mode = IW_MODE_AUTO;
+		break;
+
+	default:
+		DBGLOG(REQ, ERROR, "%s(): Get UNKNOWN Mode.\n", __func__);
+		return -EINVAL;
+	}
+
+	return 0;
+}				/* wext_get_mode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get the valid range for each configurable STA setting value.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prData Pointer to iw_point structure, not used.
+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this
+*                     function, wext_support_ioctl() or ioctl_standard_call() in
+*                     wireless.c.
+*
+* \retval 0 If data is valid.
+*
+* \note The extra buffer (pcExtra) is filled with information from driver.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_range(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, OUT char *pcExtra)
+{
+	struct iw_range *prRange = NULL;
+	PARAM_RATES_EX aucSuppRate = { 0 };	/* data buffers */
+	int i = 0;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(pcExtra);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	prRange = (struct iw_range *)pcExtra;
+
+	memset(prRange, 0, sizeof(*prRange));
+	prRange->throughput = 20000000;	/* 20Mbps */
+	prRange->min_nwid = 0;	/* not used */
+	prRange->max_nwid = 0;	/* not used */
+
+	/* scan_capa not implemented */
+
+	/* event_capa[6]: kernel + driver capabilities */
+	prRange->event_capa[0] = (IW_EVENT_CAPA_K_0 | IW_EVENT_CAPA_MASK(SIOCGIWAP)
+				  | IW_EVENT_CAPA_MASK(SIOCGIWSCAN)
+				  /* can't display meaningful string in iwlist
+				     | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW)
+				     | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE)
+				     | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE)
+				     | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND)
+				   */
+	    );
+	prRange->event_capa[1] = IW_EVENT_CAPA_K_1;
+
+	/* report 2.4G channel and frequency only */
+	prRange->num_channels = (__u16) NUM_CHANNELS;
+	prRange->num_frequency = (__u8) NUM_CHANNELS;
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		/* iwlib takes this number as channel number */
+		prRange->freq[i].i = i + 1;
+		prRange->freq[i].m = channel_freq[i];
+		prRange->freq[i].e = 6;	/* Values in table in MHz */
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQuerySupportedRates,
+			   &aucSuppRate, sizeof(aucSuppRate), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX; i++) {
+		if (aucSuppRate[i] == 0)
+			break;
+		prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000;	/* 0.5Mbps */
+	}
+	prRange->num_bitrates = i;
+
+	prRange->min_rts = 0;
+	prRange->max_rts = 2347;
+	prRange->min_frag = 256;
+	prRange->max_frag = 2346;
+
+	prRange->min_pmp = 0;	/* power management by driver */
+	prRange->max_pmp = 0;	/* power management by driver */
+	prRange->min_pmt = 0;	/* power management by driver */
+	prRange->max_pmt = 0;	/* power management by driver */
+	prRange->pmp_flags = IW_POWER_RELATIVE;	/* pm default flag */
+	prRange->pmt_flags = IW_POWER_ON;	/* pm timeout flag */
+	prRange->pm_capa = IW_POWER_ON;	/* power management by driver */
+
+	prRange->encoding_size[0] = 5;	/* wep40 */
+	prRange->encoding_size[1] = 16;	/* tkip */
+	prRange->encoding_size[2] = 16;	/* ckip */
+	prRange->encoding_size[3] = 16;	/* ccmp */
+	prRange->encoding_size[4] = 13;	/* wep104 */
+	prRange->encoding_size[5] = 16;	/* wep128 */
+	prRange->num_encoding_sizes = 6;
+	prRange->max_encoding_tokens = 6;	/* token? */
+
+#if WIRELESS_EXT < 17
+	prRange->txpower_capa = 0x0002;	/* IW_TXPOW_RELATIVE */
+#else
+	prRange->txpower_capa = IW_TXPOW_RELATIVE;
+#endif
+	prRange->num_txpower = 5;
+	prRange->txpower[0] = 0;	/* minimum */
+	prRange->txpower[1] = 25;	/* 25% */
+	prRange->txpower[2] = 50;	/* 50% */
+	prRange->txpower[3] = 100;	/* 100% */
+
+	prRange->we_version_compiled = WIRELESS_EXT;
+	prRange->we_version_source = WIRELESS_EXT;
+
+	prRange->retry_capa = IW_RETRY_LIMIT;
+	prRange->retry_flags = IW_RETRY_LIMIT;
+	prRange->min_retry = 7;
+	prRange->max_retry = 7;
+	prRange->r_time_flags = IW_RETRY_ON;
+	prRange->min_r_time = 0;
+	prRange->max_r_time = 0;
+
+	/* signal strength and link quality */
+	/* Just define range here, reporting value moved to wext_get_stats() */
+	prRange->sensitivity = -83;	/* fixed value */
+	prRange->max_qual.qual = 100;	/* max 100% */
+	prRange->max_qual.level = (__u8) (0x100 - 0);	/* max 0 dbm */
+	prRange->max_qual.noise = (__u8) (0x100 - 0);	/* max 0 dbm */
+
+	/* enc_capa */
+#if WIRELESS_EXT > 17
+	prRange->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+
+	/* min_pms; Minimal PM saving */
+	/* max_pms; Maximal PM saving */
+	/* pms_flags; How to decode max/min PM saving */
+
+	/* modul_capa; IW_MODUL_* bit field */
+	/* bitrate_capa; Types of bitrates supported */
+
+	return 0;
+}				/* wext_get_range */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set BSSID of AP to connect.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 For success.
+*
+* \note Desired AP's BSSID is set to driver.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_ap(IN struct net_device *prDev,
+	    IN struct iw_request_info *prIwrInfo, IN struct sockaddr *prAddr, IN char *pcExtra)
+{
+	return 0;
+}				/* wext_set_ap */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get AP MAC address.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 If netif_carrier_ok.
+* \retval -ENOTCONN Otherwise.
+*
+* \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_ap(IN struct net_device *prNetDev,
+	    IN struct iw_request_info *prIwrInfo, OUT struct sockaddr *prAddr, IN char *pcExtra)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prAddr);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* if (!netif_carrier_ok(prNetDev)) { */
+	/* return -ENOTCONN; */
+	/* } */
+
+	if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED) {
+		/*memset(prAddr, 0, 6);*/
+		memset(prAddr, 0, sizeof(struct sockaddr));
+		return 0;
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryBssid, prAddr->sa_data, ETH_ALEN, TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	return 0;
+}				/* wext_get_ap */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set mlme operation request.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prData Pointer of iw_point header.
+* \param[in] pcExtra Pointer to iw_mlme structure mlme request information.
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP unsupported IW_MLME_ command.
+* \retval -EINVAL Set MLME Fail, different bssid.
+*
+* \note Driver will start mlme operation if valid.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_mlme(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, IN char *pcExtra)
+{
+	struct iw_mlme *prMlme = NULL;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(pcExtra);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	prMlme = (struct iw_mlme *)pcExtra;
+	if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) {
+		if (!netif_carrier_ok(prNetDev)) {
+			DBGLOG(REQ, WARN, "[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n");
+			return 0;
+		}
+
+		rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+		return 0;
+	}
+	DBGLOG(REQ, WARN, "[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd);
+	return -EOPNOTSUPP;
+
+}				/* wext_set_mlme */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To issue scan request.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prData NULL.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 For success.
+* \retval -EFAULT Tx power is off.
+*
+* \note Device will start scanning.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_scan(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwrInfo, IN union iwreq_data *prData, IN char *pcExtra)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+	int essid_len = 0;
+
+	ASSERT(prNetDev);
+	if (FALSE == GLUE_CHK_DEV(prNetDev))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+#if WIRELESS_EXT > 17
+	/* retrieve SSID */
+	if (prData)
+		essid_len = ((struct iw_scan_req *)(((struct iw_point *)prData)->pointer))->essid_len;
+#endif
+
+	init_completion(&prGlueInfo->rScanComp);
+
+	/* TODO:  parse flags and issue different scan requests? */
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetBssidListScan, pcExtra, essid_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	/* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ); */
+	/* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */
+
+	return 0;
+}				/* wext_set_scan */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To write the ie to buffer
+*
+*/
+/*----------------------------------------------------------------------------*/
+static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
+{
+	size_t i;
+	char *pos = buf, *end = buf + buf_size;
+	int ret;
+
+	if (buf_size == 0)
+		return 0;
+
+	for (i = 0; i < len; i++) {
+		ret = snprintf(pos, end - pos, "%02x", data[i]);
+		if (ret < 0 || ret >= end - pos) {
+			end[-1] = '\0';
+			return pos - buf;
+		}
+		pos += ret;
+	}
+	end[-1] = '\0';
+	return pos - buf;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get scan results, transform results from driver's format to WE's.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prData Pointer to iw_point structure, pData->length is the size of
+*               pcExtra buffer before used, and is updated after filling scan
+*               results.
+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this
+*                     function, wext_support_ioctl() or ioctl_standard_call() in
+*                     wireless.c.
+*
+* \retval 0 For success.
+* \retval -ENOMEM If dynamic memory allocation fail.
+* \retval -E2BIG Invalid length.
+*
+* \note Scan results is filled into pcExtra buffer, data size is updated in
+*       pData->length.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_scan(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwrInfo, IN OUT struct iw_point *prData, IN char *pcExtra)
+{
+	UINT_32 i = 0;
+	UINT_32 j = 0;
+	P_PARAM_BSSID_LIST_EX_T prList = NULL;
+	P_PARAM_BSSID_EX_T prBss = NULL;
+	P_PARAM_VARIABLE_IE_T prDesiredIE = NULL;
+	struct iw_event iwEvent;	/* local iw_event buffer */
+
+	/* write pointer of extra buffer */
+	char *pcCur = NULL;
+	/* pointer to the end of  last full entry in extra buffer */
+	char *pcValidEntryEnd = NULL;
+	char *pcEnd = NULL;	/* end of extra buffer */
+
+	UINT_32 u4AllocBufLen = 0;
+
+	/* arrange rate information */
+	UINT_32 u4HighestRate = 0;
+	char aucRatesBuf[64];
+	UINT_32 u4BufIndex;
+
+	/* return value */
+	int ret = 0;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prData);
+	ASSERT(pcExtra);
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* Initialize local variables */
+	pcCur = pcExtra;
+	pcValidEntryEnd = pcExtra;
+	pcEnd = pcExtra + prData->length;	/* end of extra buffer */
+
+	/* Allocate another query buffer with the same size of extra buffer */
+	u4AllocBufLen = prData->length;
+	prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE);
+	if (prList == NULL) {
+		DBGLOG(REQ, ERROR, "[wifi] no memory for scan list:%d\n", prData->length);
+		ret = -ENOMEM;
+		goto error;
+	}
+	prList->u4NumberOfItems = 0;
+
+	/* wait scan done */
+	/* printk ("wait for scan results\n"); */
+	/* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ); */
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus == WLAN_STATUS_INVALID_LENGTH) {
+		/* Buffer length is not large enough. */
+		/* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */
+
+#if WIRELESS_EXT >= 17
+		/* This feature is supported in WE-17 or above, limited by iwlist.
+		 ** Return -E2BIG and iwlist will request again with a larger buffer.
+		 */
+		ret = -E2BIG;
+		/* Update length to give application a hint on result length */
+		prData->length = (__u16) u4BufLen;
+		goto error;
+#else
+		/* Realloc a larger query buffer here, but don't write too much to extra
+		 ** buffer when filling it later.
+		 */
+		kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen);
+
+		u4AllocBufLen = u4BufLen;
+		prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE);
+		if (prList == NULL) {
+			DBGLOG(REQ, ERROR, "[wifi] no memory for larger scan list :%u\n", u4BufLen);
+			ret = -ENOMEM;
+			goto error;
+		}
+		prList->NumberOfItems = 0;
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		if (rStatus == WLAN_STATUS_INVALID_LENGTH) {
+			DBGLOG(REQ, ERROR, "[wifi] larger buf:%u result:%u\n", u4AllocBufLen, u4BufLen);
+			ret = -E2BIG;
+			prData->length = (__u16) u4BufLen;
+			goto error;
+		}
+#endif /* WIRELESS_EXT >= 17 */
+
+	}
+
+	if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) {
+		DBGLOG(REQ, WARN, "[wifi] strange scan result count:%u\n", prList->u4NumberOfItems);
+		goto error;
+	}
+
+	/* Copy required data from pList to pcExtra */
+	prBss = &prList->arBssid[0];	/* set to the first entry */
+	for (i = 0; i < prList->u4NumberOfItems; ++i) {
+		/* BSSID */
+		iwEvent.cmd = SIOCGIWAP;
+		iwEvent.len = IW_EV_ADDR_LEN;
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER;
+		ether_addr_copy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress);
+		memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN);
+		pcCur += IW_EV_ADDR_LEN;
+
+		/* SSID */
+		iwEvent.cmd = SIOCGIWESSID;
+		/* Modification to user space pointer(essid.pointer) is not needed. */
+		iwEvent.u.essid.length = (__u16) prBss->rSsid.u4SsidLen;
+		iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length;
+
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		iwEvent.u.essid.flags = 1;
+		iwEvent.u.essid.pointer = NULL;
+
+#if WIRELESS_EXT <= 18
+		memcpy(pcCur, &iwEvent, iwEvent.len);
+#else
+		memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+		memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+#endif
+		memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length);
+		pcCur += iwEvent.len;
+		/* Frequency */
+		iwEvent.cmd = SIOCGIWFREQ;
+		iwEvent.len = IW_EV_FREQ_LEN;
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig;
+		iwEvent.u.freq.e = 3;	/* (in KHz) */
+		iwEvent.u.freq.i = 0;
+		memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN);
+		pcCur += IW_EV_FREQ_LEN;
+
+		/* Operation Mode */
+		iwEvent.cmd = SIOCGIWMODE;
+		iwEvent.len = IW_EV_UINT_LEN;
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		if (prBss->eOpMode == NET_TYPE_IBSS)
+			iwEvent.u.mode = IW_MODE_ADHOC;
+		else if (prBss->eOpMode == NET_TYPE_INFRA)
+			iwEvent.u.mode = IW_MODE_INFRA;
+		else
+			iwEvent.u.mode = IW_MODE_AUTO;
+		memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN);
+		pcCur += IW_EV_UINT_LEN;
+
+		/* Quality */
+		iwEvent.cmd = IWEVQUAL;
+		iwEvent.len = IW_EV_QUAL_LEN;
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		iwEvent.u.qual.qual = 0;	/* Quality not available now */
+		/* -100 < Rssi < -10, normalized by adding 0x100 */
+		iwEvent.u.qual.level = 0x100 + prBss->rRssi;
+		iwEvent.u.qual.noise = 0;	/* Noise not available now */
+		iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID;
+		memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN);
+		pcCur += IW_EV_QUAL_LEN;
+
+		/* Security Mode */
+		iwEvent.cmd = SIOCGIWENCODE;
+		iwEvent.len = IW_EV_POINT_LEN;
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		iwEvent.u.data.pointer = NULL;
+		iwEvent.u.data.flags = 0;
+		iwEvent.u.data.length = 0;
+		if (!prBss->u4Privacy)
+			iwEvent.u.data.flags |= IW_ENCODE_DISABLED;
+#if WIRELESS_EXT <= 18
+		memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
+#else
+		memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+		memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+#endif
+		pcCur += IW_EV_POINT_LEN;
+
+		/* rearrange rate information */
+		u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):");
+		u4HighestRate = 0;
+		for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) {
+			UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F;
+
+			if (curRate == 0)
+				break;
+
+			if (curRate > u4HighestRate)
+				u4HighestRate = curRate;
+
+			if (curRate == RATE_5_5M)
+				u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5");
+			else
+				u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2);
+#if DBG
+			if (u4BufIndex > sizeof(aucRatesBuf)) {
+				/* printk("rate info too long\n"); */
+				break;
+			}
+#endif
+		}
+		/* Report Highest Rates */
+		iwEvent.cmd = SIOCGIWRATE;
+		iwEvent.len = IW_EV_PARAM_LEN;
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		iwEvent.u.bitrate.value = u4HighestRate * 500000;
+		iwEvent.u.bitrate.fixed = 0;
+		iwEvent.u.bitrate.disabled = 0;
+		iwEvent.u.bitrate.flags = 0;
+		memcpy(pcCur, &iwEvent, iwEvent.len);
+		pcCur += iwEvent.len;
+
+#if WIRELESS_EXT >= 15		/* IWEVCUSTOM is available in WE-15 or above */
+		/* Report Residual Rates */
+		iwEvent.cmd = IWEVCUSTOM;
+		iwEvent.u.data.length = u4BufIndex;
+		iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
+		if ((pcCur + iwEvent.len) > pcEnd)
+			break;
+		iwEvent.u.data.flags = 0;
+#if WIRELESS_EXT <= 18
+		memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
+#else
+		memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+		memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+#endif
+		memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex);
+		pcCur += iwEvent.len;
+#endif /* WIRELESS_EXT >= 15 */
+
+		if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
+					 prBss->u4IELength - sizeof(PARAM_FIXED_IEs),
+					 0xDD, (PUINT_8 *) &prDesiredIE)) {
+			iwEvent.cmd = IWEVGENIE;
+			iwEvent.u.data.flags = 1;
+			iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength;
+			iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
+			if ((pcCur + iwEvent.len) > pcEnd)
+				break;
+#if WIRELESS_EXT <= 18
+			memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
+#else
+			memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+			memcpy(pcCur + IW_EV_LCP_LEN,
+			       &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+#endif
+			memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
+			pcCur += iwEvent.len;
+		}
+#if CFG_SUPPORT_WPS		/* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */
+		if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
+					 prBss->u4IELength - sizeof(PARAM_FIXED_IEs),
+					 0xDD, (PUINT_8 *) &prDesiredIE)) {
+			iwEvent.cmd = IWEVGENIE;
+			iwEvent.u.data.flags = 1;
+			iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength;
+			iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
+			if ((pcCur + iwEvent.len) > pcEnd)
+				break;
+#if WIRELESS_EXT <= 18
+			memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
+#else
+			memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+			memcpy(pcCur + IW_EV_LCP_LEN,
+			       &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+#endif
+			memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
+			pcCur += iwEvent.len;
+		}
+#endif
+
+		/* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */
+		/* pBss->IEs starts from timestamp */
+		if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
+					 prBss->u4IELength - sizeof(PARAM_FIXED_IEs),
+					 0x30, (PUINT_8 *) &prDesiredIE)) {
+
+			iwEvent.cmd = IWEVGENIE;
+			iwEvent.u.data.flags = 1;
+			iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength;
+			iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
+			if ((pcCur + iwEvent.len) > pcEnd)
+				break;
+#if WIRELESS_EXT <= 18
+			memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
+#else
+			memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+			memcpy(pcCur + IW_EV_LCP_LEN,
+			       &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+#endif
+			memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
+			pcCur += iwEvent.len;
+		}
+#if CFG_SUPPORT_WAPI		/* Android+ */
+		if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
+					  prBss->u4IELength - sizeof(PARAM_FIXED_IEs), (PUINT_8 *) &prDesiredIE)) {
+
+#if 0
+			iwEvent.cmd = IWEVGENIE;
+			iwEvent.u.data.flags = 1;
+			iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength;
+			iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
+			if ((pcCur + iwEvent.len) > pcEnd)
+				break;
+#if WIRELESS_EXT <= 18
+			memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
+#else
+			memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+			memcpy(pcCur + IW_EV_LCP_LEN,
+			       &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+#endif
+			memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
+			pcCur += iwEvent.len;
+#else
+			iwEvent.cmd = IWEVCUSTOM;
+			iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */;
+			iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
+			if ((pcCur + iwEvent.len) > pcEnd)
+				break;
+			iwEvent.u.data.flags = 1;
+
+			memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
+			memcpy(pcCur + IW_EV_LCP_LEN,
+			       &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF);
+
+			pcCur += (IW_EV_POINT_LEN);
+
+			pcCur += sprintf(pcCur, "wapi_ie=");
+
+			snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *) prDesiredIE, prDesiredIE->ucLength + 2);
+
+			pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */;
+#endif
+		}
+#endif
+		/* Complete an entry. Update end of valid entry */
+		pcValidEntryEnd = pcCur;
+		/* Extract next bss */
+		prBss = (P_PARAM_BSSID_EX_T) ((char *)prBss + prBss->u4Length);
+	}
+
+	/* Update valid data length for caller function and upper layer
+	 * applications.
+	 */
+	prData->length = (pcValidEntryEnd - pcExtra);
+	/* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */
+
+	/* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */
+
+error:
+	/* free local query buffer */
+	if (prList)
+		kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen);
+
+	return ret;
+}				/* wext_get_scan */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set desired network name ESSID.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prEssid Pointer of iw_point header.
+* \param[in] pcExtra Pointer to buffer srtoring essid string.
+*
+* \retval 0 If netif_carrier_ok.
+* \retval -E2BIG Essid string length is too big.
+* \retval -EINVAL pcExtra is null pointer.
+* \retval -EFAULT Driver fail to set new essid.
+*
+* \note If string length is ok, device will try connecting to the new network.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_essid(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, IN char *pcExtra)
+{
+	PARAM_SSID_T rNewSsid;
+	UINT_32 cipher;
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
+	ENUM_PARAM_AUTH_MODE_T eAuthMode;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prEssid);
+	ASSERT(pcExtra);
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	if (prEssid->length > IW_ESSID_MAX_SIZE)
+		return -E2BIG;
+
+	/* set auth mode */
+	if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
+		eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
+		    AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
+		/* printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n", */
+		/* (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); */
+	} else {
+		/* set auth mode */
+		switch (prGlueInfo->rWpaInfo.u4KeyMgmt) {
+		case IW_AUTH_KEY_MGMT_802_1X:
+			eAuthMode =
+			    (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ?
+			    AUTH_MODE_WPA : AUTH_MODE_WPA2;
+			/* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", */
+			/* (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); */
+			break;
+		case IW_AUTH_KEY_MGMT_PSK:
+			eAuthMode =
+			    (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ?
+			    AUTH_MODE_WPA_PSK : AUTH_MODE_WPA2_PSK;
+			/* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", */
+			/* (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); */
+			break;
+#if CFG_SUPPORT_WAPI		/* Android+ */
+		case IW_AUTH_KEY_MGMT_WAPI_PSK:
+			break;
+		case IW_AUTH_KEY_MGMT_WAPI_CERT:
+			break;
+#endif
+
+/* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */
+/* case IW_AUTH_KEY_MGMT_WPA_NONE: */
+/* eAuthMode = AUTH_MODE_WPA_NONE; */
+/* //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); */
+/* break; */
+/* #endif */
+#if CFG_SUPPORT_802_11W
+		case IW_AUTH_KEY_MGMT_802_1X_SHA256:
+			eAuthMode = AUTH_MODE_WPA2;
+			break;
+		case IW_AUTH_KEY_MGMT_PSK_SHA256:
+			eAuthMode = AUTH_MODE_WPA2_PSK;
+			break;
+#endif
+		default:
+			/* printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n", */
+			/* prGlueInfo->rWpaInfo.u4KeyMgmt); */
+			eAuthMode = AUTH_MODE_AUTO_SWITCH;
+			break;
+		}
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	/* set encryption status */
+	cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise;
+	if (cipher & IW_AUTH_CIPHER_CCMP) {
+		/* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */
+		eEncStatus = ENUM_ENCRYPTION3_ENABLED;
+	} else if (cipher & IW_AUTH_CIPHER_TKIP) {
+		/* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */
+		eEncStatus = ENUM_ENCRYPTION2_ENABLED;
+	} else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
+		/* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */
+		eEncStatus = ENUM_ENCRYPTION1_ENABLED;
+	} else if (cipher & IW_AUTH_CIPHER_NONE) {
+		/* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */
+		if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
+			eEncStatus = ENUM_ENCRYPTION1_ENABLED;
+		else
+			eEncStatus = ENUM_ENCRYPTION_DISABLED;
+	} else {
+		/* printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n"); */
+		eEncStatus = ENUM_ENCRYPTION_DISABLED;
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetEncryptionStatus,
+			   &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+#if WIRELESS_EXT < 21
+	/* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before
+	 ** 2.6.19. Cut the trailing '\0'.
+	 */
+	rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0;
+#else
+	rNewSsid.u4SsidLen = prEssid->length;
+#endif
+	kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen);
+
+	/*
+	   rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0';
+	   printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid);
+	 */
+
+	if (kalIoctl(prGlueInfo,
+		     wlanoidSetSsid,
+		     (PVOID)&rNewSsid,
+		     sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen) != WLAN_STATUS_SUCCESS) {
+		/* printk(KERN_WARNING "Fail to set ssid\n"); */
+		return -EFAULT;
+	}
+
+	return 0;
+}				/* wext_set_essid */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get current network name ESSID.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prEssid Pointer to iw_point structure containing essid information.
+* \param[out] pcExtra Pointer to buffer srtoring essid string.
+*
+* \retval 0 If netif_carrier_ok.
+* \retval -ENOTCONN Otherwise.
+*
+* \note If netif_carrier_ok, network essid is stored in pcExtra.
+*/
+/*----------------------------------------------------------------------------*/
+/* static PARAM_SSID_T ssid; */
+static int
+wext_get_essid(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, OUT char *pcExtra)
+{
+	/* PARAM_SSID_T ssid; */
+
+	P_PARAM_SSID_T prSsid;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prEssid);
+	ASSERT(pcExtra);
+
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* if (!netif_carrier_ok(prNetDev)) { */
+	/* return -ENOTCONN; */
+	/* } */
+
+	prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE);
+
+	if (!prSsid)
+		return -ENOMEM;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQuerySsid, prSsid, sizeof(PARAM_SSID_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) {
+		kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen);
+		prEssid->length = prSsid->u4SsidLen;
+		prEssid->flags = 1;
+	}
+
+	kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T));
+
+	return 0;
+}				/* wext_get_essid */
+
+#if 0
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set tx desired bit rate. Three cases here
+*        iwconfig wlan0 auto -> Set to origianl supported rate set.
+*        iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate.
+*        iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps
+*
+* \param[in] prNetDev       Pointer to the net_device handler.
+* \param[in] prIwReqInfo    Pointer to the Request Info.
+* \param[in] prRate         Pointer to the Rate Parameter.
+* \param[in] pcExtra        Pointer to the extra buffer.
+*
+* \retval 0         Update desired rate.
+* \retval -EINVAL   Wrong parameter
+*/
+/*----------------------------------------------------------------------------*/
+int
+wext_set_rate(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra)
+{
+	PARAM_RATES_EX aucSuppRate = { 0 };
+	PARAM_RATES_EX aucNewRate = { 0 };
+	UINT_32 u4NewRateLen = 0;
+	UINT_32 i;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prRate);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prRate))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/*
+	   printk("value = %d, fixed = %d, disable = %d, flags = %d\n",
+	   prRate->value, prRate->fixed, prRate->disabled, prRate->flags);
+	 */
+
+	rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
+				       wlanoidQuerySupportedRates, &aucSuppRate, sizeof(aucSuppRate), &u4BufLen);
+
+	/* Case: AUTO */
+	if (prRate->value < 0) {
+		if (prRate->fixed == 0) {
+			/* iwconfig wlan0 rate auto */
+
+			/* set full supported rate to device */
+			/* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */
+			rStatus = wlanSetInformation(prGlueInfo->prAdapter,
+						     wlanoidSetDesiredRates,
+						     &aucSuppRate, sizeof(aucSuppRate), &u4BufLen);
+			return 0;
+		}
+		/* iwconfig wlan0 rate fixed */
+
+		/* fix rate to what? DO NOTHING */
+		return -EINVAL;
+	}
+
+	aucNewRate[0] = prRate->value / 500000;	/* In unit of 500k */
+
+	for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) {
+		/* check the given value is supported */
+		if (aucSuppRate[i] == 0)
+			break;
+
+		if (aucNewRate[0] == aucSuppRate[i]) {
+			u4NewRateLen = 1;
+			break;
+		}
+	}
+
+	if (u4NewRateLen == 0) {
+		/* the given value is not supported */
+		/* return error or use given rate as upper bound? */
+		return -EINVAL;
+	}
+
+	if (prRate->fixed == 0) {
+		/* add all rates lower than desired rate */
+		for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) {
+			if (aucSuppRate[i] == 0)
+				break;
+
+			if (aucSuppRate[i] < aucNewRate[0])
+				aucNewRate[u4NewRateLen++] = aucSuppRate[i];
+		}
+	}
+
+	rStatus = wlanSetInformation(prGlueInfo->prAdapter,
+				     wlanoidSetDesiredRates, &aucNewRate, sizeof(aucNewRate), &u4BufLen);
+	return 0;
+}				/* wext_set_rate */
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get current tx bit rate.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prRate Pointer to iw_param structure to store current tx rate.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 If netif_carrier_ok.
+* \retval -ENOTCONN Otherwise.
+*
+* \note If netif_carrier_ok, current tx rate is stored in pRate.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_rate(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRate, IN char *pcExtra)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+	UINT_32 u4Rate = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prRate);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prRate))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	if (!netif_carrier_ok(prNetDev))
+		return -ENOTCONN;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+
+	prRate->value = u4Rate * 100;	/* u4Rate is in unit of 100bps */
+	prRate->fixed = 0;
+
+	return 0;
+}				/* wext_get_rate */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set RTS/CTS theshold.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prRts Pointer to iw_param structure containing rts threshold.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 For success.
+* \retval -EINVAL Given value is out of range.
+*
+* \note If given value is valid, device will follow the new setting.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_rts(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwrInfo, IN struct iw_param *prRts, IN char *pcExtra)
+{
+	PARAM_RTS_THRESHOLD u4RtsThresh;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prRts);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prRts))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	if (prRts->disabled == 1)
+		u4RtsThresh = 2347;
+	else if (prRts->value < 0 || prRts->value > 2347)
+		return -EINVAL;
+
+	u4RtsThresh = (PARAM_RTS_THRESHOLD) prRts->value;
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSetRtsThreshold,
+			   &u4RtsThresh, sizeof(u4RtsThresh), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	prRts->value = (typeof(prRts->value)) u4RtsThresh;
+	prRts->disabled = (prRts->value > 2347) ? 1 : 0;
+	prRts->fixed = 1;
+
+	return 0;
+}				/* wext_set_rts */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get RTS/CTS theshold.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prRts Pointer to iw_param structure containing rts threshold.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 Success.
+*
+* \note RTS threshold is stored in pRts.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_rts(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRts, IN char *pcExtra)
+{
+	PARAM_RTS_THRESHOLD u4RtsThresh = 0;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prRts);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prRts))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryRtsThreshold,
+			   &u4RtsThresh, sizeof(u4RtsThresh), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	prRts->value = (typeof(prRts->value)) u4RtsThresh;
+	prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0;
+	prRts->fixed = 1;
+
+	return 0;
+}				/* wext_get_rts */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get fragmentation threshold.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prFrag Pointer to iw_param structure containing frag threshold.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 Success.
+*
+* \note RTS threshold is stored in pFrag. Fragmentation is disabled.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_frag(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prFrag, IN char *pcExtra)
+{
+	ASSERT(prFrag);
+
+	prFrag->value = 2346;
+	prFrag->fixed = 1;
+	prFrag->disabled = 1;
+	return 0;
+}				/* wext_get_frag */
+
+#if 1
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set TX power, or enable/disable the radio.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prTxPow Pointer to iw_param structure containing tx power setting.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 Success.
+*
+* \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used
+*       to enable/disable the radio.
+*/
+/*----------------------------------------------------------------------------*/
+
+static int
+wext_set_txpow(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwrInfo, IN struct iw_param *prTxPow, IN char *pcExtra)
+{
+	int ret = 0;
+	/* PARAM_DEVICE_POWER_STATE ePowerState; */
+	ENUM_ACPI_STATE_T ePowerState;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prTxPow);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	if (prTxPow->disabled) {
+		/* <1> disconnect */
+		rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+		if (rStatus != WLAN_STATUS_SUCCESS)
+			DBGLOG(REQ, ERROR, "######set disassoc failed\n");
+		else
+			DBGLOG(REQ, TRACE, "######set assoc ok\n");
+		/* <2> mark to power state flag */
+		ePowerState = ACPI_STATE_D0;
+		DBGLOG(REQ, INFO, "set to acpi d3(0)\n");
+		wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState);
+
+	} else {
+		ePowerState = ACPI_STATE_D0;
+		DBGLOG(REQ, INFO, "set to acpi d0\n");
+		wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState);
+	}
+
+	prGlueInfo->ePowerState = ePowerState;
+
+	return ret;
+}				/* wext_set_txpow */
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get TX power.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prTxPow Pointer to iw_param structure containing tx power setting.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 Success.
+*
+* \note Tx power is stored in pTxPow.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_txpow(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prTxPow, IN char *pcExtra)
+{
+	/* PARAM_DEVICE_POWER_STATE ePowerState; */
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prNetDev);
+	ASSERT(prTxPow);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not
+	 * current state. Use GLUE_INFO_T to store state.
+	 */
+	/* ePowerState = prGlueInfo->ePowerState; */
+
+	/* TxPow parameters: Fixed at relative 100% */
+#if WIRELESS_EXT < 17
+	prTxPow->flags = 0x0002;	/* IW_TXPOW_RELATIVE */
+#else
+	prTxPow->flags = IW_TXPOW_RELATIVE;
+#endif
+	prTxPow->value = 100;
+	prTxPow->fixed = 1;
+	/* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE; */
+	prTxPow->disabled = TRUE;
+
+	return 0;
+}				/* wext_get_txpow */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get encryption cipher and key.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prEnc Pointer to iw_point structure containing securiry information.
+* \param[in] pcExtra Buffer to store key content.
+*
+* \retval 0 Success.
+*
+* \note Securiry information is stored in pEnc except key content.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_encode(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwrInfo, OUT struct iw_point *prEnc, IN char *pcExtra)
+{
+#if 1
+	/* ENUM_ENCRYPTION_STATUS_T eEncMode; */
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode = ENUM_WEP_ENABLED;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prEnc);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidQueryEncryptionStatus,
+			   &eEncMode, sizeof(eEncMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+
+	switch (eEncMode) {
+	case ENUM_WEP_DISABLED:
+		prEnc->flags = IW_ENCODE_DISABLED;
+		break;
+	case ENUM_WEP_ENABLED:
+		prEnc->flags = IW_ENCODE_ENABLED;
+		break;
+	case ENUM_WEP_KEY_ABSENT:
+		prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+		break;
+	default:
+		prEnc->flags = IW_ENCODE_ENABLED;
+		break;
+	}
+
+	/* Cipher, Key Content, Key ID can't be queried */
+	prEnc->flags |= IW_ENCODE_NOKEY;
+#endif
+	return 0;
+}				/* wext_get_encode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set encryption cipher and key.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prEnc Pointer to iw_point structure containing securiry information.
+* \param[in] pcExtra Pointer to key string buffer.
+*
+* \retval 0 Success.
+* \retval -EINVAL Key ID error for WEP.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note Securiry information is stored in pEnc.
+*/
+/*----------------------------------------------------------------------------*/
+static UINT_8 wepBuf[48];
+
+static int
+wext_set_encode(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra)
+{
+#if 1
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
+	ENUM_PARAM_AUTH_MODE_T eAuthMode;
+	/* UINT_8 wepBuf[48]; */
+	P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prEnc);
+	ASSERT(pcExtra);
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* reset to default mode */
+	prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
+	prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
+	prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
+	prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
+#if CFG_SUPPORT_802_11W
+	prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
+#endif
+
+	/* iwconfig wlan0 key off */
+	if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) {
+		eAuthMode = AUTH_MODE_OPEN;
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetAuthMode,
+				   &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		eEncStatus = ENUM_ENCRYPTION_DISABLED;
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetEncryptionStatus,
+				   &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		return 0;
+	}
+
+	/* iwconfig wlan0 key 0123456789 */
+	/* iwconfig wlan0 key s:abcde */
+	/* iwconfig wlan0 key 0123456789 [1] */
+	/* iwconfig wlan0 key 01234567890123456789012345 [1] */
+	/* check key size for WEP */
+	if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) {
+		/* prepare PARAM_WEP key structure */
+		prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0;
+		if (prWepKey->u4KeyIndex > 3) {
+			/* key id is out of range */
+			return -EINVAL;
+		}
+		prWepKey->u4KeyIndex |= 0x80000000;
+		prWepKey->u4Length = 12 + prEnc->length;
+		prWepKey->u4KeyLength = prEnc->length;
+		kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length);
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetAddWep,
+				   prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+		if (rStatus != WLAN_STATUS_SUCCESS) {
+			DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus);
+			return -EFAULT;
+		}
+
+		/* change to auto switch */
+		prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM;
+		eAuthMode = AUTH_MODE_AUTO_SWITCH;
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetAuthMode,
+				   &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		if (rStatus != WLAN_STATUS_SUCCESS) {
+			/* printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus); */
+			return -EFAULT;
+		}
+
+		prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
+		prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
+
+		eEncStatus = ENUM_WEP_ENABLED;
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetEncryptionStatus,
+				   &eEncStatus,
+				   sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+		if (rStatus != WLAN_STATUS_SUCCESS) {
+			/* printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus); */
+			return -EFAULT;
+		}
+
+		return 0;
+	}
+#endif
+	return -EOPNOTSUPP;
+}				/* wext_set_encode */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set power management.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prPower Pointer to iw_param structure containing tx power setting.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 Success.
+*
+* \note New Power Management Mode is set to driver.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_power(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwrInfo, IN struct iw_param *prPower, IN char *pcExtra)
+{
+#if 1
+
+	PARAM_POWER_MODE ePowerMode;
+	INT_32 i4PowerValue;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prPower);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prPower))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */
+	/* prPower->value, prPower->disabled, prPower->flags); */
+
+	if (prPower->disabled) {
+		ePowerMode = Param_PowerModeCAM;
+	} else {
+		i4PowerValue = prPower->value;
+#if WIRELESS_EXT < 21
+		i4PowerValue /= 1000000;
+#endif
+		if (i4PowerValue == 0) {
+			ePowerMode = Param_PowerModeCAM;
+		} else if (i4PowerValue == 1) {
+			ePowerMode = Param_PowerModeMAX_PSP;
+		} else if (i4PowerValue == 2) {
+			ePowerMode = Param_PowerModeFast_PSP;
+		} else {
+			DBGLOG(REQ, ERROR, "%s(): unsupported power management mode value = %d.\n",
+					    __func__, prPower->value);
+
+			return -EINVAL;
+		}
+	}
+
+	rStatus = kalIoctl(prGlueInfo,
+			   wlanoidSet802dot11PowerSaveProfile,
+			   &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		/* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */
+		return -EFAULT;
+	}
+#endif
+	return 0;
+}				/* wext_set_power */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To get power management.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[out] prPower Pointer to iw_param structure containing tx power setting.
+* \param[in] pcExtra NULL.
+*
+* \retval 0 Success.
+*
+* \note Power management mode is stored in pTxPow->value.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_get_power(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prPower, IN char *pcExtra)
+{
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+	PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM;
+
+	ASSERT(prNetDev);
+	ASSERT(prPower);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prPower))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+#if 0
+#if defined(_HIF_SDIO)
+	rStatus = sdio_io_ctrl(prGlueInfo,
+			       wlanoidQuery802dot11PowerSaveProfile,
+			       &ePowerMode, sizeof(ePowerMode), TRUE, TRUE, &u4BufLen);
+#else
+	rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
+				       wlanoidQuery802dot11PowerSaveProfile,
+				       &ePowerMode, sizeof(ePowerMode), &u4BufLen);
+#endif
+#else
+	rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
+				       wlanoidQuery802dot11PowerSaveProfile,
+				       &ePowerMode, sizeof(ePowerMode), &u4BufLen);
+#endif
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return -EFAULT;
+
+	prPower->value = 0;
+	prPower->disabled = 1;
+
+	if (Param_PowerModeCAM == ePowerMode) {
+		prPower->value = 0;
+		prPower->disabled = 1;
+	} else if (Param_PowerModeMAX_PSP == ePowerMode) {
+		prPower->value = 1;
+		prPower->disabled = 0;
+	} else if (Param_PowerModeFast_PSP == ePowerMode) {
+		prPower->value = 2;
+		prPower->disabled = 0;
+	}
+
+	prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE;
+#if WIRELESS_EXT < 21
+	prPower->value *= 1000000;
+#endif
+
+	/* printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", */
+	/* prPower->value, prPower->disabled, prPower->flags); */
+
+	return 0;
+}				/* wext_get_power */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set authentication parameters.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] rpAuth Pointer to iw_param structure containing authentication information.
+* \param[in] pcExtra Pointer to key string buffer.
+*
+* \retval 0 Success.
+* \retval -EINVAL Key ID error for WEP.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note Securiry information is stored in pEnc.
+*/
+/*----------------------------------------------------------------------------*/
+static int
+wext_set_auth(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwrInfo, IN struct iw_param *prAuth, IN char *pcExtra)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prNetDev);
+	ASSERT(prAuth);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	/* Save information to glue info and process later when ssid is set. */
+	switch (prAuth->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+#if CFG_SUPPORT_WAPI
+		if (wlanQueryWapiMode(prGlueInfo->prAdapter)) {
+			prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
+			prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
+		} else {
+			prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value;
+		}
+#else
+		prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value;
+#endif
+		break;
+
+	case IW_AUTH_CIPHER_PAIRWISE:
+		prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value;
+		break;
+
+	case IW_AUTH_CIPHER_GROUP:
+		prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value;
+		break;
+
+	case IW_AUTH_KEY_MGMT:
+		prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value;
+#if CFG_SUPPORT_WAPI
+		if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK ||
+		    prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) {
+			UINT_32 u4BufLen;
+			WLAN_STATUS rStatus;
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetWapiMode,
+					   &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value);
+		}
+#endif
+		if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS)
+			prGlueInfo->fgWpsActive = TRUE;
+		else
+			prGlueInfo->fgWpsActive = FALSE;
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value;
+		break;
+
+	case IW_AUTH_PRIVACY_INVOKED:
+		prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value;
+		break;
+#if CFG_SUPPORT_802_11W
+	case IW_AUTH_MFP:
+		/* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */
+		prGlueInfo->rWpaInfo.u4Mfp = prAuth->value;
+		break;
+#endif
+#if CFG_SUPPORT_WAPI
+	case IW_AUTH_WAPI_ENABLED:
+		{
+			UINT_32 u4BufLen;
+			WLAN_STATUS rStatus;
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetWapiMode,
+					   &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+		}
+		DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value);
+		break;
+#endif
+	default:
+		/*
+		   printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags);
+		 */
+		break;
+	}
+	return 0;
+}				/* wext_set_auth */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To set encryption cipher and key.
+*
+* \param[in] prDev Net device requested.
+* \param[in] prIwrInfo NULL.
+* \param[in] prEnc Pointer to iw_point structure containing securiry information.
+* \param[in] pcExtra Pointer to key string buffer.
+*
+* \retval 0 Success.
+* \retval -EINVAL Key ID error for WEP.
+* \retval -EFAULT Setting parameters to driver fail.
+* \retval -EOPNOTSUPP Key size not supported.
+*
+* \note Securiry information is stored in pEnc.
+*/
+/*----------------------------------------------------------------------------*/
+#if CFG_SUPPORT_WAPI
+UINT_8 keyStructBuf[320];	/* add/remove key shared buffer */
+#else
+UINT_8 keyStructBuf[100];	/* add/remove key shared buffer */
+#endif
+
+static int
+wext_set_encode_ext(IN struct net_device *prNetDev,
+		    IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra)
+{
+	P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf;
+	P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf;
+
+	P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
+
+	struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *)pcExtra;
+
+	ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
+	ENUM_PARAM_AUTH_MODE_T eAuthMode;
+	/* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */
+
+#if CFG_SUPPORT_WAPI
+	P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
+#endif
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prEnc);
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	memset(keyStructBuf, 0, sizeof(keyStructBuf));
+
+#if CFG_SUPPORT_WAPI
+	if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
+		if (prEnc->flags & IW_ENCODE_DISABLED) {
+			/* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */
+			return 0;
+		}
+		/* KeyID */
+		prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX);
+		prWpiKey->ucKeyID--;
+		if (prWpiKey->ucKeyID > 1) {
+			/* key id is out of range */
+			/* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */
+			return -EINVAL;
+		}
+
+		if (prIWEncExt->key_len != 32) {
+			/* key length not valid */
+			/* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */
+			return -EINVAL;
+		}
+		/* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */
+
+		if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+			prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
+			prWpiKey->eDirection = ENUM_WPI_RX;
+		} else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+			prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
+			prWpiKey->eDirection = ENUM_WPI_RX_TX;
+		}
+
+		/* PN */
+		{
+			UINT_32 i;
+
+			for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++)
+				prWpiKey->aucPN[i] = prIWEncExt->tx_seq[i];
+			for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++)
+				prWpiKey->aucPN[IW_ENCODE_SEQ_MAX_SIZE + i] = prIWEncExt->rx_seq[i];
+		}
+
+		/* BSSID */
+		memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6);
+
+		memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
+		prWpiKey->u4LenWPIEK = 16;
+
+		memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
+		prWpiKey->u4LenWPICK = 16;
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetWapiKey,
+				   prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+		if (rStatus != WLAN_STATUS_SUCCESS) {
+			/* Do nothing */
+			/* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */
+		}
+	} else
+#endif
+	{
+
+		if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) {
+			prRemoveKey->u4Length = sizeof(*prRemoveKey);
+			memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6);
+			/*
+			   printk("IW_ENCODE_DISABLED: ID:%d, Addr:[ %pM ]\n",
+			   prRemoveKey->KeyIndex, prRemoveKey->BSSID);
+			 */
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetRemoveKey,
+					   prRemoveKey, prRemoveKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS)
+				DBGLOG(REQ, INFO, "remove key error:%x\n", rStatus);
+			return 0;
+		}
+		/* return 0; */
+		/* printk ("alg %x\n", prIWEncExt->alg); */
+
+		switch (prIWEncExt->alg) {
+		case IW_ENCODE_ALG_NONE:
+			break;
+		case IW_ENCODE_ALG_WEP:
+			/* iwconfig wlan0 key 0123456789 */
+			/* iwconfig wlan0 key s:abcde */
+			/* iwconfig wlan0 key 0123456789 [1] */
+			/* iwconfig wlan0 key 01234567890123456789012345 [1] */
+			/* check key size for WEP */
+			if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) {
+				/* prepare PARAM_WEP key structure */
+				prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
+				    (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0;
+				if (prWepKey->u4KeyIndex > 3) {
+					/* key id is out of range */
+					return -EINVAL;
+				}
+				prWepKey->u4KeyIndex |= 0x80000000;
+				prWepKey->u4Length = 12 + prIWEncExt->key_len;
+				prWepKey->u4KeyLength = prIWEncExt->key_len;
+				/* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len); */
+				kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
+
+				rStatus = kalIoctl(prGlueInfo,
+						   wlanoidSetAddWep,
+						   prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+				if (rStatus != WLAN_STATUS_SUCCESS) {
+					DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus);
+					return -EFAULT;
+				}
+
+				/* change to auto switch */
+				prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM;
+				eAuthMode = AUTH_MODE_AUTO_SWITCH;
+
+				rStatus = kalIoctl(prGlueInfo,
+						   wlanoidSetAuthMode,
+						   &eAuthMode,
+						   sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+				if (rStatus != WLAN_STATUS_SUCCESS) {
+					DBGLOG(REQ, ERROR, "wlanoidSetAuthMode fail 0x%x\n", rStatus);
+					return -EFAULT;
+				}
+
+				prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
+				prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
+
+				eEncStatus = ENUM_WEP_ENABLED;
+
+				rStatus = kalIoctl(prGlueInfo,
+						   wlanoidSetEncryptionStatus,
+						   &eEncStatus,
+						   sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T),
+						   FALSE, FALSE, FALSE, FALSE, &u4BufLen);
+
+				if (rStatus != WLAN_STATUS_SUCCESS) {
+					DBGLOG(REQ, ERROR, "wlanoidSetEncryptionStatus fail 0x%x\n", rStatus);
+					return -EFAULT;
+				}
+
+			} else {
+				DBGLOG(REQ, INFO, "key length %x\n", prIWEncExt->key_len);
+				DBGLOG(REQ, INFO, "key error\n");
+			}
+
+			break;
+		case IW_ENCODE_ALG_TKIP:
+		case IW_ENCODE_ALG_CCMP:
+#if CFG_SUPPORT_802_11W
+		case IW_ENCODE_ALG_AES_CMAC:
+#endif
+			{
+
+				/* KeyID */
+				prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
+				    (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0;
+#if CFG_SUPPORT_802_11W
+				if (prKey->u4KeyIndex > 5) {
+#else
+				if (prKey->u4KeyIndex > 3) {
+#endif
+					DBGLOG(REQ, ERROR, "key index error:0x%x\n", prKey->u4KeyIndex);
+					/* key id is out of range */
+					return -EINVAL;
+				}
+
+				/* bit(31) and bit(30) are shared by pKey and pRemoveKey */
+				/* Tx Key Bit(31) */
+				if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+					prKey->u4KeyIndex |= 0x1UL << 31;
+					/* Code style */
+				}
+				/* Pairwise Key Bit(30) */
+				if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+					/* Do nothing */
+					/* group key */
+				} else {
+					/* pairwise key */
+					prKey->u4KeyIndex |= 0x1UL << 30;
+				}
+			}
+			/* Rx SC Bit(29) */
+			if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+				prKey->u4KeyIndex |= 0x1UL << 29;
+				memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE);
+			}
+
+			/* BSSID */
+			memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6);
+
+			/* switch tx/rx MIC key for sta */
+			if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) {
+				memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16);
+				memcpy(((PUINT_8) prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8);
+				memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8);
+			} else {
+				memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
+			}
+
+			prKey->u4KeyLength = prIWEncExt->key_len;
+			prKey->u4Length = ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + prKey->u4KeyLength;
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetAddKey,
+					   prKey, prKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				DBGLOG(REQ, ERROR, "add key error:%x\n", rStatus);
+				return -EFAULT;
+			}
+			break;
+		}
+	}
+
+	return 0;
+}				/* wext_set_encode_ext */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Set country code
+*
+* \param[in] prNetDev Net device requested.
+* \param[in] prData iwreq.u.data carries country code value.
+*
+* \retval 0  For success.
+* \retval -EEFAULT For fail.
+*
+* \note Country code is stored and channel list is updated based on current country domain.
+*/
+/*----------------------------------------------------------------------------*/
+static int wext_set_country(IN struct net_device *prNetDev, IN struct iw_point *prData)
+{
+	P_GLUE_INFO_T prGlueInfo;
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	UINT_8 aucCountry[2];
+
+	ASSERT(prNetDev);
+
+	/* prData->pointer should be like "COUNTRY US", "COUNTRY EU"
+	 * and "COUNTRY JP"
+	 */
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prData) || !prData->pointer || prData->length < 10)
+		return -EINVAL;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	aucCountry[0] = *((PUINT_8)prData->pointer + 8);
+	aucCountry[1] = *((PUINT_8)prData->pointer + 9);
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, &aucCountry[0], 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+	if (rStatus != WLAN_STATUS_SUCCESS) {
+		DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To report the iw private args table to user space.
+*
+* \param[in] prNetDev Net device requested.
+* \param[out] prData iwreq.u.data to carry the private args table.
+*
+* \retval 0  For success.
+* \retval -E2BIG For user's buffer size is too small.
+* \retval -EFAULT For fail.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int wext_get_priv(IN struct net_device *prNetDev, OUT struct iw_point *prData)
+{
+	UINT_16 u2BufferSize = prData->length;
+
+	/* Update our private args table size */
+	prData->length = (__u16)sizeof(rIwPrivTable);
+	if (u2BufferSize < prData->length)
+		return -E2BIG;
+
+	if (prData->length) {
+		if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable)))
+			return -EFAULT;
+	}
+
+	return 0;
+}				/* wext_get_priv */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief ioctl() (Linux Wireless Extensions) routines
+*
+* \param[in] prDev Net device requested.
+* \param[in] ifr The ifreq structure for seeting the wireless extension.
+* \param[in] i4Cmd The wireless extension ioctl command.
+*
+* \retval zero On success.
+* \retval -EOPNOTSUPP If the cmd is not supported.
+* \retval -EFAULT If copy_to_user goes wrong.
+* \retval -EINVAL If any value's out of range.
+*
+* \note
+*/
+/*----------------------------------------------------------------------------*/
+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd)
+{
+	struct iwreq *iwr = (struct iwreq *)prIfReq;
+	struct iw_request_info rIwReqInfo;
+	int ret = 0;
+	char *prExtraBuf = NULL;
+	UINT_32 u4ExtraSize = 0;
+	P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	WLAN_STATUS rStatus;
+	UINT_32 u4BufLen;
+	P_PARAM_PMKID_T prPmkid;
+
+	/* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */
+
+	rIwReqInfo.cmd = (__u16) i4Cmd;
+	rIwReqInfo.flags = 0;
+
+	switch (i4Cmd) {
+	case SIOCGIWNAME:	/* 0x8B01, get wireless protocol name */
+		ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL);
+		break;
+
+		/* case SIOCSIWNWID: 0x8B02, deprecated */
+		/* case SIOCGIWNWID: 0x8B03, deprecated */
+
+	case SIOCSIWFREQ:	/* 0x8B04, set channel */
+		ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL);
+		break;
+
+	case SIOCGIWFREQ:	/* 0x8B05, get channel */
+		ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL);
+		break;
+
+	case SIOCSIWMODE:	/* 0x8B06, set operation mode */
+		ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL);
+		/* ret = 0; */
+		break;
+
+	case SIOCGIWMODE:	/* 0x8B07, get operation mode */
+		ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL);
+		break;
+
+		/* case SIOCSIWSENS: 0x8B08, unsupported */
+		/* case SIOCGIWSENS: 0x8B09, unsupported */
+
+		/* case SIOCSIWRANGE: 0x8B0A, unused */
+	case SIOCGIWRANGE:	/* 0x8B0B, get range of parameters */
+		if (iwr->u.data.pointer != NULL) {
+			/* Buffer size should be large enough */
+			if (iwr->u.data.length < sizeof(struct iw_range)) {
+				ret = -E2BIG;
+				break;
+			}
+
+			prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE);
+			if (!prExtraBuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			/* reset all fields */
+			memset(prExtraBuf, 0, sizeof(struct iw_range));
+			iwr->u.data.length = sizeof(struct iw_range);
+
+			ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf);
+			/* Push up to the caller */
+			if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length))
+				ret = -EFAULT;
+
+			kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range));
+			prExtraBuf = NULL;
+		} else {
+			ret = -EINVAL;
+		}
+		break;
+
+	case SIOCSIWPRIV:	/* 0x8B0C, set country code */
+		ret = wext_set_country(prDev, &iwr->u.data);
+		break;
+
+	case SIOCGIWPRIV:	/* 0x8B0D, get private args table */
+		ret = wext_get_priv(prDev, &iwr->u.data);
+		break;
+
+		/* case SIOCSIWSTATS: 0x8B0E, unused */
+		/* case SIOCGIWSTATS:
+		   get statistics, intercepted by wireless_process_ioctl() in wireless.c,
+		   redirected to dev_iwstats(), dev->get_wireless_stats().
+		 */
+		/* case SIOCSIWSPY: 0x8B10, unsupported */
+		/* case SIOCGIWSPY: 0x8B11, unsupported */
+		/* case SIOCSIWTHRSPY: 0x8B12, unsupported */
+		/* case SIOCGIWTHRSPY: 0x8B13, unsupported */
+
+	case SIOCSIWAP:	/* 0x8B14, set access point MAC addresses (BSSID) */
+		if (iwr->u.ap_addr.sa_data[0] == 0 &&
+		    iwr->u.ap_addr.sa_data[1] == 0 &&
+		    iwr->u.ap_addr.sa_data[2] == 0 &&
+		    iwr->u.ap_addr.sa_data[3] == 0 &&
+		    iwr->u.ap_addr.sa_data[4] == 0 && iwr->u.ap_addr.sa_data[5] == 0) {
+			/* WPA Supplicant will set 000000000000 in
+			 ** wpa_driver_wext_deinit(), do nothing here or disassoc again?
+			 */
+			ret = 0;
+			break;
+		}
+		ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL);
+
+		break;
+
+	case SIOCGIWAP:	/* 0x8B15, get access point MAC addresses (BSSID) */
+		ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL);
+		break;
+
+	case SIOCSIWMLME:	/* 0x8B16, request MLME operation */
+		/* Fixed length structure */
+		if (iwr->u.data.length != sizeof(struct iw_mlme)) {
+			DBGLOG(REQ, ERROR, "MLME buffer strange:%d\n", iwr->u.data.length);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!iwr->u.data.pointer) {
+			ret = -EINVAL;
+			break;
+		}
+
+		prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE);
+		if (!prExtraBuf) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme)))
+			ret = -EFAULT;
+		else
+			ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf);
+
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme));
+		prExtraBuf = NULL;
+		break;
+
+		/* case SIOCGIWAPLIST: 0x8B17, deprecated */
+	case SIOCSIWSCAN:	/* 0x8B18, scan request */
+		if (iwr->u.data.pointer == NULL)
+			ret = wext_set_scan(prDev, NULL, NULL, NULL);
+#if WIRELESS_EXT > 17
+		else if (iwr->u.data.length == sizeof(struct iw_scan_req)) {
+			prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE);
+			if (!prExtraBuf) {
+				ret = -ENOMEM;
+				break;
+			}
+			if (copy_from_user(prExtraBuf, ((struct iw_scan_req *)(iwr->u.data.pointer))->essid,
+					   ((struct iw_scan_req *)(iwr->u.data.pointer))->essid_len)) {
+				ret = -EFAULT;
+			} else {
+				ret = wext_set_scan(prDev, NULL, (union iwreq_data *)&(iwr->u.data), prExtraBuf);
+			}
+
+			kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN);
+			prExtraBuf = NULL;
+		}
+#endif
+		else
+			ret = -EINVAL;
+		break;
+#if 1
+	case SIOCGIWSCAN:	/* 0x8B19, get scan results */
+		if (!iwr->u.data.pointer || !iwr->u.essid.pointer) {
+			ret = -EINVAL;
+			break;
+		}
+
+		u4ExtraSize = iwr->u.data.length;
+		/* allocate the same size of kernel buffer to store scan results. */
+		prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
+		if (!prExtraBuf) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		/* iwr->u.data.length may be updated by wext_get_scan() */
+		ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf);
+		if (ret != 0) {
+			if (ret == -E2BIG)
+				DBGLOG(REQ, WARN, "[wifi] wext_get_scan -E2BIG\n");
+		} else {
+			/* check updated length is valid */
+			ASSERT(iwr->u.data.length <= u4ExtraSize);
+			if (iwr->u.data.length > u4ExtraSize) {
+				DBGLOG(REQ, INFO, "Updated result length is larger than allocated (%d > %u)\n",
+						    iwr->u.data.length, u4ExtraSize);
+				iwr->u.data.length = u4ExtraSize;
+			}
+
+			if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length))
+				ret = -EFAULT;
+		}
+
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
+		prExtraBuf = NULL;
+
+		break;
+
+#endif
+
+#if 1
+	case SIOCSIWESSID:	/* 0x8B1A, set SSID (network name) */
+		if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) {
+			ret = -E2BIG;
+			break;
+		}
+		if (!iwr->u.essid.pointer) {
+			ret = -EINVAL;
+			break;
+		}
+
+		prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE);
+		if (!prExtraBuf) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, iwr->u.essid.length)) {
+			ret = -EFAULT;
+		} else {
+			/* Add trailing '\0' for printk */
+			/* prExtraBuf[iwr->u.essid.length] = 0; */
+			/* printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length); */
+			ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf);
+			/* printk ("set essid %d\n", ret); */
+		}
+
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4);
+		prExtraBuf = NULL;
+		break;
+
+#endif
+
+	case SIOCGIWESSID:	/* 0x8B1B, get SSID */
+		if (!iwr->u.essid.pointer) {
+			ret = -EINVAL;
+			break;
+		}
+
+		if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) {
+			DBGLOG(REQ, ERROR, "[wifi] iwr->u.essid.length:%d too small\n", iwr->u.essid.length);
+			ret = -E2BIG;	/* let caller try larger buffer */
+			break;
+		}
+
+		prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE);
+		if (!prExtraBuf) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		/* iwr->u.essid.length is updated by wext_get_essid() */
+
+		ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf);
+		if (ret == 0) {
+			if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length))
+				ret = -EFAULT;
+		}
+
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE);
+		prExtraBuf = NULL;
+
+		break;
+
+		/* case SIOCSIWNICKN: 0x8B1C, not supported */
+		/* case SIOCGIWNICKN: 0x8B1D, not supported */
+
+	case SIOCSIWRATE:	/* 0x8B20, set default bit rate (bps) */
+		/* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL); */
+		break;
+
+	case SIOCGIWRATE:	/* 0x8B21, get current bit rate (bps) */
+		ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL);
+		break;
+
+	case SIOCSIWRTS:	/* 0x8B22, set rts/cts threshold */
+		ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL);
+		break;
+
+	case SIOCGIWRTS:	/* 0x8B23, get rts/cts threshold */
+		ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL);
+		break;
+
+		/* case SIOCSIWFRAG: 0x8B24, unsupported */
+	case SIOCGIWFRAG:	/* 0x8B25, get frag threshold */
+		ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL);
+		break;
+
+	case SIOCSIWTXPOW:	/* 0x8B26, set relative tx power (in %) */
+		ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL);
+		break;
+
+	case SIOCGIWTXPOW:	/* 0x8B27, get relative tx power (in %) */
+		ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL);
+		break;
+
+		/* case SIOCSIWRETRY: 0x8B28, unsupported */
+		/* case SIOCGIWRETRY: 0x8B29, unsupported */
+
+#if 1
+	case SIOCSIWENCODE:	/* 0x8B2A, set encoding token & mode */
+		/* Only DISABLED case has NULL pointer and length == 0 */
+		if (iwr->u.encoding.pointer) {
+			if (iwr->u.encoding.length > 16) {
+				ret = -E2BIG;
+				break;
+			}
+
+			u4ExtraSize = iwr->u.encoding.length;
+			prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
+			if (!prExtraBuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length))
+				ret = -EFAULT;
+		} else if (iwr->u.encoding.length != 0) {
+			ret = -EINVAL;
+			break;
+		}
+
+		if (ret == 0)
+			ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf);
+
+		if (prExtraBuf) {
+			kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
+			prExtraBuf = NULL;
+		}
+		break;
+
+	case SIOCGIWENCODE:	/* 0x8B2B, get encoding token & mode */
+		/* check pointer */
+		ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL);
+		break;
+
+	case SIOCSIWPOWER:	/* 0x8B2C, set power management */
+		ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL);
+		break;
+
+	case SIOCGIWPOWER:	/* 0x8B2D, get power management */
+		ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL);
+		break;
+
+#if WIRELESS_EXT > 17
+	case SIOCSIWGENIE:	/* 0x8B30, set gen ie */
+		if (iwr->u.data.pointer == NULL)
+			break;
+
+		if (0 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */)
+			break;
+
+		/* Fixed length structure */
+#if CFG_SUPPORT_WAPI
+		if (iwr->u.data.length > 42 /* The max wapi ie buffer */) {
+			ret = -EINVAL;
+			break;
+		}
+#endif
+		u4ExtraSize = iwr->u.data.length;
+		if (u4ExtraSize == 0)
+			break;
+
+		prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
+		if (!prExtraBuf) {
+			ret = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(prExtraBuf, iwr->u.data.pointer, iwr->u.data.length)) {
+			ret = -EFAULT;
+		} else {
+#if CFG_SUPPORT_WAPI
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetWapiAssocInfo,
+					   prExtraBuf,
+					   u4ExtraSize, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+			if (rStatus != WLAN_STATUS_SUCCESS) {
+				/* printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n",
+				rStatus); */
+#endif
+#if CFG_SUPPORT_WPS2
+				PUINT_8 prDesiredIE = NULL;
+
+				if (wextSrchDesiredWPSIE(prExtraBuf,
+							 u4ExtraSize,
+							 0xDD, (PUINT_8 *) &prDesiredIE)) {
+					rStatus = kalIoctl(prGlueInfo,
+							   wlanoidSetWSCAssocInfo,
+							   prDesiredIE,
+							   IE_SIZE(prDesiredIE),
+							   FALSE,
+							   FALSE, TRUE, FALSE, &u4BufLen);
+					if (rStatus != WLAN_STATUS_SUCCESS) {
+						/* printk(KERN_INFO "[WSC] set WSC assoc info
+						error:%lx\n", rStatus); */
+					}
+				}
+#endif
+#if CFG_SUPPORT_WAPI
+			}
+#endif
+		}
+		kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
+		prExtraBuf = NULL;
+		break;
+
+	case SIOCGIWGENIE:	/* 0x8B31, get gen ie, unused */
+		break;
+
+#endif
+
+	case SIOCSIWAUTH:	/* 0x8B32, set auth mode params */
+		ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL);
+		break;
+
+		/* case SIOCGIWAUTH: 0x8B33, unused? */
+	case SIOCSIWENCODEEXT:	/* 0x8B34, set extended encoding token & mode */
+		if (iwr->u.encoding.pointer) {
+			u4ExtraSize = iwr->u.encoding.length;
+			prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
+			if (!prExtraBuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length))
+				ret = -EFAULT;
+		} else if (iwr->u.encoding.length != 0) {
+			ret = -EINVAL;
+			break;
+		}
+
+		if (ret == 0)
+			ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf);
+
+		if (prExtraBuf) {
+			kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
+			prExtraBuf = NULL;
+		}
+		break;
+
+		/* case SIOCGIWENCODEEXT: 0x8B35, unused? */
+
+	case SIOCSIWPMKSA:	/* 0x8B36, pmksa cache operation */
+#if 1
+		if (iwr->u.data.pointer) {
+			/* Fixed length structure */
+			if (iwr->u.data.length != sizeof(struct iw_pmksa)) {
+				ret = -EINVAL;
+				break;
+			}
+
+			u4ExtraSize = sizeof(struct iw_pmksa);
+			prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
+			if (!prExtraBuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_pmksa))) {
+				ret = -EFAULT;
+			} else {
+				switch (((struct iw_pmksa *)prExtraBuf)->cmd) {
+				case IW_PMKSA_ADD:
+					/*
+					   printk(KERN_INFO "IW_PMKSA_ADD [ %pM ]\n",
+					   (((struct iw_pmksa *)pExtraBuf)->bssid.sa_data));
+					 */
+					prPmkid =
+					    (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T),
+									  VIR_MEM_TYPE);
+					if (!prPmkid) {
+						DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n");
+						ret = -ENOMEM;
+						break;
+					}
+
+					prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
+					prPmkid->u4BSSIDInfoCount = 1;
+					kalMemCopy(prPmkid->arBSSIDInfo->arBSSID,
+						   ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data, 6);
+					kalMemCopy(prPmkid->arBSSIDInfo->arPMKID,
+						   ((struct iw_pmksa *)prExtraBuf)->pmkid, IW_PMKID_LEN);
+
+					rStatus = kalIoctl(prGlueInfo,
+							   wlanoidSetPmkid,
+							   prPmkid,
+							   sizeof(PARAM_PMKID_T),
+							   FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+					if (rStatus != WLAN_STATUS_SUCCESS)
+						DBGLOG(REQ, ERROR, "add pmkid error:%x\n", rStatus);
+					kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
+					break;
+				case IW_PMKSA_REMOVE:
+					/*
+					   printk(KERN_INFO "IW_PMKSA_REMOVE [ %pM ]\n",
+					   (((struct iw_pmksa *)buf)->bssid.sa_data));
+					 */
+					break;
+				case IW_PMKSA_FLUSH:
+					/*
+					   printk(KERN_INFO "IW_PMKSA_FLUSH\n");
+					 */
+					prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE);
+					if (!prPmkid) {
+						DBGLOG(REQ, ERROR,
+						       "Can not alloc memory for IW_PMKSA_FLUSH\n");
+						ret = -ENOMEM;
+						break;
+					}
+
+					prPmkid->u4Length = 8;
+					prPmkid->u4BSSIDInfoCount = 0;
+
+					rStatus = kalIoctl(prGlueInfo,
+							   wlanoidSetPmkid,
+							   prPmkid,
+							   sizeof(PARAM_PMKID_T),
+							   FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+					if (rStatus != WLAN_STATUS_SUCCESS)
+						DBGLOG(REQ, ERROR, "flush pmkid error:%x\n", rStatus);
+					kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
+					break;
+				default:
+					DBGLOG(REQ, WARN, "UNKNOWN iw_pmksa command:%d\n",
+							    ((struct iw_pmksa *)prExtraBuf)->cmd);
+					ret = -EFAULT;
+					break;
+				}
+			}
+
+			if (prExtraBuf) {
+				kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
+				prExtraBuf = NULL;
+			}
+		} else if (iwr->u.data.length != 0) {
+			ret = -EINVAL;
+			break;
+		}
+#endif
+		break;
+
+#endif
+
+	default:
+		/* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	/* printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); */
+
+	return ret;
+}				/* wext_support_ioctl */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief To send an event (RAW socket pacekt) to user process actively.
+*
+* \param[in] prGlueInfo Glue layer info.
+* \param[in] u4cmd Whcih event command we want to indicate to user process.
+* \param[in] pData Data buffer to be indicated.
+* \param[in] dataLen Available data size in pData.
+*
+* \return (none)
+*
+* \note Event is indicated to upper layer if cmd is supported and data is valid.
+*       Using of kernel symbol wireless_send_event(), which is defined in
+*      <net/iw_handler.h> after WE-14 (2.4.20).
+*/
+/*----------------------------------------------------------------------------*/
+void
+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo,
+			 IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4dataLen)
+{
+	union iwreq_data wrqu;
+	unsigned char *pucExtraInfo = NULL;
+#if WIRELESS_EXT >= 15
+	unsigned char *pucDesiredIE = NULL;
+	unsigned char aucExtraInfoBuf[200];
+#endif
+#if WIRELESS_EXT < 18
+	int i;
+#endif
+
+	memset(&wrqu, 0, sizeof(wrqu));
+
+	switch (u4Cmd) {
+	case SIOCGIWTXPOW:
+		memcpy(&wrqu.power, pucData, u4dataLen);
+		break;
+	case SIOCGIWSCAN:
+		complete_all(&prGlueInfo->rScanComp);
+		break;
+
+	case SIOCGIWAP:
+		if (pucData)
+			ether_addr_copy((u8 *)&(wrqu.ap_addr.sa_data), pucData);
+			/*memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);*/
+		else
+			memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+		break;
+
+	case IWEVASSOCREQIE:
+#if WIRELESS_EXT < 15
+		/* under WE-15, no suitable Event can be used */
+		goto skip_indicate_event;
+#else
+		/* do supplicant a favor, parse to the start of WPA/RSN IE */
+		if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) {
+			/* RSN IE found */
+			/* Do nothing */
+#if 0
+		} else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) {
+			/* WPS IE found */
+			/* Do nothing */
+#endif
+		} else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) {
+			/* WPA IE found */
+			/* Do nothing*/
+#if CFG_SUPPORT_WAPI		/* Android+ */
+		} else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) {
+			/* WAPI IE found */
+			/* printk("wextSrchDesiredWAPIIE!!\n"); */
+#endif
+		} else {
+			/* no WPA/RSN IE found, skip this event */
+			goto skip_indicate_event;
+		}
+#if WIRELESS_EXT < 18
+		/* under WE-18, only IWEVCUSTOM can be used */
+		u4Cmd = IWEVCUSTOM;
+		pucExtraInfo = aucExtraInfoBuf;
+		pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs=");
+		/* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */
+		/* translate binary string to hex string, requirement of IWEVCUSTOM */
+		for (i = 0; i < pucDesiredIE[1] + 2; ++i)
+			pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]);
+		pucExtraInfo = aucExtraInfoBuf;
+		wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2;
+#else
+		/* IWEVASSOCREQIE, indicate binary string */
+		pucExtraInfo = pucDesiredIE;
+		wrqu.data.length = pucDesiredIE[1] + 2;
+#endif
+#endif /* WIRELESS_EXT < 15 */
+		break;
+
+	case IWEVMICHAELMICFAILURE:
+#if WIRELESS_EXT < 15
+		/* under WE-15, no suitable Event can be used */
+		goto skip_indicate_event;
+#else
+		if (pucData) {
+			P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T) pucData;
+			/* under WE-18, only IWEVCUSTOM can be used */
+			u4Cmd = IWEVCUSTOM;
+			pucExtraInfo = aucExtraInfoBuf;
+			pucExtraInfo += sprintf(pucExtraInfo, "MLME-MICHAELMICFAILURE.indication ");
+			pucExtraInfo += sprintf(pucExtraInfo,
+						"%s",
+						(pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ?
+						"groupcast " : "unicast ");
+
+			wrqu.data.length = pucExtraInfo - aucExtraInfoBuf;
+			pucExtraInfo = aucExtraInfoBuf;
+		}
+#endif /* WIRELESS_EXT < 15 */
+		break;
+
+	case IWEVPMKIDCAND:
+		if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 &&
+		    prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) {
+
+			/* only used in WPA2 */
+#if WIRELESS_EXT >= 18
+			P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T) pucData;
+
+			struct iw_pmkid_cand rPmkidCand;
+
+			pucExtraInfo = aucExtraInfoBuf;
+
+			rPmkidCand.flags = prPmkidCand->u4Flags;
+			rPmkidCand.index = 0;
+			rPmkidCand.bssid.sa_family = 0;
+			kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6);
+
+			kalMemCopy(pucExtraInfo, (PUINT_8) &rPmkidCand, sizeof(struct iw_pmkid_cand));
+			wrqu.data.length = sizeof(struct iw_pmkid_cand);
+
+			/* pmkid canadidate list is supported after WE-18 */
+			/* indicate struct iw_pmkid_cand */
+#else
+			/* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */
+			goto skip_indicate_event;
+#endif
+		} else {
+			/* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */
+			goto skip_indicate_event;
+		}
+		break;
+
+	case IWEVCUSTOM:
+		u4Cmd = IWEVCUSTOM;
+		pucExtraInfo = aucExtraInfoBuf;
+		kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T));
+		wrqu.data.length = sizeof(PTA_IPC_T);
+		break;
+
+	default:
+		/* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */
+		goto skip_indicate_event;
+	}
+
+	/* Send event to user space */
+	wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo);
+
+skip_indicate_event:
+	return;
+}				/* wext_indicate_wext_event */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief A method of struct net_device, to get the network interface statistical
+*        information.
+*
+* Whenever an application needs to get statistics for the interface, this method
+* is called. This happens, for example, when ifconfig or netstat -i is run.
+*
+* \param[in] pDev Pointer to struct net_device.
+*
+* \return net_device_stats buffer pointer.
+*
+*/
+/*----------------------------------------------------------------------------*/
+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev)
+{
+
+	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	struct iw_statistics *pStats = NULL;
+	INT_32 i4Rssi;
+	UINT_32 bufLen = 0;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	ASSERT(prGlueInfo);
+	if (!prGlueInfo)
+		goto stat_out;
+
+	pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats));
+
+	if (!prDev || !netif_carrier_ok(prDev)) {
+		/* network not connected */
+		goto stat_out;
+	}
+
+	rStatus = kalIoctl(prGlueInfo, wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, FALSE, &bufLen);
+
+stat_out:
+	return pStats;
+}				/* wlan_get_wireless_stats */
+
+
+#endif /* WIRELESS_EXT */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c
new file mode 100644
index 0000000000000..2b6c3df845942
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c
@@ -0,0 +1,3142 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext_priv.c#4
+*/
+
+/*! \file gl_wext_priv.c
+    \brief This file includes private ioctl support.
+*/
+
+/*
+** Log: gl_wext_priv.c
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Let netdev bring up.
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 03 20 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * [WCXRP00001202] [MT6628 Wi-Fi][FW] Adding the New PN init code
+ * use return to avoid the ioctl return not supported
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 01 16 2012 wh.su
+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl
+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6)..
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 01 02 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 11 02 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Fixed typo.
+ *
+ * 09 20 2011 chinglan.wang
+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
+ * .
+ *
+ * 07 28 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings
+ * Add BWCS cmd and event.
+ *
+ * 07 18 2011 chinghwa.yu
+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
+ * Add CMD/Event for RDD and BWCS.
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 01 27 2011 cm.chang
+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default
+ * .
+ *
+ * 01 26 2011 wh.su
+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux
+ * adding the SW cmd ioctl support, use set/get structure ioctl.
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Adjust OID order.
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Add Oid for sw control debug command
+ *
+ * 01 07 2011 cm.chang
+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
+ * Add a new compiling option to control if MCR read/write is permitted
+ *
+ * 12 31 2010 cm.chang
+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
+ * Add some iwpriv commands to support test mode operation
+ *
+ * 12 15 2010 george.huang
+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
+ * Support set PS profile and set WMM-PS related iwpriv.
+ *
+ * 11 08 2010 wh.su
+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
+ * add the message check code from mt5921.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 09 24 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * correct typo for NVRAM access.
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add skeleton for NVRAM integration
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * revert changelist #15371, efuse read/write access will be done by RF test approach
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * add OID definitions for EFUSE read/write access.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 01 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * enable OID_CUSTOM_MTK_WIFI_TEST for RFTest & META tool
+ *
+ * 05 29 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * fix private ioctl for rftest
+ *
+ * 04 21 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add for private ioctl support
+**  \main\maintrunk.MT5921\32 2009-10-08 10:33:25 GMT mtk01090
+**  Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input
+**  parameters and pointers.
+**  \main\maintrunk.MT5921\31 2009-09-29 16:46:21 GMT mtk01090
+**  Remove unused functions
+**  \main\maintrunk.MT5921\30 2009-09-29 14:46:47 GMT mtk01090
+**  Fix compile warning
+**  \main\maintrunk.MT5921\29 2009-09-29 14:28:48 GMT mtk01090
+**  Fix compile warning
+**  \main\maintrunk.MT5921\28 2009-09-28 22:21:38 GMT mtk01090
+**  Refine lines to suppress compile warning
+**  \main\maintrunk.MT5921\27 2009-09-28 20:19:14 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\26 2009-08-18 22:56:53 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\25 2009-05-07 22:26:15 GMT mtk01089
+**  Add mandatory and private IO control for Linux BWCS
+**  \main\maintrunk.MT5921\24 2009-04-29 10:07:05 GMT mtk01088
+**  fixed the compiling error at linux
+**  \main\maintrunk.MT5921\23 2009-04-24 09:09:45 GMT mtk01088
+**  mark the code not used at linux supplicant v0.6.7
+**  \main\maintrunk.MT5921\22 2008-11-24 21:03:51 GMT mtk01425
+**  1. Add PTA_ENABLED flag
+**  \main\maintrunk.MT5921\21 2008-08-29 14:55:59 GMT mtk01088
+**  adjust the code for meet the coding style, and add assert check
+**  \main\maintrunk.MT5921\20 2008-07-16 15:23:20 GMT mtk01104
+**  Support GPIO2 mode
+**  \main\maintrunk.MT5921\19 2008-07-15 17:43:11 GMT mtk01084
+**  modify variable name
+**  \main\maintrunk.MT5921\18 2008-07-14 14:37:58 GMT mtk01104
+**  Add exception handle about length in function priv_set_struct()
+**  \main\maintrunk.MT5921\17 2008-07-14 13:55:32 GMT mtk01104
+**  Support PRIV_CMD_BT_COEXIST
+**  \main\maintrunk.MT5921\16 2008-07-09 00:20:15 GMT mtk01461
+**  Add priv oid to support WMM_PS_TEST
+**  \main\maintrunk.MT5921\15 2008-06-02 11:15:22 GMT mtk01461
+**  Update after wlanoidSetPowerMode changed
+**  \main\maintrunk.MT5921\14 2008-05-30 19:31:07 GMT mtk01461
+**  Add IOCTL for Power Mode
+**  \main\maintrunk.MT5921\13 2008-05-30 18:57:15 GMT mtk01461
+**  Not use wlanoidSetCSUMOffloadForLinux()
+**  \main\maintrunk.MT5921\12 2008-05-30 15:13:18 GMT mtk01084
+**  rename wlanoid
+**  \main\maintrunk.MT5921\11 2008-05-29 14:16:31 GMT mtk01084
+**  rename for wlanoidSetBeaconIntervalForLinux
+**  \main\maintrunk.MT5921\10 2008-04-17 23:06:37 GMT mtk01461
+**  Add iwpriv support for AdHocMode setting
+**  \main\maintrunk.MT5921\9 2008-03-31 21:00:55 GMT mtk01461
+**  Add priv IOCTL for VOIP setting
+**  \main\maintrunk.MT5921\8 2008-03-31 13:49:43 GMT mtk01461
+**  Add priv ioctl to turn on / off roaming
+**  \main\maintrunk.MT5921\7 2008-03-26 15:35:14 GMT mtk01461
+**  Add CSUM offload priv ioctl for Linux
+**  \main\maintrunk.MT5921\6 2008-03-11 14:50:59 GMT mtk01461
+**  Unify priv ioctl
+**  \main\maintrunk.MT5921\5 2007-11-06 19:32:30 GMT mtk01088
+**  add WPS code
+**  \main\maintrunk.MT5921\4 2007-10-30 12:01:39 GMT MTK01425
+**  1. Update wlanQueryInformation and wlanSetInformation
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "precomp.h"
+
+#include "gl_os.h"
+#include "gl_wext_priv.h"
+#if CFG_SUPPORT_WAPI
+#include "gl_sec.h"
+#endif
+#if CFG_ENABLE_WIFI_DIRECT
+#include "gl_p2p_os.h"
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define NUM_SUPPORTED_OIDS      (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY))
+#define CMD_START			"START"
+#define CMD_STOP			"STOP"
+#define CMD_SCAN_ACTIVE			"SCAN-ACTIVE"
+#define CMD_SCAN_PASSIVE		"SCAN-PASSIVE"
+#define CMD_RSSI			"RSSI"
+#define CMD_LINKSPEED			"LINKSPEED"
+#define CMD_RXFILTER_START		"RXFILTER-START"
+#define CMD_RXFILTER_STOP		"RXFILTER-STOP"
+#define CMD_RXFILTER_ADD		"RXFILTER-ADD"
+#define CMD_RXFILTER_REMOVE		"RXFILTER-REMOVE"
+#define CMD_BTCOEXSCAN_START		"BTCOEXSCAN-START"
+#define CMD_BTCOEXSCAN_STOP		"BTCOEXSCAN-STOP"
+#define CMD_BTCOEXMODE			"BTCOEXMODE"
+#define CMD_SETSUSPENDOPT		"SETSUSPENDOPT"
+#define CMD_SETSUSPENDMODE		"SETSUSPENDMODE"
+#define CMD_P2P_DEV_ADDR		"P2P_DEV_ADDR"
+#define CMD_SETFWPATH			"SETFWPATH"
+#define CMD_SETBAND			"SETBAND"
+#define CMD_GETBAND			"GETBAND"
+#define CMD_COUNTRY			"COUNTRY"
+#define CMD_P2P_SET_NOA			"P2P_SET_NOA"
+#define CMD_P2P_GET_NOA			"P2P_GET_NOA"
+#define CMD_P2P_SET_PS			"P2P_SET_PS"
+#define CMD_SET_AP_WPS_P2P_IE		"SET_AP_WPS_P2P_IE"
+#define CMD_SETROAMMODE			"SETROAMMODE"
+#define CMD_MIRACAST			"MIRACAST"
+
+#define CMD_PNOSSIDCLR_SET	"PNOSSIDCLR"
+#define CMD_PNOSETUP_SET	"PNOSETUP "
+#define CMD_PNOENABLE_SET	"PNOFORCE"
+#define CMD_PNODEBUG_SET	"PNODEBUG"
+#define CMD_WLS_BATCHING	"WLS_BATCHING"
+
+#define CMD_OKC_SET_PMK		"SET_PMK"
+#define CMD_OKC_ENABLE		"OKC_ENABLE"
+
+/* miracast related definition */
+#define MIRACAST_MODE_OFF	0
+#define MIRACAST_MODE_SOURCE	1
+#define MIRACAST_MODE_SINK	2
+
+#ifndef MIRACAST_AMPDU_SIZE
+#define MIRACAST_AMPDU_SIZE	8
+#endif
+
+#ifndef MIRACAST_MCHAN_ALGO
+#define MIRACAST_MCHAN_ALGO     1
+#endif
+
+#ifndef MIRACAST_MCHAN_BW
+#define MIRACAST_MCHAN_BW       25
+#endif
+
+#define	CMD_BAND_AUTO	0
+#define	CMD_BAND_5G		1
+#define	CMD_BAND_2G		2
+#define	CMD_BAND_ALL	3
+
+/* Mediatek private command */
+
+#define CMD_SET_SW_CTRL	        "SET_SW_CTRL"
+#define CMD_GET_SW_CTRL         "GET_SW_CTRL"
+#define CMD_SET_CFG             "SET_CFG"
+#define CMD_GET_CFG             "GET_CFG"
+#define CMD_SET_CHIP            "SET_CHIP"
+#define CMD_GET_CHIP            "GET_CHIP"
+#define CMD_SET_DBG_LEVEL       "SET_DBG_LEVEL"
+#define CMD_GET_DBG_LEVEL       "GET_DBG_LEVEL"
+#define PRIV_CMD_SIZE			512
+
+static UINT_32 g_ucMiracastMode = MIRACAST_MODE_OFF;
+
+typedef struct cmd_tlv {
+	char prefix;
+	char version;
+	char subver;
+	char reserved;
+} cmd_tlv_t;
+
+typedef struct priv_driver_cmd_s {
+	char buf[PRIV_CMD_SIZE];
+	int used_len;
+	int total_len;
+} priv_driver_cmd_t;
+
+#if CFG_SUPPORT_BATCH_SCAN
+#define CMD_BATCH_SET           "WLS_BATCHING SET"
+#define CMD_BATCH_GET           "WLS_BATCHING GET"
+#define CMD_BATCH_STOP          "WLS_BATCHING STOP"
+#endif
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static int
+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen);
+
+static int
+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen);
+
+#if 0				/* CFG_SUPPORT_WPS */
+static int
+priv_set_appie(IN struct net_device *prNetDev,
+	       IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra);
+
+static int
+priv_set_filter(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra);
+#endif /* CFG_SUPPORT_WPS */
+
+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY * ppWlanReqEntry);
+
+#if 0
+static WLAN_STATUS
+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+static WLAN_STATUS
+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+#endif
+
+static WLAN_STATUS
+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
+
+/*******************************************************************************
+*                       P R I V A T E   D A T A
+********************************************************************************
+*/
+static UINT_8 aucOidBuf[4096] = { 0 };
+
+/* OID processing table */
+/* Order is important here because the OIDs should be in order of
+   increasing value for binary searching. */
+static WLAN_REQ_ENTRY arWlanOidReqTable[] = {
+	/*
+	   {(NDIS_OID)rOid,
+	   (PUINT_8)pucOidName,
+	   fgQryBufLenChecking, fgSetBufLenChecking, fgIsHandleInGlueLayerOnly, u4InfoBufLen,
+	   pfOidQueryHandler,
+	   pfOidSetHandler}
+	 */
+	/* General Operational Characteristics */
+
+	/* Ethernet Operational Characteristics */
+	{OID_802_3_CURRENT_ADDRESS,
+	 DISP_STRING("OID_802_3_CURRENT_ADDRESS"),
+	 TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr,
+	 NULL},
+
+	/* OID_802_3_MULTICAST_LIST */
+	/* OID_802_3_MAXIMUM_LIST_SIZE */
+	/* Ethernet Statistics */
+
+	/* NDIS 802.11 Wireless LAN OIDs */
+	{OID_802_11_SUPPORTED_RATES,
+	 DISP_STRING("OID_802_11_SUPPORTED_RATES"),
+	 TRUE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_RATES_EX),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates,
+	 NULL}
+	,
+	/*
+	   {OID_802_11_CONFIGURATION,
+	   DISP_STRING("OID_802_11_CONFIGURATION"),
+	   TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_802_11_CONFIG_T),
+	   (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration,
+	   (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration},
+	 */
+	{OID_PNP_SET_POWER,
+	 DISP_STRING("OID_PNP_SET_POWER"),
+	 TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_DEVICE_POWER_STATE),
+	 NULL,
+	 (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState}
+	,
+
+	/* Custom OIDs */
+	{OID_CUSTOM_OID_INTERFACE_VERSION,
+	 DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"),
+	 TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion,
+	 NULL}
+	,
+
+	/*
+	   #if PTA_ENABLED
+	   {OID_CUSTOM_BT_COEXIST_CTRL,
+	   DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"),
+	   FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_BT_COEXIST_T),
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl},
+	   #endif
+	 */
+
+	/*
+	   {OID_CUSTOM_POWER_MANAGEMENT_PROFILE,
+	   DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"),
+	   FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam},
+	   {OID_CUSTOM_PATTERN_CONFIG,
+	   DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"),
+	   TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUCT_T),
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig},
+	   {OID_CUSTOM_BG_SSID_SEARCH_CONFIG,
+	   DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"),
+	   FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam},
+	   {OID_CUSTOM_VOIP_SETUP,
+	   DISP_STRING("OID_CUSTOM_VOIP_SETUP"),
+	   TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus},
+	   {OID_CUSTOM_ADD_TS,
+	   DISP_STRING("OID_CUSTOM_ADD_TS"),
+	   TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS},
+	   {OID_CUSTOM_DEL_TS,
+	   DISP_STRING("OID_CUSTOM_DEL_TS"),
+	   TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS},
+	 */
+
+	/*
+	   #if CFG_LP_PATTERN_SEARCH_SLT
+	   {OID_CUSTOM_SLT,
+	   DISP_STRING("OID_CUSTOM_SLT"),
+	   FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode},
+	   #endif
+
+	   {OID_CUSTOM_ROAMING_EN,
+	   DISP_STRING("OID_CUSTOM_ROAMING_EN"),
+	   TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction},
+	   {OID_CUSTOM_WMM_PS_TEST,
+	   DISP_STRING("OID_CUSTOM_WMM_PS_TEST"),
+	   TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest},
+	   {OID_CUSTOM_COUNTRY_STRING,
+	   DISP_STRING("OID_CUSTOM_COUNTRY_STRING"),
+	   FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry},
+
+	   #if CFG_SUPPORT_802_11D
+	   {OID_CUSTOM_MULTI_DOMAIN_CAPABILITY,
+	   DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"),
+	   FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap},
+	   #endif
+
+	   {OID_CUSTOM_GPIO2_MODE,
+	   DISP_STRING("OID_CUSTOM_GPIO2_MODE"),
+	   FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_PARAM_GPIO2_MODE_T),
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode},
+	   {OID_CUSTOM_CONTINUOUS_POLL,
+	   DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"),
+	   FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CONTINUOUS_POLL_T),
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile},
+	   {OID_CUSTOM_DISABLE_BEACON_DETECTION,
+	   DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"),
+	   FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryDisableBeaconDetectionFunc,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc},
+	 */
+
+	/* WPS */
+	/*
+	   {OID_CUSTOM_DISABLE_PRIVACY_CHECK,
+	   DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"),
+	   FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	   NULL,
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck},
+	 */
+
+	{OID_CUSTOM_MCR_RW,
+	 DISP_STRING("OID_CUSTOM_MCR_RW"),
+	 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite}
+	,
+
+	{OID_CUSTOM_EEPROM_RW,
+	 DISP_STRING("OID_CUSTOM_EEPROM_RW"),
+	 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite}
+	,
+
+	{OID_CUSTOM_SW_CTRL,
+	 DISP_STRING("OID_CUSTOM_SW_CTRL"),
+	 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite}
+	,
+
+	{OID_CUSTOM_MEM_DUMP,
+	 DISP_STRING("OID_CUSTOM_MEM_DUMP"),
+	 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MEM_DUMP_STRUCT_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump,
+	 NULL}
+	,
+
+	{OID_CUSTOM_TEST_MODE,
+	 DISP_STRING("OID_CUSTOM_TEST_MODE"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	 NULL,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode}
+	,
+
+	/*
+	   {OID_CUSTOM_TEST_RX_STATUS,
+	   DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"),
+	   FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T),
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus,
+	   NULL},
+	   {OID_CUSTOM_TEST_TX_STATUS,
+	   DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"),
+	   FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T),
+	   (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus,
+	   NULL},
+	 */
+	{OID_CUSTOM_ABORT_TEST_MODE,
+	 DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	 NULL,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode}
+	,
+	{OID_CUSTOM_MTK_WIFI_TEST,
+	 DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"),
+	 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest}
+	,
+
+	/* OID_CUSTOM_EMULATION_VERSION_CONTROL */
+
+	/* BWCS */
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
+	{OID_CUSTOM_BWCS_CMD,
+	 DISP_STRING("OID_CUSTOM_BWCS_CMD"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PTA_IPC_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT}
+	,
+#endif
+
+/*    {OID_CUSTOM_SINGLE_ANTENNA,
+	DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"),
+	FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4,
+	(PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna,
+	(PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna},
+    {OID_CUSTOM_SET_PTA,
+	DISP_STRING("OID_CUSTOM_SET_PTA"),
+	FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4,
+	(PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta,
+	(PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta},
+    */
+
+	{OID_CUSTOM_MTK_NVRAM_RW,
+	 DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"),
+	 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite}
+	,
+
+	{OID_CUSTOM_CFG_SRC_TYPE,
+	 DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_CFG_SRC_TYPE_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType,
+	 NULL}
+	,
+
+	{OID_CUSTOM_EEPROM_TYPE,
+	 DISP_STRING("OID_CUSTOM_EEPROM_TYPE"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_EEPROM_TYPE_T),
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType,
+	 NULL}
+	,
+
+#if CFG_SUPPORT_WAPI
+	{OID_802_11_WAPI_MODE,
+	 DISP_STRING("OID_802_11_WAPI_MODE"),
+	 FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4,
+	 NULL,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode}
+	,
+	{OID_802_11_WAPI_ASSOC_INFO,
+	 DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	 NULL,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo}
+	,
+	{OID_802_11_SET_WAPI_KEY,
+	 DISP_STRING("OID_802_11_SET_WAPI_KEY"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_WPI_KEY_T),
+	 NULL,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey}
+	,
+#endif
+
+#if CFG_SUPPORT_WPS2
+	{OID_802_11_WSC_ASSOC_INFO,
+	 DISP_STRING("OID_802_11_WSC_ASSOC_INFO"),
+	 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
+	 NULL,
+	 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWSCAssocInfo}
+	,
+#endif
+};
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~
+*   SIOCIWLASTPRIV).
+*
+* \param[in] prNetDev Net device requested.
+* \param[in] prIfReq Pointer to ifreq structure.
+* \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV.
+*
+* \retval 0 for success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+* \retval -EFAULT For fail.
+*
+*/
+/*----------------------------------------------------------------------------*/
+int priv_support_ioctl(IN struct net_device *prNetDev, IN OUT struct ifreq *prIfReq, IN int i4Cmd)
+{
+	/* prIfReq is verified in the caller function wlanDoIOCTL() */
+	struct iwreq *prIwReq = (struct iwreq *)prIfReq;
+	struct iw_request_info rIwReqInfo;
+
+	/* prDev is verified in the caller function wlanDoIOCTL() */
+
+	/* Prepare the call */
+	rIwReqInfo.cmd = (__u16) i4Cmd;
+	rIwReqInfo.flags = 0;
+
+	switch (i4Cmd) {
+	case IOCTL_SET_INT:
+		/* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */
+		return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u));
+
+	case IOCTL_GET_INT:
+		/* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */
+		return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u));
+
+	case IOCTL_SET_STRUCT:
+	case IOCTL_SET_STRUCT_FOR_EM:
+		return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u));
+
+	case IOCTL_GET_STRUCT:
+		return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u));
+
+	default:
+		return -EOPNOTSUPP;
+
+	}			/* end of switch */
+
+}				/* priv_support_ioctl */
+
+#if CFG_SUPPORT_BATCH_SCAN
+
+EVENT_BATCH_RESULT_T g_rEventBatchResult[CFG_BATCH_MAX_MSCAN];
+
+UINT_32 batchChannelNum2Freq(UINT_32 u4ChannelNum)
+{
+	UINT_32 u4ChannelInMHz;
+
+	if (u4ChannelNum >= 1 && u4ChannelNum <= 13)
+		u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5;
+	else if (u4ChannelNum == 14)
+		u4ChannelInMHz = 2484;
+	else if (u4ChannelNum == 133)
+		u4ChannelInMHz = 3665;	/* 802.11y */
+	else if (u4ChannelNum == 137)
+		u4ChannelInMHz = 3685;	/* 802.11y */
+	else if (u4ChannelNum >= 34 && u4ChannelNum <= 165)
+		u4ChannelInMHz = 5000 + u4ChannelNum * 5;
+	else if (u4ChannelNum >= 183 && u4ChannelNum <= 196)
+		u4ChannelInMHz = 4000 + u4ChannelNum * 5;
+	else
+		u4ChannelInMHz = 0;
+
+	return u4ChannelInMHz;
+}
+
+#define TMP_TEXT_LEN_S 40
+#define TMP_TEXT_LEN_L 60
+static UCHAR text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], text3[TMP_TEXT_LEN_L];	/* A safe len */
+
+WLAN_STATUS
+batchConvertResult(IN P_EVENT_BATCH_RESULT_T prEventBatchResult,
+		   OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen)
+{
+	CHAR *p = pvBuffer;
+	CHAR ssid[ELEM_MAX_LEN_SSID + 1];
+	INT_32 nsize = 0, nsize1, nsize2, nsize3, scancount;
+	INT_32 i, j, nleft;
+	UINT_32 freq;
+
+	P_EVENT_BATCH_RESULT_ENTRY_T prEntry;
+	P_EVENT_BATCH_RESULT_T pBr;
+
+	nleft = u4MaxBufferLen - 5;	/* -5 for "----\n" */
+
+	pBr = prEventBatchResult;
+	scancount = 0;
+	for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) {
+		scancount += pBr->ucScanCount;
+		pBr++;
+	}
+
+	nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "scancount=%x\nnextcount=%x\n", scancount, scancount);
+	if (nsize1 < nleft) {
+		p += nsize1 = kalSprintf(p, "%s", text1);
+		nleft -= nsize1;
+	} else
+		goto short_buf;
+
+	pBr = prEventBatchResult;
+	for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) {
+		DBGLOG(SCN, TRACE, "convert mscan = %d, apcount=%d, nleft=%d\n", j, pBr->ucScanCount, nleft);
+
+		if (pBr->ucScanCount == 0) {
+			pBr++;
+			continue;
+		}
+
+		nleft -= 5;	/* -5 for "####\n" */
+
+		/* We only support one round scan result now. */
+		nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", pBr->ucScanCount);
+		if (nsize1 < nleft) {
+			p += nsize1 = kalSprintf(p, "%s", text1);
+			nleft -= nsize1;
+		} else
+			goto short_buf;
+
+		for (i = 0; i < pBr->ucScanCount; i++) {
+			prEntry = &pBr->arBatchResult[i];
+
+			nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "bssid=" MACSTR "\n",
+					     prEntry->aucBssid[0],
+					     prEntry->aucBssid[1],
+					     prEntry->aucBssid[2],
+					     prEntry->aucBssid[3],
+					     prEntry->aucBssid[4], prEntry->aucBssid[5]);
+
+			kalMemCopy(ssid,
+				   prEntry->aucSSID,
+				   (prEntry->ucSSIDLen < ELEM_MAX_LEN_SSID ? prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID));
+			ssid[(prEntry->ucSSIDLen <
+			      (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : (ELEM_MAX_LEN_SSID - 1))] = '\0';
+			nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", ssid);
+
+			freq = batchChannelNum2Freq(prEntry->ucFreq);
+			nsize3 =
+			    kalSnprintf(text3, TMP_TEXT_LEN_L,
+					"freq=%u\nlevel=%d\ndist=%u\ndistSd=%u\n====\n", freq,
+					prEntry->cRssi, prEntry->u4Dist, prEntry->u4Distsd);
+
+			nsize = nsize1 + nsize2 + nsize3;
+			if (nsize < nleft) {
+
+				kalStrnCpy(p, text1, TMP_TEXT_LEN_S);
+				p += nsize1;
+
+				kalStrnCpy(p, text2, TMP_TEXT_LEN_L);
+				p += nsize2;
+
+				kalStrnCpy(p, text3, TMP_TEXT_LEN_L);
+				p += nsize3;
+
+				nleft -= nsize;
+			} else {
+				DBGLOG(SCN, TRACE, "Warning: Early break! (%d)\n", i);
+				break;	/* discard following entries, TODO: apcount? */
+			}
+		}
+
+		nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n");
+		p += kalSprintf(p, "%s", text1);
+
+		pBr++;
+	}
+
+	nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n");
+	kalSprintf(p, "%s", text1);
+
+	*pu4RetLen = u4MaxBufferLen - nleft;
+	DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen);
+
+	return WLAN_STATUS_SUCCESS;
+
+short_buf:
+	DBGLOG(SCN, TRACE,
+	       "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft),
+		u4MaxBufferLen, (char *)pvBuffer);
+	return WLAN_STATUS_INVALID_LENGTH;
+}
+#endif
+
+#if CFG_SUPPORT_GET_CH_ENV
+WLAN_STATUS
+scanEnvResult(P_GLUE_INFO_T prGlueInfo, OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	CHAR *p = pvBuffer;
+	INT_32 nsize;
+	INT_32 i, nleft;
+	P_SCAN_INFO_T prScanInfo;
+	P_LINK_T prBSSDescList;
+	P_BSS_DESC_T prBssDesc;
+	CH_ENV_T chEnvInfo[54];	/* 54: from FW define; TODO: sync MAXIMUM_OPERATION_CHANNEL_LIST */
+	UINT_32 i4GetCh = 0;
+	INT_32 i4Argc = 0;
+	PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
+	UINT_8 ucTextLen = 40;
+	UCHAR text[ucTextLen];
+	INT_32 u4Ret;
+
+	prAdapter = prGlueInfo->prAdapter;
+	prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
+	prBSSDescList = &prScanInfo->rBSSDescList;
+
+	kalMemZero(chEnvInfo, sizeof(chEnvInfo));
+
+	DBGLOG(SCN, TRACE, "pvBuffer:%s, pu4RetLen:%d\n", (char *)pvBuffer, *pu4RetLen);
+
+	wlanCfgParseArgument(pvBuffer, &i4Argc, apcArgv);
+	DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
+
+	if (i4Argc >= 2) {
+		u4Ret = kalkStrtou32(apcArgv[1], 0, &i4GetCh);
+		if (u4Ret)
+			DBGLOG(SCN, TRACE, "parse pvBuffer error u4Ret=%d\n", u4Ret);
+		/* i4GetCh = kalStrtoul(apcArgv[1], NULL, 0); */
+	}
+
+	nleft = u4MaxBufferLen - 5;	/* -5 for "----\n" */
+
+	nsize = kalSnprintf(text, ucTextLen, "%s", "scanEnvResult\nResult:1\n");/* Always return 1 for alpha version. */
+
+	if (nsize < nleft) {
+		p += nsize = kalSnprintf(p, ucTextLen, "%s", text);
+		nleft -= nsize;
+	} else
+		goto short_buf;
+
+	/* Search BSS Desc from current SCAN result list. */
+	LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
+		if (prBssDesc->ucChannelNum > 0) {
+			if (prBssDesc->ucChannelNum <= 14) {	/* 1~14 */
+				chEnvInfo[prBssDesc->ucChannelNum - 1].ucChNum = prBssDesc->ucChannelNum;
+				chEnvInfo[prBssDesc->ucChannelNum - 1].ucApNum++;
+			} else if (prBssDesc->ucChannelNum <= 64) {	/* 15~22 */
+				chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucChNum = prBssDesc->ucChannelNum;
+				chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucApNum++;
+			} else if (prBssDesc->ucChannelNum <= 116) {	/* 23~27 */
+				chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucChNum = prBssDesc->ucChannelNum;
+				chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucApNum++;
+			} else if (prBssDesc->ucChannelNum <= 140) {	/* 28~30 */
+				chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucChNum = prBssDesc->ucChannelNum;
+				chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucApNum++;
+			} else if (prBssDesc->ucChannelNum <= 165) {	/* 31~35 */
+				chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucChNum = prBssDesc->ucChannelNum;
+				chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucApNum++;
+			}
+		}
+	}
+
+	for (i = 0; i < 54; i++) {
+		if (chEnvInfo[i].ucChNum != 0) {
+			if (i4GetCh == 0 || (chEnvInfo[i].ucChNum == (UINT_8)i4GetCh)) {
+				DBGLOG(SCN, TRACE, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, chEnvInfo[i].ucApNum);
+				p += nsize =
+				    kalSnprintf(p, ucTextLen, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum,
+						chEnvInfo[i].ucApNum);
+				nleft -= nsize;
+			}
+		}
+	}
+
+	p += nsize = kalSnprintf(p, ucTextLen, "%s", "----\n");
+	nleft -= nsize;
+
+	*pu4RetLen = u4MaxBufferLen - nleft;
+	DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen);
+
+	return WLAN_STATUS_SUCCESS;
+
+short_buf:
+	DBGLOG(SCN, TRACE, "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), u4MaxBufferLen, p);
+	return WLAN_STATUS_INVALID_LENGTH;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Private ioctl set int handler.
+*
+* \param[in] prNetDev Net device requested.
+* \param[in] prIwReqInfo Pointer to iwreq structure.
+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command.
+* \param[in] pcExtra The buffer with input value
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+* \retval -EINVAL If a value is out of range.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+_priv_set_int(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	UINT_32 u4SubCmd;
+	PUINT_32 pu4IntBuf;
+	P_NDIS_TRANSPORT_STRUCT prNdisReq;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4BufLen = 0;
+	int status = 0;
+	P_PTA_IPC_T prPtaIpc;
+
+	ASSERT(prNetDev);
+	ASSERT(prIwReqInfo);
+	ASSERT(prIwReqData);
+	ASSERT(pcExtra);
+
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	u4SubCmd = (UINT_32) prIwReqData->mode;
+	pu4IntBuf = (PUINT_32) pcExtra;
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_TEST_MODE:
+		/* printk("TestMode=%ld\n", pu4IntBuf[1]); */
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) {
+			prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE;
+		} else if (pu4IntBuf[1] == 0) {
+			prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE;
+		} else {
+			status = 0;
+			break;
+		}
+		prNdisReq->inNdisOidlength = 0;
+		prNdisReq->outNdisOidLength = 0;
+
+		/* Execute this OID */
+		status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
+		break;
+
+	case PRIV_CMD_TEST_CMD:
+		/* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		/* Execute this OID */
+		status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
+		break;
+
+#if CFG_SUPPORT_PRIV_MCR_RW
+	case PRIV_CMD_ACCESS_MCR:
+		/* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		if (!prGlueInfo->fgMcrAccessAllowed) {
+			if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY)
+				prGlueInfo->fgMcrAccessAllowed = TRUE;
+			status = 0;
+			break;
+		}
+
+		kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		/* Execute this OID */
+		status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
+		break;
+#endif
+
+	case PRIV_CMD_SW_CTRL:
+		/* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		/* Execute this OID */
+		status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
+		break;
+
+#if 0
+	case PRIV_CMD_BEACON_PERIOD:
+		rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBeaconInterval,
+					    (PVOID)&pu4IntBuf[1],/* pu4IntBuf[0] is used as input SubCmd */
+					     sizeof(UINT_32), &u4BufLen);
+		break;
+#endif
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+	case PRIV_CMD_CSUM_OFFLOAD:
+		{
+			UINT_32 u4CSUMFlags;
+
+			if (pu4IntBuf[1] == 1)
+				u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
+			else if (pu4IntBuf[1] == 0)
+				u4CSUMFlags = 0;
+			else
+				return -EINVAL;
+
+			if (kalIoctl(prGlueInfo,
+				     wlanoidSetCSUMOffload,
+				     (PVOID)&u4CSUMFlags,
+				     sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) {
+				if (pu4IntBuf[1] == 1)
+					prNetDev->features |= NETIF_F_HW_CSUM;
+				else if (pu4IntBuf[1] == 0)
+					prNetDev->features &= ~NETIF_F_HW_CSUM;
+			}
+		}
+		break;
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+	case PRIV_CMD_POWER_MODE:
+		kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile,
+			(PVOID)&pu4IntBuf[1],	/* pu4IntBuf[0] is used as input SubCmd */
+			 sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+		break;
+
+	case PRIV_CMD_WMM_PS:
+		{
+			PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T rWmmPsTest;
+
+			rWmmPsTest.bmfgApsdEnAc = (UINT_8) pu4IntBuf[1];
+			rWmmPsTest.ucIsEnterPsAtOnce = (UINT_8) pu4IntBuf[2];
+			rWmmPsTest.ucIsDisableUcTrigger = (UINT_8) pu4IntBuf[3];
+			rWmmPsTest.reserved = 0;
+
+			kalIoctl(prGlueInfo,
+				 wlanoidSetWiFiWmmPsTest,
+				 (PVOID)&rWmmPsTest,
+				 sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+		}
+		break;
+
+#if 0
+	case PRIV_CMD_ADHOC_MODE:
+		rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetAdHocMode,
+					    (PVOID)&pu4IntBuf[1],	/* pu4IntBuf[0] is used as input SubCmd */
+					     sizeof(UINT_32), &u4BufLen);
+		break;
+#endif
+
+	case PRIV_CUSTOM_BWCS_CMD:
+
+		DBGLOG(REQ, INFO, "pu4IntBuf[1] = %x, size of PTA_IPC_T = %zu.\n",
+				   pu4IntBuf[1], sizeof(PARAM_PTA_IPC_T));
+
+		prPtaIpc = (P_PTA_IPC_T) aucOidBuf;
+		prPtaIpc->u.aucBTPParams[0] = (UINT_8) (pu4IntBuf[1] >> 24);
+		prPtaIpc->u.aucBTPParams[1] = (UINT_8) (pu4IntBuf[1] >> 16);
+		prPtaIpc->u.aucBTPParams[2] = (UINT_8) (pu4IntBuf[1] >> 8);
+		prPtaIpc->u.aucBTPParams[3] = (UINT_8) (pu4IntBuf[1]);
+
+		DBGLOG(REQ, INFO,
+		       "BCM BWCS CMD : BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n",
+			prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2],
+			prPtaIpc->u.aucBTPParams[3]);
+
+#if 0
+		status = wlanSetInformation(prGlueInfo->prAdapter,
+					    wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen);
+#endif
+
+		status = wlanoidSetBT(prGlueInfo->prAdapter,
+				      (PVOID)&aucOidBuf[0], sizeof(PARAM_PTA_IPC_T), &u4BufLen);
+
+		if (WLAN_STATUS_SUCCESS != status)
+			status = -EFAULT;
+
+		break;
+
+	case PRIV_CMD_BAND_CONFIG:
+		{
+			DBGLOG(REQ, INFO, "CMD set_band=%u\n", (UINT_32) pu4IntBuf[1]);
+		}
+		break;
+
+#if CFG_ENABLE_WIFI_DIRECT
+	case PRIV_CMD_P2P_MODE:
+		{
+			/* no use, move to set_p2p_mode_handler() */
+			PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode;
+
+			p2pmode.u4Enable = pu4IntBuf[1];
+			p2pmode.u4Mode = pu4IntBuf[2];
+			set_p2p_mode_handler(prNetDev, p2pmode);
+#if 0
+			PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P;
+			WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
+			BOOLEAN fgIsP2PEnding;
+
+			GLUE_SPIN_LOCK_DECLARATION();
+
+			/* avoid remove & p2p off command simultaneously */
+			GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+			fgIsP2PEnding = g_u4P2PEnding;
+			g_u4P2POnOffing = 1;
+			GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+
+			if (fgIsP2PEnding == 1) {
+				/* skip the command if we are removing */
+				GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+				g_u4P2POnOffing = 0;
+				GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+				break;
+			}
+			rSetP2P.u4Enable = pu4IntBuf[1];
+			rSetP2P.u4Mode = pu4IntBuf[2];
+
+			if (!rSetP2P.u4Enable)
+				p2pNetUnregister(prGlueInfo, TRUE);
+
+			/* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */
+			/*
+			   Scenario:
+			   1. System enters suspend/resume but not yet enter wlanearlysuspend()
+			   or wlanlateresume();
+
+			   2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl()
+			   and get g_halt_sem then do glRegisterEarlySuspend() or
+			   glUnregisterEarlySuspend();
+
+			   But system suspend/resume procedure is not yet finished so we
+			   suspend;
+
+			   3. System switches back to do suspend/resume procedure and execute
+			   kalIoctl(). But driver does not yet release g_halt_sem so system
+			   suspend in wlanearlysuspend() or wlanlateresume();
+
+			   ==> deadlock occurs.
+			 */
+			if ((!rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) {
+				/* fgIsP2PRegistered == TRUE means P2P is enabled */
+				DBGLOG(P2P, INFO, "p2pEalySuspendReg\n");
+				p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable);	/* p2p remove */
+			}
+
+			DBGLOG(P2P, INFO,
+			       "wlanoidSetP2pMode 0x%p %d %d\n", &rSetP2P, rSetP2P.u4Enable, rSetP2P.u4Mode);
+			rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode,
+					      (PVOID)&rSetP2P,	/* pu4IntBuf[0] is used as input SubCmd */
+					       sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T),
+					       FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+			DBGLOG(P2P, INFO, "wlanoidSetP2pMode ok\n");
+
+			/* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */
+			if ((rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) {
+				/* fgIsP2PRegistered == TRUE means P2P on successfully */
+				p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable);	/* p2p on */
+			}
+
+			if (rSetP2P.u4Enable)
+				p2pNetRegister(prGlueInfo, TRUE);
+
+			GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
+			g_u4P2POnOffing = 0;
+			GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
+#endif
+		}
+		break;
+#endif
+
+#if (CFG_SUPPORT_MET_PROFILING == 1)
+	case PRIV_CMD_MET_PROFILING:
+		{
+			/* PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; */
+			/* rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1]; */
+			/* rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2]; */
+			/* DBGLOG(REQ, INFO,("WFD Debug Mode:%d Period:%d\n",
+			rWfdDebugModeInfo.ucWFDDebugMode,rWfdDebugModeInfo.u2SNPeriod)); */
+			prGlueInfo->u8MetProfEnable = (UINT_8) pu4IntBuf[1];
+			prGlueInfo->u16MetUdpPort = (UINT_16) pu4IntBuf[2];
+			DBGLOG(REQ, INFO, "MET_PROF: Enable=%d UDP_PORT=%d\n", prGlueInfo->u8MetProfEnable,
+			       prGlueInfo->u16MetUdpPort);
+
+		}
+		break;
+
+#endif
+	case PRIV_CMD_WFD_DEBUG_CODE:
+		{
+			PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo;
+
+			rWfdDebugModeInfo.ucWFDDebugMode = (UINT_8) pu4IntBuf[1];
+			rWfdDebugModeInfo.u2SNPeriod = (UINT_16) pu4IntBuf[2];
+			DBGLOG(REQ, INFO, "WFD Debug Mode:%d Period:%d\n", rWfdDebugModeInfo.ucWFDDebugMode,
+			       rWfdDebugModeInfo.u2SNPeriod);
+			kalIoctl(prGlueInfo, wlanoidSetWfdDebugMode, (PVOID)&rWfdDebugModeInfo,
+				 sizeof(PARAM_CUSTOM_WFD_DEBUG_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
+
+		}
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Private ioctl get int handler.
+*
+* \param[in] pDev Net device requested.
+* \param[out] pIwReq Pointer to iwreq structure.
+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command.
+* \param[out] pcExtra The buffer with put the return value
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+* \retval -EFAULT For fail.
+*
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 gucBufDbgCode[1000];
+
+static int
+_priv_get_int(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
+{
+	UINT_32 u4SubCmd;
+	PUINT_32 pu4IntBuf;
+	P_GLUE_INFO_T prGlueInfo;
+	UINT_32 u4BufLen = 0;
+	int status = 0;
+	P_NDIS_TRANSPORT_STRUCT prNdisReq;
+
+	ASSERT(prNetDev);
+	ASSERT(prIwReqInfo);
+	ASSERT(prIwReqData);
+	ASSERT(pcExtra);
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	u4SubCmd = (UINT_32) prIwReqData->mode;
+	pu4IntBuf = (PUINT_32) pcExtra;
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_TEST_CMD:
+		/* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
+		if (status == 0) {
+			/* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
+			prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4];
+			/*
+			   if (copy_to_user(prIwReqData->data.pointer,
+			   &prNdisReq->ndisOidContent[4], 4)) {
+			   printk(KERN_NOTICE "priv_get_int() copy_to_user oidBuf fail(3)\n");
+			   return -EFAULT;
+			   }
+			 */
+		}
+		return status;
+
+#if CFG_SUPPORT_PRIV_MCR_RW
+	case PRIV_CMD_ACCESS_MCR:
+		/* printk("addr=0x%08lx\n", pu4IntBuf[1]); */
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		if (!prGlueInfo->fgMcrAccessAllowed) {
+			status = 0;
+			return status;
+		}
+
+		kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
+		if (status == 0) {
+			/* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
+			prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4];
+		}
+		return status;
+#endif
+
+	case PRIV_CMD_DUMP_MEM:
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+#if 1
+		if (!prGlueInfo->fgMcrAccessAllowed) {
+			status = 0;
+			return status;
+		}
+#endif
+		kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
+		if (status == 0)
+			prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[0];
+		return status;
+
+	case PRIV_CMD_SW_CTRL:
+		/* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */
+
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
+		if (status == 0) {
+			/* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
+			prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4];
+		}
+		return status;
+
+#if 0
+	case PRIV_CMD_BEACON_PERIOD:
+		status = wlanQueryInformation(prGlueInfo->prAdapter,
+					      wlanoidQueryBeaconInterval,
+					      (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen);
+		return status;
+
+	case PRIV_CMD_POWER_MODE:
+		status = wlanQueryInformation(prGlueInfo->prAdapter,
+					      wlanoidQuery802dot11PowerSaveProfile,
+					      (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen);
+		return status;
+
+	case PRIV_CMD_ADHOC_MODE:
+		status = wlanQueryInformation(prGlueInfo->prAdapter,
+					      wlanoidQueryAdHocMode, (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen);
+		return status;
+#endif
+
+	case PRIV_CMD_BAND_CONFIG:
+		DBGLOG(REQ, INFO, "CMD get_band=\n");
+		prIwReqData->mode = 0;
+		return status;
+
+	default:
+		break;
+	}
+
+	u4SubCmd = (UINT_32) prIwReqData->data.flags;
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_GET_CH_LIST:
+		{
+			UINT_16 i, j = 0;
+			UINT_8 NumOfChannel = 50;
+			UINT_8 ucMaxChannelNum = 50;
+			INT_32 ch[50];
+			/*RF_CHANNEL_INFO_T aucChannelList[50];*/
+			P_RF_CHANNEL_INFO_T paucChannelList;
+			P_RF_CHANNEL_INFO_T ChannelList_t;
+
+			paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE);
+			if (paucChannelList == NULL) {
+				DBGLOG(REQ, INFO, "alloc ChannelList fail\n");
+				return -EFAULT;
+			}
+			kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50);
+			kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList);
+			if (NumOfChannel > 50) {
+				ASSERT(0);
+				NumOfChannel = 50;
+			}
+
+			ChannelList_t = paucChannelList;
+			if (kalIsAPmode(prGlueInfo)) {
+				for (i = 0; i < NumOfChannel; i++) {
+					if ((ChannelList_t->ucChannelNum <= 13)
+						|| (ChannelList_t->ucChannelNum == 36
+						|| ChannelList_t->ucChannelNum == 40
+						|| ChannelList_t->ucChannelNum == 44
+						|| ChannelList_t->ucChannelNum == 48)) {
+							ch[j] = (INT_32) ChannelList_t->ucChannelNum;
+							ChannelList_t++;
+							j++;
+					}
+				}
+			} else {
+				for (j = 0; j < NumOfChannel; j++) {
+					ch[j] = (INT_32) ChannelList_t->ucChannelNum;
+					ChannelList_t++;
+				}
+			}
+
+			kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50);
+
+			prIwReqData->data.length = j;
+			if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32)))
+				return -EFAULT;
+			else
+				return status;
+		}
+
+	case PRIV_CMD_GET_BUILD_DATE_CODE:
+		{
+			UINT_8 aucBuffer[16];
+
+			if (kalIoctl(prGlueInfo,
+				     wlanoidQueryBuildDateCode,
+				     (PVOID) aucBuffer,
+				     sizeof(UINT_8) * 16, TRUE, TRUE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) {
+				prIwReqData->data.length = sizeof(UINT_8) * 16;
+
+				if (copy_to_user(prIwReqData->data.pointer, aucBuffer, prIwReqData->data.length))
+					return -EFAULT;
+				else
+					return status;
+			} else {
+				return -EFAULT;
+			}
+		}
+
+	case PRIV_CMD_GET_DEBUG_CODE:
+		{
+			wlanQueryDebugCode(prGlueInfo->prAdapter);
+
+			kalMemSet(gucBufDbgCode, '.', sizeof(gucBufDbgCode));
+			if (copy_to_user(prIwReqData->data.pointer, gucBufDbgCode, prIwReqData->data.length))
+				return -EFAULT;
+			else
+				return status;
+		}
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return status;
+}				/* priv_get_int */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Private ioctl set int array handler.
+*
+* \param[in] prNetDev Net device requested.
+* \param[in] prIwReqInfo Pointer to iwreq structure.
+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command.
+* \param[in] pcExtra The buffer with input value
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+* \retval -EINVAL If a value is out of range.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+_priv_set_ints(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	UINT_32 u4SubCmd, u4BufLen;
+	P_GLUE_INFO_T prGlueInfo;
+	int status = 0;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	P_SET_TXPWR_CTRL_T prTxpwr;
+
+	ASSERT(prNetDev);
+	ASSERT(prIwReqInfo);
+	ASSERT(prIwReqData);
+	ASSERT(pcExtra);
+
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	u4SubCmd = (UINT_32) prIwReqData->data.flags;
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_SET_TX_POWER:
+		{
+			INT_32 *setting = prIwReqData->data.pointer;
+			UINT_16 i;
+
+#if 0
+			DBGLOG(REQ, INFO, "Tx power num = %d\n", prIwReqData->data.length);
+
+			DBGLOG(REQ, INFO, "Tx power setting = %d %d %d %d\n",
+				setting[0], setting[1], setting[2], setting[3]);
+#endif
+			prTxpwr = &prGlueInfo->rTxPwr;
+			if (setting[0] == 0 && prIwReqData->data.length == 4 /* argc num */) {
+				/* 0 (All networks), 1 (legacy STA), 2 (Hotspot AP), 3 (P2P), 4 (BT over Wi-Fi) */
+				if (setting[1] == 1 || setting[1] == 0) {
+					if (setting[2] == 0 || setting[2] == 1)
+						prTxpwr->c2GLegacyStaPwrOffset = setting[3];
+					if (setting[2] == 0 || setting[2] == 2)
+						prTxpwr->c5GLegacyStaPwrOffset = setting[3];
+				}
+				if (setting[1] == 2 || setting[1] == 0) {
+					if (setting[2] == 0 || setting[2] == 1)
+						prTxpwr->c2GHotspotPwrOffset = setting[3];
+					if (setting[2] == 0 || setting[2] == 2)
+						prTxpwr->c5GHotspotPwrOffset = setting[3];
+				}
+				if (setting[1] == 3 || setting[1] == 0) {
+					if (setting[2] == 0 || setting[2] == 1)
+						prTxpwr->c2GP2pPwrOffset = setting[3];
+					if (setting[2] == 0 || setting[2] == 2)
+						prTxpwr->c5GP2pPwrOffset = setting[3];
+				}
+				if (setting[1] == 4 || setting[1] == 0) {
+					if (setting[2] == 0 || setting[2] == 1)
+						prTxpwr->c2GBowPwrOffset = setting[3];
+					if (setting[2] == 0 || setting[2] == 2)
+						prTxpwr->c5GBowPwrOffset = setting[3];
+				}
+			} else if (setting[0] == 1 && prIwReqData->data.length == 2) {
+				prTxpwr->ucConcurrencePolicy = setting[1];
+			} else if (setting[0] == 2 && prIwReqData->data.length == 3) {
+				if (setting[1] == 0) {
+					for (i = 0; i < 14; i++)
+						prTxpwr->acTxPwrLimit2G[i] = setting[2];
+				} else if (setting[1] <= 14)
+					prTxpwr->acTxPwrLimit2G[setting[1] - 1] = setting[2];
+			} else if (setting[0] == 3 && prIwReqData->data.length == 3) {
+				if (setting[1] == 0) {
+					for (i = 0; i < 4; i++)
+						prTxpwr->acTxPwrLimit5G[i] = setting[2];
+				} else if (setting[1] <= 4)
+					prTxpwr->acTxPwrLimit5G[setting[1] - 1] = setting[2];
+			} else if (setting[0] == 4 && prIwReqData->data.length == 2) {
+				if (setting[1] == 0)
+					wlanDefTxPowerCfg(prGlueInfo->prAdapter);
+				rStatus = kalIoctl(prGlueInfo,
+						   wlanoidSetTxPower,
+						   prTxpwr,
+						   sizeof(SET_TXPWR_CTRL_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
+			} else
+				return -EFAULT;
+		}
+		return status;
+	default:
+		break;
+	}
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Private ioctl get int array handler.
+*
+* \param[in] pDev Net device requested.
+* \param[out] pIwReq Pointer to iwreq structure.
+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command.
+* \param[out] pcExtra The buffer with put the return value
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+* \retval -EFAULT For fail.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+_priv_get_ints(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
+{
+	UINT_32 u4SubCmd;
+	P_GLUE_INFO_T prGlueInfo;
+	int status = 0;
+	INT_32 ch[50];
+
+	ASSERT(prNetDev);
+	ASSERT(prIwReqInfo);
+	ASSERT(prIwReqData);
+	ASSERT(pcExtra);
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	u4SubCmd = (UINT_32) prIwReqData->data.flags;
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_GET_CH_LIST:
+		{
+			UINT_16 i;
+			UINT_8 NumOfChannel = 50;
+			UINT_8 ucMaxChannelNum = 50;
+			/*RF_CHANNEL_INFO_T aucChannelList[50];*/
+			P_RF_CHANNEL_INFO_T paucChannelList;
+			P_RF_CHANNEL_INFO_T ChannelList_t;
+
+			paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE);
+			if (paucChannelList == NULL) {
+				DBGLOG(REQ, INFO, "alloc fail\n");
+				return -EINVAL;
+			}
+			kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50);
+
+			kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList);
+			if (NumOfChannel > 50)
+				NumOfChannel = 50;
+
+			ChannelList_t = paucChannelList;
+			for (i = 0; i < NumOfChannel; i++) {
+				ch[i] = (INT_32) ChannelList_t->ucChannelNum;
+				ChannelList_t++;
+			}
+
+			kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50);
+			prIwReqData->data.length = NumOfChannel;
+			if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32)))
+				return -EFAULT;
+			else
+				return status;
+		}
+	default:
+		break;
+	}
+
+	return status;
+}				/* priv_get_int */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Private ioctl set structure handler.
+*
+* \param[in] pDev Net device requested.
+* \param[in] prIwReqData Pointer to iwreq_data structure.
+*
+* \retval 0 For success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+* \retval -EINVAL If a value is out of range.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+_priv_set_struct(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	UINT_32 u4SubCmd = 0;
+	int status = 0;
+	/* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */
+	UINT_32 u4CmdLen = 0;
+	P_NDIS_TRANSPORT_STRUCT prNdisReq;
+	PUINT_32 pu4IntBuf = NULL;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_32 u4BufLen = 0;
+
+	ASSERT(prNetDev);
+	/* ASSERT(prIwReqInfo); */
+	ASSERT(prIwReqData);
+	/* ASSERT(pcExtra); */
+
+	kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf));
+
+	if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData))
+		return -EINVAL;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	u4SubCmd = (UINT_32) prIwReqData->data.flags;
+
+#if 0
+	DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n",
+	       prIwReqInfo->cmd, u4SubCmd);
+#endif
+
+	switch (u4SubCmd) {
+#if 0				/* PTA_ENABLED */
+	case PRIV_CMD_BT_COEXIST:
+		u4CmdLen = prIwReqData->data.length * sizeof(UINT_32);
+		ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen);
+		if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen)
+			return -EFAULT;
+
+		if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) {
+			status = -EFAULT;	/* return -EFAULT; */
+			break;
+		}
+
+		rStatus = wlanSetInformation(prGlueInfo->prAdapter,
+					     wlanoidSetBtCoexistCtrl, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen);
+		if (WLAN_STATUS_SUCCESS != rStatus)
+			status = -EFAULT;
+		break;
+#endif
+
+	case PRIV_CUSTOM_BWCS_CMD:
+		u4CmdLen = prIwReqData->data.length * sizeof(UINT_32);
+		ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen);
+		if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen)
+			return -EFAULT;
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG
+		DBGLOG(REQ, INFO,
+		       "ucCmdLen = %d, size of PTA_IPC_T = %d, prIwReqData->data = 0x%x.\n", u4CmdLen,
+			sizeof(PARAM_PTA_IPC_T), prIwReqData->data);
+
+		DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%u)\n",
+				   prIwReqInfo->cmd, u4SubCmd);
+
+		DBGLOG(REQ, INFO, "*pcExtra = 0x%x\n", *pcExtra);
+#endif
+
+		if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) {
+			status = -EFAULT;	/* return -EFAULT; */
+			break;
+		}
+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG
+		DBGLOG(REQ, INFO, "priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n",
+				   aucOidBuf[2], aucOidBuf[3], aucOidBuf[4], aucOidBuf[5]);
+#endif
+
+#if 0
+		status = wlanSetInformation(prGlueInfo->prAdapter,
+					    wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen);
+#endif
+
+#if 1
+		status = wlanoidSetBT(prGlueInfo->prAdapter, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen);
+#endif
+
+		if (WLAN_STATUS_SUCCESS != status)
+			status = -EFAULT;
+
+		break;
+
+#if CFG_SUPPORT_WPS2
+	case PRIV_CMD_WSC_PROBE_REQ:
+		{
+			/* retrieve IE for Probe Request */
+			if (prIwReqData->data.length > 0) {
+				if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer,
+						   prIwReqData->data.length)) {
+					status = -EFAULT;
+					break;
+				}
+				prGlueInfo->u2WSCIELen = prIwReqData->data.length;
+			} else {
+				prGlueInfo->u2WSCIELen = 0;
+			}
+		}
+		break;
+#endif
+	case PRIV_CMD_OID:
+		if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) {
+			status = -EFAULT;
+			break;
+		}
+		if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length))
+			DBGLOG(REQ, INFO, "pcExtra buffer is valid\n");
+		else
+			DBGLOG(REQ, INFO, "pcExtra 0x%p\n", pcExtra);
+		/* Execute this OID */
+		status = priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0], &u4BufLen);
+		/* Copy result to user space */
+		((P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0])->outNdisOidLength = u4BufLen;
+
+		if (copy_to_user(prIwReqData->data.pointer,
+				 &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) {
+			DBGLOG(REQ, INFO, "copy_to_user oidBuf fail\n");
+			status = -EFAULT;
+		}
+
+		break;
+
+	case PRIV_CMD_SW_CTRL:
+		pu4IntBuf = (PUINT_32) prIwReqData->data.pointer;
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		/* kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); */
+		if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer,
+			prIwReqData->data.length)) {
+			status = -EFAULT;
+			break;
+		}
+		prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		/* Execute this OID */
+		status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Private ioctl get struct handler.
+*
+* \param[in] pDev Net device requested.
+* \param[out] pIwReq Pointer to iwreq structure.
+* \param[in] cmd Private sub-command.
+*
+* \retval 0 For success.
+* \retval -EFAULT If copy from user space buffer fail.
+* \retval -EOPNOTSUPP Parameter "cmd" not recognized.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+_priv_get_struct(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
+{
+	UINT_32 u4SubCmd = 0;
+	P_NDIS_TRANSPORT_STRUCT prNdisReq = NULL;
+
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_32 u4BufLen = 0;
+	PUINT_32 pu4IntBuf = NULL;
+	int status = 0;
+
+	kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf));
+
+	ASSERT(prNetDev);
+	ASSERT(prIwReqData);
+	if (!prNetDev || !prIwReqData) {
+		DBGLOG(REQ, INFO, "priv_get_struct(): invalid param(0x%p, 0x%p)\n", prNetDev, prIwReqData);
+		return -EINVAL;
+	}
+
+	u4SubCmd = (UINT_32) prIwReqData->data.flags;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+	ASSERT(prGlueInfo);
+	if (!prGlueInfo) {
+		DBGLOG(REQ, INFO, "priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n",
+				   prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev)));
+		return -EINVAL;
+	}
+#if 0
+	DBGLOG(REQ, INFO, "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n",
+	       prIwReqInfo->cmd, u4SubCmd);
+#endif
+	memset(aucOidBuf, 0, sizeof(aucOidBuf));
+
+	switch (u4SubCmd) {
+	case PRIV_CMD_OID:
+		if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, sizeof(NDIS_TRANSPORT_STRUCT))) {
+			DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n");
+			return -EFAULT;
+		}
+
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+#if 0
+		DBGLOG(REQ, INFO, "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n",
+		       cmd, pIwReq->u.data.length, ndisReq->ndisOidCmd, ndisReq->inNdisOidlength);
+#endif
+		if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) {
+			prNdisReq->outNdisOidLength = u4BufLen;
+			if (copy_to_user(prIwReqData->data.pointer,
+					 &aucOidBuf[0],
+					 u4BufLen + sizeof(NDIS_TRANSPORT_STRUCT) -
+					 sizeof(prNdisReq->ndisOidContent))) {
+				DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(1)\n");
+				return -EFAULT;
+			}
+			return 0;
+		}
+		prNdisReq->outNdisOidLength = u4BufLen;
+		if (copy_to_user(prIwReqData->data.pointer,
+				 &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) {
+			DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n");
+		}
+		return -EFAULT;
+
+	case PRIV_CMD_SW_CTRL:
+		pu4IntBuf = (PUINT_32) prIwReqData->data.pointer;
+		prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
+
+		if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer,
+			prIwReqData->data.length)) {
+			DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n");
+			return -EFAULT;
+		}
+
+		prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
+		prNdisReq->inNdisOidlength = 8;
+		prNdisReq->outNdisOidLength = 8;
+
+		status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
+		if (status == 0) {
+			prNdisReq->outNdisOidLength = u4BufLen;
+			/* printk("len=%d Result=%08lx\n", u4BufLen, *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
+
+			if (copy_to_user(prIwReqData->data.pointer,
+					 &prNdisReq->ndisOidContent[4],
+					 4 /* OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent) */)) {
+				DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n");
+			}
+		}
+		return 0;
+
+	default:
+		DBGLOG(REQ, WARN, "get struct cmd:0x%x\n", u4SubCmd);
+		return -EOPNOTSUPP;
+	}
+}				/* priv_get_struct */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The routine handles a set operation for a single OID.
+*
+* \param[in] pDev Net device requested.
+* \param[in] ndisReq Ndis request OID information copy from user.
+* \param[out] outputLen_p If the call is successful, returns the number of
+*                         bytes written into the query buffer. If the
+*                         call failed due to invalid length of the query
+*                         buffer, returns the amount of storage needed..
+*
+* \retval 0 On success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen)
+{
+	P_WLAN_REQ_ENTRY prWlanReqEntry = NULL;
+	WLAN_STATUS status = WLAN_STATUS_SUCCESS;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_32 u4SetInfoLen = 0;
+
+	ASSERT(prNetDev);
+	ASSERT(prNdisReq);
+	ASSERT(pu4OutputLen);
+
+	if (!prNetDev || !prNdisReq || !pu4OutputLen) {
+		DBGLOG(REQ, INFO, "priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n",
+				   prNetDev, prNdisReq, pu4OutputLen);
+		return -EINVAL;
+	}
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+	ASSERT(prGlueInfo);
+	if (!prGlueInfo) {
+		DBGLOG(REQ, INFO, "priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n",
+				   prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev)));
+		return -EINVAL;
+	}
+#if 0
+	DBGLOG(REQ, INFO, "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd);
+#endif
+
+	if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) {
+		/* WARNLOG(("Set OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */
+		return -EOPNOTSUPP;
+	}
+
+	if (NULL == prWlanReqEntry->pfOidSetHandler) {
+		/* WARNLOG(("Set %s: Null set handler\n", prWlanReqEntry->pucOidName)); */
+		return -EOPNOTSUPP;
+	}
+#if 0
+	DBGLOG(REQ, INFO, "priv_set_ndis(): %s\n", prWlanReqEntry->pucOidName);
+#endif
+
+	if (prWlanReqEntry->fgSetBufLenChecking) {
+		if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) {
+			DBGLOG(REQ, WARN, "Set %s: Invalid length (current=%u, needed=%u)\n",
+					   prWlanReqEntry->pucOidName,
+					   prNdisReq->inNdisOidlength, prWlanReqEntry->u4InfoBufLen);
+
+			*pu4OutputLen = prWlanReqEntry->u4InfoBufLen;
+			return -EINVAL;
+		}
+	}
+
+	if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) {
+		/* GLUE sw info only */
+		status = prWlanReqEntry->pfOidSetHandler(prGlueInfo,
+							 prNdisReq->ndisOidContent,
+							 prNdisReq->inNdisOidlength, &u4SetInfoLen);
+	} else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) {
+		/* multiple sw operations */
+		status = prWlanReqEntry->pfOidSetHandler(prGlueInfo,
+							 prNdisReq->ndisOidContent,
+							 prNdisReq->inNdisOidlength, &u4SetInfoLen);
+	} else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) {
+		/* driver core */
+
+		status = kalIoctl(prGlueInfo,
+				  (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler,
+				  prNdisReq->ndisOidContent,
+				  prNdisReq->inNdisOidlength, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+	} else {
+		DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod);
+		return -EOPNOTSUPP;
+	}
+
+	*pu4OutputLen = u4SetInfoLen;
+
+	switch (status) {
+	case WLAN_STATUS_SUCCESS:
+		break;
+
+	case WLAN_STATUS_INVALID_LENGTH:
+		/* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */
+		/* prWlanReqEntry->pucOidName, */
+		/* prNdisReq->inNdisOidlength, */
+		/* u4SetInfoLen)); */
+		break;
+	}
+
+	if (WLAN_STATUS_SUCCESS != status)
+		return -EFAULT;
+
+	return 0;
+}				/* priv_set_ndis */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The routine handles a query operation for a single OID. Basically we
+*   return information about the current state of the OID in question.
+*
+* \param[in] pDev Net device requested.
+* \param[in] ndisReq Ndis request OID information copy from user.
+* \param[out] outputLen_p If the call is successful, returns the number of
+*                        bytes written into the query buffer. If the
+*                        call failed due to invalid length of the query
+*                        buffer, returns the amount of storage needed..
+*
+* \retval 0 On success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+* \retval -EINVAL invalid input parameters
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen)
+{
+	P_WLAN_REQ_ENTRY prWlanReqEntry = NULL;
+	UINT_32 u4BufLen = 0;
+	WLAN_STATUS status = WLAN_STATUS_SUCCESS;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	ASSERT(prNetDev);
+	ASSERT(prNdisReq);
+	ASSERT(pu4OutputLen);
+
+	if (!prNetDev || !prNdisReq || !pu4OutputLen) {
+		DBGLOG(REQ, INFO, "priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n",
+				   prNetDev, prNdisReq, pu4OutputLen);
+		return -EINVAL;
+	}
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+	ASSERT(prGlueInfo);
+	if (!prGlueInfo) {
+		DBGLOG(REQ, INFO, "priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n",
+				   prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev)));
+		return -EINVAL;
+	}
+#if 0
+	DBGLOG(REQ, INFO, "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd);
+#endif
+
+	if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) {
+		/* WARNLOG(("Query OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */
+		return -EOPNOTSUPP;
+	}
+
+	if (NULL == prWlanReqEntry->pfOidQueryHandler) {
+		/* WARNLOG(("Query %s: Null query handler\n", prWlanReqEntry->pucOidName)); */
+		return -EOPNOTSUPP;
+	}
+#if 0
+	DBGLOG(REQ, INFO, "priv_get_ndis(): %s\n", prWlanReqEntry->pucOidName);
+#endif
+
+	if (prWlanReqEntry->fgQryBufLenChecking) {
+		if (prNdisReq->inNdisOidlength < prWlanReqEntry->u4InfoBufLen) {
+			/* Not enough room in InformationBuffer. Punt */
+			/* WARNLOG(("Query %s: Buffer too short (current=%ld, needed=%ld)\n", */
+			/* prWlanReqEntry->pucOidName, */
+			/* prNdisReq->inNdisOidlength, */
+			/* prWlanReqEntry->u4InfoBufLen)); */
+
+			*pu4OutputLen = prWlanReqEntry->u4InfoBufLen;
+
+			status = WLAN_STATUS_INVALID_LENGTH;
+			return -EINVAL;
+		}
+	}
+
+	if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) {
+		/* GLUE sw info only */
+		status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo,
+							   prNdisReq->ndisOidContent,
+							   prNdisReq->inNdisOidlength, &u4BufLen);
+	} else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) {
+		/* multiple sw operations */
+		status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo,
+							   prNdisReq->ndisOidContent,
+							   prNdisReq->inNdisOidlength, &u4BufLen);
+	} else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) {
+		/* driver core */
+
+		status = kalIoctl(prGlueInfo,
+				  (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidQueryHandler,
+				  prNdisReq->ndisOidContent,
+				  prNdisReq->inNdisOidlength, TRUE, TRUE, TRUE, FALSE, &u4BufLen);
+	} else {
+		DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod);
+		return -EOPNOTSUPP;
+	}
+
+	*pu4OutputLen = u4BufLen;
+
+	switch (status) {
+	case WLAN_STATUS_SUCCESS:
+		break;
+
+	case WLAN_STATUS_INVALID_LENGTH:
+		/* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */
+		/* prWlanReqEntry->pucOidName, */
+		/* prNdisReq->inNdisOidlength, */
+		/* u4BufLen)); */
+		break;
+	}
+
+	if (WLAN_STATUS_SUCCESS != status)
+		return -EOPNOTSUPP;
+
+	return 0;
+}				/* priv_get_ndis */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Parse command value in a string.
+*
+* @param InStr  Pointer to the string buffer.
+* @param OutStr  Pointer to the next command value.
+* @param OutLen  Record the resident buffer length.
+*
+* @retval Command value.
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen)
+{
+	unsigned char Charc, *Buf;
+	unsigned int Num;
+	int Maxloop;
+	int ReadId;
+	int TotalLen;
+
+	/* init */
+	Num = 0;
+	Maxloop = 0;
+	ReadId = 0;
+	Buf = (unsigned char *)InStr;
+	TotalLen = *OutLen;
+	*OutStr = Buf;
+
+	/* sanity check */
+	if (Buf[0] == 0x00)
+		return 0;
+
+	/* check the value is decimal or hex */
+	if ((Buf[ReadId] == 'x') || ((Buf[ReadId] == '0') && (Buf[ReadId + 1] == 'x'))) {
+		/* skip x or 0x */
+		if (Buf[ReadId] == 'x')
+			ReadId++;
+		else
+			ReadId += 2;
+
+		/* translate the hex number */
+		while (Maxloop++ < 10) {
+			Charc = Buf[ReadId];
+			if ((Charc >= 0x30) && (Charc <= 0x39))
+				Charc -= 0x30;
+			else if ((Charc >= 'a') && (Charc <= 'f'))
+				Charc -= 'a';
+			else if ((Charc >= 'A') && (Charc <= 'F'))
+				Charc -= 'A';
+			else
+				break;	/* exit the parsing */
+			Num = Num * 16 + Charc + 10;
+			ReadId++;
+			TotalLen--;
+		}
+	} else {
+		/* translate the decimal number */
+		while (Maxloop++ < 10) {
+			Charc = Buf[ReadId];
+			if ((Charc < 0x30) || (Charc > 0x39))
+				break;	/* exit the parsing */
+			Charc -= 0x30;
+			Num = Num * 10 + Charc;
+			ReadId++;
+			TotalLen--;
+		}
+	}
+
+	if (Buf[ReadId] == 0x00)
+		*OutStr = &Buf[ReadId];
+	else
+		*OutStr = &Buf[ReadId + 1];	/* skip the character: _ */
+
+	*OutLen = TotalLen - 1;	/* skip the character: _ */
+	return Num;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* @brief Parse command MAC address in a string.
+*
+* @param InStr  Pointer to the string buffer.
+* @param OutStr  Pointer to the next command value.
+* @param OutLen  Record the resident buffer length.
+*
+* @retval Command value.
+*/
+/*----------------------------------------------------------------------------*/
+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac)
+{
+	unsigned char Charc, *Buf;
+	unsigned int Num;
+	int Maxloop;
+	int ReadId;
+	int TotalLen;
+
+	/* init */
+	Num = 0;
+	Maxloop = 0;
+	ReadId = 0;
+	Buf = (unsigned char *)InStr;
+	TotalLen = *OutLen;
+	*OutStr = Buf;
+
+	/* sanity check */
+	if (Buf[0] == 0x00)
+		return 0;
+
+	/* parse MAC */
+	while (Maxloop < 6) {
+		Charc = Buf[ReadId];
+		if ((Charc >= 0x30) && (Charc <= 0x39))
+			Charc -= 0x30;
+		else if ((Charc >= 'a') && (Charc <= 'f'))
+			Charc = Charc - 'a' + 10;
+		else if ((Charc >= 'A') && (Charc <= 'F'))
+			Charc = Charc - 'A' + 10;
+		else
+			return -1;	/* error, exit the parsing */
+
+		Num = Charc;
+		ReadId++;
+		TotalLen--;
+
+		Charc = Buf[ReadId];
+		if ((Charc >= 0x30) && (Charc <= 0x39))
+			Charc -= 0x30;
+		else if ((Charc >= 'a') && (Charc <= 'f'))
+			Charc = Charc - 'a' + 10;
+		else if ((Charc >= 'A') && (Charc <= 'F'))
+			Charc = Charc - 'A' + 10;
+		else
+			return -1;	/* error, exit the parsing */
+
+		Num = Num * 16 + Charc;
+		ReadId += 2;	/* skip the character and ':' */
+		TotalLen -= 2;
+
+		OutMac[Maxloop] = Num;
+		Maxloop++;
+	}
+
+	*OutStr = &Buf[ReadId];	/* skip the character: _ */
+	*OutLen = TotalLen;	/* skip the character: _ */
+	return Num;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief The routine handles a set operation for a single OID.
+*
+* \param[in] pDev Net device requested.
+* \param[in] ndisReq Ndis request OID information copy from user.
+* \param[out] outputLen_p If the call is successful, returns the number of
+*                         bytes written into the query buffer. If the
+*                         call failed due to invalid length of the query
+*                         buffer, returns the amount of storage needed..
+*
+* \retval 0 On success.
+* \retval -EOPNOTSUPP If cmd is not supported.
+*
+*/
+/*----------------------------------------------------------------------------*/
+static int
+_priv_set_string(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	P_GLUE_INFO_T GlueInfo;
+	INT_32 Status;
+	UINT_32 Subcmd;
+	UINT_8 *InBuf;
+	UINT_32 InBufLen;
+
+	/* sanity check */
+	ASSERT(prNetDev);
+	ASSERT(prIwReqInfo);
+	ASSERT(prIwReqData);
+	ASSERT(pcExtra);
+
+	/* init */
+	DBGLOG(REQ, INFO, "priv_set_string (%s)(%d)\n",
+			   (UINT8 *) prIwReqData->data.pointer, (INT32) prIwReqData->data.length);
+
+	if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra))
+		return -EINVAL;
+	GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	InBuf = aucOidBuf;
+	InBufLen = prIwReqData->data.length;
+	Status = 0;
+
+	if (copy_from_user(InBuf, prIwReqData->data.pointer, prIwReqData->data.length))
+		return -EFAULT;
+
+	Subcmd = CmdStringDecParse(prIwReqData->data.pointer, &InBuf, &InBufLen);
+	DBGLOG(REQ, INFO, "priv_set_string> command = %u\n", (UINT32) Subcmd);
+
+	/* handle the command */
+	switch (Subcmd) {
+#if (CFG_SUPPORT_TDLS == 1)
+	case PRIV_CMD_OTHER_TDLS:
+		TdlsexCmd(GlueInfo, InBuf, InBufLen);
+		break;
+#endif /* CFG_SUPPORT_TDLS */
+
+#if (CFG_SUPPORT_TXR_ENC == 1)
+	case PRIV_CMD_OTHER_TAR:
+	{
+		rlmCmd(GlueInfo, InBuf, InBufLen);
+		break;
+	}
+#endif /* CFG_SUPPORT_TXR_ENC */
+	default:
+		break;
+	}
+
+	return Status;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to search desired OID.
+*
+* \param rOid[in]               Desired NDIS_OID
+* \param ppWlanReqEntry[out]    Found registered OID entry
+*
+* \retval TRUE: Matched OID is found
+* \retval FALSE: No matched OID is found
+*/
+/*----------------------------------------------------------------------------*/
+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY *ppWlanReqEntry)
+{
+	INT_32 i, j, k;
+
+	i = 0;
+	j = NUM_SUPPORTED_OIDS - 1;
+
+	while (i <= j) {
+		k = (i + j) / 2;
+
+		if (rOid == arWlanOidReqTable[k].rOid) {
+			*ppWlanReqEntry = &arWlanOidReqTable[k];
+			return TRUE;
+		} else if (rOid < arWlanOidReqTable[k].rOid) {
+			j = k - 1;
+		} else {
+			i = k + 1;
+		}
+	}
+
+	return FALSE;
+}				/* reqSearchSupportedOidEntry */
+
+#if 0
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to query the radio configuration used in IBSS
+*        mode and RF test mode.
+*
+* \param[in] prGlueInfo         Pointer to the GLUE_INFO_T structure.
+* \param[out] pvQueryBuffer     Pointer to the buffer that holds the result of the query.
+* \param[in] u4QueryBufferLen   The length of the query buffer.
+* \param[out] pu4QueryInfoLen   If the call is successful, returns the number of
+*                               bytes written into the query buffer. If the call
+*                               failed due to invalid length of the query buffer,
+*                               returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+*/
+/*----------------------------------------------------------------------------*/
+static WLAN_STATUS
+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo,
+			 OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+	P_PARAM_802_11_CONFIG_T prQueryConfig = (P_PARAM_802_11_CONFIG_T) pvQueryBuffer;
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	UINT_32 u4QueryInfoLen = 0;
+
+	DEBUGFUNC("wlanoidQueryConfiguration");
+
+	ASSERT(prGlueInfo);
+	ASSERT(pu4QueryInfoLen);
+
+	*pu4QueryInfoLen = sizeof(PARAM_802_11_CONFIG_T);
+	if (u4QueryBufferLen < sizeof(PARAM_802_11_CONFIG_T))
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	ASSERT(pvQueryBuffer);
+
+	kalMemZero(prQueryConfig, sizeof(PARAM_802_11_CONFIG_T));
+
+	/* Update the current radio configuration. */
+	prQueryConfig->u4Length = sizeof(PARAM_802_11_CONFIG_T);
+
+#if defined(_HIF_SDIO)
+	rStatus = sdio_io_ctrl(prGlueInfo,
+			       wlanoidSetBeaconInterval,
+			       &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen);
+#else
+	rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
+				       wlanoidQueryBeaconInterval,
+				       &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), &u4QueryInfoLen);
+#endif
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return rStatus;
+#if defined(_HIF_SDIO)
+	rStatus = sdio_io_ctrl(prGlueInfo,
+			       wlanoidQueryAtimWindow,
+			       &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen);
+#else
+	rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
+				       wlanoidQueryAtimWindow,
+				       &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), &u4QueryInfoLen);
+#endif
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return rStatus;
+#if defined(_HIF_SDIO)
+	rStatus = sdio_io_ctrl(prGlueInfo,
+			       wlanoidQueryFrequency,
+			       &prQueryConfig->u4DSConfig, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen);
+#else
+	rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
+				       wlanoidQueryFrequency,
+				       &prQueryConfig->u4DSConfig, sizeof(UINT_32), &u4QueryInfoLen);
+#endif
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return rStatus;
+
+	prQueryConfig->rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
+
+	return rStatus;
+
+}				/* end of reqExtQueryConfiguration() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set the radio configuration used in IBSS
+*        mode.
+*
+* \param[in] prGlueInfo     Pointer to the GLUE_INFO_T structure.
+* \param[in] pvSetBuffer    A pointer to the buffer that holds the data to be set.
+* \param[in] u4SetBufferLen The length of the set buffer.
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*                           bytes read from the set buffer. If the call failed
+*                           due to invalid length of the set buffer, returns
+*                           the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_LENGTH
+* \retval WLAN_STATUS_NOT_ACCEPTED
+*/
+/*----------------------------------------------------------------------------*/
+static WLAN_STATUS
+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo,
+		       IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	P_PARAM_802_11_CONFIG_T prNewConfig = (P_PARAM_802_11_CONFIG_T) pvSetBuffer;
+	UINT_32 u4SetInfoLen = 0;
+
+	DEBUGFUNC("wlanoidSetConfiguration");
+
+	ASSERT(prGlueInfo);
+	ASSERT(pu4SetInfoLen);
+
+	*pu4SetInfoLen = sizeof(PARAM_802_11_CONFIG_T);
+
+	if (u4SetBufferLen < *pu4SetInfoLen)
+		return WLAN_STATUS_INVALID_LENGTH;
+
+	/* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be returned. */
+	if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)
+		return WLAN_STATUS_NOT_ACCEPTED;
+
+	ASSERT(pvSetBuffer);
+
+#if defined(_HIF_SDIO)
+	rStatus = sdio_io_ctrl(prGlueInfo,
+			       wlanoidSetBeaconInterval,
+			       &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen);
+#else
+	rStatus = wlanSetInformation(prGlueInfo->prAdapter,
+				     wlanoidSetBeaconInterval,
+				     &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), &u4SetInfoLen);
+#endif
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return rStatus;
+#if defined(_HIF_SDIO)
+	rStatus = sdio_io_ctrl(prGlueInfo,
+			       wlanoidSetAtimWindow,
+			       &prNewConfig->u4ATIMWindow, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen);
+#else
+	rStatus = wlanSetInformation(prGlueInfo->prAdapter,
+				     wlanoidSetAtimWindow, &prNewConfig->u4ATIMWindow, sizeof(UINT_32), &u4SetInfoLen);
+#endif
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return rStatus;
+#if defined(_HIF_SDIO)
+	rStatus = sdio_io_ctrl(prGlueInfo,
+			       wlanoidSetFrequency,
+			       &prNewConfig->u4DSConfig, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen);
+#else
+	rStatus = wlanSetInformation(prGlueInfo->prAdapter,
+				     wlanoidSetFrequency, &prNewConfig->u4DSConfig, sizeof(UINT_32), &u4SetInfoLen);
+#endif
+
+	if (rStatus != WLAN_STATUS_SUCCESS)
+		return rStatus;
+
+	return rStatus;
+
+}				/* end of reqExtSetConfiguration() */
+
+#endif
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to set beacon detection function enable/disable state
+*        This is mainly designed for usage under BT inquiry state (disable function).
+*
+* \param[in] pvAdapter Pointer to the Adapter structure
+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
+* \param[in] u4SetBufferLen The length of the set buffer
+* \param[out] pu4SetInfoLen If the call is successful, returns the number of
+*   bytes read from the set buffer. If the call failed due to invalid length of
+*   the set buffer, returns the amount of storage needed.
+*
+* \retval WLAN_STATUS_SUCCESS
+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
+* \retval WLAN_STATUS_INVALID_LENGTH
+*
+*/
+/*----------------------------------------------------------------------------*/
+static WLAN_STATUS
+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo,
+			      IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+
+	ASSERT(prGlueInfo);
+	ASSERT(pvSetBuffer);
+	ASSERT(pu4SetInfoLen);
+
+	/* WIFI is enabled, when ACPI is D0 (ParamDeviceStateD0 = 1). And vice versa */
+
+	/* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */
+	/* wlanoidSetAcpiDevicePowerState, */
+	/* pvSetBuffer, */
+	/* u4SetBufferLen, */
+	/* pu4SetInfoLen); */
+	return rStatus;
+}
+
+int priv_driver_set_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_ADAPTER_T prAdapter = NULL;
+	UINT_32 u4BufLen = 0;
+	INT_32 i4BytesWritten = 0;
+	UINT_32 u4CmdLen = 0;
+	UINT_32 u4PrefixLen = 0;
+	/* INT_32 i4Argc = 0; */
+	/* PCHAR  apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */
+
+	PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T rChipConfigInfo;
+
+	ASSERT(prNetDev);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand))
+		return -1;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+	prAdapter = prGlueInfo->prAdapter;
+	DBGLOG(REQ, INFO, "priv_driver_set_chip_config command is %s\n", pcCommand);
+	/* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */
+	/* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */
+	/*  */
+	u4CmdLen = kalStrnLen(pcCommand, i4TotalLen);
+	u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */;
+
+	kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo));
+
+	/* if(i4Argc >= 2) { */
+	if (u4CmdLen > u4PrefixLen) {
+
+		rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE;
+		/* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */
+		rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen;
+		/* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */
+		if (u4PrefixLen <= CHIP_CONFIG_RESP_SIZE) {
+			kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen,
+				   CHIP_CONFIG_RESP_SIZE - u4PrefixLen);
+
+			rStatus = kalIoctl(prGlueInfo,
+					   wlanoidSetChipConfig,
+					   &rChipConfigInfo,
+					   sizeof(rChipConfigInfo), FALSE, FALSE, TRUE, TRUE, &u4BufLen);
+		} else {
+
+			DBGLOG(REQ, INFO, "%s: kalIoctl Command Len > %d\n", __func__, CHIP_CONFIG_RESP_SIZE);
+			rStatus = WLAN_STATUS_FAILURE;
+		}
+
+		if (rStatus != WLAN_STATUS_SUCCESS) {
+			DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, rStatus);
+			i4BytesWritten = -1;
+		}
+	}
+
+	return i4BytesWritten;
+
+}
+
+int priv_driver_set_miracast(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+	P_ADAPTER_T prAdapter = NULL;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	UINT_32 i4BytesWritten = 0;
+	/* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */
+	/* UINT_32 u4BufLen = 0; */
+	INT_32 i4Argc = 0;
+	UINT_32 ucMode = 0;
+	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
+	P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL;
+	PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
+	INT_32 u4Ret;
+
+	ASSERT(prNetDev);
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand))
+		return -1;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	DBGLOG(REQ, LOUD, "command is %s\n", pcCommand);
+	wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
+	DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
+
+	prAdapter = prGlueInfo->prAdapter;
+	if (i4Argc >= 2) {
+		u4Ret = kalkStrtou32(apcArgv[1], 0, &ucMode); /* ucMode = kalStrtoul(apcArgv[1], NULL, 0); */
+		if (u4Ret)
+			DBGLOG(REQ, LOUD, "parse pcCommand error u4Ret=%d\n", u4Ret);
+
+		if (g_ucMiracastMode == ucMode)
+			;
+			/* XXX: continue or skip */
+
+		g_ucMiracastMode = ucMode;
+		prMsgWfdCfgUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T));
+
+		if (prMsgWfdCfgUpdate != NULL) {
+
+			prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings);
+			prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE;
+			prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings;
+
+			if (ucMode == MIRACAST_MODE_OFF) {
+				prWfdCfgSettings->ucWfdEnable = 0;
+				snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0");
+			} else if (ucMode == MIRACAST_MODE_SOURCE) {
+				prWfdCfgSettings->ucWfdEnable = 1;
+				snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 1");
+			} else if (ucMode == MIRACAST_MODE_SINK) {
+				prWfdCfgSettings->ucWfdEnable = 2;
+				snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 2");
+			} else {
+				prWfdCfgSettings->ucWfdEnable = 0;
+				snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0");
+			}
+			mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF);
+
+			priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen);
+
+		} /* prMsgWfdCfgUpdate */
+		else {
+			ASSERT(FALSE);
+			i4BytesWritten = -1;
+		}
+	}
+
+	/* i4Argc */
+	return i4BytesWritten;
+}
+
+int priv_support_driver_cmd(IN struct net_device *prNetDev, IN OUT struct ifreq *prReq, IN int i4Cmd)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	int ret = 0;
+	char *pcCommand = NULL;
+	priv_driver_cmd_t *priv_cmd = NULL;
+	int i4BytesWritten = 0;
+	int i4TotalLen = 0;
+
+	if (!prReq->ifr_data) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	if (!prGlueInfo) {
+		DBGLOG(REQ, WARN, "No glue info\n");
+		ret = -EFAULT;
+		goto exit;
+	}
+	if (prGlueInfo->u4ReadyFlag == 0) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	priv_cmd = kzalloc(sizeof(priv_driver_cmd_t), GFP_KERNEL);
+	if (!priv_cmd) {
+		DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	if (copy_from_user(priv_cmd, prReq->ifr_data, sizeof(priv_driver_cmd_t))) {
+		DBGLOG(REQ, INFO, "%s: copy_from_user fail\n", __func__);
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	i4TotalLen = priv_cmd->total_len;
+
+	if (i4TotalLen <= 0) {
+		ret = -EINVAL;
+		DBGLOG(REQ, INFO, "%s: i4TotalLen invalid\n", __func__);
+		goto exit;
+	}
+
+	pcCommand = priv_cmd->buf;
+
+	DBGLOG(REQ, INFO, "%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, prReq->ifr_name);
+
+	i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen);
+
+	if (i4BytesWritten < 0) {
+		DBGLOG(REQ, INFO, "%s: command %s failed; Written is %d\n",
+			__func__, pcCommand, i4BytesWritten);
+		ret = -EFAULT;
+	}
+
+exit:
+	kfree(priv_cmd);
+
+	return ret;
+}
+
+#if CFG_SUPPORT_BATCH_SCAN
+#define CMD_BATCH_SET           "WLS_BATCHING SET"
+#define CMD_BATCH_GET           "WLS_BATCHING GET"
+#define CMD_BATCH_STOP          "WLS_BATCHING STOP"
+#endif
+
+#if CFG_SUPPORT_GET_CH_ENV
+#define CMD_CH_ENV_GET			"CH_ENV_GET"
+#endif
+
+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4BytesWritten = 0;
+	INT_32 i4CmdFound = 0;
+
+	if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand))
+		return -1;
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	if (i4CmdFound == 0) {
+		i4CmdFound = 1;
+
+		if (strnicmp(pcCommand, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0)
+			i4BytesWritten = priv_driver_set_miracast(prNetDev, pcCommand, i4TotalLen);
+#if CFG_SUPPORT_BATCH_SCAN
+		else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) {
+			kalIoctl(prGlueInfo,
+				 wlanoidSetBatchScanReq,
+				 (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten);
+		} else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) {
+			/* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */
+			/* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */
+			/* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */
+
+			UINT_32 u4BufLen;
+			int i;
+			/* int rlen=0; */
+
+			for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) {
+				g_rEventBatchResult[i].ucScanCount = i + 1;	/* for get which mscan */
+				kalIoctl(prGlueInfo,
+					 wlanoidQueryBatchScanResult,
+					 (PVOID)&g_rEventBatchResult[i],
+					 sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
+			}
+
+#if 0
+			DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount);
+			for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) {
+				prEntry = &g_rEventBatchResult.arBatchResult[i];
+				DBGLOG(SCN, INFO, "Entry %u\n", i);
+				DBGLOG(SCN, INFO, "	 BSSID = %pM\n", prEntry->aucBssid);
+				DBGLOG(SCN, INFO, "	 SSID = %s\n", prEntry->aucSSID);
+				DBGLOG(SCN, INFO, "	 SSID len = %u\n", prEntry->ucSSIDLen);
+				DBGLOG(SCN, INFO, "	 RSSI = %d\n", prEntry->cRssi);
+				DBGLOG(SCN, INFO, "	 Freq = %u\n", prEntry->ucFreq);
+			}
+#endif
+
+			batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten);
+
+			/* Dump for debug */
+			/* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand,
+			i4BytesWritten, TRUE); */
+
+		} else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) {
+			kalIoctl(prGlueInfo,
+				 wlanoidSetBatchScanReq,
+				 (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten);
+		}
+#endif
+#if CFG_SUPPORT_GET_CH_ENV
+		else if (strnicmp(pcCommand, CMD_CH_ENV_GET, strlen(CMD_CH_ENV_GET)) == 0)
+			scanEnvResult(prGlueInfo, pcCommand, i4TotalLen, &i4BytesWritten);
+#endif
+
+#if 0
+
+		else if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
+			/* i4BytesWritten = wl_android_get_rssi(net, command, i4TotalLen); */
+		} else if (strnicmp(pcCommand, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) {
+			i4BytesWritten = priv_driver_get_linkspeed(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) {
+			/* Do nothing */
+		} else if (strnicmp(pcCommand, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) {
+			/* Do nothing */
+		} else if (strnicmp(pcCommand, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) {
+			/* Do nothing */
+		} else if (strnicmp(pcCommand, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) {
+			/* i4BytesWritten = wl_android_set_suspendopt(net, pcCommand, i4TotalLen); */
+		} else if (strnicmp(pcCommand, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) {
+			i4BytesWritten = priv_driver_set_suspend_mode(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
+			i4BytesWritten = priv_driver_set_band(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
+			/* i4BytesWritten = wl_android_get_band(net, pcCommand, i4TotalLen); */
+		} else if (strnicmp(pcCommand, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
+			i4BytesWritten = priv_driver_set_country(prNetDev, pcCommand, i4TotalLen);
+		}
+		/* Mediatek private command  */
+		else if (strnicmp(pcCommand, CMD_SET_SW_CTRL, strlen(CMD_SET_SW_CTRL)) == 0) {
+			i4BytesWritten = priv_driver_set_sw_ctrl(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_GET_SW_CTRL, strlen(CMD_GET_SW_CTRL)) == 0) {
+			i4BytesWritten = priv_driver_get_sw_ctrl(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_SET_CFG, strlen(CMD_SET_CFG)) == 0) {
+			i4BytesWritten = priv_driver_set_cfg(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_GET_CFG, strlen(CMD_GET_CFG)) == 0) {
+			i4BytesWritten = priv_driver_get_cfg(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_SET_CHIP, strlen(CMD_SET_CHIP)) == 0) {
+			i4BytesWritten = priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_GET_CHIP, strlen(CMD_GET_CHIP)) == 0) {
+			i4BytesWritten = priv_driver_get_chip_config(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_SET_DBG_LEVEL, strlen(CMD_SET_DBG_LEVEL)) == 0) {
+			i4BytesWritten = priv_driver_set_dbg_level(prNetDev, pcCommand, i4TotalLen);
+		} else if (strnicmp(pcCommand, CMD_GET_DBG_LEVEL, strlen(CMD_GET_DBG_LEVEL)) == 0) {
+			i4BytesWritten = priv_driver_get_dbg_level(prNetDev, pcCommand, i4TotalLen);
+		}
+#if CFG_SUPPORT_BATCH_SCAN
+		else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) {
+			kalIoctl(prGlueInfo,
+				 wlanoidSetBatchScanReq,
+				 (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten);
+		} else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) {
+			/* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */
+			/* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */
+			/* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */
+
+			UINT_32 u4BufLen;
+			int i;
+			/* int rlen=0; */
+
+			for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) {
+				g_rEventBatchResult[i].ucScanCount = i + 1;	/* for get which mscan */
+				kalIoctl(prGlueInfo,
+					 wlanoidQueryBatchScanResult,
+					 (PVOID)&g_rEventBatchResult[i],
+					 sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, &u4BufLen);
+			}
+
+#if 0
+			DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount);
+			for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) {
+				prEntry = &g_rEventBatchResult.arBatchResult[i];
+				DBGLOG(SCN, INFO, "Entry %u\n", i);
+				DBGLOG(SCN, INFO, "	 BSSID = %pM\n", prEntry->aucBssid);
+				DBGLOG(SCN, INFO, "	 SSID = %s\n", prEntry->aucSSID);
+				DBGLOG(SCN, INFO, "	 SSID len = %u\n", prEntry->ucSSIDLen);
+				DBGLOG(SCN, INFO, "	 RSSI = %d\n", prEntry->cRssi);
+				DBGLOG(SCN, INFO, "	 Freq = %u\n", prEntry->ucFreq);
+			}
+#endif
+
+			batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten);
+
+			/* Dump for debug */
+			/* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, i4BytesWritten,
+			TRUE); */
+
+		} else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) {
+			kalIoctl(prGlueInfo,
+				 wlanoidSetBatchScanReq,
+				 (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten);
+		}
+#endif
+
+#endif
+
+		else
+			i4CmdFound = 0;
+	}
+
+	/* i4CmdFound */
+	if (i4CmdFound == 0)
+		DBGLOG(REQ, TRACE, "Unknown driver command %s - ignored\n", pcCommand);
+
+	if (i4BytesWritten >= 0) {
+		if ((i4BytesWritten == 0) && (i4TotalLen > 0)) {
+			/* reset the command buffer */
+			pcCommand[0] = '\0';
+		}
+
+		if (i4BytesWritten >= i4TotalLen) {
+			DBGLOG(REQ, INFO,
+			       "%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__, i4BytesWritten, i4TotalLen);
+			i4BytesWritten = i4TotalLen;
+		} else {
+			pcCommand[i4BytesWritten] = '\0';
+			i4BytesWritten++;
+		}
+	}
+
+	return i4BytesWritten;
+
+}
+
+static int compat_priv(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra,
+	     int (*priv_func)(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra))
+{
+	struct iw_point *prIwp;
+	int ret = 0;
+#ifdef CONFIG_COMPAT
+	struct compat_iw_point *iwp_compat = NULL;
+	struct iw_point iwp;
+#endif
+
+	if (!prIwReqData)
+		return -EINVAL;
+
+#ifdef CONFIG_COMPAT
+	if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) {
+		iwp_compat = (struct compat_iw_point *) &prIwReqData->data;
+		iwp.pointer = compat_ptr(iwp_compat->pointer);
+		iwp.length = iwp_compat->length;
+		iwp.flags = iwp_compat->flags;
+		prIwp = &iwp;
+	} else
+#endif
+	prIwp = &prIwReqData->data;
+
+
+	ret = priv_func(prNetDev, prIwReqInfo, (union iwreq_data *)prIwp, pcExtra);
+
+#ifdef CONFIG_COMPAT
+	if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) {
+		iwp_compat->pointer = ptr_to_compat(iwp.pointer);
+		iwp_compat->length = iwp.length;
+		iwp_compat->flags = iwp.flags;
+	}
+#endif
+	return ret;
+}
+
+int
+priv_set_int(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_int);
+}
+
+int
+priv_get_int(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
+{
+	return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_int);
+}
+
+int
+priv_set_ints(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_ints);
+}
+
+int
+priv_get_ints(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
+{
+	return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_ints);
+}
+
+int
+priv_set_struct(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_struct);
+}
+
+int
+priv_get_struct(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
+{
+	return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_struct);
+}
+
+int
+priv_set_string(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)
+{
+	return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_string);
+}
+
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c
new file mode 100644
index 0000000000000..c13d24906bf88
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c
@@ -0,0 +1,1643 @@
+/******************************************************************************
+*[File]             ahb.c
+*[Version]          v1.0
+*[Revision Date]    2013-01-16
+*[Author]
+*[Description]
+*    The program provides AHB HIF driver
+*[Copyright]
+*    Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved.
+******************************************************************************/
+
+/*
+** Log: ahb.c
+ *
+ * 01 16 2013 vend_samp.lin
+ * Port sdio.c to ahb.c on MT6572/MT6582
+ * 1) Initial version
+ *
+ * 04 12 2012 terry.wu
+ * NULL
+ * Add AEE message support
+ * 1) Show AEE warning(red screen) if SDIO access error occurs
+ *
+ * 02 14 2012 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * include correct header file upon setting.
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 09 20 2011 cp.wu
+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized
+ * 1. always show error message for SDIO bus errors.
+ * 2. reset bus error flag when re-initialization
+ *
+ * 08 17 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * add MT6628 related definitions for Linux/Android driver.
+ *
+ * 05 18 2011 cp.wu
+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC
+ * add device ID for MT5931.
+ *
+ * 04 08 2011 pat.lu
+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver
+ *
+ * 03 22 2011 pat.lu
+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
+ *
+ * 03 18 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
+ * memory consumption
+ * deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK.
+ *
+ * 03 15 2011 cp.wu
+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
+ * memory consumption
+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
+ * 2. Use common coalescing buffer for both TX/RX directions
+ *
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 11 15 2010 jeffrey.chang
+ * [WCXRP00000181] [MT6620 Wi-Fi][Driver] fix the driver message "GLUE_FLAG_HALT skip INT" during unloading
+ * Fix GLUE_FALG_HALT message which cause driver to hang
+ *
+ * 11 08 2010 cp.wu
+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
+ * correct typo
+ *
+ * 11 08 2010 cp.wu
+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time
+ *
+ * 11 01 2010 yarco.yang
+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
+ * Add code to run WlanIST in SDIO callback.
+ *
+ * 10 19 2010 cp.wu
+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration
+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time.
+ *
+ * 10 19 2010 jeffrey.chang
+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK
+ * HIF by default
+ * Refine linux kernel module to the license of MTK and enable MTK HIF
+ *
+ * 08 21 2010 jeffrey.chang
+ * NULL
+ * 1) add sdio two setting
+ * 2) bug fix of sdio glue
+ *
+ * 08 18 2010 jeffrey.chang
+ * NULL
+ * support multi-function sdio
+ *
+ * 08 18 2010 cp.wu
+ * NULL
+ * #if defined(__X86__) is not working, change to use #ifdef CONFIG_X86.
+ *
+ * 08 17 2010 cp.wu
+ * NULL
+ * add ENE SDIO host workaround for x86 linux platform.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Fix hotplug bug
+ *
+ * 03 28 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * clear sdio interrupt
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/interrupt.h>
+/* #include <linux/kernel.h> */
+#include <linux/device.h>
+/* #include <linux/errno.h> */
+#include <linux/platform_device.h>
+/* #include <linux/fs.h> */
+/* #include <linux/cdev.h> */
+/* #include <linux/poll.h> */
+
+#include <linux/mm.h>
+#ifndef CONFIG_X86
+#include <asm/memory.h>
+#endif
+
+#ifdef CONFIG_OF
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#else
+
+#endif
+
+/* #include <mach/mt_pm_ldo.h>
+#include <mach/mt_gpt.h> */
+
+#include "gl_os.h"
+
+#if defined(MT6620)
+#include "mt6620_reg.h"
+#elif defined(MT6628)
+#include "mtreg.h"
+#endif
+
+#if !defined(CONFIG_MTK_CLKMGR)
+#include <linux/clk.h>
+#endif
+
+/* #define MTK_DMA_BUF_MEMCPY_SUP */ /* no virt_to_phys() use */
+/* #define HIF_DEBUG_SUP */
+/* #define HIF_DEBUG_SUP_TX */
+
+#ifdef HIF_DEBUG_SUP
+#define HIF_DBG(msg)	(printk msg)
+#else
+#define HIF_DBG(msg)
+#endif /* HIF_DEBUG_SUP */
+
+#ifdef HIF_DEBUG_SUP_TX
+#define HIF_DBG_TX(msg)	(printk msg)
+#else
+#define HIF_DBG_TX(msg)
+#endif /* HIF_DEBUG_SUP */
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static UINT_32
+HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T *GlueInfo, IN UINT_32 BurstLen, IN UINT_32 PortId, IN UINT_32 TransByte);
+
+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg);
+
+static int HifAhbProbe(VOID);
+
+static int HifAhbRemove(VOID);
+
+#if (MTK_WCN_SINGLE_MODULE == 0)
+static int HifAhbBusCntGet(VOID);
+
+static int HifAhbBusCntClr(VOID);
+
+static int HifTxCnt;
+#endif /* MTK_WCN_SINGLE_MODULE */
+
+#if (CONF_HIF_DEV_MISC == 1)
+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos);
+
+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos);
+
+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg);
+
+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp);
+
+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp);
+#else
+
+static int HifAhbPltmProbe(IN struct platform_device *PDev);
+
+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev);
+
+#ifdef CONFIG_PM
+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message);
+
+static int HifAhbPltmResume(IN struct platform_device *PDev);
+#endif /* CONFIG_PM */
+
+#endif /* CONF_HIF_DEV_MISC */
+
+#if (CONF_HIF_LOOPBACK_AUTO == 1)	/* only for development test */
+static VOID HifAhbLoopbkAuto(IN unsigned long arg);
+#endif /* CONF_HIF_LOOPBACK_AUTO */
+
+#if (CONF_HIF_DMA_INT == 1)
+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg);
+#endif /* CONF_HIF_DMA_INT */
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/* initialiation function from other module */
+static probe_card pfWlanProbe;
+
+/* release function from other module */
+static remove_card pfWlanRemove;
+
+static BOOLEAN WlanDmaFatalErr;
+
+#if (CONF_HIF_DEV_MISC == 1)
+static const struct file_operations MtkAhbOps = {
+	.owner = THIS_MODULE,
+	.read = HifAhbMiscRead,
+	.write = HifAhbMiscWrite,
+	.unlocked_ioctl = HifAhbMiscIoctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = HifAhbMiscIoctl,
+#endif
+	.open = HifAhbMiscOpen,
+	.release = HifAhbMiscClose,
+};
+
+static struct miscdevice MtkAhbDriver = {
+	.minor = MISC_DYNAMIC_MINOR,	/* any minor number */
+	.name = HIF_MOD_NAME,
+	.fops = &MtkAhbOps,
+};
+#else
+
+#ifdef CONFIG_OF
+static const struct of_device_id apwifi_of_ids[] = {
+	{.compatible = "mediatek,wifi", .data = (void *)0},
+	{.compatible = "mediatek,mt7623-wifi", .data = (void *)0x7623},
+	{}
+};
+#endif
+
+struct platform_driver MtkPltmAhbDriver = {
+	.driver = {
+	.name = "mt-wifi",
+	.owner = THIS_MODULE,
+#ifdef CONFIG_OF
+	.of_match_table = apwifi_of_ids,
+#endif
+	},
+	.probe = HifAhbPltmProbe,
+#ifdef CONFIG_PM
+	.suspend = HifAhbPltmSuspend,
+	.resume = HifAhbPltmResume,
+#else
+	.suspend = NULL,
+	.resume = NULL,
+#endif /* CONFIG_PM */
+	.remove = __exit_p(HifAhbPltmRemove),
+};
+
+static struct platform_device *HifAhbPDev;
+
+#endif /* CONF_HIF_DEV_MISC */
+
+/*******************************************************************************
+*                       P U B L I C   F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will register sdio bus to the os
+*
+* \param[in] pfProbe    Function pointer to detect card
+* \param[in] pfRemove   Function pointer to remove card
+*
+* \return The result of registering HIF driver (WLAN_STATUS_SUCCESS = 0)
+*/
+/*----------------------------------------------------------------------------*/
+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove)
+{
+	WLAN_STATUS Ret;
+
+	ASSERT(pfProbe);
+	ASSERT(pfRemove);
+
+	pfWlanProbe = pfProbe;	/* wlan card initialization in other modules = wlanProbe() */
+	pfWlanRemove = pfRemove;
+
+#if (CONF_HIF_DEV_MISC == 1)
+	Ret = misc_register(&MtkAhbDriver);
+	if (Ret != 0)
+		return Ret;
+	HifAhbProbe();
+#else
+	Ret = platform_driver_register(&MtkPltmAhbDriver);
+#endif /* CONF_HIF_DEV_MISC */
+
+	return Ret;
+
+} /* end of glRegisterBus() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will unregister sdio bus to the os
+*
+* \param[in] pfRemove   Function pointer to remove card
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID glUnregisterBus(remove_card pfRemove)
+{
+	ASSERT(pfRemove);
+
+	pfRemove();
+
+#if (CONF_HIF_DEV_MISC == 1)
+	HifAhbRemove();
+
+	if ((misc_deregister(&MtkAhbDriver)) != 0)
+		;
+#else
+
+	platform_driver_unregister(&MtkPltmAhbDriver);
+#endif /* CONF_HIF_DEV_MISC */
+
+	return;
+
+} /* end of glUnregisterBus() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will inform us whole chip reset start event.
+*
+* \param[in] GlueInfo   Pointer to glue info structure
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID glResetHif(GLUE_INFO_T *GlueInfo)
+{
+	GL_HIF_INFO_T *HifInfo;
+
+	ASSERT(GlueInfo);
+	HifInfo = &GlueInfo->rHifInfo;
+	if (HifInfo->DmaOps)
+		HifInfo->DmaOps->DmaReset(HifInfo);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function stores hif related info, which is initialized before.
+*
+* \param[in] GlueInfo Pointer to glue info structure
+* \param[in] u4Cookie   Pointer to UINT_32 memory base variable for _HIF_HPI
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID glSetHifInfo(GLUE_INFO_T *GlueInfo, ULONG ulCookie)
+{
+	GL_HIF_INFO_T *HifInfo;
+	const struct of_device_id *of_id;
+
+	/* Init HIF */
+	ASSERT(GlueInfo);
+	HifInfo = &GlueInfo->rHifInfo;
+#if (CONF_HIF_DEV_MISC == 1)
+	HifInfo->Dev = MtkAhbDriver.this_device;
+#else
+	HifInfo->Dev = &HifAhbPDev->dev;
+#endif /* CONF_HIF_DEV_MISC */
+	SET_NETDEV_DEV(GlueInfo->prDevHandler, HifInfo->Dev);
+
+	HifInfo->HifRegBaseAddr = ioremap(HIF_DRV_BASE, HIF_DRV_LENGTH);
+	HifInfo->McuRegBaseAddr = ioremap(CONN_MCU_DRV_BASE, CONN_MCU_REG_LENGTH);
+	DBGLOG(INIT, INFO, "[WiFi/HIF]HifInfo->HifRegBaseAddr=0x%p, HifInfo->McuRegBaseAddr=0x%p\n",
+	       HifInfo->HifRegBaseAddr, HifInfo->McuRegBaseAddr);
+
+	/* default disable DMA */
+	HifInfo->fgDmaEnable = FALSE;
+	HifInfo->DmaRegBaseAddr = 0;
+	HifInfo->DmaOps = NULL;
+	of_id = of_match_node(apwifi_of_ids, HifAhbPDev->dev.of_node);
+	if (of_id && of_id->data) {
+		HifInfo->ChipID = (UINT_32)(unsigned long)of_id->data;
+	} else {
+		/* read chip ID */
+		HifInfo->ChipID = HIF_REG_READL(HifInfo, MCR_WCIR) & 0xFFFF;
+		if (HifInfo->ChipID == 0x0321 || HifInfo->ChipID == 0x0335 || HifInfo->ChipID == 0x0337)
+			HifInfo->ChipID = 0x6735;	/* Denali ChipID transition */
+		if (HifInfo->ChipID == 0x0326)
+			HifInfo->ChipID = 0x6755;
+	}
+	DBGLOG(INIT, INFO, "[WiFi/HIF] ChipID = 0x%x\n", HifInfo->ChipID);
+#ifdef CONFIG_OF
+#if !defined(CONFIG_MTK_CLKMGR)
+	HifInfo->clk_wifi_dma = devm_clk_get(&HifAhbPDev->dev, "wifi-dma");
+	if (IS_ERR(HifInfo->clk_wifi_dma))
+		DBGLOG(INIT, ERROR, "[WiFi/HIF][CCF]cannot get HIF clk_wifi_dma clock.\n");
+	DBGLOG(INIT, TRACE, "[WiFi/HIF][CCF]HIF clk_wifi_dma=0x%p\n", HifInfo->clk_wifi_dma);
+#endif
+#endif
+
+	/* Init DMA */
+	WlanDmaFatalErr = 0;	/* reset error flag */
+
+#if (CONF_MTK_AHB_DMA == 1)
+	spin_lock_init(&HifInfo->DdmaLock);
+
+	HifPdmaInit(HifInfo);
+#endif /* CONF_MTK_AHB_DMA */
+
+	/* Start loopback test after 10 seconds */
+#if (CONF_HIF_LOOPBACK_AUTO == 1)	/* only for development test */
+	{
+		init_timer(&(HifInfo->HifTmrLoopbkFn));
+		HifInfo->HifTmrLoopbkFn.function = HifAhbLoopbkAuto;
+		HifInfo->HifTmrLoopbkFn.data = (unsigned long)GlueInfo;
+
+		init_waitqueue_head(&HifInfo->HifWaitq);
+		HifInfo->HifTaskLoopbkFn = kthread_run(kalDevLoopbkThread, GlueInfo->prDevHandler, "LoopbkThread");
+		HifInfo->HifLoopbkFlg = 0;
+
+		/* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */
+		HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(30000);
+		add_timer(&(HifInfo->HifTmrLoopbkFn));
+
+		HIF_DBG(("[WiFi/HIF] Start loopback test after 10 seconds (jiffies = %u)...\n", jiffies));
+	}
+#endif /* CONF_HIF_LOOPBACK_AUTO */
+
+#if (CONF_HIF_DMA_INT == 1)
+	init_waitqueue_head(&HifInfo->HifDmaWaitq);
+	HifInfo->HifDmaWaitFlg = 0;
+#endif /* CONF_HIF_DMA_INT */
+
+} /* end of glSetHifInfo() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function clears hif related info.
+*
+* \param[in] GlueInfo Pointer to glue info structure
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID glClearHifInfo(GLUE_INFO_T *GlueInfo)
+{
+	iounmap(GlueInfo->rHifInfo.HifRegBaseAddr);
+	iounmap(GlueInfo->rHifInfo.DmaRegBaseAddr);
+	iounmap(GlueInfo->rHifInfo.McuRegBaseAddr);
+	return;
+
+} /* end of glClearHifInfo() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function clears hif related info.
+*
+* \param[in] GlueInfo Pointer to glue info structure
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf)
+{
+	GL_HIF_INFO_T *HifInfo;
+
+	HifInfo = &GlueInfo->rHifInfo;
+	DBGLOG(INIT, TRACE, "glGetChipInfo ChipID = 0x%x\n", HifInfo->ChipID);
+	switch (HifInfo->ChipID) {
+	case MTK_CHIP_ID_6571:
+	case MTK_CHIP_ID_8127:
+	case MTK_CHIP_ID_6752:
+	case MTK_CHIP_ID_8163:
+	case MTK_CHIP_ID_6735:
+	case MTK_CHIP_ID_6580:
+	case MTK_CHIP_ID_6755:
+	case MTK_CHIP_ID_7623:
+		kalSprintf(pucChipBuf, "%04x", HifInfo->ChipID);
+		break;
+	default:
+		kalMemCopy(pucChipBuf, "SOC", strlen("SOC"));
+	}
+} /* end of glGetChipInfo() */
+
+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function to check if we need wakelock under Hotspot mode.
+*
+* \param[in] GlueInfo Pointer to glue info structure
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo)
+{
+	GL_HIF_INFO_T *HifInfo;
+
+	HifInfo = &GlueInfo->rHifInfo;
+	if (HifInfo->ChipID == MTK_CHIP_ID_6572 || HifInfo->ChipID == MTK_CHIP_ID_6582)
+		return TRUE;
+	else
+		return FALSE;
+} /* end of glIsChipNeedWakelock() */
+#endif /* CFG_SPM_WORKAROUND_FOR_HOTSPOT */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Initialize bus operation and hif related information, request resources.
+*
+* \param[out] pvData    A pointer to HIF-specific data type buffer.
+*                       For eHPI, pvData is a pointer to UINT_32 type and stores a
+*                       mapped base address.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN glBusInit(PVOID pvData)
+{
+	return TRUE;
+} /* end of glBusInit() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Stop bus operation and release resources.
+*
+* \param[in] pvData A pointer to struct net_device.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID glBusRelease(PVOID pvData)
+{
+} /* end of glBusRelease() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Setup bus interrupt operation and interrupt handler for os.
+*
+* \param[in] pvData     A pointer to struct net_device.
+* \param[in] pfnIsr     A pointer to interrupt handler function.
+* \param[in] pvCookie   Private data for pfnIsr function.
+*
+* \retval WLAN_STATUS_SUCCESS   if success
+*         NEGATIVE_VALUE   if fail
+*/
+/*----------------------------------------------------------------------------*/
+#ifdef CONFIG_OF
+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie)
+{
+	struct device_node *node = NULL;
+	unsigned int irq_info[3] = { 0, 0, 0 };
+	/* unsigned int phy_base; */
+	unsigned int irq_id = 0;
+	unsigned int irq_flags = 0;
+
+	struct net_device *prNetDevice;
+
+	ASSERT(pvData);
+	if (!pvData)
+		return -1;
+	prNetDevice = (struct net_device *)pvData;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,wifi");
+	if (node) {
+		irq_id = irq_of_parse_and_map(node, 0);
+		DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id);
+	} else {
+		DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n");
+	}
+
+	/* get the interrupt line behaviour */
+	if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) {
+		DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n");
+	} else {
+		irq_flags = irq_info[2];
+		DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags);
+	}
+
+	/* Register AHB IRQ */
+	if (request_irq(irq_id, HifAhbISR, irq_flags, HIF_MOD_NAME, prNetDevice)) {
+		DBGLOG(INIT, ERROR, "WIFI-OF: request irq %d fail!\n", irq_id);
+		return -1;
+	}
+
+	return 0;
+}
+
+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie)
+{
+	struct device_node *node = NULL;
+	unsigned int irq_info[3] = { 0, 0, 0 };
+	/* unsigned int phy_base; */
+	unsigned int irq_id = 0;
+	unsigned int irq_flags = 0;
+
+	struct net_device *prNetDevice;
+
+	/* Init */
+	ASSERT(pvData);
+	if (!pvData)
+		return;
+	prNetDevice = (struct net_device *)pvData;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,wifi");
+	if (node) {
+		irq_id = irq_of_parse_and_map(node, 0);
+		DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id);
+	} else {
+		DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n");
+	}
+
+	/* get the interrupt line behaviour */
+	if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) {
+		DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n");
+	} else {
+		irq_flags = irq_info[2];
+		DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags);
+	}
+
+	/* Free the IRQ */
+	free_irq(irq_id, prNetDevice);
+	return;
+
+}
+#else
+/* the name is different in 72 and 82 */
+#ifndef MT_WF_HIF_IRQ_ID	/* for MT6572/82/92 */
+#define MT_WF_HIF_IRQ_ID   WF_HIF_IRQ_ID
+#endif /* MT_WF_HIF_IRQ_ID */
+
+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie)
+{
+	int ret = 0;
+	struct net_device *prNetDevice;
+	GLUE_INFO_T *GlueInfo;
+	GL_HIF_INFO_T *HifInfo;
+
+	/* Init */
+	ASSERT(pvData);
+	if (!pvData)
+		return -1;
+
+	prNetDevice = (struct net_device *)pvData;
+	GlueInfo = (GLUE_INFO_T *) pvCookie;
+	ASSERT(GlueInfo);
+	if (!GlueInfo) {
+		DBGLOG(INIT, ERROR, "GlueInfo == NULL!\n");
+		return -1;
+	}
+
+	HifInfo = &GlueInfo->rHifInfo;
+
+	/* Register AHB IRQ */
+	if (request_irq(MT_WF_HIF_IRQ_ID, HifAhbISR, IRQF_TRIGGER_LOW, HIF_MOD_NAME, prNetDevice)) {
+		DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_WF_HIF_IRQ_ID);
+		return -1;
+	}
+#if (CONF_HIF_DMA_INT == 1)
+	if (request_irq(MT_GDMA2_IRQ_ID, HifDmaISR, IRQF_TRIGGER_LOW, "AHB_DMA", prNetDevice)) {
+		DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_GDMA2_IRQ_ID);
+		free_irq(MT_WF_HIF_IRQ_ID, prNetDevice);
+		return -1;
+	}
+#endif /* CONF_HIF_DMA_INT */
+
+	return ret;
+
+} /* end of glBusSetIrq() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Stop bus interrupt operation and disable interrupt handling for os.
+*
+* \param[in] pvData     A pointer to struct net_device.
+* \param[in] pvCookie   Private data for pfnIsr function.
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie)
+{
+	struct net_device *prNetDevice;
+	GLUE_INFO_T *GlueInfo;
+	GL_HIF_INFO_T *HifInfo;
+
+	/* Init */
+	ASSERT(pvData);
+	if (!pvData)
+		return;
+
+	prNetDevice = (struct net_device *)pvData;
+	GlueInfo = (GLUE_INFO_T *) pvCookie;
+	ASSERT(GlueInfo);
+	if (!GlueInfo)
+		return;
+
+	HifInfo = &GlueInfo->rHifInfo;
+
+	/* Free the IRQ */
+	free_irq(MT_WF_HIF_IRQ_ID, prNetDevice);
+	return;
+
+} /* end of glBusreeIrq() */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Read a 32-bit device register
+*
+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure.
+* \param[in] RegOffset Register offset
+* \param[in] pu4Value   Pointer to variable used to store read value
+*
+* \retval TRUE          operation success
+* \retval FALSE         operation fail
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalDevRegRead(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, OUT UINT_32 *pu4Value)
+{
+	GL_HIF_INFO_T *HifInfo;
+
+	/* sanity check and init */
+	ASSERT(GlueInfo);
+	ASSERT(pu4Value);
+	HifInfo = &GlueInfo->rHifInfo;
+
+	/* use PIO mode to read register */
+	if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR)
+		return FALSE;
+	*pu4Value = HIF_REG_READL(HifInfo, RegOffset);
+
+	if ((RegOffset == MCR_WRDR0) || (RegOffset == MCR_WRDR1))
+		HIF_DBG(("[WiFi/HIF] kalDevRegRead from Data Port 0 or 1\n"));
+
+	return TRUE;
+
+} /* end of kalDevRegRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Write a 32-bit device register
+*
+* \param[in] GlueInfo   Pointer to the GLUE_INFO_T structure.
+* \param[in] RegOffset  Register offset
+* \param[in] RegValue   RegValue to be written
+*
+* \retval TRUE          operation success
+* \retval FALSE         operation fail
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalDevRegWrite(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, IN UINT_32 RegValue)
+{
+	GL_HIF_INFO_T *HifInfo;
+
+	/* sanity check and init */
+	ASSERT(GlueInfo);
+	HifInfo = &GlueInfo->rHifInfo;
+
+	/* use PIO mode to write register */
+	if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR)
+		return FALSE;
+	HIF_REG_WRITEL(HifInfo, RegOffset, RegValue);
+
+	if ((RegOffset == MCR_WTDR0) || (RegOffset == MCR_WTDR1))
+		HIF_DBG(("[WiFi/HIF] kalDevRegWrite to Data Port 0 or 1\n"));
+
+	return TRUE;
+
+} /* end of kalDevRegWrite() */
+
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Read device I/O port
+*
+* \param[in] GlueInfo   Pointer to the GLUE_INFO_T structure.
+* \param[in] Port       I/O port offset
+* \param[in] Size       Length to be read
+* \param[out] Buf       Pointer to read buffer
+* \param[in] MaxBufSize Length of the buffer valid to be accessed
+*
+* \retval TRUE          operation success
+* \retval FALSE         operation fail
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+kalDevPortRead(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, OUT PUINT_8 Buf, IN UINT_32 MaxBufSize)
+{
+	GL_HIF_INFO_T *HifInfo;
+	UINT_32 u4HSTCRValue = 0;
+	UINT_32 RegWHLPCR = 0;
+
+	/* sanity check */
+	if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) {
+		DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n",
+				WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter));
+		return FALSE;
+	}
+	/* Init */
+	ASSERT(GlueInfo);
+	HifInfo = &GlueInfo->rHifInfo;
+
+	ASSERT(Buf);
+	ASSERT(Size <= MaxBufSize);
+
+	/* Note: burst length should be equal to the one used in DMA */
+	if (Port == MCR_WRDR0)
+		u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD0, Size);
+	else if (Port == MCR_WRDR1)
+		u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD1, Size);
+	else if (Port == MCR_WHISR)
+		u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_WHISR, Size);
+
+	RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR);
+	if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1)
+		HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
+
+	/* Read */
+#if (CONF_MTK_AHB_DMA == 1)
+	if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL)
+		&& ((Port == MCR_WRDR0) || (Port == MCR_WRDR1))) {
+		/* only for data port */
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+		VOID *DmaVBuf = NULL, *DmaPBuf = NULL;
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+		GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps;
+		MTK_WCN_HIF_DMA_CONF DmaConf;
+		UINT_32 LoopCnt;
+		unsigned long PollTimeout;
+#if (CONF_HIF_DMA_INT == 1)
+		INT_32 RtnVal = 0;
+#endif
+		/* config DMA, Port = MCR_WRDR0 or MCR_WRDR1 */
+		DmaConf.Count = Size;
+		DmaConf.Dir = HIF_DMA_DIR_RX;
+		DmaConf.Src = HIF_DRV_BASE + Port;	/* must be physical addr */
+
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+		DmaConf.Dst = kalIOPhyAddrGet(Buf);	/* must be physical addr */
+
+		/* TODO: use virt_to_phys() */
+		if (DmaConf.Dst == NULL) {
+			HIF_DBG(("[WiFi/HIF] Use Dma Buffer to RX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE));
+			ASSERT(Size <= CFG_RX_MAX_PKT_SIZE);
+
+			kalDmaBufGet(&DmaVBuf, &DmaPBuf);
+			DmaConf.Dst = (ULONG) DmaPBuf;
+		}
+#else
+		/*
+		   http://kernelnewbies.org/KernelMemoryAllocation
+		   Since the cache-coherent mapping may be expensive, also a streaming allocation exists.
+
+		   This is a buffer for one-way communication, which means coherency is limited to
+		   flushing the data from the cache after a write finishes. The buffer has to be
+		   pre-allocated (e.g. using kmalloc()). DMA for it is set up with dma_map_single().
+
+		   When the DMA is finished (e.g. when the device has sent an interrupt signaling end of
+		   DMA), call dma_unmap_single(). Between map and unmap, the device is in control of the
+		   buffer: if you write to the device, do it before dma_map_single(), if you read from
+		   it, do it after dma_unmap_single().
+		 */
+		/* DMA_FROM_DEVICE invalidated (without writeback) the cache */
+		/* TODO: if dst_off was not cacheline aligned */
+		DmaConf.Dst = dma_map_single(HifInfo->Dev, Buf, Size, DMA_FROM_DEVICE);
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+
+		/* start to read data */
+		AP_DMA_HIF_LOCK(HifInfo);	/* lock to avoid other codes config GDMA */
+
+		prDmaOps->DmaClockCtrl(TRUE);
+		prDmaOps->DmaConfig(HifInfo, &DmaConf);
+		prDmaOps->DmaStart(HifInfo);
+
+#if (CONF_HIF_DMA_INT == 1)
+		RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000);
+		if (RtnVal <= 0)
+			DBGLOG(RX, ERROR, "fatal error1! reset DMA!\n");
+		HifInfo->HifDmaWaitFlg = 0;
+#else
+		PollTimeout = jiffies + HZ * 5;
+
+		do {
+			if (time_before(jiffies, PollTimeout))
+				continue;
+			DBGLOG(RX, INFO, "RX DMA Timeout, HSTCR: 0x%08x, and dump WHISR EnhanceMode data\n",
+					u4HSTCRValue);
+			HifDumpEnhanceModeData(GlueInfo->prAdapter);
+			if (prDmaOps->DmaRegDump != NULL)
+				prDmaOps->DmaRegDump(HifInfo);
+			WlanDmaFatalErr = 1;
+			/* we still need complete dma progress even dma timeout */
+			break;
+		} while (!prDmaOps->DmaPollIntr(HifInfo));
+#endif /* CONF_HIF_DMA_INT */
+		/* we should disable dma interrupt then clear dma interrupt, otherwise,
+			for dma timeout case, interrupt may be set after we clear it */
+		prDmaOps->DmaStop(HifInfo);
+		prDmaOps->DmaAckIntr(HifInfo);
+
+		LoopCnt = 0;
+		do {
+			if (LoopCnt++ > 100000) {
+				/* TODO: impossible! reset DMA */
+				DBGLOG(RX, ERROR, "fatal error2! reset DMA!\n");
+				break;
+			}
+		} while (prDmaOps->DmaPollStart(HifInfo) != 0);
+
+		prDmaOps->DmaClockCtrl(FALSE);
+
+		AP_DMA_HIF_UNLOCK(HifInfo);
+
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+		if (DmaVBuf != NULL)
+			kalMemCopy(Buf, DmaVBuf, Size);
+#else
+		dma_unmap_single(HifInfo->Dev, DmaConf.Dst, Size, DMA_FROM_DEVICE);
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+
+		if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1)
+			HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+		if (WlanDmaFatalErr) {
+			if (!fgIsResetting)
+				glDoChipReset();
+			return FALSE;
+		}
+		HIF_DBG(("[WiFi/HIF] DMA RX OK!\n"));
+	} else
+#endif /* CONF_MTK_AHB_DMA */
+	{
+		UINT_32 IdLoop, MaxLoop;
+		UINT_32 *LoopBuf;
+
+		/* default PIO mode */
+		MaxLoop = Size >> 2;
+		if (Size & 0x3)
+			MaxLoop++;
+		LoopBuf = (UINT_32 *) Buf;
+
+		for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) {
+
+			*LoopBuf = HIF_REG_READL(HifInfo, Port);
+			LoopBuf++;
+		}
+
+		if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1)
+			HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET);
+	}
+
+	return TRUE;
+
+}				/* end of kalDevPortRead() */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Write device I/O port
+*
+* \param[in] GlueInfo   Pointer to the GLUE_INFO_T structure.
+* \param[in] Port       I/O port offset
+* \param[in] Size       Length to be write
+* \param[in] Buf        Pointer to write buffer
+* \param[in] MaxBufSize Length of the buffer valid to be accessed
+*
+* \retval TRUE          operation success
+* \retval FALSE         operation fail
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN
+kalDevPortWrite(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, IN PUINT_8 Buf, IN UINT_32 MaxBufSize)
+{
+	GL_HIF_INFO_T *HifInfo;
+	UINT_32 u4HSTCRValue = 0;
+	UINT_32 RegWHLPCR = 0;
+
+	/* sanity check */
+	if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) {
+		DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n",
+				WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter));
+		return FALSE;
+	}
+
+	/* Init */
+	ASSERT(GlueInfo);
+	HifInfo = &GlueInfo->rHifInfo;
+
+	ASSERT(Buf);
+	ASSERT(Size <= MaxBufSize);
+
+	HifTxCnt++;
+
+	/* Note: burst length should be equal to the one used in DMA */
+	if (Port == MCR_WTDR0)
+		u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD0, Size);
+	else if (Port == MCR_WTDR1)
+		u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD1, Size);
+	/* else other non-data port */
+
+	RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR);
+	if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1)
+		HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
+
+	/* Write */
+#if (CONF_MTK_AHB_DMA == 1)
+	if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) && ((Port == MCR_WTDR0) ||
+		(Port == MCR_WTDR1))) {
+		/* only for data port */
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+		VOID *DmaVBuf = NULL, *DmaPBuf = NULL;
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+		GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps;
+		MTK_WCN_HIF_DMA_CONF DmaConf;
+		UINT_32 LoopCnt;
+		unsigned long PollTimeout;
+#if (CONF_HIF_DMA_INT == 1)
+		INT_32 RtnVal = 0;
+#endif
+
+		/* config GDMA */
+		HIF_DBG_TX(("[WiFi/HIF/DMA] Prepare to send data...\n"));
+		DmaConf.Count = Size;
+		DmaConf.Dir = HIF_DMA_DIR_TX;
+		DmaConf.Dst = HIF_DRV_BASE + Port;	/* must be physical addr */
+
+#ifdef MTK_DMA_BUF_MEMCPY_SUP
+		DmaConf.Src = kalIOPhyAddrGet(Buf);	/* must be physical addr */
+
+		/* TODO: use virt_to_phys() */
+		if (DmaConf.Src == NULL) {
+			HIF_DBG_TX(("[WiFi/HIF] Use Dma Buffer to TX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE));
+			ASSERT(Size <= CFG_RX_MAX_PKT_SIZE);
+
+			kalDmaBufGet(&DmaVBuf, &DmaPBuf);
+			DmaConf.Src = (ULONG) DmaPBuf;
+
+			kalMemCopy(DmaVBuf, Buf, Size);
+		}
+#else
+
+		/* DMA_TO_DEVICE writeback the cache */
+		DmaConf.Src = dma_map_single(HifInfo->Dev, Buf, Size, DMA_TO_DEVICE);
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+
+		/* start to write */
+		AP_DMA_HIF_LOCK(HifInfo);
+
+		prDmaOps->DmaClockCtrl(TRUE);
+		prDmaOps->DmaConfig(HifInfo, &DmaConf);
+		prDmaOps->DmaStart(HifInfo);
+
+#if (CONF_HIF_DMA_INT == 1)
+		RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000);
+		if (RtnVal <= 0)
+			DBGLOG(TX, ERROR, "fatal error1! reset DMA!\n");
+		HifInfo->HifDmaWaitFlg = 0;
+#else
+
+		LoopCnt = 0;
+		PollTimeout = jiffies + HZ * 5;
+
+		do {
+			if (time_before(jiffies, PollTimeout))
+				continue;
+			DBGLOG(TX, INFO, "TX DMA Timeout, HSTCR: 0x%08x\n", u4HSTCRValue);
+			if (prDmaOps->DmaRegDump != NULL)
+				prDmaOps->DmaRegDump(HifInfo);
+			WlanDmaFatalErr = 1;
+			/* we still need complete dma progress even dma timeout */
+			break;
+		} while (!prDmaOps->DmaPollIntr(HifInfo));
+#endif /* CONF_HIF_DMA_INT */
+		/* we should disable dma interrupt then clear dma interrupt, otherwise,
+			for dma timeout case, interrupt may be set after we clear it */
+		prDmaOps->DmaStop(HifInfo);
+		prDmaOps->DmaAckIntr(HifInfo);
+
+		LoopCnt = 0;
+		do {
+			if (LoopCnt++ > 100000) {
+				DBGLOG(TX, ERROR, "fatal error2! reset DMA!\n");
+				break;
+			}
+		} while (prDmaOps->DmaPollStart(HifInfo) != 0);
+
+		prDmaOps->DmaClockCtrl(FALSE);
+
+		AP_DMA_HIF_UNLOCK(HifInfo);
+
+#ifndef MTK_DMA_BUF_MEMCPY_SUP
+		dma_unmap_single(HifInfo->Dev, DmaConf.Src, Size, DMA_TO_DEVICE);
+#endif /* MTK_DMA_BUF_MEMCPY_SUP */
+
+		if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1)
+			HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+		if (WlanDmaFatalErr) {
+			if (!fgIsResetting)
+				glDoChipReset();
+			return FALSE;
+		}
+		HIF_DBG_TX(("[WiFi/HIF] DMA TX OK!\n"));
+	} else
+#endif /* CONF_MTK_AHB_DMA */
+	{
+		UINT_32 IdLoop, MaxLoop;
+		UINT_32 *LoopBuf;
+
+		/* PIO mode */
+		MaxLoop = Size >> 2;
+		LoopBuf = (UINT_32 *) Buf;
+
+		HIF_DBG_TX(("[WiFi/HIF/PIO] Prepare to send data (%d 0x%p-0x%p)...\n",
+			    Size, LoopBuf, (((UINT8 *) LoopBuf) + (Size & (~0x03)))));
+
+		if (Size & 0x3)
+			MaxLoop++;
+
+		for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) {
+			HIF_REG_WRITEL(HifInfo, Port, *LoopBuf);
+			LoopBuf++;
+		}
+
+		if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1)
+			HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+		HIF_DBG_TX(("\n\n"));
+	}
+
+	return TRUE;
+
+} /* end of kalDevPortWrite() */
+
+/*******************************************************************************
+*                       P R I V A T E   F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is a SDIO interrupt callback function
+*
+* \param[in] func  pointer to SDIO handle
+*
+* \return void
+*/
+/*----------------------------------------------------------------------------*/
+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg)
+{
+	struct net_device *prNetDevice = (struct net_device *)Arg;
+	GLUE_INFO_T *GlueInfo;
+	GL_HIF_INFO_T *HifInfo;
+
+	/* Init */
+	IsrCnt++;
+	ASSERT(prNetDevice);
+	GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice));
+	ASSERT(GlueInfo);
+
+	if (!GlueInfo)
+		return IRQ_HANDLED;
+
+	HifInfo = &GlueInfo->rHifInfo;
+
+	GlueInfo->IsrCnt++;
+
+	if (GlueInfo->ulFlag & GLUE_FLAG_HALT) {
+		HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
+		return IRQ_HANDLED;
+	}
+
+	HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
+
+	/* lock 100ms to avoid suspend */
+	kalHifAhbKalWakeLockTimeout(GlueInfo);
+
+	/* Wake up main thread */
+	set_bit(GLUE_FLAG_INT_BIT, &GlueInfo->ulFlag);
+
+	/* when we got sdio interrupt, we wake up the tx servie thread */
+	wake_up_interruptible(&GlueInfo->waitq);
+
+	IsrPassCnt++;
+	GlueInfo->IsrPassCnt++;
+	return IRQ_HANDLED;
+
+}
+
+#if (CONF_HIF_DMA_INT == 1)
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is a SDIO interrupt callback function
+*
+* \param[in] func  pointer to SDIO handle
+*
+* \return void
+*/
+/*----------------------------------------------------------------------------*/
+
+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg)
+{
+	struct net_device *prNetDevice = (struct net_device *)Arg;
+	GLUE_INFO_T *GlueInfo;
+	GL_HIF_INFO_T *HifInfo;
+
+	/* Init */
+	ASSERT(prNetDevice);
+	GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice));
+	ASSERT(GlueInfo);
+
+	if (!GlueInfo)
+		return IRQ_HANDLED;
+	HifInfo = &GlueInfo->rHifInfo;
+
+	/* disable interrupt */
+	HifInfo->DmaOps->DmaAckIntr(HifInfo);
+
+	/* Wake up main thread */
+	set_bit(1, &HifInfo->HifDmaWaitFlg);
+
+	/* when we got sdio interrupt, we wake up the tx servie thread */
+	wake_up_interruptible(&HifInfo->HifDmaWaitq);
+
+	return IRQ_HANDLED;
+
+}
+#endif /* CONF_HIF_DMA_INT */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is a SDIO probe function
+*
+* \param[in] func   pointer to SDIO handle
+* \param[in] id     pointer to SDIO device id table
+*
+* \return void
+*/
+/*----------------------------------------------------------------------------*/
+#if defined(CONFIG_MTK_CLKMGR)
+#if defined(MTK_EXTERNAL_LDO) || defined(MTK_ALPS_BOX_SUPPORT)
+#include <mach/mt_gpio.h>
+#endif
+#endif
+
+static int HifAhbProbe(VOID)
+{
+	int Ret = 0;
+
+	DBGLOG(INIT, INFO, "HifAhbProbe()\n");
+
+	/* power on WiFi TX PA 3.3V and HIF GDMA clock */
+	{
+#ifdef CONFIG_MTK_PMIC_MT6397
+#if defined(CONFIG_MTK_CLKMGR)
+#ifdef MTK_EXTERNAL_LDO
+		/* for 8127 tablet */
+		mt_set_gpio_mode(GPIO51, GPIO_MODE_04);
+		mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT);
+		mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE);
+		mt_set_gpio_pull_select(GPIO51, GPIO_PULL_UP);
+#elif defined(MTK_ALPS_BOX_SUPPORT)
+		/* for 8127 box */
+		mt_set_gpio_mode(GPIO89, GPIO_MODE_04);
+		mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT);
+		mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE);
+		mt_set_gpio_pull_select(GPIO89, GPIO_PULL_UP);
+#else
+		hwPowerOn(MT65XX_POWER_LDO_VGP4, VOL_3300, "WLAN");
+#endif
+#endif
+#else
+#ifdef CONFIG_OF		/*for MT6752 */
+		mtk_wcn_consys_hw_wifi_paldo_ctrl(1);	/* switch to HW mode */
+#else				/*for MT6572/82/92 */
+		hwPowerOn(MT6323_POWER_LDO_VCN33_WIFI, VOL_3300, "WLAN");
+		upmu_set_vcn33_on_ctrl_wifi(1);	/* switch to HW mode */
+#endif
+#endif
+
+	}
+
+#if (CONF_HIF_DEV_MISC == 1)
+	if (pfWlanProbe((PVOID) &MtkAhbDriver.this_device) != WLAN_STATUS_SUCCESS) {
+#else
+	if (pfWlanProbe((PVOID) &HifAhbPDev->dev) != WLAN_STATUS_SUCCESS) {
+#endif /* CONF_HIF_DEV_MISC */
+
+		pfWlanRemove();
+		Ret = -1;
+	}
+
+	return Ret;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function will do module remove.
+*
+* \param[in] None
+*
+* \return The result of remove (WLAN_STATUS_SUCCESS = 0)
+*/
+/*----------------------------------------------------------------------------*/
+static int HifAhbRemove(VOID)
+{
+	DBGLOG(INIT, INFO, "HifAhbRemove()\n");
+
+	pfWlanRemove();
+
+	{
+#ifdef CONFIG_MTK_PMIC_MT6397
+#if defined(CONFIG_MTK_CLKMGR)
+#ifdef MTK_EXTERNAL_LDO
+		/* for 8127 tablet */
+		mt_set_gpio_mode(GPIO51, GPIO_MODE_04);
+		mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT);
+		mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE);
+		mt_set_gpio_pull_select(GPIO51, GPIO_PULL_DOWN);
+#elif defined(MTK_ALPS_BOX_SUPPORT)
+		/* for 8127 box */
+		mt_set_gpio_mode(GPIO89, GPIO_MODE_04);
+		mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT);
+		mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE);
+		mt_set_gpio_pull_select(GPIO89, GPIO_PULL_DOWN);
+#else
+		hwPowerDown(MT65XX_POWER_LDO_VGP4, "WLAN");
+#endif
+#endif
+#else
+#ifdef CONFIG_OF		/*for MT6752 */
+		mtk_wcn_consys_hw_wifi_paldo_ctrl(0);	/* switch to SW mode */
+#else				/*for MT6572/82/92 */
+		upmu_set_vcn33_on_ctrl_wifi(0);	/* switch to SW mode */
+		hwPowerDown(MT6323_POWER_LDO_VCN33_WIFI, "WLAN");
+#endif
+#endif
+
+	}
+
+	return 0;
+}
+
+#if (MTK_WCN_SINGLE_MODULE == 0)
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function gets the TX count pass through HIF AHB bus.
+*
+* \param[in] None
+*
+* \return TX count
+*/
+/*----------------------------------------------------------------------------*/
+static int HifAhbBusCntGet(VOID)
+{
+	return HifTxCnt;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function resets the TX count pass through HIF AHB bus.
+*
+* \param[in] None
+*
+* \return 0
+*/
+/*----------------------------------------------------------------------------*/
+static int HifAhbBusCntClr(VOID)
+{
+	HifTxCnt = 0;
+	return 0;
+}
+#endif /* MTK_WCN_SINGLE_MODULE */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function configs the DMA TX/RX settings before any real TX/RX.
+*
+* \param[in] GlueInfo       Pointer to the GLUE_INFO_T structure.
+* \param[in] BurstLen       0(1DW), 1(4DW), 2(8DW), Others(Reserved)
+* \param[in] PortId         0(TXD0), 1(TXD1), 2(RXD0), 3(RXD1), 4(WHISR enhance)
+* \param[in] TransByte      Should be 4-byte align.
+*
+* \return void
+*/
+/*----------------------------------------------------------------------------*/
+static UINT_32 HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T * GlueInfo, UINT_32 BurstLen, UINT_32 PortId, UINT_32 TransByte)
+{
+	GL_HIF_INFO_T *HifInfo;
+	UINT_32 RegHSTCR;
+
+	ASSERT(GlueInfo);
+	HifInfo = &GlueInfo->rHifInfo;
+
+	RegHSTCR = HIF_REG_READL(HifInfo, MCR_WHIER);
+
+	RegHSTCR = HIF_REG_READL(HifInfo, MCR_HSTCR);
+	RegHSTCR =
+	    ((BurstLen << HSTCR_AFF_BURST_LEN_OFFSET) & HSTCR_AFF_BURST_LEN) |
+	    ((PortId << HSTCR_TRANS_TARGET_OFFSET) & HSTCR_TRANS_TARGET) |
+	    (((TransByte & 0x3) == 0) ? (TransByte & HSTCR_HSIF_TRANS_CNT) : ((TransByte + 4) & HSTCR_HSIF_TRANS_CNT));
+	HIF_REG_WRITEL(HifInfo, MCR_HSTCR, RegHSTCR);
+	return RegHSTCR;
+}
+
+VOID glSetPowerState(IN GLUE_INFO_T *GlueInfo, IN UINT_32 ePowerMode)
+{
+
+}
+
+#if (CONF_HIF_DEV_MISC == 1)
+/* no use */
+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos)
+{
+	return 0;
+}
+
+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos)
+{
+	return 0;
+}
+
+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg)
+{
+	return 0;
+}
+
+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp)
+{
+	return 0;
+}
+
+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp)
+{
+	return 0;
+}
+#else
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called by OS platform device module.
+*
+* \param[in] PDev           Pointer to the platform device structure.
+*
+* \return 0
+*/
+/*----------------------------------------------------------------------------*/
+static int HifAhbPltmProbe(IN struct platform_device *PDev)
+{
+	HifAhbPDev = PDev;
+
+	DBGLOG(INIT, INFO, "HifAhbPltmProbe\n");
+
+#if (CONF_HIF_PMIC_TEST == 1)
+	wmt_set_jtag_for_mcu();
+	wmt_set_jtag_for_gps();
+
+#endif /* CONF_HIF_PMIC_TEST */
+
+#if (MTK_WCN_SINGLE_MODULE == 1)
+	HifAhbProbe();		/* only for test purpose without WMT module */
+
+#else
+
+	/* register WiFi function to WMT */
+	DBGLOG(INIT, INFO, "mtk_wcn_wmt_wlan_reg\n");
+	{
+		MTK_WCN_WMT_WLAN_CB_INFO WmtCb;
+
+		WmtCb.wlan_probe_cb = HifAhbProbe;
+		WmtCb.wlan_remove_cb = HifAhbRemove;
+		WmtCb.wlan_bus_cnt_get_cb = HifAhbBusCntGet;
+		WmtCb.wlan_bus_cnt_clr_cb = HifAhbBusCntClr;
+		mtk_wcn_wmt_wlan_reg(&WmtCb);
+	}
+#endif /* MTK_WCN_SINGLE_MODULE */
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called by OS platform device module.
+*
+* \param[in] PDev           Pointer to the platform device structure.
+*
+* \return 0
+*/
+/*----------------------------------------------------------------------------*/
+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev)
+{
+#if (MTK_WCN_SINGLE_MODULE == 0)
+	mtk_wcn_wmt_wlan_unreg();
+#endif /* MTK_WCN_SINGLE_MODULE */
+	return 0;
+}
+
+#ifdef CONFIG_PM
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called by OS platform device module.
+*
+* \param[in] PDev           Pointer to the platform device structure.
+* \param[in] Message
+*
+* \return 0
+*/
+/*----------------------------------------------------------------------------*/
+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message)
+{
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is called by OS platform device module.
+*
+* \param[in] PDev           Pointer to the platform device structure.
+*
+* \return 0
+*/
+/*----------------------------------------------------------------------------*/
+static int HifAhbPltmResume(IN struct platform_device *PDev)
+{
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+#endif /* CONF_HIF_DEV_MISC */
+
+#if (CONF_HIF_LOOPBACK_AUTO == 1)
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Trigger to do HIF loopback test.
+*
+* \param[in] arg   Pointer to the GLUE_INFO_T structure.
+*
+* \retval None
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifAhbLoopbkAuto(IN unsigned long arg)
+{
+
+	P_GLUE_INFO_T GlueInfo = (P_GLUE_INFO_T) arg;
+	GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo;
+
+	ASSERT(GlueInfo);
+
+	HIF_DBG(("[WiFi/HIF] Trigger to do loopback test...\n"));
+
+	set_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &HifInfo->HifLoopbkFlg);
+	wake_up_interruptible(&HifInfo->HifWaitq);
+
+}
+#endif /* CONF_HIF_LOOPBACK_AUTO */
+
+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo)
+{
+	GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo;
+	unsigned short j;
+
+	for (j = 0; j < 512; j++) {
+		DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(prHifInfo, CONN_MCU_CPUPCR));
+		if ((j + 1) % 16 == 0)
+			DBGLOG(INIT, WARN, "\n");
+	}
+}
+
+/* End of ahb.c */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c
new file mode 100644
index 0000000000000..6b719028ae934
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c
@@ -0,0 +1,31 @@
+/******************************************************************************
+*[File]             mt6516-evb.c
+*[Version]          v1.0
+*[Revision Date]    2010-03-01
+*[Author]
+*[Description]
+*    dummy file for build system
+*[Copyright]
+*    Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved.
+******************************************************************************/
+
+/*
+** Log: mt6516-evb.c
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 04 19 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * remove debug message
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**
+*/
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h
new file mode 100644
index 0000000000000..1507d5560040e
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h
@@ -0,0 +1,340 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1
+*/
+
+/*! \file   "hif.h"
+    \brief  Functions for the driver to register bus and setup the IRQ
+
+    Functions for the driver to register bus and setup the IRQ
+*/
+
+/*
+** Log: hif.h
+ *
+ * 11 01 2010 yarco.yang
+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
+ * Add GPIO debug function
+ *
+ * 10 19 2010 jeffrey.chang
+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK
+ * HIF by default
+ * Refine linux kernel module to the license of MTK and enable MTK HIF
+ *
+ * 08 18 2010 jeffrey.chang
+ * NULL
+ * support multi-function sdio
+ *
+ * 08 17 2010 cp.wu
+ * NULL
+ * add ENE SDIO host workaround for x86 linux platform.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\4 2009-10-20 17:38:28 GMT mtk01090
+**  Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests,
+**  and then stop hw.
+**  \main\maintrunk.MT5921\3 2009-09-28 20:19:20 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\2 2009-08-18 22:57:05 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\2 2008-09-22 23:18:17 GMT mtk01461
+**  Update driver for code review
+** Revision 1.1  2007/07/05 07:25:33  MTK01461
+** Add Linux initial code, modify doc, add 11BB, RF init code
+**
+** Revision 1.3  2007/06/27 02:18:51  MTK01461
+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
+**
+*/
+
+#ifndef _HIF_H
+#define _HIF_H
+
+#include "gl_typedef.h"
+#include "mtk_porting.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+#define CONF_MTK_AHB_DMA         1	/* PIO mode is default mode if DMA is disabled */
+
+#define CONF_HIF_DEV_MISC        0	/* register as misc device */
+#define CONF_HIF_LOOPBACK_AUTO   0	/* hif loopback test triggered by open() */
+				    /* only for development test */
+
+#define CONF_HIF_PMIC_TEST       0	/* test purpose: power on CONNSYS */
+
+#define CONF_HIF_DMA_INT         0	/* DMA interrupt mode */
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+extern phys_addr_t gConEmiPhyBase;
+extern BOOLEAN fgIsResetting;
+extern UINT_32 IsrCnt, IsrPassCnt;
+extern int kalDevLoopbkThread(IN void *data);
+
+#ifdef CONFIG_MTK_PMIC_MT6397
+#else
+#ifdef CONFIG_OF		/*for MT6752 */
+extern INT_32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT_32 enable);
+#else				/*for MT6572/82/92 */
+extern void upmu_set_vcn33_on_ctrl_wifi(UINT_32 val);
+#endif
+#endif
+
+#if (CONF_HIF_DEV_MISC == 1)
+#else
+/* extern INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_en); */
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#ifndef CONN_MCU_CONFIG_BASE
+#define CONN_MCU_CONFIG_BASE         0xF8070000	/* MT6572 */
+#endif /* CONN_MCU_CONFIG_BASE */
+
+#define CONSYS_CPUPCR_REG		    (CONN_MCU_CONFIG_BASE + 0x00000160)
+#define CONSYS_REG_READ(addr)       (*((volatile unsigned int *)(addr)))
+
+#define CONN_MCU_DRV_BASE                0x18070000
+#define CONN_MCU_REG_LENGTH              0x0200
+#define CONN_MCU_CPUPCR                  0x0160
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/* host interface's private data structure, which is attached to os glue
+** layer info structure.
+ */
+typedef struct _GL_HIF_DMA_OPS_T {	/* DMA Operators */
+	VOID (*DmaConfig)(IN VOID *HifInfo, IN VOID *Conf);
+
+	VOID (*DmaStart)(IN VOID *HifInfo);
+
+	VOID (*DmaStop)(IN VOID *HifInfo);
+
+	MTK_WCN_BOOL (*DmaPollStart)(IN VOID *HifInfo);
+
+	MTK_WCN_BOOL (*DmaPollIntr)(IN VOID *HifInfo);
+
+	VOID (*DmaAckIntr)(IN VOID *HifInfo);
+
+	VOID (*DmaClockCtrl)(IN UINT_32 FlgIsEnabled);
+
+	VOID (*DmaRegDump)(IN VOID *HifInfo);
+
+	VOID (*DmaReset)(IN VOID *HifInfo);
+
+} GL_HIF_DMA_OPS_T;
+
+typedef struct _GL_HIF_INFO_T {
+
+	/* General */
+	VOID *Dev;		/* struct device */
+
+#define MTK_CHIP_ID_6571    0x6571
+#define MTK_CHIP_ID_6572    0x6572
+#define MTK_CHIP_ID_6582    0x6582
+#define MTK_CHIP_ID_8127    0x8127
+#define MTK_CHIP_ID_6752    0x6752
+#define MTK_CHIP_ID_8163    0x8163
+#define MTK_CHIP_ID_6735    0x6735
+#define MTK_CHIP_ID_6580    0x6580
+#define MTK_CHIP_ID_6755    0x6755
+#define MTK_CHIP_ID_7623    0x7623
+
+	UINT_32 ChipID;
+
+	/* Control flag */
+	BOOLEAN fgIntReadClear;
+	BOOLEAN fgMbxReadClear;
+	BOOLEAN fgDmaEnable;	/* TRUE: DMA mode is used (default) */
+
+	/* HIF related */
+	UINT_8 *HifRegBaseAddr;	/* HIF register base */
+	UINT_8 *McuRegBaseAddr;	/* CONN MCU register base */
+
+#if (CONF_HIF_LOOPBACK_AUTO == 1)
+	struct timer_list HifTmrLoopbkFn;	/* HIF loopback test trigger timer */
+	wait_queue_head_t HifWaitq;
+	UINT_32 HifLoopbkFlg;
+	struct task_struct *HifTaskLoopbkFn;	/* HIF loopback test task */
+#endif				/* CONF_HIF_LOOPBACK_AUTO */
+
+#if (CONF_HIF_DMA_INT == 1)
+	wait_queue_head_t HifDmaWaitq;
+	UINT_32 HifDmaWaitFlg;
+#endif				/* CONF_HIF_DMA_INT */
+
+	/* DMA related */
+#define AP_DMA_HIF_LOCK(_lock)	/* spin_lock_bh(&(_lock)->DdmaLock) */
+#define AP_DMA_HIF_UNLOCK(_lock)	/* spin_unlock_bh(&(_lock)->DdmaLock) */
+	spinlock_t DdmaLock;	/* protect DMA access */
+
+	UINT_8 *DmaRegBaseAddr;	/* DMA register base */
+	GL_HIF_DMA_OPS_T *DmaOps;	/* DMA Operators */
+
+#if !defined(CONFIG_MTK_CLKMGR)
+	struct clk *clk_wifi_dma;
+#endif
+} GL_HIF_INFO_T, *P_GL_HIF_INFO_T;
+
+#define HIF_MOD_NAME                "AHB_SLAVE_HIF"
+
+#define HIF_DRV_BASE                0x180F0000
+#define HIF_DRV_LENGTH				0x005c
+
+typedef enum _MTK_WCN_HIF_BURST_LEN {
+	HIF_BURST_1DW = 0,
+	HIF_BURST_4DW,
+	HIF_BURST_8DW
+} MTK_WCN_HIF_BURST_LEN;
+
+typedef enum _MTK_WCN_HIF_TXRX_TARGET {
+	HIF_TARGET_TXD0 = 0,
+	HIF_TARGET_TXD1,
+	HIF_TARGET_RXD0,
+	HIF_TARGET_RXD1,
+	HIF_TARGET_WHISR
+} MTK_WCN_HIF_TXRX_TARGET;
+
+typedef enum _MTK_WCN_HIF_DMA_DIR {
+	HIF_DMA_DIR_TX = 0,
+	HIF_DMA_DIR_RX
+} MTK_WCN_HIF_DMA_DIR;
+
+typedef struct _MTK_WCN_HIF_DMA_CONF {
+	UINT_32 Count;
+	MTK_WCN_HIF_DMA_DIR Dir;
+	UINT_32 Burst;
+	UINT_32 Wsize;
+	UINT_32 Ratio;
+	UINT_32 Connect;
+	UINT_32 Fix_en;
+	ULONG Src;
+	ULONG Dst;
+} MTK_WCN_HIF_DMA_CONF;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define MCU_REG_READL(_hif, _addr)          \
+	    readl((volatile UINT_32 *)((_hif)->McuRegBaseAddr + _addr))
+
+/* PIO mode HIF register read/write */
+#define HIF_REG_READL(_hif, _addr)          \
+	    readl((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))
+
+#define HIF_REG_WRITEL(_hif, _addr, _val)   \
+	    writel(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr)))
+
+#define HIF_REG_WRITEB(_hif, _addr, _val)   \
+	    writeb(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr)))
+
+/* PIO mode DMA register read/write */
+#define HIF_DMAR_READL(_hif, _addr)          \
+	    readl((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr))
+
+#define HIF_DMAR_WRITEL(_hif, _addr, _val)   \
+	    writel(_val, ((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr)))
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+#ifndef MODULE_AHB_DMA
+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter);
+
+VOID HifRegDump(P_ADAPTER_T prAdapter);
+
+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter);
+
+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove);
+
+VOID glUnregisterBus(remove_card pfRemove);
+
+VOID glResetHif(GLUE_INFO_T *GlueInfo);
+
+VOID glSetHifInfo(P_GLUE_INFO_T prGlueInfo, ULONG ulCookie);
+
+VOID glClearHifInfo(P_GLUE_INFO_T prGlueInfo);
+
+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf);
+
+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT
+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo);
+#endif
+
+BOOLEAN glBusInit(PVOID pvData);
+
+VOID glBusRelease(PVOID pData);
+
+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie);
+
+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie);
+
+VOID glSetPowerState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 ePowerMode);
+
+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo);
+
+#endif /* MODULE_AHB_DMA */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Config GDMA TX/RX.
+*
+* \param[in] DmaRegBaseAddr     Pointer to the IO register base.
+* \param[in] Conf               Pointer to the DMA operator.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+VOID HifGdmaInit(GL_HIF_INFO_T *HifInfo);
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Config PDMA TX/RX.
+*
+* \param[in] DmaRegBaseAddr     Pointer to the IO register base.
+* \param[in] Conf               Pointer to the DMA operator.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _HIF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h
new file mode 100644
index 0000000000000..094c07f98eff2
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h
@@ -0,0 +1,154 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1
+*/
+
+/*! \file   "hif_gdma.h"
+    \brief  MARCO, definition, structure for GDMA.
+
+    MARCO, definition, structure for GDMA.
+*/
+
+/*
+** Log: hif_gdma.h
+ *
+ * 01 16 2013 vend_samp.lin
+ * Add AHB GDMA support
+ * 1) Initial version
+**
+*/
+
+#ifndef _HIF_GDMA_H
+#define _HIF_GDMA_H
+
+#include "mtk_porting.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _MTK_WCN_HIF_GDMA_BURST_LEN {
+	HIF_GDMA_BURST_1_8 = 0,
+	HIF_GDMA_BURST_2_8,
+	HIF_GDMA_BURST_3_8,
+	HIF_GDMA_BURST_4_8,
+	HIF_GDMA_BURST_5_8,
+	HIF_GDMA_BURST_6_8,
+	HIF_GDMA_BURST_7_8,
+	HIF_GDMA_BURST_8_8	/* same as HIF_GDMA_BURST_7_8 */
+} MTK_WCN_HIF_GDMA_BURST_LEN;
+
+typedef enum _MTK_WCN_HIF_GDMA_WRITE_LEN {
+	HIF_GDMA_WRITE_0 = 0,	/* transaction size is 1 byte */
+	HIF_GDMA_WRITE_1,	/* transaction size is 2 byte */
+	HIF_GDMA_WRITE_2,	/* transaction size is 4 byte */
+	HIF_GDMA_WRITE_3	/* transaction size is 1 byte */
+} MTK_WCN_HIF_GDMA_WRITE_LEN;
+
+typedef enum _MTK_WCN_HIF_GDMA_RATIO {
+	HIF_GDMA_RATIO_0 = 0,	/* 1/2 */
+	HIF_GDMA_RATIO_1	/* 1/1 */
+} MTK_WCN_HIF_GDMA_RATIO;
+
+typedef enum _MTK_WCN_HIF_GDMA_CONNECT {
+	HIF_GDMA_CONNECT_NO = 0,	/* no connect */
+	HIF_GDMA_CONNECT_SET1,	/* connect set1 (req/ack) */
+	HIF_GDMA_CONNECT_SET2,	/* connect set2 (req/ack) */
+	HIF_GDMA_CONNECT_SET3	/* connect set3 (req/ack) */
+} MTK_WCN_HIF_GDMA_CONNECT;
+
+/* reference to MT6572_AP_P_DMA_Spec.doc */
+#define AP_DMA_HIF_BASE             0x11000100
+
+#define AP_P_DMA_G_DMA_2_INT_FLAG   (0x0000)
+#define AP_P_DMA_G_DMA_2_CON        (0x0018)
+#define AP_P_DMA_G_DMA_2_CONNECT    (0x0034)
+#define AP_P_DMA_G_DMA_2_LEN1       (0x0024)
+#define AP_P_DMA_G_DMA_2_SRC_ADDR   (0x001C)
+#define AP_P_DMA_G_DMA_2_DST_ADDR   (0x0020)
+#define AP_P_DMA_G_DMA_2_INT_EN     (0x0004)
+#define AP_P_DMA_G_DMA_2_EN         (0x0008)
+#define AP_P_DMA_G_DMA_2_RST        (0x000C)
+#define AP_P_DMA_G_DMA_2_STOP       (0x0010)
+
+#define AP_DMA_HIF_0_LENGTH         0x0038
+
+/* AP_DMA_HIF_0_INT_FLAG */
+#define ADH_CR_FLAG_0               BIT(0)
+
+/* AP_DMA_HIF_0_INT_EN */
+#define ADH_CR_INTEN_FLAG_0         BIT(0)
+
+/* AP_DMA_HIF_0_EN */
+#define ADH_CR_EN                   BIT(0)
+#define ADH_CR_CONN_BUR_EN          BIT(1)
+
+/* AP_DMA_HIF_0_STOP */
+#define ADH_CR_PAUSE                BIT(1)
+#define ADH_CR_STOP                 BIT(0)
+
+/* AP_P_DMA_G_DMA_2_CON */
+#define ADH_CR_FLAG_FINISH          BIT(30)
+#define ADH_CR_RSIZE                BITS(28, 29)
+#define ADH_CR_RSIZE_OFFSET         28
+#define ADH_CR_WSIZE                BITS(24, 25)
+#define ADH_CR_WSIZE_OFFSET         24
+#define ADH_CR_BURST_LEN            BITS(16, 18)
+#define ADH_CR_BURST_LEN_OFFSET     16
+#define ADH_CR_WADDR_FIX_EN         BIT(3)
+#define ADH_CR_WADDR_FIX_EN_OFFSET  3
+#define ADH_CR_RADDR_FIX_EN         BIT(4)
+#define ADH_CR_RADDR_FIX_EN_OFFSET  4
+
+/* AP_P_DMA_G_DMA_2_CONNECT */
+#define ADH_CR_RATIO                BIT(3)
+#define ADH_CR_RATIO_OFFSET         3
+#define ADH_CR_DIR                  BIT(2)
+#define ADH_CR_DIR_OFFSET           2
+#define ADH_CR_CONNECT              BITS(0, 1)
+
+/* AP_DMA_HIF_0_LEN */
+#define ADH_CR_LEN                  BITS(0, 19)
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _HIF_GDMA_H */
+
+/* End of hif_gdma.h */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h
new file mode 100644
index 0000000000000..32224e8f17d85
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h
@@ -0,0 +1,141 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1
+*/
+
+/*! \file   "hif_pdma.h"
+    \brief  MARCO, definition, structure for PDMA.
+
+    MARCO, definition, structure for PDMA.
+*/
+
+/*
+** Log: hif_pdma.h
+ *
+ * 01 16 2013 vend_samp.lin
+ * Add AHB PDMA support
+ * 1) Initial version
+**
+*/
+
+#ifndef _HIF_PDMA_H
+#define _HIF_PDMA_H
+
+#include "mtk_porting.h"
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+typedef enum _MTK_WCN_HIF_PDMA_BURST_LEN {
+	HIF_PDMA_BURST_1_4 = 0,
+	HIF_PDMA_BURST_2_4,
+	HIF_PDMA_BURST_3_4,
+	HIF_PDMA_BURST_4_4
+} MTK_WCN_HIF_PDMA_BURST_LEN;
+
+/* reference to MT6572_AP_P_DMA_Spec.doc */
+#ifdef CONFIG_OF
+/*for MT6752*/
+#define AP_DMA_HIF_BASE             0x11000080
+#else
+/*for MT6572/82/92*/
+#define AP_DMA_HIF_BASE             0x11000180
+#endif
+
+#define AP_DMA_HIF_0_INT_FLAG       (0x0000)
+#define AP_DMA_HIF_0_INT_EN         (0x0004)
+#define AP_DMA_HIF_0_EN             (0x0008)
+#define AP_DMA_HIF_0_RST            (0x000C)
+#define AP_DMA_HIF_0_STOP           (0x0010)
+#define AP_DMA_HIF_0_FLUSH          (0x0014)
+#define AP_DMA_HIF_0_CON            (0x0018)
+#define AP_DMA_HIF_0_SRC_ADDR       (0x001C)
+#define AP_DMA_HIF_0_DST_ADDR       (0x0020)
+#define AP_DMA_HIF_0_LEN            (0x0024)
+#define AP_DMA_HIF_0_INT_BUF_SIZE   (0x0038)
+#define AP_DMA_HIF_0_DEBUG_STATUS   (0x0050)
+#define AP_DMA_HIF_0_SRC_ADDR2		(0x0054)
+#define AP_DMA_HIF_0_DST_ADDR2		(0x0058)
+
+#define AP_DMA_HIF_0_LENGTH         0x0080
+
+/* AP_DMA_HIF_0_INT_FLAG */
+#define ADH_CR_FLAG_0               BIT(0)
+
+/* AP_DMA_HIF_0_INT_EN */
+#define ADH_CR_INTEN_FLAG_0         BIT(0)
+
+/* AP_DMA_HIF_0_EN */
+#define ADH_CR_EN                   BIT(0)
+
+/* AP_DMA_HIF_0_RST */
+#define ADH_CR_HARD_RST             BIT(1)
+#define ADH_CR_WARM_RST             BIT(0)
+
+/* AP_DMA_HIF_0_STOP */
+#define ADH_CR_PAUSE                BIT(1)
+#define ADH_CR_STOP                 BIT(0)
+
+/* AP_DMA_HIF_0_FLUSH */
+#define ADH_CR_FLUSH                BIT(0)
+
+/* AP_DMA_HIF_0_CON */
+#define ADH_CR_BURST_LEN            BITS(16, 17)
+#define ADH_CR_BURST_LEN_OFFSET     16
+#define ADH_CR_SLOW_CNT             BITS(5, 14)
+#define ADH_CR_SLOW_EN              BIT(2)
+#define ADH_CR_FIX_EN               BIT(1)
+#define ADH_CR_FIX_EN_OFFSET        1
+#define ADH_CR_DIR                  BIT(0)
+
+/* AP_DMA_HIF_0_LEN */
+#define ADH_CR_LEN                  BITS(0, 19)
+
+/* AP_DMA_HIF_0_SRC_ADDR2 */
+#define ADH_CR_SRC_ADDR2		BIT(0)
+/* AP_DMA_HIF_0_DST_ADDR2 */
+#define ADH_CR_DST_ADDR2		BIT(0)
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+#endif /* _HIF_PDMA_H */
+
+/* End of hif_gdma.h */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h
new file mode 100644
index 0000000000000..91557137af9af
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h
@@ -0,0 +1,91 @@
+/* porting layer */
+/* Android */
+
+#ifndef _MTK_PORTING_H_
+#define _MTK_PORTING_H_
+
+#include <linux/kernel.h>	/* include stddef.h for NULL */
+
+#define CONF_MTK_AHB_DMA            1
+
+/* Type definition for signed integers */
+/*typedef signed char INT8, *PINT8;
+typedef signed short INT16, *PINT16;
+typedef signed int INT_32, *PINT32;*/
+
+/* Type definition for unsigned integers */
+/*typedef unsigned char UINT8, *PUINT8;
+typedef unsigned short UINT16, *PUINT16;
+typedef unsigned int UINT32, *PUINT32;*/
+
+#ifndef VOID
+/*typedef void VOID, *PVOID;*/
+#endif
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+#ifndef INTOUT
+#define INOUT
+#endif
+
+#ifndef TRUE
+#define TRUE        1
+#endif
+
+#ifndef FALSE
+#define FALSE       0
+#endif
+
+#ifndef BIT
+#define BIT(n)                          ((UINT_32) 1U << (n))
+#endif /* BIT */
+
+#ifndef BITS
+/* bits range: for example BITS(16,23) = 0xFF0000
+ *   ==>  (BIT(m)-1)   = 0x0000FFFF     ~(BIT(m)-1)   => 0xFFFF0000
+ *   ==>  (BIT(n+1)-1) = 0x00FFFFFF
+ */
+#define BITS(m, n)                       (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n)))
+#endif /* BIT */
+
+#ifndef BOOLEAN
+#define BOOLEAN         unsigned char
+#endif
+
+typedef int MTK_WCN_BOOL;
+#ifndef MTK_WCN_BOOL_TRUE
+#define MTK_WCN_BOOL_FALSE               ((MTK_WCN_BOOL) 0)
+#define MTK_WCN_BOOL_TRUE                ((MTK_WCN_BOOL) 1)
+#endif
+
+typedef int MTK_WCN_MUTEX;
+
+typedef int MTK_WCN_TIMER;
+
+/* system APIs */
+/* mutex */
+typedef MTK_WCN_MUTEX(*MUTEX_CREATE) (const char *const name);
+typedef INT_32(*MUTEX_DESTROY) (MTK_WCN_MUTEX mtx);
+typedef INT_32(*MUTEX_LOCK) (MTK_WCN_MUTEX mtx);
+typedef INT_32(*MUTEX_UNLOCK) (MTK_WCN_MUTEX mtx, unsigned long flags);
+/* debug */
+typedef INT_32(*DBG_PRINT) (const char *str, ...);
+typedef INT_32(*DBG_ASSERT) (INT_32 expr, const char *file, INT_32 line);
+/* timer */
+typedef void (*MTK_WCN_TIMER_CB) (void);
+typedef MTK_WCN_TIMER(*TIMER_CREATE) (const char *const name);
+typedef INT_32(*TIMER_DESTROY) (MTK_WCN_TIMER tmr);
+typedef INT_32(*TIMER_START) (MTK_WCN_TIMER tmr, UINT_32 timeout, MTK_WCN_TIMER_CB tmr_cb, void *param);
+typedef INT_32(*TIMER_STOP) (MTK_WCN_TIMER tmr);
+/* kernel lib */
+typedef void *(*SYS_MEMCPY) (void *dest, const void *src, UINT_32 n);
+typedef void *(*SYS_MEMSET) (void *s, INT_32 c, UINT_32 n);
+typedef INT_32(*SYS_SPRINTF) (char *str, const char *format, ...);
+
+#endif /* _MTK_PORTING_H_ */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c
new file mode 100644
index 0000000000000..94cc05ba32249
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c
@@ -0,0 +1,480 @@
+/******************************************************************************
+*[File]             ahb_pdma.c
+*[Version]          v1.0
+*[Revision Date]    2013-03-13
+*[Author]
+*[Description]
+*    The program provides AHB PDMA driver
+*[Copyright]
+*    Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved.
+******************************************************************************/
+
+/*
+** Log: ahb_pdma.c
+ *
+ * 03 13 2013 vend_samp.lin
+ * Add AHB PDMA support
+ * 1) Initial version
+**
+*/
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#define MODULE_AHB_DMA
+
+#include <linux/version.h>	/* constant of kernel version */
+
+#include <linux/kernel.h>	/* bitops.h */
+
+#include <linux/timer.h>	/* struct timer_list */
+#include <linux/jiffies.h>	/* jiffies */
+#include <linux/delay.h>	/* udelay and mdelay macro */
+
+#if 0
+#if CONFIG_ANDROID
+#include <linux/wakelock.h>
+#endif
+#endif
+
+#include <linux/irq.h>		/* IRQT_FALLING */
+
+#include <linux/netdevice.h>	/* struct net_device, struct net_device_stats */
+#include <linux/etherdevice.h>	/* for eth_type_trans() function */
+#include <linux/wireless.h>	/* struct iw_statistics */
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>	/* struct in_device */
+
+#include <linux/ip.h>		/* struct iphdr */
+
+#include <linux/string.h>	/* for memcpy()/memset() function */
+#include <linux/stddef.h>	/* for offsetof() macro */
+
+#include <linux/proc_fs.h>	/* The proc filesystem constants/structures */
+
+#include <linux/rtnetlink.h>	/* for rtnl_lock() and rtnl_unlock() */
+#include <linux/kthread.h>	/* kthread_should_stop(), kthread_run() */
+#include <asm/uaccess.h>	/* for copy_from_user() */
+#include <linux/fs.h>		/* for firmware download */
+#include <linux/vmalloc.h>
+
+#include <linux/kfifo.h>	/* for kfifo interface */
+#include <linux/cdev.h>		/* for cdev interface */
+
+#include <linux/firmware.h>	/* for firmware download */
+
+#include <linux/random.h>
+
+#include <asm/io.h>		/* readw and writew */
+
+#include <linux/module.h>
+
+#if defined(CONFIG_MTK_CLKMGR)
+#include <mach/mt_clkmgr.h>
+#else
+#include <linux/clk.h>
+#endif /* defined(CONFIG_MTK_CLKMGR) */
+
+#include "hif.h"
+#include "hif_pdma.h"
+#include "gl_os.h"
+
+/* #include <mach/emi_mpu.h> */
+
+/* #if (CONF_MTK_AHB_DMA == 1) */
+
+/* #define PDMA_DEBUG_SUP */
+
+#ifdef PDMA_DEBUG_SUP
+#define PDMA_DBG	pr_debug
+#else
+#define PDMA_DBG(_fmt, ...)
+#endif /* PDMA_DEBUG_SUP */
+
+#if !defined(CONFIG_MTK_CLKMGR)
+struct clk *g_clk_wifi_pdma;
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Conf);
+
+static VOID HifPdmaStart(IN void *HifInfoSrc);
+
+static VOID HifPdmaStop(IN void *HifInfoSrc);
+
+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc);
+
+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc);
+
+static VOID HifPdmaAckIntr(IN void *HifInfoSrc);
+
+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled);
+
+static VOID HifPdmaRegDump(IN void *HifInfoSrc);
+
+static VOID HifPdmaReset(IN void *HifInfoSrc);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+GL_HIF_DMA_OPS_T HifPdmaOps = {
+	.DmaConfig = HifPdmaConfig,
+	.DmaStart = HifPdmaStart,
+	.DmaStop = HifPdmaStop,
+	.DmaPollStart = HifPdmaPollStart,
+	.DmaPollIntr = HifPdmaPollIntr,
+	.DmaAckIntr = HifPdmaAckIntr,
+	.DmaClockCtrl = HifPdmaClockCtrl,
+	.DmaRegDump = HifPdmaRegDump,
+	.DmaReset = HifPdmaReset
+};
+
+/*******************************************************************************
+*                        P U B L I C   F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Config PDMA TX/RX.
+*
+* \param[in] prGlueInfo         Pointer to the GLUE_INFO_T structure.
+* \param[in] Conf               Pointer to the settings.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo)
+{
+	/* IO remap PDMA register memory */
+#ifdef AP_DMA_HIF_BASE
+#undef AP_DMA_HIF_BASE
+#define AP_DMA_HIF_BASE		0x11000180
+#endif
+	HifInfo->DmaRegBaseAddr = ioremap(AP_DMA_HIF_BASE, AP_DMA_HIF_0_LENGTH);
+
+	/* assign PDMA operators */
+	HifInfo->DmaOps = &HifPdmaOps;
+
+	/* enable PDMA mode */
+	HifInfo->fgDmaEnable = TRUE;
+
+	/* Set EMI protection here */
+#if 0
+#ifdef MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT
+	DBGLOG(INIT, INFO, "WIFI set EMI MPU for TEE project\n");
+	emi_mpu_set_region_protection(gConEmiPhyBase,
+				      gConEmiPhyBase + SZ_1M / 2,
+				      5, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN));
+#else
+	DBGLOG(INIT, INFO, "WIFI set EMI MPU for non-TEE project\n");
+	emi_mpu_set_region_protection(gConEmiPhyBase,
+				      gConEmiPhyBase + SZ_1M / 2,
+				      4, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN));
+#endif
+#endif
+
+#if !defined(CONFIG_MTK_CLKMGR)
+	g_clk_wifi_pdma = HifInfo->clk_wifi_dma;
+#endif
+
+	PDMA_DBG("PDMA> HifPdmaInit ok!\n");
+}
+
+/*******************************************************************************
+*                       P R I V A T E   F U N C T I O N S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Config PDMA TX/RX.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+* \param[in] Param              Pointer to the settings.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Param)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *) Param;
+	UINT32 RegVal;
+
+	/* Assign fixed value */
+	Conf->Burst = HIF_PDMA_BURST_4_4;	/* vs. HIF_BURST_4DW */
+	Conf->Fix_en = FALSE;
+
+	/* AP_P_DMA_G_DMA_2_CON */
+	PDMA_DBG("PDMA> Conf->Dir = %d\n", Conf->Dir);
+
+	/* AP_DMA_HIF_0_CON */
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_CON);
+	RegVal &= ~(ADH_CR_BURST_LEN | ADH_CR_FIX_EN | ADH_CR_DIR);
+	RegVal |= (((Conf->Burst << ADH_CR_BURST_LEN_OFFSET) & ADH_CR_BURST_LEN) |
+		   (Conf->Fix_en << ADH_CR_FIX_EN_OFFSET) | (Conf->Dir));
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_CON, RegVal);
+	PDMA_DBG("PDMA> AP_DMA_HIF_0_CON = 0x%08x\n", RegVal);
+
+	/* AP_DMA_HIF_0_SRC_ADDR */
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_SRC_ADDR, Conf->Src);
+	PDMA_DBG("PDMA> AP_DMA_HIF_0_SRC_ADDR = 0x%08lx\n", Conf->Src);
+
+	/* AP_DMA_HIF_0_DST_ADDR */
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_DST_ADDR, Conf->Dst);
+	PDMA_DBG("PDMA> AP_DMA_HIF_0_DST_ADDR = 0x%08lx\n", Conf->Dst);
+
+	/* AP_DMA_HIF_0_LEN */
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_LEN, (Conf->Count & ADH_CR_LEN));
+	PDMA_DBG("PDMA> AP_DMA_HIF_0_LEN = %u\n", (UINT_32)(Conf->Count & ADH_CR_LEN));
+
+}				/* End of HifPdmaConfig */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Start PDMA TX/RX.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifPdmaStart(IN void *HifInfoSrc)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	UINT32 RegVal;
+
+	/* Enable interrupt */
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN);
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0));
+
+	/* Start DMA */
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN);
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_EN, (RegVal | ADH_CR_EN));
+
+	PDMA_DBG("PDMA> HifPdmaStart...\n");
+
+}				/* End of HifPdmaStart */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Stop PDMA TX/RX.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifPdmaStop(IN void *HifInfoSrc)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	UINT32 RegVal;
+/* UINT32 pollcnt; */
+
+	/* Disable interrupt */
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN);
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal & ~(ADH_CR_INTEN_FLAG_0)));
+
+#if 0				/* DE says we donot need to do it */
+	/* Stop DMA */
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_STOP);
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_STOP, (RegVal | ADH_CR_STOP));
+
+	/* Polling START bit turn to 0 */
+	pollcnt = 0;
+	do {
+		RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN);
+		if (pollcnt++ > 100000)
+			; /* TODO: warm reset PDMA */
+	} while (RegVal & ADH_CR_EN);
+#endif
+
+}				/* End of HifPdmaStop */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Enable PDMA TX/RX.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	UINT32 RegVal;
+
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN);
+	return ((RegVal & ADH_CR_EN) != 0) ? TRUE : FALSE;
+
+}				/* End of HifPdmaPollStart */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Poll PDMA TX/RX done.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	UINT32 RegVal;
+
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG);
+	return ((RegVal & ADH_CR_FLAG_0) != 0) ? TRUE : FALSE;
+
+}				/* End of HifPdmaPollIntr */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Acknowledge PDMA TX/RX done.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifPdmaAckIntr(IN void *HifInfoSrc)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	UINT32 RegVal;
+
+	/* Write 0 to clear interrupt */
+	RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG);
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0));
+
+}				/* End of HifPdmaAckIntr */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Acknowledge PDMA TX/RX done.
+*
+* \param[in] FlgIsEnabled       TRUE: enable; FALSE: disable
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled)
+{
+#if !defined(CONFIG_MTK_CLKMGR)
+	int ret = 0;
+#endif
+#if defined(CONFIG_MTK_CLKMGR)
+	if (FlgIsEnabled == TRUE)
+		enable_clock(MT_CG_INFRA_APDMA, "WLAN");
+	else
+		disable_clock(MT_CG_INFRA_APDMA, "WLAN");
+#else
+	if (FlgIsEnabled == TRUE) {
+		ret = clk_prepare_enable(g_clk_wifi_pdma);
+		if (ret)
+			DBGLOG(INIT, TRACE, "[CCF]clk_prepare_enable ret= %d\n", ret);
+	} else {
+		clk_disable_unprepare(g_clk_wifi_pdma);
+	}
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Dump PDMA related registers.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifPdmaRegDump(IN void *HifInfoSrc)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	UINT32 RegId, RegVal;
+	UINT32 RegNum = 0;
+
+	DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE);
+	for (RegId = 0; RegId < AP_DMA_HIF_0_LENGTH; RegId += 4) {
+		RegVal = HIF_DMAR_READL(HifInfo, RegId);
+		DBGLOG(INIT, INFO, "0x%08x ", RegVal);
+
+		if (RegNum++ >= 3) {
+			DBGLOG(INIT, INFO, "\n");
+			DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE + RegId + 4);
+			RegNum = 0;
+		}
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Reset DMA.
+*
+* \param[in] HifInfo            Pointer to the GL_HIF_INFO_T structure.
+*
+* \retval NONE
+*/
+/*----------------------------------------------------------------------------*/
+static VOID HifPdmaReset(IN void *HifInfoSrc)
+{
+	GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc;
+	UINT32 LoopCnt;
+
+	/* do warm reset: DMA will wait for current traction finished */
+	DBGLOG(INIT, INFO, "\nDMA> do warm reset...\n");
+
+	/* normally, we need to sure that bit0 of AP_P_DMA_G_DMA_2_EN is 1 here */
+
+	HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x01);
+
+	for (LoopCnt = 0; LoopCnt < 10000; LoopCnt++) {
+		if (!HifPdmaPollStart(HifInfo))
+			break;	/* reset ok */
+	}
+
+	if (HifPdmaPollStart(HifInfo)) {
+		/* do hard reset because warm reset fails */
+		DBGLOG(INIT, INFO, "\nDMA> do hard reset...\n");
+		HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x02);
+		mdelay(1);
+		HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x00);
+	}
+}
+
+/* #endif */ /* CONF_MTK_AHB_DMA */
+
+/* End of ahb_pdma.c */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h
new file mode 100644
index 0000000000000..ec9f46bdab2e4
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h
@@ -0,0 +1,341 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_cfg80211.h#1
+*/
+
+/*! \file   gl_cfg80211.h
+    \brief  This file is for Portable Driver linux cfg80211 support.
+*/
+
+/*
+** Log: gl_cfg80211.h
+**
+** 09 03 2013 cp.wu
+** add path for reassociation
+**
+** 09 12 2012 wcpadmin
+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
+** .
+**
+** 08 30 2012 chinglan.wang
+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
+** .
+ *
+*/
+
+#ifndef _GL_CFG80211_H
+#define _GL_CFG80211_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+
+#include "gl_os.h"
+extern void wlanHandleSystemResume(void);
+extern void wlanHandleSystemSuspend(void);
+extern void p2pHandleSystemResume(void);
+extern void p2pHandleSystemSuspend(void);
+
+#if CFG_SUPPORT_WAPI
+extern UINT_8 keyStructBuf[1024];	/* add/remove key shared buffer */
+#else
+extern UINT_8 keyStructBuf[100];	/* add/remove key shared buffer */
+#endif
+
+extern struct delayed_work sched_workq;
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#if CONFIG_NL80211_TESTMODE
+#define NL80211_DRIVER_TESTMODE_VERSION 2
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+#if CONFIG_NL80211_TESTMODE
+
+typedef struct _NL80211_DRIVER_GET_STA_STATISTICS_PARAMS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	UINT_32 u4Version;
+	UINT_32 u4Flag;
+	UINT_8 aucMacAddr[MAC_ADDR_LEN];
+} NL80211_DRIVER_GET_STA_STATISTICS_PARAMS, *P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS;
+
+typedef struct _NL80211_DRIVER_POORLINK_PARAMS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	INT_8 cRssi;		/* cRssi=0 means it is a invalid value. */
+	UINT_8 ucLinkSpeed;	/* ucLinkSpeed=0 means it is a invalid value */
+	UINT_16 u2Reserved;
+} NL80211_DRIVER_POORLINK_PARAMS, *P_NL80211_DRIVER_POORLINK_PARAMS;
+
+typedef enum _ENUM_TESTMODE_STA_STATISTICS_ATTR {
+	NL80211_TESTMODE_STA_STATISTICS_INVALID = 0,
+	NL80211_TESTMODE_STA_STATISTICS_VERSION,
+	NL80211_TESTMODE_STA_STATISTICS_MAC,
+	NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE,
+	NL80211_TESTMODE_STA_STATISTICS_FLAG,
+
+	NL80211_TESTMODE_STA_STATISTICS_PER,
+	NL80211_TESTMODE_STA_STATISTICS_RSSI,
+	NL80211_TESTMODE_STA_STATISTICS_PHY_MODE,
+	NL80211_TESTMODE_STA_STATISTICS_TX_RATE,
+
+	NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT,
+
+	NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME,
+	NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME,
+	NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME,
+	NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME,
+
+	NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME,
+
+	NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY,
+	NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY,
+
+	NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY,
+	NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY,
+
+	/*
+	 * how many packages TX during statistics interval
+	 */
+	NL80211_TESTMODE_STA_STATISTICS_ENQUEUE,
+
+	/*
+	 * how many packages this TX during statistics interval
+	 */
+	NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE,
+
+	/*
+	 * how many packages dequeue during statistics interval
+	 */
+	NL80211_TESTMODE_STA_STATISTICS_DEQUEUE,
+
+	/*
+	 * how many packages this sta dequeue during statistics interval
+	 */
+	NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE,
+
+	/*
+	 * how many TC[0-3] resource back from firmware during
+	 * statistics interval
+	 */
+	NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY,
+	NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY,
+	NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY,
+	NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY,
+
+	NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT,
+	NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT,
+
+	NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY,
+
+	NL80211_TESTMODE_STA_STATISTICS_NUM
+} ENUM_TESTMODE_STA_STATISTICS_ATTR;
+typedef struct _NL80211_DRIVER_SET_NFC_PARAMS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	UINT_32 NFC_Enable;
+
+} NL80211_DRIVER_SET_NFC_PARAMS, *P_NL80211_DRIVER_SET_NFC_PARAMS;
+typedef struct _NL80211_DRIVER_GET_SCANDONE_PARAMS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	UINT_32 u4ScanDone;
+
+} NL80211_DRIVER_GET_SCANDONE_PARAMS, *P_NL80211_DRIVER_GET_SCANDONE_PARAMS;
+
+typedef enum _ENUM_TESTMODE_LINK_DETECTION_ATTR {
+	NL80211_TESTMODE_LINK_INVALID = 0,
+	NL80211_TESTMODE_LINK_TX_FAIL_CNT,
+	NL80211_TESTMODE_LINK_TX_RETRY_CNT,
+	NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT,
+	NL80211_TESTMODE_LINK_ACK_FAIL_CNT,
+	NL80211_TESTMODE_LINK_FCS_ERR_CNT,
+
+	NL80211_TESTMODE_LINK_DETECT_NUM,
+} ENUM_TESTMODE_LINK_DETECTION_ATTR;
+
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+
+typedef struct _NL80211_DRIVER_GET_LTE_PARAMS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	UINT_32 u4Version;
+	UINT_32 u4Flag;
+
+} NL80211_DRIVER_GET_LTE_PARAMS, *P_NL80211_DRIVER_GET_LTE_PARAMS;
+
+/*typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR{
+	NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0,
+	NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1,
+	NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34,
+	NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149,
+	NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184,
+
+	NL80211_TESTMODE_AVAILABLE_CHAN_NUM,
+}ENUM_TESTMODE_AVAILABLE_CHAN_ATTR;*/
+
+#endif
+#endif
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/* cfg80211 hooks */
+int
+mtk_cfg80211_change_iface(struct wiphy *wiphy,
+			  struct net_device *ndev, enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params);
+
+int
+mtk_cfg80211_add_key(struct wiphy *wiphy,
+		     struct net_device *ndev,
+		     u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params);
+
+int
+mtk_cfg80211_get_key(struct wiphy *wiphy,
+		     struct net_device *ndev,
+		     u8 key_index,
+		     bool pairwise,
+		     const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)
+);
+
+int
+mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr);
+
+int
+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast);
+
+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index);
+
+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo);
+
+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev,
+				const u8 *mac, struct station_parameters *params);
+
+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
+				const u8 *mac, struct station_parameters *params);
+
+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params);
+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac);
+
+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request);
+
+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme);
+
+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code);
+
+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params);
+
+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev);
+
+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout);
+
+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa);
+
+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa);
+
+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev);
+
+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   struct ieee80211_channel *chan,
+				   unsigned int duration, u64 *cookie);
+
+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie);
+
+int
+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy,
+		     struct wireless_dev *wdev,
+		     struct cfg80211_mgmt_tx_params *params,
+		     u64 *cookie);
+
+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy,
+				      IN struct wireless_dev *wdev,
+				      IN u16 frame_type, IN bool reg);
+
+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie);
+
+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req);
+
+int
+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy,
+			      IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request);
+
+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev,u64 reqid);
+
+#if CONFIG_NL80211_TESTMODE
+#if CFG_AUTO_CHANNEL_SEL_SUPPORT
+WLAN_STATUS
+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter,
+			   IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+
+int
+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo);
+#endif
+int
+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy,
+					 IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo);
+
+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo);
+
+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len);
+
+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len);
+#if CFG_SUPPORT_WAPI
+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len);
+#endif
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len);
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211
+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len);
+#endif
+
+#else
+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct"
+#endif
+int	mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
+int mtk_cfg80211_resume(struct wiphy *wiphy);
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _GL_CFG80211_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h
new file mode 100644
index 0000000000000..1406905095e64
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h
@@ -0,0 +1,1565 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_kal.h#1
+*/
+
+/*! \file   gl_kal.h
+    \brief  Declaration of KAL functions - kal*() which is provided by GLUE Layer.
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*
+** Log: gl_kal.h
+ *
+ * 06 13 2012 yuche.tsai
+ * NULL
+ * Update maintrunk driver.
+ * Add support for driver compose assoc request frame.
+ *
+ * 04 12 2012 terry.wu
+ * NULL
+ * Add AEE message support
+ * 1) Show AEE warning(red screen) if SDIO access error occurs
+
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Snc CFG80211 modification for ICS migration from branch 2.2.
+ *
+ * 02 06 2012 wh.su
+ * [WCXRP00001177] [MT6620 Wi-Fi][Driver][2.2] Adding the query channel filter for AP mode
+ * adding the channel query filter for AP mode.
+ *
+ * 01 02 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
+ *
+ * 12 13 2011 cm.chang
+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer
+ * Add wake lock if timer timeout value is smaller than 5 seconds
+ *
+ * 11 24 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adjust the code for Non-DBG and no XLOG.
+ *
+ * 11 22 2011 cp.wu
+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to asynchronous
+ * approach to avoid incomplete state termination
+ * 1. change RDD related compile option brace position.
+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state without join
+ * timeout timer ticking
+ * 3. otherwise, insert AIS_REQUEST into pending request queue
+ *
+ * 11 11 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * modify the xlog related code.
+ *
+ * 11 10 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Modify the QM xlog level and remove LOG_FUNC.
+ *
+ * 11 10 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Using the new XLOG define for dum Memory.
+ *
+ * 11 08 2011 eddie.chen
+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
+ * Add xlog function.
+ *
+ * 11 08 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters, eCurPsProf, for PS.
+ *
+ * 11 08 2011 cm.chang
+ * NULL
+ * Add RLM and CNM debug message for XLOG
+ *
+ * 11 07 2011 tsaiyuan.hsu
+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
+ * add debug counters and periodically dump counters for debugging.
+ *
+ * 11 03 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * Add dumpMemory8 at XLOG support.
+ *
+ * 11 02 2011 wh.su
+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
+ * adding the code for XLOG.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated
+ * network type
+ * include link.h for linux's port.
+ *
+ * 04 12 2011 cp.wu
+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated
+ * network type
+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected
+ *
+ * 04 01 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface
+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR
+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26
+ *
+ * 03 16 2011 cp.wu
+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
+ * after system running for a long period
+ * 1. pre-allocate physical continuous buffer while module is being loaded
+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
+ *
+ * The windows part remained the same as before, but added similar APIs to hide the difference.
+ *
+ * 03 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Add BOW table.
+ *
+ * 03 07 2011 terry.wu
+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
+ * Toggle non-standard debug messages to comments.
+ *
+ * 03 06 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Sync BOW Driver to latest person development branch version..
+ *
+ * 03 02 2011 cp.wu
+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after
+ * connection is built.
+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
+ *
+ * 02 24 2011 cp.wu
+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep
+ * long enough for specified interval such as 500ms
+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
+ * implementation of separate BT_OVER_WIFI data path.
+ *
+ * 01 04 2011 cp.wu
+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
+ * physically continuous memory demands
+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
+ *
+ * 12 31 2010 cp.wu
+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system
+ * scheduling
+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
+ * loaded
+ *
+ * 12 31 2010 jeffrey.chang
+ * [WCXRP00000332] [MT6620 Wi-Fi][Driver] add kal sleep function for delay which use blocking call
+ * modify the implementation of kalDelay to msleep
+ *
+ * 12 22 2010 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * 1. header file restructure for more clear module isolation
+ * 2. add function interface definition for implementing Service Discovery callbacks
+ *
+ * 11 30 2010 yuche.tsai
+ * NULL
+ * Invitation & Provision Discovery Indication.
+ *
+ * 11 26 2010 cp.wu
+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field
+ * checking
+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used
+ * to indicate user is attached
+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown
+ *
+ * 11 08 2010 cp.wu
+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+ * 10 04 2010 wh.su
+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
+ * add a kal function for set cipher.
+ *
+ * 10 04 2010 wh.su
+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
+ * fixed compiling error while enable p2p.
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 21 2010 cp.wu
+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
+ * associated
+ * Do a complete reset with STA-REC null checking for RF test re-entry
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
+ * Eliminate Linux Compile Warning
+ *
+ * 09 10 2010 wh.su
+ * NULL
+ * fixed the compiling error at win XP.
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 06 2010 wh.su
+ * NULL
+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 08 06 2010 cp.wu
+ * NULL
+ * driver hook modifications corresponding to ioctl interface change.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * [Wi-Fi Direct] add framework for driver hooks
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * modify kalSetEvent declaration
+ *
+ * 07 29 2010 cp.wu
+ * NULL
+ * simplify post-handling after TX_DONE interrupt is handled.
+ *
+ * 07 23 2010 cp.wu
+ *
+ * 1) re-enable AIS-FSM beacon timeout handling.
+ * 2) scan done API revised
+ *
+ * 07 23 2010 jeffrey.chang
+ *
+ * fix kal header file
+ *
+ * 07 22 2010 jeffrey.chang
+ *
+ * use different spin lock for security frame
+ *
+ * 07 22 2010 jeffrey.chang
+ *
+ * add new spinlock
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * add kal api for scanning done
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * modify cmd/data path for new design
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * add new kal api
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * Linux port modification
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 21 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * change MAC address updating logic.
+ *
+ * 06 18 2010 cm.chang
+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
+ *
+ * 06 11 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * 1) migrate assoc.c.
+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
+ * 3) add configuration options for CNM_MEM and RSN modules
+ * 4) add data path for management frames
+ * 5) eliminate rPacketInfo of MSDU_INFO_T
+ *
+ * 06 07 2010 cp.wu
+ * [WPD00003833][MT6620 and MT5931] Driver migration
+ * gl_kal merged
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic handling framework for wireless extension ioctls.
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl for controlling p2p scan phase parameters
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * fill network type field while doing frame identification.
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement basic wi-fi direct framework
+ *
+ * 05 07 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic framework for implementating P2P driver hook.
+ *
+ * 05 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * modify kalMemAlloc method
+ *
+ * 04 28 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change prefix for data structure used to communicate with 802.11 PAL
+ * to avoid ambiguous naming with firmware interface
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add multiple physical link support
+ *
+ * 04 27 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * follow Linux's firmware framework, and remove unused kal API
+ *
+ * 04 22 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * when acquiring driver-own, wait for up to 8 seconds.
+ *
+ * 04 22 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ *
+ * 1) modify rx path code for supporting Wi-Fi direct
+ * 2) modify config.h since Linux dont need to consider retaining packet
+ *
+ * 04 21 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add for private ioctl support
+ *
+ * 04 20 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL
+ *  * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well.
+ *
+ * 04 14 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * information buffer for query oid/ioctl is now buffered in prCmdInfo
+ *  *  *  *  *  *  *  * instead of glue-layer variable to improve multiple oid/ioctl capability
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *    capability
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) add spinlock
+ *  *  * 2) add KAPI for handling association info
+ *
+ * 04 09 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * adding firmware download KAPI
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * finish non-glue layer access to glue variables
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * accessing to firmware load/start address, and access to OID handling information
+ *  *  *  * are now handled in glue layer
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  *  *  *  *  *  *  * are done in adapter layer.
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer.
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) for some OID, never do timeout expiration
+ *  *  *  * 2) add 2 kal API for later integration
+ *
+ * 03 30 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * emulate NDIS Pending OID facility
+ *
+ * 03 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * adding firmware download KAPI
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\41 2009-09-28 20:19:23 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\40 2009-08-18 22:57:09 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\39 2009-06-23 23:19:15 GMT mtk01090
+**  Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
+**  \main\maintrunk.MT5921\38 2009-02-09 14:03:17 GMT mtk01090
+**  Add KAL function kalDevSetPowerState(). It is not implemented yet. Only add an empty macro.
+**
+**  \main\maintrunk.MT5921\37 2009-01-22 13:05:59 GMT mtk01088
+**  new defeine to got 1x value at packet reserved field
+**  \main\maintrunk.MT5921\36 2008-12-08 16:15:02 GMT mtk01461
+**  Add kalQueryValidBufferLength() macro
+**  \main\maintrunk.MT5921\35 2008-11-13 20:33:15 GMT mtk01104
+**  Remove lint warning
+**  \main\maintrunk.MT5921\34 2008-10-22 11:05:52 GMT mtk01461
+**  Remove unused macro
+**  \main\maintrunk.MT5921\33 2008-10-16 15:48:17 GMT mtk01461
+**  Update driver to fix lint warning
+**  \main\maintrunk.MT5921\32 2008-09-02 11:50:51 GMT mtk01461
+**  SPIN_LOCK_SDIO_DDK_TX_QUE
+**  \main\maintrunk.MT5921\31 2008-08-29 15:58:30 GMT mtk01088
+**  remove non-used function for code refine
+**  \main\maintrunk.MT5921\30 2008-08-21 00:33:29 GMT mtk01461
+**  Update for Driver Review
+**  \main\maintrunk.MT5921\29 2008-06-19 13:29:14 GMT mtk01425
+**  1. Add declaration of SPIN_LOCK_SDIO_DDK_TX_QUE and SPIN_LOCK_SDIO_DDK_RX_QUE
+**  \main\maintrunk.MT5921\28 2008-05-30 20:27:34 GMT mtk01461
+**  Rename KAL function
+**  \main\maintrunk.MT5921\27 2008-05-30 14:42:05 GMT mtk01461
+**  Remove WMM Assoc Flag in KAL
+**  \main\maintrunk.MT5921\26 2008-05-29 14:15:18 GMT mtk01084
+**  remove un-used function
+**  \main\maintrunk.MT5921\25 2008-04-23 14:02:20 GMT mtk01084
+**  modify KAL port access function prototype
+**  \main\maintrunk.MT5921\24 2008-04-17 23:06:41 GMT mtk01461
+**  Add iwpriv support for AdHocMode setting
+**  \main\maintrunk.MT5921\23 2008-04-08 15:38:50 GMT mtk01084
+**  add KAL function to setting pattern search function enable/ disable
+**  \main\maintrunk.MT5921\22 2008-03-26 15:34:48 GMT mtk01461
+**  Add update MAC address func
+**  \main\maintrunk.MT5921\21 2008-03-18 15:56:15 GMT mtk01084
+**  update ENUM_NIC_INITIAL_PARAM_E
+**  \main\maintrunk.MT5921\20 2008-03-18 11:49:28 GMT mtk01084
+**  update function for initial value access
+**  \main\maintrunk.MT5921\19 2008-03-18 10:21:31 GMT mtk01088
+**  use kal update associate request at linux
+**  \main\maintrunk.MT5921\18 2008-03-14 18:03:41 GMT mtk01084
+**  refine register and port access function
+**  \main\maintrunk.MT5921\17 2008-03-11 14:51:02 GMT mtk01461
+**  Add copy_to(from)_user macro
+**  \main\maintrunk.MT5921\16 2008-03-06 23:42:21 GMT mtk01385
+**  1. add Query Registry Mac address function.
+**  \main\maintrunk.MT5921\15 2008-02-26 09:48:04 GMT mtk01084
+**  modify KAL set network address/ checksum offload part
+**  \main\maintrunk.MT5921\14 2008-01-09 17:54:58 GMT mtk01084
+**  Modify the argument of kalQueryPacketInfo
+**  \main\maintrunk.MT5921\13 2007-11-29 02:05:20 GMT mtk01461
+**  Fix Windows RX multiple packet retain problem
+**  \main\maintrunk.MT5921\12 2007-11-26 19:43:45 GMT mtk01461
+**  Add OS_TIMESTAMP macro
+**
+**  \main\maintrunk.MT5921\11 2007-11-09 16:36:15 GMT mtk01425
+**  1. Modify for CSUM offloading with Tx Fragment
+**  \main\maintrunk.MT5921\10 2007-11-07 18:38:37 GMT mtk01461
+**  Add Tx Fragmentation Support
+**  \main\maintrunk.MT5921\9 2007-11-06 19:36:50 GMT mtk01088
+**  add the WPS related code
+**  \main\maintrunk.MT5921\8 2007-11-02 01:03:57 GMT mtk01461
+**  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
+** Revision 1.4  2007/07/05 07:25:33  MTK01461
+** Add Linux initial code, modify doc, add 11BB, RF init code
+**
+** Revision 1.3  2007/06/27 02:18:50  MTK01461
+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
+**
+** Revision 1.2  2007/06/25 06:16:23  MTK01461
+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
+**
+*/
+
+#ifndef _GL_KAL_H
+#define _GL_KAL_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "config.h"
+#include "gl_typedef.h"
+#include "gl_os.h"
+#include "link.h"
+#include "nic/mac.h"
+#include "nic/wlan_def.h"
+#include "wlan_lib.h"
+#include "wlan_oid.h"
+#include "gl_wext_priv.h"
+#include <asm/div64.h>
+
+#if CFG_ENABLE_BT_OVER_WIFI
+#include "nic/bow.h"
+#endif
+
+#if DBG
+extern int allocatedMemSize;
+#endif
+
+#if CFG_SUPPORT_MET_PROFILING
+#include "linux/kallsyms.h"
+#include <linux/ftrace_event.h>
+#endif
+
+extern BOOLEAN fgIsUnderSuspend;
+extern UINT_32 TaskIsrCnt;
+extern BOOLEAN fgIsResetting;
+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev);
+extern UINT_32 u4MemAllocCnt, u4MemFreeCnt;
+
+
+extern struct delayed_work sched_workq;
+
+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT
+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID);
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* #define USEC_PER_MSEC   (1000) */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_SPIN_LOCK_CATEGORY_E {
+	SPIN_LOCK_FSM = 0,
+
+	/* FIX ME */
+	SPIN_LOCK_RX_QUE,
+	SPIN_LOCK_TX_QUE,
+	SPIN_LOCK_CMD_QUE,
+	SPIN_LOCK_TX_RESOURCE,
+	SPIN_LOCK_CMD_RESOURCE,
+	SPIN_LOCK_QM_TX_QUEUE,
+	SPIN_LOCK_CMD_PENDING,
+	SPIN_LOCK_CMD_SEQ_NUM,
+	SPIN_LOCK_TX_MSDU_INFO_LIST,
+	SPIN_LOCK_TXING_MGMT_LIST,
+	SPIN_LOCK_TX_SEQ_NUM,
+	SPIN_LOCK_TX_COUNT,
+	SPIN_LOCK_TXS_COUNT,
+	/* end    */
+	SPIN_LOCK_TX,
+	SPIN_LOCK_IO_REQ,
+	SPIN_LOCK_INT,
+
+	SPIN_LOCK_MGT_BUF,
+	SPIN_LOCK_MSG_BUF,
+	SPIN_LOCK_STA_REC,
+
+	SPIN_LOCK_MAILBOX,
+	SPIN_LOCK_TIMER,
+
+	SPIN_LOCK_BOW_TABLE,
+
+	SPIN_LOCK_EHPI_BUS,	/* only for EHPI */
+	SPIN_LOCK_NET_DEV,
+	SPIN_LOCK_NUM
+} ENUM_SPIN_LOCK_CATEGORY_E;
+
+/* event for assoc information update */
+typedef struct _EVENT_ASSOC_INFO {
+	UINT_8 ucAssocReq;	/* 1 for assoc req, 0 for assoc rsp */
+	UINT_8 ucReassoc;	/* 0 for assoc, 1 for reassoc */
+	UINT_16 u2Length;
+	PUINT_8 pucIe;
+} EVENT_ASSOC_INFO, *P_EVENT_ASSOC_INFO;
+
+typedef enum _ENUM_KAL_NETWORK_TYPE_INDEX_T {
+	KAL_NETWORK_TYPE_AIS_INDEX = 0,
+#if CFG_ENABLE_WIFI_DIRECT
+	KAL_NETWORK_TYPE_P2P_INDEX,
+#endif
+#if CFG_ENABLE_BT_OVER_WIFI
+	KAL_NETWORK_TYPE_BOW_INDEX,
+#endif
+	KAL_NETWORK_TYPE_INDEX_NUM
+} ENUM_KAL_NETWORK_TYPE_INDEX_T;
+
+typedef enum _ENUM_KAL_MEM_ALLOCATION_TYPE_E {
+	PHY_MEM_TYPE,		/* physically continuous */
+	VIR_MEM_TYPE,		/* virtually continuous */
+	MEM_TYPE_NUM
+} ENUM_KAL_MEM_ALLOCATION_TYPE;
+
+#if CONFIG_ANDROID		/* Defined in Android kernel source */
+typedef struct wake_lock KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T;
+#else
+typedef UINT_32 KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T;
+#endif
+
+#if CFG_SUPPORT_AGPS_ASSIST
+typedef enum _ENUM_MTK_AGPS_ATTR {
+	MTK_ATTR_AGPS_INVALID,
+	MTK_ATTR_AGPS_CMD,
+	MTK_ATTR_AGPS_DATA,
+	MTK_ATTR_AGPS_IFINDEX,
+	MTK_ATTR_AGPS_IFNAME,
+	MTK_ATTR_AGPS_MAX
+} ENUM_MTK_CCX_ATTR;
+
+typedef enum _ENUM_AGPS_EVENT {
+	AGPS_EVENT_WLAN_ON,
+	AGPS_EVENT_WLAN_OFF,
+	AGPS_EVENT_WLAN_AP_LIST,
+	WIFI_EVENT_CHIP_RESET,
+} ENUM_CCX_EVENT;
+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen);
+#endif
+
+struct KAL_HALT_CTRL_T {
+	struct semaphore lock;
+	struct task_struct *owner;
+	BOOLEAN fgHalt;
+	BOOLEAN fgHeldByKalIoctl;
+	OS_SYSTIME u4HoldStart;
+};
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*----------------------------------------------------------------------------*/
+/* Macros of bit operation                                                    */
+/*----------------------------------------------------------------------------*/
+#define KAL_SET_BIT(bitOffset, value)             set_bit(bitOffset, &value)
+#define KAL_CLR_BIT(bitOffset, value)             clear_bit(bitOffset, &value)
+#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value)  test_and_clear_bit(bitOffset, &value)
+#define KAL_TEST_BIT(bitOffset, value)            test_bit(bitOffset, &value)
+
+/*----------------------------------------------------------------------------*/
+/* Macros of SPIN LOCK operations for using in Driver Layer                   */
+/*----------------------------------------------------------------------------*/
+#define KAL_SPIN_LOCK_DECLARATION()             unsigned long __u4Flags
+
+#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory)   \
+	    kalAcquireSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, &__u4Flags)
+
+#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory)   \
+	    kalReleaseSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, __u4Flags)
+
+/*----------------------------------------------------------------------------*/
+/* Macros for accessing Reserved Fields of native packet                      */
+/*----------------------------------------------------------------------------*/
+#define KAL_GET_PKT_QUEUE_ENTRY(_p)             GLUE_GET_PKT_QUEUE_ENTRY(_p)
+#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry)   GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry)
+#define KAL_GET_PKT_TID(_p)                     GLUE_GET_PKT_TID(_p)
+#define KAL_GET_PKT_IS1X(_p)                    GLUE_GET_PKT_IS1X(_p)
+#define KAL_GET_PKT_HEADER_LEN(_p)              GLUE_GET_PKT_HEADER_LEN(_p)
+#define KAL_GET_PKT_PAYLOAD_LEN(_p)             GLUE_GET_PKT_PAYLOAD_LEN(_p)
+#define KAL_GET_PKT_ARRIVAL_TIME(_p)            GLUE_GET_PKT_ARRIVAL_TIME(_p)
+
+/*----------------------------------------------------------------------------*/
+/* Macros of wake_lock operations for using in Driver Layer                   */
+/*----------------------------------------------------------------------------*/
+#if CONFIG_ANDROID		/* Defined in Android kernel source */
+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \
+	wake_lock_init(_prWakeLock, WAKE_LOCK_SUSPEND, _pcName)
+
+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \
+	wake_lock_destroy(_prWakeLock)
+
+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \
+	wake_lock(_prWakeLock)
+
+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \
+	wake_lock_timeout(_prWakeLock, _u4Timeout)
+
+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \
+	wake_unlock(_prWakeLock)
+
+#else
+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName)
+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock)
+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock)
+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout)
+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock)
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Cache memory allocation
+*
+* \param[in] u4Size Required memory size.
+* \param[in] eMemType  Memory allocation type
+*
+* \return Pointer to allocated memory
+*         or NULL
+*/
+/*----------------------------------------------------------------------------*/
+#if DBG
+#define kalMemAlloc(u4Size, eMemType) ({ \
+	void *pvAddr; \
+	if (eMemType == PHY_MEM_TYPE) { \
+		pvAddr = kmalloc(u4Size, GFP_KERNEL); \
+	} \
+	else { \
+		pvAddr = vmalloc(u4Size); \
+	} \
+	if (pvAddr) {   \
+		allocatedMemSize += u4Size;   \
+		DBGLOG(INIT, INFO, "%p(%u) allocated (%s:%s)\n", \
+			pvAddr, (UINT_32)u4Size, __FILE__, __func__); \
+	} \
+	pvAddr; \
+})
+#else
+#define kalMemAlloc(u4Size, eMemType) ({ \
+	void *pvAddr; \
+	if (eMemType == PHY_MEM_TYPE) { \
+		pvAddr = kmalloc(u4Size, GFP_KERNEL); \
+	} \
+	else { \
+		pvAddr = vmalloc(u4Size); \
+	} \
+	pvAddr; \
+})
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Free allocated cache memory
+*
+* \param[in] pvAddr Required memory size.
+* \param[in] eMemType  Memory allocation type
+* \param[in] u4Size Allocated memory size.
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+#if DBG
+#define kalMemFree(pvAddr, eMemType, u4Size) \
+{   \
+	if (pvAddr) { \
+		allocatedMemSize -= u4Size; \
+		DBGLOG(INIT, INFO, "%p(%u) freed (%s:%s)\n", \
+			pvAddr, (UINT_32)u4Size, __FILE__, __func__);  \
+	} \
+	if (eMemType == PHY_MEM_TYPE) { \
+		kfree(pvAddr); \
+	} \
+	else { \
+		vfree(pvAddr); \
+	} \
+}
+#else
+#define kalMemFree(pvAddr, eMemType, u4Size) \
+{   \
+	if (eMemType == PHY_MEM_TYPE) { \
+		kfree(pvAddr); \
+	} \
+	else { \
+		vfree(pvAddr); \
+	} \
+}
+#endif
+
+#define kalUdelay(u4USec)                           udelay(u4USec)
+
+#define kalMdelay(u4MSec)                           mdelay(u4MSec)
+#define kalMsleep(u4MSec)                           msleep(u4MSec)
+
+/* Copy memory from user space to kernel space */
+#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N)    copy_from_user(_pvTo, _pvFrom, _u4N)
+
+/* Copy memory from kernel space to user space */
+#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N)      copy_to_user(_pvTo, _pvFrom, _u4N)
+
+/* Copy memory block with specific size */
+#define kalMemCopy(pvDst, pvSrc, u4Size)            memcpy(pvDst, pvSrc, u4Size)
+
+/* Set memory block with specific pattern */
+#define kalMemSet(pvAddr, ucPattern, u4Size)        memset(pvAddr, ucPattern, u4Size)
+
+/* Compare two memory block with specific length.
+ * Return zero if they are the same.
+ */
+#define kalMemCmp(pvAddr1, pvAddr2, u4Size)         memcmp(pvAddr1, pvAddr2, u4Size)
+
+/* Zero specific memory block */
+#define kalMemZero(pvAddr, u4Size)                  memset(pvAddr, 0, u4Size)
+
+/* string operation */
+#define kalStrCpy(dest, src)                         strcpy(dest, src)
+#define kalStrnCpy(dest, src, n)                      strncpy(dest, src, n)
+#define kalStrCmp(ct, cs)                            strcmp(ct, cs)
+#define kalStrnCmp(ct, cs, n)                         strncmp(ct, cs, n)
+#define kalStrChr(s, c)                              strchr(s, c)
+#define kalStrrChr(s, c)                             strrchr(s, c)
+#define kalStrnChr(s, n, c)                           strnchr(s, n, c)
+#define kalStrLen(s)                                strlen(s)
+#define kalStrnLen(s, b)                             strnlen(s, b)
+//#define kalStrniCmp(s1, s2, n)                          strnicmp(s1, s2, n)
+#define kalStrniCmp(s1, s2, n)                          strncasecmp(s1, s2, n)
+#define strnicmp(s1, s2, n)                              strncasecmp(s1, s2, n)
+/* #define kalStrtoul(cp, endp, base)                    simple_strtoul(cp, endp, base)
+#define kalStrtol(cp, endp, base)                     simple_strtol(cp, endp, base) */
+#define kalkStrtou32(cp, base, resp)                   kstrtou32(cp, base, resp)
+#define kalkStrtos32(cp, base, resp)                    kstrtos32(cp, base, resp)
+#define kalSnprintf(buf, size, fmt, ...)              snprintf(buf, size, fmt, __VA_ARGS__)
+#define kalSprintf(buf, fmt, ...)                     sprintf(buf, fmt, __VA_ARGS__)
+/* remove for AOSP */
+/* #define kalSScanf(buf, fmt, ...)                      sscanf(buf, fmt, __VA_ARGS__) */
+#define kalStrStr(ct, cs)                            strstr(ct, cs)
+#define kalStrSep(s, ct)                            strsep(s, ct)
+#define kalStrCat(dest, src)                         strcat(dest, src)
+
+/* defined for wince sdio driver only */
+#if defined(_HIF_SDIO)
+#define kalDevSetPowerState(prGlueInfo, ePowerMode) glSetPowerState(prGlueInfo, ePowerMode)
+#else
+#define kalDevSetPowerState(prGlueInfo, ePowerMode)
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Notify OS with SendComplete event of the specific packet. Linux should
+*        free packets here.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] pvPacket       Pointer of Packet Handle
+* \param[in] status         Status Code for OS upper layer
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+#define kalSendComplete(prGlueInfo, pvPacket, status)   \
+	    kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket)
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is used to locate the starting address of incoming ethernet
+*        frame for skb.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] pvPacket       Pointer of Packet Handle
+*
+* \return starting address of ethernet frame buffer.
+*/
+/*----------------------------------------------------------------------------*/
+#define kalQueryBufferPointer(prGlueInfo, pvPacket)     \
+	    ((PUINT_8)((struct sk_buff *)pvPacket)->data)
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is used to query the length of valid buffer which is accessible during
+*         port read/write.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] pvPacket       Pointer of Packet Handle
+*
+* \return starting address of ethernet frame buffer.
+*/
+/*----------------------------------------------------------------------------*/
+#define kalQueryValidBufferLength(prGlueInfo, pvPacket)     \
+	    ((UINT_32)((struct sk_buff *)pvPacket)->end -  \
+	     (UINT_32)((struct sk_buff *)pvPacket)->data)
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This function is used to copy the entire frame from skb to the destination
+*        address in the input parameter.
+*
+* \param[in] prGlueInfo     Pointer of GLUE Data Structure
+* \param[in] pvPacket       Pointer of Packet Handle
+* \param[in] pucDestBuffer  Destination Address
+*
+* \return -
+*/
+/*----------------------------------------------------------------------------*/
+#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer)   \
+	do {struct sk_buff *skb = (struct sk_buff *)pvPacket; \
+	memcpy(pucDestBuffer, skb->data, skb->len); } while (0)
+
+#define kalGetTimeTick()                            jiffies_to_msecs(jiffies)
+
+#define kalPrint                                    pr_debug
+
+#if !DBG
+#define AIS_ERROR_LOGFUNC(_Fmt...)
+#define AIS_WARN_LOGFUNC(_Fmt...)
+#define AIS_INFO_LOGFUNC(_Fmt...)
+#define AIS_STATE_LOGFUNC(_Fmt...)
+#define AIS_EVENT_LOGFUNC(_Fmt...)
+#define AIS_TRACE_LOGFUNC(_Fmt...)
+#define AIS_LOUD_LOGFUNC(_Fmt...)
+#define AIS_TEMP_LOGFUNC(_Fmt...)
+
+#define INTR_ERROR_LOGFUNC(_Fmt...)
+#define INTR_WARN_LOGFUNC(_Fmt...)
+#define INTR_INFO_LOGFUNC(_Fmt...)
+#define INTR_STATE_LOGFUNC(_Fmt...)
+#define INTR_EVENT_LOGFUNC(_Fmt...)
+#define INTR_TRACE_LOGFUNC(_Fmt...)
+#define INTR_LOUD_LOGFUNC(_Fmt...)
+#define INTR_TEMP_LOGFUNC(_Fmt...)
+
+#define INIT_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define INIT_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define INIT_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define INIT_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define INIT_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define INIT_TRACE_LOGFUNC(_Fmt...)
+#define INIT_LOUD_LOGFUNC(_Fmt...)
+#define INIT_TEMP_LOGFUNC(_Fmt...)
+
+#define AAA_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define AAA_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define AAA_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define AAA_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define AAA_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define AAA_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define AAA_LOUD_LOGFUNC(_Fmt...)
+#define AAA_TEMP_LOGFUNC(_Fmt...)
+
+#define ROAMING_ERROR_LOGFUNC(_Fmt...)
+#define ROAMING_WARN_LOGFUNC(_Fmt...)
+#define ROAMING_INFO_LOGFUNC(_Fmt...)
+#define ROAMING_STATE_LOGFUNC(_Fmt...)
+#define ROAMING_EVENT_LOGFUNC(_Fmt...)
+#define ROAMING_TRACE_LOGFUNC(_Fmt...)
+#define ROAMING_LOUD_LOGFUNC(_Fmt...)
+#define ROAMING_TEMP_LOGFUNC(_Fmt...)
+
+#define REQ_ERROR_LOGFUNC(_Fmt...)
+#define REQ_WARN_LOGFUNC(_Fmt...)
+#define REQ_INFO_LOGFUNC(_Fmt...)
+#define REQ_STATE_LOGFUNC(_Fmt...)
+#define REQ_EVENT_LOGFUNC(_Fmt...)
+#define REQ_TRACE_LOGFUNC(_Fmt...)
+#define REQ_LOUD_LOGFUNC(_Fmt...)
+#define REQ_TEMP_LOGFUNC(_Fmt...)
+
+#define TX_ERROR_LOGFUNC(_Fmt...)
+#define TX_WARN_LOGFUNC(_Fmt...)
+#define TX_INFO_LOGFUNC(_Fmt...)
+#define TX_STATE_LOGFUNC(_Fmt...)
+#define TX_EVENT_LOGFUNC(_Fmt...)
+#define TX_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define TX_LOUD_LOGFUNC(_Fmt...)
+#define TX_TEMP_LOGFUNC(_Fmt...)
+
+#define RX_ERROR_LOGFUNC(_Fmt...)
+#define RX_WARN_LOGFUNC(_Fmt...)
+#define RX_INFO_LOGFUNC(_Fmt...)
+#define RX_STATE_LOGFUNC(_Fmt...)
+#define RX_EVENT_LOGFUNC(_Fmt...)
+#define RX_TRACE_LOGFUNC(_Fmt...)
+#define RX_LOUD_LOGFUNC(_Fmt...)
+#define RX_TEMP_LOGFUNC(_Fmt...)
+
+#define RFTEST_ERROR_LOGFUNC(_Fmt...)
+#define RFTEST_WARN_LOGFUNC(_Fmt...)
+#define RFTEST_INFO_LOGFUNC(_Fmt...)
+#define RFTEST_STATE_LOGFUNC(_Fmt...)
+#define RFTEST_EVENT_LOGFUNC(_Fmt...)
+#define RFTEST_TRACE_LOGFUNC(_Fmt...)
+#define RFTEST_LOUD_LOGFUNC(_Fmt...)
+#define RFTEST_TEMP_LOGFUNC(_Fmt...)
+
+#define EMU_ERROR_LOGFUNC(_Fmt...)
+#define EMU_WARN_LOGFUNC(_Fmt...)
+#define EMU_INFO_LOGFUNC(_Fmt...)
+#define EMU_STATE_LOGFUNC(_Fmt...)
+#define EMU_EVENT_LOGFUNC(_Fmt...)
+#define EMU_TRACE_LOGFUNC(_Fmt...)
+#define EMU_LOUD_LOGFUNC(_Fmt...)
+#define EMU_TEMP_LOGFUNC(_Fmt...)
+
+#define HEM_ERROR_LOGFUNC(_Fmt...)
+#define HEM_WARN_LOGFUNC(_Fmt...)
+#define HEM_INFO_LOGFUNC(_Fmt...)
+#define HEM_STATE_LOGFUNC(_Fmt...)
+#define HEM_EVENT_LOGFUNC(_Fmt...)
+#define HEM_TRACE_LOGFUNC(_Fmt...)
+#define HEM_LOUD_LOGFUNC(_Fmt...)
+#define HEM_TEMP_LOGFUNC(_Fmt...)
+
+#define RLM_ERROR_LOGFUNC(_Fmt...)
+#define RLM_WARN_LOGFUNC(_Fmt...)
+#define RLM_INFO_LOGFUNC(_Fmt...)
+#define RLM_STATE_LOGFUNC(_Fmt...)
+#define RLM_EVENT_LOGFUNC(_Fmt...)
+#define RLM_TRACE_LOGFUNC(_Fmt...)
+#define RLM_LOUD_LOGFUNC(_Fmt...)
+#define RLM_TEMP_LOGFUNC(_Fmt...)
+
+#define MEM_ERROR_LOGFUNC(_Fmt...)
+#define MEM_WARN_LOGFUNC(_Fmt...)
+#define MEM_INFO_LOGFUNC(_Fmt...)
+#define MEM_STATE_LOGFUNC(_Fmt...)
+#define MEM_EVENT_LOGFUNC(_Fmt...)
+#define MEM_TRACE_LOGFUNC(_Fmt...)
+#define MEM_LOUD_LOGFUNC(_Fmt...)
+#define MEM_TEMP_LOGFUNC(_Fmt...)
+
+#define CNM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define CNM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define CNM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define CNM_STATE_LOGFUNC(_Fmt...)
+#define CNM_EVENT_LOGFUNC(_Fmt...)
+#define CNM_TRACE_LOGFUNC(_Fmt...)
+#define CNM_LOUD_LOGFUNC(_Fmt...)
+#define CNM_TEMP_LOGFUNC(_Fmt...)
+
+#define RSN_ERROR_LOGFUNC(_Fmt...)
+#define RSN_WARN_LOGFUNC(_Fmt...)
+#define RSN_INFO_LOGFUNC(_Fmt...)
+#define RSN_STATE_LOGFUNC(_Fmt...)
+#define RSN_EVENT_LOGFUNC(_Fmt...)
+#define RSN_TRACE_LOGFUNC(_Fmt...)
+#define RSN_LOUD_LOGFUNC(_Fmt...)
+#define RSN_TEMP_LOGFUNC(_Fmt...)
+
+#define BSS_ERROR_LOGFUNC(_Fmt...)
+#define BSS_WARN_LOGFUNC(_Fmt...)
+#define BSS_INFO_LOGFUNC(_Fmt...)
+#define BSS_STATE_LOGFUNC(_Fmt...)
+#define BSS_EVENT_LOGFUNC(_Fmt...)
+#define BSS_TRACE_LOGFUNC(_Fmt...)
+#define BSS_LOUD_LOGFUNC(_Fmt...)
+#define BSS_TEMP_LOGFUNC(_Fmt...)
+
+#define SCN_ERROR_LOGFUNC(_Fmt...)
+#define SCN_WARN_LOGFUNC(_Fmt...)
+#define SCN_INFO_LOGFUNC(_Fmt...)
+#define SCN_STATE_LOGFUNC(_Fmt...)
+#define SCN_EVENT_LOGFUNC(_Fmt...)
+#define SCN_TRACE_LOGFUNC(_Fmt...)
+#define SCN_LOUD_LOGFUNC(_Fmt...)
+#define SCN_TEMP_LOGFUNC(_Fmt...)
+
+#define SAA_ERROR_LOGFUNC(_Fmt...)
+#define SAA_WARN_LOGFUNC(_Fmt...)
+#define SAA_INFO_LOGFUNC(_Fmt...)
+#define SAA_STATE_LOGFUNC(_Fmt...)
+#define SAA_EVENT_LOGFUNC(_Fmt...)
+#define SAA_TRACE_LOGFUNC(_Fmt...)
+#define SAA_LOUD_LOGFUNC(_Fmt...)
+#define SAA_TEMP_LOGFUNC(_Fmt...)
+
+#define P2P_ERROR_LOGFUNC(_Fmt...)
+#define P2P_WARN_LOGFUNC(_Fmt...)
+#define P2P_INFO_LOGFUNC(_Fmt...)
+#define P2P_STATE_LOGFUNC(_Fmt...)
+#define P2P_EVENT_LOGFUNC(_Fmt...)
+#define P2P_TRACE_LOGFUNC(_Fmt...)
+#define P2P_LOUD_LOGFUNC(_Fmt...)
+#define P2P_TEMP_LOGFUNC(_Fmt...)
+
+#define QM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define QM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define QM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define QM_STATE_LOGFUNC(_Fmt...)
+#define QM_EVENT_LOGFUNC(_Fmt...)
+#define QM_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define QM_LOUD_LOGFUNC(_Fmt...)
+#define QM_TEMP_LOGFUNC(_Fmt...)
+
+#define SEC_ERROR_LOGFUNC(_Fmt...)
+#define SEC_WARN_LOGFUNC(_Fmt...)
+#define SEC_INFO_LOGFUNC(_Fmt...)
+#define SEC_STATE_LOGFUNC(_Fmt...)
+#define SEC_EVENT_LOGFUNC(_Fmt...)
+#define SEC_TRACE_LOGFUNC(_Fmt...)
+#define SEC_LOUD_LOGFUNC(_Fmt...)
+#define SEC_TEMP_LOGFUNC(_Fmt...)
+
+#define BOW_ERROR_LOGFUNC(_Fmt...)
+#define BOW_WARN_LOGFUNC(_Fmt...)
+#define BOW_INFO_LOGFUNC(_Fmt...)
+#define BOW_STATE_LOGFUNC(_Fmt...)
+#define BOW_EVENT_LOGFUNC(_Fmt...)
+#define BOW_TRACE_LOGFUNC(_Fmt...)
+#define BOW_LOUD_LOGFUNC(_Fmt...)
+#define BOW_TEMP_LOGFUNC(_Fmt...)
+
+#define HAL_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define HAL_WARN_LOGFUNC(_Fmt...)
+#define HAL_INFO_LOGFUNC(_Fmt...)
+#define HAL_STATE_LOGFUNC(_Fmt...)
+#define HAL_EVENT_LOGFUNC(_Fmt...)
+#define HAL_TRACE_LOGFUNC(_Fmt...)
+#define HAL_LOUD_LOGFUNC(_Fmt...)
+#define HAL_TEMP_LOGFUNC(_Fmt...)
+
+#define WAPI_ERROR_LOGFUNC(_Fmt...)
+#define WAPI_WARN_LOGFUNC(_Fmt...)
+#define WAPI_INFO_LOGFUNC(_Fmt...)
+#define WAPI_STATE_LOGFUNC(_Fmt...)
+#define WAPI_EVENT_LOGFUNC(_Fmt...)
+#define WAPI_TRACE_LOGFUNC(_Fmt...)
+#define WAPI_LOUD_LOGFUNC(_Fmt...)
+#define WAPI_TEMP_LOGFUNC(_Fmt...)
+
+#define TDLS_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt)
+#define TDLS_WARN_LOGFUNC(_Fmt...)  kalPrint(_Fmt)
+#define TDLS_INFO_LOGFUNC(_Fmt...)  kalPrint(_Fmt)
+#define TDLS_STATE_LOGFUNC(_Fmt...)
+#define TDLS_EVENT_LOGFUNC(_Fmt...)
+#define TDLS_TRACE_LOGFUNC(_Fmt...)
+#define TDLS_LOUD_LOGFUNC(_Fmt...)
+#define TDLS_TEMP_LOGFUNC(_Fmt...)
+
+#define SW1_ERROR_LOGFUNC(_Fmt...)
+#define SW1_WARN_LOGFUNC(_Fmt...)
+#define SW1_INFO_LOGFUNC(_Fmt...)
+#define SW1_STATE_LOGFUNC(_Fmt...)
+#define SW1_EVENT_LOGFUNC(_Fmt...)
+#define SW1_TRACE_LOGFUNC(_Fmt...)
+#define SW1_LOUD_LOGFUNC(_Fmt...)
+#define SW1_TEMP_LOGFUNC(_Fmt...)
+
+#define SW2_ERROR_LOGFUNC(_Fmt...)
+#define SW2_WARN_LOGFUNC(_Fmt...)
+#define SW2_INFO_LOGFUNC(_Fmt...)
+#define SW2_STATE_LOGFUNC(_Fmt...)
+#define SW2_EVENT_LOGFUNC(_Fmt...)
+#define SW2_TRACE_LOGFUNC(_Fmt...)
+#define SW2_LOUD_LOGFUNC(_Fmt...)
+#define SW2_TEMP_LOGFUNC(_Fmt...)
+
+#define SW3_ERROR_LOGFUNC(_Fmt...)
+#define SW3_WARN_LOGFUNC(_Fmt...)
+#define SW3_INFO_LOGFUNC(_Fmt...)
+#define SW3_STATE_LOGFUNC(_Fmt...)
+#define SW3_EVENT_LOGFUNC(_Fmt...)
+#define SW3_TRACE_LOGFUNC(_Fmt...)
+#define SW3_LOUD_LOGFUNC(_Fmt...)
+#define SW3_TEMP_LOGFUNC(_Fmt...)
+
+#define SW4_ERROR_LOGFUNC(_Fmt...)
+#define SW4_WARN_LOGFUNC(_Fmt...)
+#define SW4_INFO_LOGFUNC(_Fmt...)
+#define SW4_STATE_LOGFUNC(_Fmt...)
+#define SW4_EVENT_LOGFUNC(_Fmt...)
+#define SW4_TRACE_LOGFUNC(_Fmt...)
+#define SW4_LOUD_LOGFUNC(_Fmt...)
+#define SW4_TEMP_LOGFUNC(_Fmt...)
+#endif
+
+#define kalBreakPoint() \
+do { \
+	BUG(); \
+	panic("Oops"); \
+} while (0)
+
+#if CFG_ENABLE_AEE_MSG
+#define kalSendAeeException                         aee_kernel_exception
+#define kalSendAeeWarning                           aee_kernel_warning
+#define kalSendAeeReminding                         aee_kernel_reminding
+#else
+#define kalSendAeeException(_module, _desc, ...)
+#define kalSendAeeWarning(_module, _desc, ...)
+#define kalSendAeeReminding(_module, _desc, ...)
+#endif
+
+#define PRINTF_ARG(...)                             __VA_ARGS__
+#define SPRINTF(buf, arg)                           {buf += sprintf((char *)(buf), PRINTF_ARG arg); }
+
+#define USEC_TO_SYSTIME(_usec)      ((_usec) / USEC_PER_MSEC)
+#define MSEC_TO_SYSTIME(_msec)      (_msec)
+
+#define MSEC_TO_JIFFIES(_msec)      msecs_to_jiffies(_msec)
+
+#define KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE		3000 /* 3s */
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Routines in gl_kal.c                                                       */
+/*----------------------------------------------------------------------------*/
+VOID
+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo,
+		   IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags);
+
+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags);
+
+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr);
+
+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket);
+
+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData);
+
+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler);
+
+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN OS_SYSTIME rInterval);
+
+WLAN_STATUS
+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen,
+		   /* IN PBOOLEAN           pfgIsRetain, */
+		   IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aeCSUM[]
+);
+
+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum);
+
+VOID
+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen);
+
+VOID
+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo,
+			IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest);
+
+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen);
+
+#if CFG_TX_FRAGMENT
+BOOLEAN
+kalQueryTxPacketHeader(IN P_GLUE_INFO_T prGlueInfo,
+		       IN PVOID pvPacket, OUT PUINT_16 pu2EtherTypeLen, OUT PUINT_8 pucEthDestAddr);
+#endif /* CFG_TX_FRAGMENT */
+
+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket);
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag);
+
+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T eCSUM[]
+);
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr);
+
+VOID
+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo,
+		  IN UINT_64 u8Cookie,
+		  IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs);
+
+VOID
+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo,
+			  IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum);
+
+VOID
+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo,
+			IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen);
+
+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb);
+
+/*----------------------------------------------------------------------------*/
+/* Routines in interface - ehpi/sdio.c                                                       */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalDevRegRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value);
+
+BOOLEAN kalDevRegWrite(P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value);
+
+BOOLEAN
+kalDevPortRead(IN P_GLUE_INFO_T prGlueInfo,
+	       IN UINT_16 u2Port, IN UINT_32 u2Len, OUT PUINT_8 pucBuf, IN UINT_32 u2ValidOutBufSize);
+
+BOOLEAN
+kalDevPortWrite(P_GLUE_INFO_T prGlueInfo,
+		IN UINT_16 u2Port, IN UINT_32 u2Len, IN PUINT_8 pucBuf, IN UINT_32 u2ValidInBufSize);
+
+BOOLEAN kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData);
+
+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo);
+
+#if CFG_SUPPORT_EXT_CONFIG
+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo);
+#endif
+
+BOOLEAN
+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo,
+				   IN P_NATIVE_PACKET prPacket,
+				   OUT PUINT_8 pucPriorityParam,
+				   OUT PUINT_32 pu4PacketLen,
+				   OUT PUINT_8 pucEthDestAddr,
+				   OUT PBOOLEAN pfgIs1X,
+				   OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType,
+				   OUT PVOID prGenUse);
+
+VOID
+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo,
+	       IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus);
+
+WLAN_STATUS
+kalIoctl(IN P_GLUE_INFO_T prGlueInfo,
+	 IN PFN_OID_HANDLER_FUNC pfnOidHandler,
+	 IN PVOID pvInfoBuf,
+	 IN UINT_32 u4InfoBufLen,
+	 IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen);
+
+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo);
+
+#if CFG_ENABLE_FW_DOWNLOAD
+
+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength);
+
+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf);
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* Card Removal Check                                                         */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo);
+
+/*----------------------------------------------------------------------------*/
+/* TX                                                                         */
+/*----------------------------------------------------------------------------*/
+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo);
+
+/*----------------------------------------------------------------------------*/
+/* Media State Indication                                                     */
+/*----------------------------------------------------------------------------*/
+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate);
+
+/*----------------------------------------------------------------------------*/
+/* OID handling                                                               */
+/*----------------------------------------------------------------------------*/
+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry);
+
+#if CFG_ENABLE_BT_OVER_WIFI
+/*----------------------------------------------------------------------------*/
+/* Bluetooth over Wi-Fi handling                                              */
+/*----------------------------------------------------------------------------*/
+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent);
+
+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr);
+
+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, PARAM_MAC_ADDRESS rPeerAddr);
+
+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo);
+
+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo);
+
+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr);
+
+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr);
+
+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo);
+
+#if CFG_BOW_SEPARATE_DATA_PATH
+/*----------------------------------------------------------------------------*/
+/* Bluetooth over Wi-Fi Net Device Init/Uninit                                */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName);
+
+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo);
+#endif /* CFG_BOW_SEPARATE_DATA_PATH */
+#endif /* CFG_ENABLE_BT_OVER_WIFI */
+
+/*----------------------------------------------------------------------------*/
+/* Firmware Download Handling                                                 */
+/*----------------------------------------------------------------------------*/
+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo);
+
+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo);
+
+/*----------------------------------------------------------------------------*/
+/* Security Frame Clearance                                                   */
+/*----------------------------------------------------------------------------*/
+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus);
+
+/*----------------------------------------------------------------------------*/
+/* Management Frame Clearance                                                 */
+/*----------------------------------------------------------------------------*/
+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx);
+
+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo);
+
+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval);
+
+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status);
+
+UINT_32 kalRandomNumber(VOID);
+
+VOID kalTimeoutHandler(struct timer_list *t);
+
+VOID kalSetEvent(P_GLUE_INFO_T pr);
+
+/*----------------------------------------------------------------------------*/
+/* NVRAM/Registry Service                                                     */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo);
+
+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID
+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo,
+			   OUT PUINT_16 pu2Part1CfgOwnVersion,
+			   OUT PUINT_16 pu2Part1CfgPeerVersion,
+			   OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion);
+
+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data);
+
+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, IN UINT_16 u2Data);
+
+/*----------------------------------------------------------------------------*/
+/* WSC Connection                                                     */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo);
+
+/*----------------------------------------------------------------------------*/
+/* RSSI Updating                                                              */
+/*----------------------------------------------------------------------------*/
+VOID
+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo,
+	      IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality);
+
+/*----------------------------------------------------------------------------*/
+/* I/O Buffer Pre-allocation                                                  */
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalInitIOBuffer(VOID);
+
+VOID kalUninitIOBuffer(VOID);
+
+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize);
+
+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size);
+
+VOID
+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo,
+		  IN ENUM_BAND_T eSpecificBand,
+		  IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList);
+
+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo);
+
+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr);
+
+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr);
+
+#if CFG_SUPPORT_802_11W
+/*----------------------------------------------------------------------------*/
+/* 802.11W                                                                    */
+/*----------------------------------------------------------------------------*/
+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo);
+#endif
+
+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size);
+
+/*----------------------------------------------------------------------------*/
+/* NL80211                                                                    */
+/*----------------------------------------------------------------------------*/
+VOID
+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo,
+		   IN PUINT_8 pucFrameBuf, IN UINT_32 u4BufLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength);
+
+/*----------------------------------------------------------------------------*/
+/* PNO Support                                                                */
+/*----------------------------------------------------------------------------*/
+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+int tx_thread(void *data);
+
+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo);
+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb);
+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo);
+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo);
+int kalMetRemoveProcfs(void);
+
+UINT_64 kalGetBootTime(void);
+
+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize);
+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG
+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T  prAdapter);
+#endif
+INT_32 kalHaltLock(UINT_32 waitMs);
+INT_32 kalHaltTryLock(VOID);
+VOID kalHaltUnlock(VOID);
+VOID kalSetHalted(BOOLEAN fgHalt);
+BOOLEAN kalIsHalted(VOID);
+
+INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo);
+INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo);
+INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo);
+INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo);
+INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo);
+INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo);
+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam);
+INT32 kalBoostCpu(UINT_32 core_num);
+
+#endif /* _GL_KAL_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h
new file mode 100644
index 0000000000000..a4321e7f9a119
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h
@@ -0,0 +1,1270 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_os.h#2
+*/
+
+/*! \file   gl_os.h
+    \brief  List the external reference to OS for GLUE Layer.
+
+    In this file we define the data structure - GLUE_INFO_T to store those objects
+    we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the
+    external reference (header file, extern func() ..) to OS for GLUE Layer should
+    also list down here.
+*/
+
+/*
+** Log: gl_os.h
+**
+** 08 20 2012 yuche.tsai
+** NULL
+** Fix possible KE issue.
+**
+** 08 20 2012 yuche.tsai
+** [ALPS00339327] [Rose][6575JB][BSP Package][Free Test][KE][WIFI]There is no response when you tap the turn off/on
+** button,wait a minutes, the device will reboot automatically and "KE" will pop up.
+** Fix possible KE when netlink operate mgmt frame register.
+ *
+ * 04 12 2012 terry.wu
+ * NULL
+ * Add AEE message support
+ * 1) Show AEE warning(red screen) if SDIO access error occurs
+
+ *
+ * 03 02 2012 terry.wu
+ * NULL
+ * Enable CFG80211 Support.
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 12 13 2011 cm.chang
+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer
+ * Add wake lock if timer timeout value is smaller than 5 seconds
+ *
+ * 11 18 2011 yuche.tsai
+ * NULL
+ * CONFIG P2P support RSSI query, default turned off.
+ *
+ * 11 16 2011 yuche.tsai
+ * NULL
+ * Avoid using work thread.
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix work thread cancel issue.
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 29 2011 terry.wu
+ * NULL
+ * Show DRV_NAME by chip id.
+ *
+ * 04 18 2011 terry.wu
+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
+ * Remove flag CFG_WIFI_DIRECT_MOVED.
+ *
+ * 03 29 2011 cp.wu
+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
+ * RESET_START and RESET_END events
+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability improvement
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * support concurrent network
+ *
+ * 03 03 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * modify net device relative functions to support multiple H/W queues
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add security check code.
+ *
+ * 02 21 2011 cp.wu
+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
+ * simplify logic for checking NVRAM existence only once.
+ *
+ * 02 16 2011 jeffrey.chang
+ * NULL
+ * Add query ipv4 and ipv6 address during early suspend and late resume
+ *
+ * 02 10 2011 chinghwa.yu
+ * [WCXRP00000065] Update BoW design and settings
+ * Fix kernel API change issue.
+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is
+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock);
+ * After ALPS 2.3, kfifo_alloc() is changed to
+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask);
+ *
+ * 02 09 2011 wh.su
+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module with structure miss-align
+ * pointer issue
+ * always pre-allio WAPI related structure for align p2p module.
+ *
+ * 02 09 2011 terry.wu
+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
+ * Halt p2p module init and exit until TxThread finished p2p register and unregister.
+ *
+ * 02 01 2011 cm.chang
+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
+ * .
+ *
+ * 01 27 2011 cm.chang
+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default
+ * .
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
+ * implementation of separate BT_OVER_WIFI data path.
+ *
+ * 01 12 2011 cp.wu
+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation
+ * needs such information
+ * fill mac header length information for 802.1x frames.
+ *
+ * 01 11 2011 chinglan.wang
+ * NULL
+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP.  Connection establish
+ * successfully.
+ * Use the WPS function to connect AP, the privacy bit always is set to 1.
+ *
+ * 01 10 2011 cp.wu
+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues
+ * due to multiple access
+ * use mutex to protect kalIoctl() for thread safe.
+ *
+ * 01 05 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * ioctl implementations for P2P Service Discovery
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
+ * The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 09 28 2010 wh.su
+ * NULL
+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add skeleton for NVRAM integration
+ *
+ * 09 13 2010 cp.wu
+ * NULL
+ * add waitq for poll() and read().
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 09 06 2010 wh.su
+ * NULL
+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
+ *
+ * 09 03 2010 kevin.huang
+ * NULL
+ * Refine #include sequence and solve recursive/nested #include issue
+ *
+ * 09 01 2010 wh.su
+ * NULL
+ * adding the wapi support for integration test.
+ *
+ * 08 31 2010 kevin.huang
+ * NULL
+ * Use LINK LIST operation to process SCAN result
+ *
+ * 08 23 2010 cp.wu
+ * NULL
+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * revised implementation of Wi-Fi Direct io controls.
+ *
+ * 08 11 2010 cp.wu
+ * NULL
+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting)
+ * 2) extending scanning result to 64 instead of 48
+ *
+ * 08 06 2010 cp.wu
+ * NULL
+ * driver hook modifications corresponding to ioctl interface change.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * [Wi-Fi Direct] add framework for driver hooks
+ *
+ * 08 02 2010 jeffrey.chang
+ * NULL
+ * 1) modify tx service thread to avoid busy looping
+ * 2) add spin lock declartion for linux build
+ *
+ * 07 23 2010 jeffrey.chang
+ *
+ * add new KAL api
+ *
+ * 07 22 2010 jeffrey.chang
+ *
+ * modify tx thread and remove some spinlock
+ *
+ * 07 19 2010 jeffrey.chang
+ *
+ * add security frame pending count
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 01 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl to configure scan mode for p2p connection
+ *
+ * 05 31 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add cfg80211 interface, which is to replace WE, for further extension
+ *
+ * 05 14 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * p2p ioctls revised.
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl for controlling p2p scan phase parameters
+ *
+ * 05 10 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement basic wi-fi direct framework
+ *
+ * 05 07 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * prevent supplicant accessing driver during resume
+ *
+ * 05 07 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add basic framework for implementating P2P driver hook.
+ *
+ * 05 05 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * change variable names for multiple physical link to match with coding convention
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame
+ *
+ * 04 27 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add multiple physical link support
+ *
+ * 04 27 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * 1) fix firmware download bug
+ * 2) remove query statistics for acelerating firmware download
+ *
+ * 04 27 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * follow Linux's firmware framework, and remove unused kal API
+ *
+ * 04 23 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * surpress compiler warning
+ *
+ * 04 19 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * supporting power management
+ *
+ * 04 14 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * pvInformationBuffer and u4InformationBufferLength are no longer in glue
+ *
+ * 04 13 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add framework for BT-over-Wi-Fi support.
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *    handler capability
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other
+ *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *    purpose
+ *
+ * 04 07 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * rWlanInfo should be placed at adapter rather than glue due to most operations
+ *  *  *  *  *  *  *  *  *  * are done in adapter layer.
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * Tag the packet for QoS on Tx path
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * (1)deliver the kalOidComplete status to upper layer
+ *  * (2) fix spin lock
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * add timeout check in the kalOidComplete
+ *
+ * 04 06 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * improve none-glue code portability
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
+ *
+ * 04 06 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
+ *
+ * 03 30 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * emulate NDIS Pending OID facility
+ *
+ * 03 26 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * [WPD00003826] Initial import for Linux port
+ * adding firmware download related data type
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00001943]Create WiFi test driver framework on WinXP
+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior.
+ *  *  *  * the frequency is used for adhoc connection only
+ *  *  *  * 2) update with SD1 v0.9 CMD/EVENT documentation
+ *
+ * 03 25 2010 cp.wu
+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
+ * add Bluetooth-over-Wifi frame header check
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\30 2009-10-20 17:38:31 GMT mtk01090
+**  Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests,
+**  and then stop hw.
+**  \main\maintrunk.MT5921\29 2009-10-08 10:33:33 GMT mtk01090
+**  Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input
+**  parameters and pointers.
+**  \main\maintrunk.MT5921\28 2009-09-28 20:19:26 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\27 2009-08-18 22:57:12 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\26 2009-07-06 21:42:25 GMT mtk01088
+**  fixed the compiling error at linux
+**  \main\maintrunk.MT5921\25 2009-07-06 20:51:46 GMT mtk01088
+**  adding the wapi 1x ether type define
+**  \main\maintrunk.MT5921\24 2009-06-23 23:19:18 GMT mtk01090
+**  Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
+**  \main\maintrunk.MT5921\23 2009-02-07 15:05:06 GMT mtk01088
+**  add the privacy flag to ingo driver the supplicant selected ap's security
+**  \main\maintrunk.MT5921\22 2009-02-05 15:34:09 GMT mtk01088
+**  fixed the compiling error for using bits marco for only one parameter
+**  \main\maintrunk.MT5921\21 2009-01-22 13:02:13 GMT mtk01088
+**  data frame is or not 802.1x value share with tid, using the same reserved byte, provide the function to set and get
+**  \main\maintrunk.MT5921\20 2008-10-24 12:04:16 GMT mtk01088
+**  move the config.h from precomp.h to here for lint check
+**  \main\maintrunk.MT5921\19 2008-09-22 23:19:02 GMT mtk01461
+**  Update driver for code review
+**  \main\maintrunk.MT5921\18 2008-09-05 17:25:13 GMT mtk01461
+**  Update Driver for Code Review
+**  \main\maintrunk.MT5921\17 2008-08-01 13:32:47 GMT mtk01084
+**  Prevent redundent driver assertion in driver logic when BUS is detached
+**  \main\maintrunk.MT5921\16 2008-05-30 14:41:43 GMT mtk01461
+**  Remove WMM Assoc Flag in KAL
+**  \main\maintrunk.MT5921\15 2008-05-29 14:16:25 GMT mtk01084
+**  remoev un-used variable
+**  \main\maintrunk.MT5921\14 2008-05-03 15:17:14 GMT mtk01461
+**  Add Media Status variable in Glue Layer
+**  \main\maintrunk.MT5921\13 2008-04-24 11:58:41 GMT mtk01461
+**  change threshold to 256
+**  \main\maintrunk.MT5921\12 2008-03-11 14:51:05 GMT mtk01461
+**  Remove redundant GL_CONN_INFO_T
+**  \main\maintrunk.MT5921\11 2008-01-07 15:07:41 GMT mtk01461
+**  Adjust the netif stop threshold to 150
+**  \main\maintrunk.MT5921\10 2007-11-26 19:43:46 GMT mtk01461
+**  Add OS_TIMESTAMP macro
+**
+**  \main\maintrunk.MT5921\9 2007-11-07 18:38:38 GMT mtk01461
+**  Move definition
+**  \main\maintrunk.MT5921\8 2007-11-02 01:04:00 GMT mtk01461
+**  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
+** Revision 1.5  2007/07/12 11:04:28  MTK01084
+** update macro to delay for ms order
+**
+** Revision 1.4  2007/07/05 07:25:34  MTK01461
+** Add Linux initial code, modify doc, add 11BB, RF init code
+**
+** Revision 1.3  2007/06/27 02:18:51  MTK01461
+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
+**
+** Revision 1.2  2007/06/25 06:16:24  MTK01461
+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
+**
+*/
+
+#ifndef _GL_OS_H
+#define _GL_OS_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+/*------------------------------------------------------------------------------
+ * Flags for LINUX(OS) dependent
+ *------------------------------------------------------------------------------
+ */
+#define CFG_MAX_WLAN_DEVICES                1	/* number of wlan card will coexist */
+
+#define CFG_MAX_TXQ_NUM                     4	/* number of tx queue for support multi-queue h/w  */
+
+#define CFG_USE_SPIN_LOCK_BOTTOM_HALF       0	/* 1: Enable use of SPIN LOCK Bottom Half for LINUX
+						   0: Disable - use SPIN LOCK IRQ SAVE instead */
+
+#define CFG_TX_PADDING_SMALL_ETH_PACKET     0	/* 1: Enable - Drop ethernet packet if it < 14 bytes.
+						   And pad ethernet packet with dummy 0 if it < 60 bytes.
+						   0: Disable */
+
+#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD   256	/* packets */
+
+#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD   256	/* packets */
+#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD  128	/* packets */
+
+#define ETH_P_1X                            0x888E
+#define IPTOS_PREC_OFFSET                   5
+#define USER_PRIORITY_DEFAULT               0
+
+#define ETH_WPI_1X                         0x88B4
+
+#define ETH_HLEN                                14
+#define ETH_TYPE_LEN_OFFSET                     12
+#define ETH_P_IP                                0x0800
+#define ETH_P_1X                                0x888E
+#define ETH_P_PRE_1X                            0x88C7
+#define ETH_P_ARP								0x0806
+
+#define ARP_PRO_REQ								1
+#define ARP_PRO_RSP								2
+
+#define IPVERSION                               4
+#define IP_HEADER_LEN                           20
+
+#define IP_PRO_ICMP								0x01
+#define IP_PRO_UDP								0x11
+#define IP_PRO_TCP								0x06
+
+#define UDP_PORT_DHCPS							0x43
+#define UDP_PORT_DHCPC							0x44
+#define UDP_PORT_DNS							0x35
+
+#define IPVH_VERSION_OFFSET                     4	/* For Little-Endian */
+#define IPVH_VERSION_MASK                       0xF0
+#define IPTOS_PREC_OFFSET                       5
+#define IPTOS_PREC_MASK                         0xE0
+
+#define SOURCE_PORT_LEN                         2
+/* NOTE(Kevin): Without IP Option Length */
+#define LOOK_AHEAD_LEN                          (ETH_HLEN + IP_HEADER_LEN + SOURCE_PORT_LEN)
+
+/* 802.2 LLC/SNAP */
+#define ETH_LLC_OFFSET                          (ETH_HLEN)
+#define ETH_LLC_LEN                             3
+#define ETH_LLC_DSAP_SNAP                       0xAA
+#define ETH_LLC_SSAP_SNAP                       0xAA
+#define ETH_LLC_CONTROL_UNNUMBERED_INFORMATION  0x03
+
+/* Bluetooth SNAP */
+#define ETH_SNAP_OFFSET                         (ETH_HLEN + ETH_LLC_LEN)
+#define ETH_SNAP_LEN                            5
+#define ETH_SNAP_BT_SIG_OUI_0                   0x00
+#define ETH_SNAP_BT_SIG_OUI_1                   0x19
+#define ETH_SNAP_BT_SIG_OUI_2                   0x58
+
+#define BOW_PROTOCOL_ID_SECURITY_FRAME          0x0003
+
+#if defined(MT6620)
+#define CHIP_NAME    "MT6620"
+#elif defined(MT6628)
+#define CHIP_NAME    "MT6582"
+#endif
+
+#define DRV_NAME "["CHIP_NAME"]: "
+
+#define CONFIG_ANDROID 1
+/* Define if target platform is Android.
+ * It should already be defined in Android kernel source
+ */
+
+/* for CFG80211 IE buffering mechanism */
+#define CFG_CFG80211_IE_BUF_LEN     (512)
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/version.h>	/* constant of kernel version */
+
+#include <linux/kernel.h>	/* bitops.h */
+
+#include <linux/timer.h>	/* struct timer_list */
+#include <linux/jiffies.h>	/* jiffies */
+#include <linux/delay.h>	/* udelay and mdelay macro */
+
+#if CONFIG_ANDROID
+#include <linux/wakelock.h>
+#endif
+
+#include <linux/irq.h>		/* IRQT_FALLING */
+
+#include <linux/netdevice.h>	/* struct net_device, struct net_device_stats */
+#include <linux/etherdevice.h>	/* for eth_type_trans() function */
+#include <linux/wireless.h>	/* struct iw_statistics */
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>	/* struct in_device */
+
+#include <linux/ip.h>		/* struct iphdr */
+
+#include <linux/string.h>	/* for memcpy()/memset() function */
+#include <linux/stddef.h>	/* for offsetof() macro */
+
+#include <linux/proc_fs.h>	/* The proc filesystem constants/structures */
+
+#include <linux/rtnetlink.h>	/* for rtnl_lock() and rtnl_unlock() */
+#include <linux/kthread.h>	/* kthread_should_stop(), kthread_run() */
+#include <asm/uaccess.h>	/* for copy_from_user() */
+#include <linux/fs.h>		/* for firmware download */
+#include <linux/vmalloc.h>
+
+#include <linux/kfifo.h>	/* for kfifo interface */
+#include <linux/cdev.h>		/* for cdev interface */
+
+#include <linux/firmware.h>	/* for firmware download */
+
+#if defined(_HIF_SDIO)
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+#endif
+
+#include <linux/random.h>
+
+#include <linux/lockdep.h>
+#include <linux/time.h>
+
+#include <asm/io.h>		/* readw and writew */
+
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif
+
+#include "version.h"
+#include "config.h"
+
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+#endif
+
+#include <linux/module.h>
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+#include <net/addrconf.h>
+#endif
+
+#include "gl_typedef.h"
+#include "typedef.h"
+#include "queue.h"
+#include "gl_kal.h"
+#include "hif.h"
+#if CFG_CHIP_RESET_SUPPORT
+#include "gl_rst.h"
+#endif
+
+#if (CFG_SUPPORT_TDLS == 1)
+#include "tdls_extr.h"
+#endif
+#include "debug.h"
+
+#include "wlan_lib.h"
+#include "wlan_oid.h"
+
+#if CFG_ENABLE_AEE_MSG
+#include <mt-plat/aee.h>
+#endif
+
+extern BOOLEAN fgIsBusAccessFailed;
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define GLUE_FLAG_HALT          BIT(0)
+#define GLUE_FLAG_INT           BIT(1)
+#define GLUE_FLAG_OID           BIT(2)
+#define GLUE_FLAG_TIMEOUT       BIT(3)
+#define GLUE_FLAG_TXREQ         BIT(4)
+#define GLUE_FLAG_SUB_MOD_INIT  BIT(5)
+#define GLUE_FLAG_SUB_MOD_EXIT  BIT(6)
+#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7)
+#define GLUE_FLAG_FRAME_FILTER      BIT(8)
+#define GLUE_FLAG_FRAME_FILTER_AIS  BIT(9)
+#define GLUE_FLAG_HIF_LOOPBK_AUTO   BIT(10)
+#define GLUE_FLAG_HALT_BIT          (0)
+#define GLUE_FLAG_INT_BIT           (1)
+#define GLUE_FLAG_OID_BIT           (2)
+#define GLUE_FLAG_TIMEOUT_BIT       (3)
+#define GLUE_FLAG_TXREQ_BIT         (4)
+#define GLUE_FLAG_SUB_MOD_INIT_BIT  (5)
+#define GLUE_FLAG_SUB_MOD_EXIT_BIT  (6)
+#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7)
+#define GLUE_FLAG_FRAME_FILTER_BIT  (8)
+#define GLUE_FLAG_FRAME_FILTER_AIS_BIT  (9)
+#define GLUE_FLAG_HIF_LOOPBK_AUTO_BIT   (10)
+
+#define GLUE_BOW_KFIFO_DEPTH        (1024)
+/* #define GLUE_BOW_DEVICE_NAME        "MT6620 802.11 AMP" */
+#define GLUE_BOW_DEVICE_NAME        "ampc0"
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _GL_WPA_INFO_T {
+	UINT_32 u4WpaVersion;
+	UINT_32 u4KeyMgmt;
+	UINT_32 u4CipherGroup;
+	UINT_32 u4CipherPairwise;
+	UINT_32 u4AuthAlg;
+	BOOLEAN fgPrivacyInvoke;
+#if CFG_SUPPORT_802_11W
+	UINT_32 u4Mfp;
+#endif
+} GL_WPA_INFO_T, *P_GL_WPA_INFO_T;
+
+typedef enum _ENUM_RSSI_TRIGGER_TYPE {
+	ENUM_RSSI_TRIGGER_NONE,
+	ENUM_RSSI_TRIGGER_GREATER,
+	ENUM_RSSI_TRIGGER_LESS,
+	ENUM_RSSI_TRIGGER_TRIGGERED,
+	ENUM_RSSI_TRIGGER_NUM
+} ENUM_RSSI_TRIGGER_TYPE;
+
+#if CFG_ENABLE_WIFI_DIRECT
+typedef enum _ENUM_SUB_MODULE_IDX_T {
+	P2P_MODULE = 0,
+	SUB_MODULE_NUM
+} ENUM_SUB_MODULE_IDX_T;
+
+typedef enum _ENUM_NET_REG_STATE_T {
+	ENUM_NET_REG_STATE_UNREGISTERED,
+	ENUM_NET_REG_STATE_REGISTERING,
+	ENUM_NET_REG_STATE_REGISTERED,
+	ENUM_NET_REG_STATE_UNREGISTERING,
+	ENUM_NET_REG_STATE_NUM
+} ENUM_NET_REG_STATE_T;
+
+#endif
+
+typedef struct _GL_IO_REQ_T {
+	QUE_ENTRY_T rQueEntry;
+	/* wait_queue_head_t       cmdwait_q; */
+	BOOLEAN fgRead;
+	BOOLEAN fgWaitResp;
+#if CFG_ENABLE_WIFI_DIRECT
+	BOOLEAN fgIsP2pOid;
+#endif
+	P_ADAPTER_T prAdapter;
+	PFN_OID_HANDLER_FUNC pfnOidHandler;
+	PVOID pvInfoBuf;
+	UINT_32 u4InfoBufLen;
+	PUINT_32 pu4QryInfoLen;
+	WLAN_STATUS rStatus;
+	UINT_32 u4Flag;
+} GL_IO_REQ_T, *P_GL_IO_REQ_T;
+
+#if CFG_ENABLE_BT_OVER_WIFI
+typedef struct _GL_BOW_INFO {
+	BOOLEAN fgIsRegistered;
+	dev_t u4DeviceNumber;	/* dynamic device number */
+/* struct kfifo            *prKfifo; */    /* for buffering indicated events */
+	struct kfifo rKfifo;	/* for buffering indicated events */
+	spinlock_t rSpinLock;	/* spin lock for kfifo */
+	struct cdev cdev;
+	UINT_32 u4FreqInKHz;	/* frequency */
+
+	UINT_8 aucRole[CFG_BOW_PHYSICAL_LINK_NUM];	/* 0: Responder, 1: Initiator */
+	ENUM_BOW_DEVICE_STATE aeState[CFG_BOW_PHYSICAL_LINK_NUM];
+	PARAM_MAC_ADDRESS arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM];
+
+	wait_queue_head_t outq;
+
+#if CFG_BOW_SEPARATE_DATA_PATH
+	/* Device handle */
+	struct net_device *prDevHandler;
+	BOOLEAN fgIsNetRegistered;
+#endif
+
+} GL_BOW_INFO, *P_GL_BOW_INFO;
+#endif
+
+#if (CFG_SUPPORT_TDLS == 1)
+typedef struct _TDLS_INFO_LINK_T {
+	/* start time when link is built, end time when link is broken */
+	unsigned long jiffies_start, jiffies_end;
+
+	/* the peer MAC */
+	UINT8 aucPeerMac[6];
+
+	/* broken reason */
+	UINT8 ucReasonCode;
+
+	/* TRUE: torn down is triggerred by us */
+	UINT8 fgIsFromUs;
+
+	/* duplicate count; same reason */
+	UINT8 ucDupCount;
+
+	/* HT capability */
+#define TDLS_INFO_LINK_HT_CAP_SUP			0x01
+	UINT8 ucHtCap;
+#define TDLS_INFO_LINK_HT_BA_SETUP			0x01
+#define TDLS_INFO_LINK_HT_BA_SETUP_OK		0x02
+#define TDLS_INFO_LINK_HT_BA_SETUP_DECLINE	0x04
+#define TDLS_INFO_LINK_HT_BA_PEER			0x10
+#define TDLS_INFO_LINK_HT_BA_RSP_OK			0x20
+#define TDLS_INFO_LINK_HT_BA_RSP_DECLINE	0x40
+	UINT8 ucHtBa[8];	/* TID0 ~ TID7 */
+} TDLS_INFO_LINK_T;
+
+typedef struct _TDLS_INFO_T {
+	/* link history */
+#define TDLS_LINK_HISTORY_MAX				30
+	TDLS_INFO_LINK_T rLinkHistory[TDLS_LINK_HISTORY_MAX];
+	UINT32 u4LinkIdx;
+
+	/* TRUE: support 20/40 bandwidth in TDLS link */
+	BOOLEAN fgIs2040Sup;
+
+	/* total TDLS link count */
+	INT8 cLinkCnt;
+} TDLS_INFO_T;
+#endif /* CFG_SUPPORT_TDLS */
+
+/*
+* type definition of pointer to p2p structure
+*/
+typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T;
+
+struct _GLUE_INFO_T {
+	/* Device handle */
+	struct net_device *prDevHandler;
+
+	/* Device Index(index of arWlanDevInfo[]) */
+	INT_32 i4DevIdx;
+
+	/* Device statistics */
+	struct net_device_stats rNetDevStats;
+
+	/* Wireless statistics struct net_device */
+	struct iw_statistics rIwStats;
+
+	/* spinlock to sync power save mechanism */
+	spinlock_t rSpinLock[SPIN_LOCK_NUM];
+
+	/* semaphore for ioctl */
+	struct semaphore ioctl_sem;
+
+	UINT_64 u8Cookie;
+
+	ULONG ulFlag;		/* GLUE_FLAG_XXX */
+	UINT_32 u4PendFlag;
+	/* UINT_32 u4TimeoutFlag; */
+	UINT_32 u4OidCompleteFlag;
+	UINT_32 u4ReadyFlag;	/* check if card is ready */
+
+	UINT_32 u4OsMgmtFrameFilter;
+
+	/* Number of pending frames, also used for debuging if any frame is
+	 * missing during the process of unloading Driver.
+	 *
+	 * NOTE(Kevin): In Linux, we also use this variable as the threshold
+	 * for manipulating the netif_stop(wake)_queue() func.
+	 */
+	INT_32 ai4TxPendingFrameNumPerQueue[4][CFG_MAX_TXQ_NUM];
+	INT_32 i4TxPendingFrameNum;
+	INT_32 i4TxPendingSecurityFrameNum;
+
+	/* current IO request for kalIoctl */
+	GL_IO_REQ_T OidEntry;
+
+	/* registry info */
+	REG_INFO_T rRegInfo;
+
+	/* firmware */
+	struct firmware *prFw;
+
+	/* Host interface related information */
+	/* defined in related hif header file */
+	GL_HIF_INFO_T rHifInfo;
+
+	/*! \brief wext wpa related information */
+	GL_WPA_INFO_T rWpaInfo;
+
+	/* Pointer to ADAPTER_T - main data structure of internal protocol stack */
+	P_ADAPTER_T prAdapter;
+
+#ifdef WLAN_INCLUDE_PROC
+	struct proc_dir_entry *pProcRoot;
+#endif				/* WLAN_INCLUDE_PROC */
+
+	/* Indicated media state */
+	ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicated;
+
+	/* Device power state D0~D3 */
+	PARAM_DEVICE_POWER_STATE ePowerState;
+
+	struct completion rScanComp;	/* indicate scan complete */
+	struct completion rHaltComp;	/* indicate main thread halt complete */
+	struct completion rPendComp;	/* indicate main thread halt complete */
+#if CFG_ENABLE_WIFI_DIRECT
+	struct completion rSubModComp;	/*indicate sub module init or exit complete */
+#endif
+	WLAN_STATUS rPendStatus;
+
+	QUE_T rTxQueue;
+
+	/* OID related */
+	QUE_T rCmdQueue;
+	/* PVOID                   pvInformationBuffer; */
+	/* UINT_32                 u4InformationBufferLength; */
+	/* PVOID                   pvOidEntry; */
+	/* PUINT_8                 pucIOReqBuff; */
+	/* QUE_T                   rIOReqQueue; */
+	/* QUE_T                   rFreeIOReqQueue; */
+
+	wait_queue_head_t waitq;
+	struct task_struct *main_thread;
+
+	struct timer_list tickfn;
+
+#if CFG_SUPPORT_EXT_CONFIG
+	UINT_16 au2ExtCfg[256];	/* NVRAM data buffer */
+	UINT_32 u4ExtCfgLength;	/* 0 means data is NOT valid */
+#endif
+
+#if 1				/* CFG_SUPPORT_WAPI */
+	/* Should be large than the PARAM_WAPI_ASSOC_INFO_T */
+	UINT_8 aucWapiAssocInfoIEs[42];
+	UINT_16 u2WapiAssocInfoIESz;
+#endif
+
+#if CFG_ENABLE_BT_OVER_WIFI
+	GL_BOW_INFO rBowInfo;
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+	P_GL_P2P_INFO_T prP2PInfo;
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+	/* Wireless statistics struct net_device */
+	struct iw_statistics rP2pIwStats;
+#endif
+#endif
+	BOOLEAN fgWpsActive;
+	UINT_8 aucWSCIE[500];	/*for probe req */
+	UINT_16 u2WSCIELen;
+	UINT_8 aucWSCAssocInfoIE[200];	/*for Assoc req */
+	UINT_16 u2WSCAssocInfoIELen;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+	UINT_8 aucHS20AssocInfoIE[200];	/*for Assoc req */
+	UINT_16 u2HS20AssocInfoIELen;
+	UINT_8 ucHotspotConfig;
+	BOOLEAN fgConnectHS20AP;
+#endif
+
+	/* NVRAM availability */
+	BOOLEAN fgNvramAvailable;
+
+	BOOLEAN fgMcrAccessAllowed;
+
+	/* MAC Address Overridden by IOCTL */
+	BOOLEAN fgIsMacAddrOverride;
+	PARAM_MAC_ADDRESS rMacAddrOverride;
+
+	SET_TXPWR_CTRL_T rTxPwr;
+
+	/* for cfg80211 scan done indication */
+	struct cfg80211_scan_request *prScanRequest;
+
+	/* for cfg80211 scheduled scan */
+	struct cfg80211_sched_scan_request *prSchedScanRequest;
+
+	/* to indicate registered or not */
+	BOOLEAN fgIsRegistered;
+
+	/* for cfg80211 connected indication */
+	UINT_32 u4RspIeLength;
+	UINT_8 aucRspIe[CFG_CFG80211_IE_BUF_LEN];
+
+	UINT_32 u4ReqIeLength;
+	UINT_8 aucReqIe[CFG_CFG80211_IE_BUF_LEN];
+
+	KAL_WAKE_LOCK_T rAhbIsrWakeLock;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+	BOOLEAN fgIsDad;
+	UINT_8 aucDADipv4[4];
+	BOOLEAN fgIs6Dad;
+	UINT_8 aucDADipv6[16];
+#endif
+#if (CFG_SUPPORT_MET_PROFILING == 1)
+	UINT_8 u8MetProfEnable;
+	INT_16 u16MetUdpPort;
+#endif
+	BOOLEAN fgPoorlinkValid;
+	UINT_64 u8Statistic[2];
+	UINT_64 u8TotalFailCnt;
+	UINT_32 u4LinkspeedThreshold;
+	INT_32 i4RssiThreshold;
+	INT_32 i4RssiCache;
+	UINT_32 u4LinkSpeedCache;
+
+#if (CFG_SUPPORT_TDLS == 1)
+	TDLS_INFO_T rTdlsLink;
+
+	UINT8 aucTdlsHtPeerMac[6];
+	IE_HT_CAP_T rTdlsHtCap;	/* temp to queue HT capability element */
+
+	/*
+	   [0~7]: jiffies
+	   [8~13]: Peer MAC
+	   [14]: Reason Code
+	   [15]: From us or peer
+	   [16]: Duplicate Count
+	 */
+/* UINT8                                   aucTdlsDisconHistory[TDLS_DISCON_HISTORY_MAX][20]; */
+/* UINT32                                  u4TdlsDisconIdx; */
+#endif				/* CFG_SUPPORT_TDLS */
+	UINT_32 IsrCnt;
+	UINT_32 IsrPassCnt;
+	UINT_32 TaskIsrCnt;
+
+	UINT_32 IsrPreCnt;
+	UINT_32 IsrPrePassCnt;
+	UINT_32 TaskPreIsrCnt;
+
+	UINT_32 IsrAbnormalCnt;
+	UINT_32 IsrSoftWareCnt;
+	UINT_32 IsrTxCnt;
+	UINT_32 IsrRxCnt;
+	UINT_64 u8SkbToDriver;
+	UINT_64 u8SkbFreed;
+};
+
+typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, struct pt_regs *regs);
+
+typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long);
+
+/* generic sub module init/exit handler
+*   now, we only have one sub module, p2p
+*/
+#if CFG_ENABLE_WIFI_DIRECT
+typedef BOOLEAN(*SUB_MODULE_INIT) (P_GLUE_INFO_T prGlueInfo);
+typedef BOOLEAN(*SUB_MODULE_EXIT) (P_GLUE_INFO_T prGlueInfo);
+
+typedef struct _SUB_MODULE_HANDLER {
+	SUB_MODULE_INIT subModInit;
+	SUB_MODULE_EXIT subModExit;
+	BOOLEAN fgIsInited;
+} SUB_MODULE_HANDLER, *P_SUB_MODULE_HANDLER;
+
+#endif
+
+
+#ifdef CONFIG_NL80211_TESTMODE
+enum TestModeCmdType {
+	/* old test mode command id, compatible with exist testmode command */
+	TESTMODE_CMD_ID_SW_CMD = 1,
+	TESTMODE_CMD_ID_WAPI = 2,
+	TESTMODE_CMD_ID_HS20 = 3,
+	TESTMODE_CMD_ID_POORLINK = 4,
+	TESTMODE_CMD_ID_STATISTICS = 0x10,
+	TESTMODE_CMD_ID_LINK_DETECT = 0x20,
+	/* old test mode command id, compatible with exist testmode command */
+
+	/* all new added test mode command should great than TESTMODE_CMD_ID_NEW_BEGIN */
+	TESTMODE_CMD_ID_NEW_BEGIN = 100,
+	TESTMODE_CMD_ID_SUSPEND = 101,
+};
+#if CFG_SUPPORT_HOTSPOT_2_0
+enum Hs20CmdType {
+	HS20_CMD_ID_SET_BSSID_POOL = 0,
+	NUM_OF_HS20_CMD_ID
+};
+#endif
+
+typedef struct _NL80211_DRIVER_TEST_MODE_PARAMS {
+	UINT_32 index;
+	UINT_32 buflen;
+} NL80211_DRIVER_TEST_MODE_PARAMS, *P_NL80211_DRIVER_TEST_MODE_PARAMS;
+
+/*SW CMD */
+typedef struct _NL80211_DRIVER_SW_CMD_PARAMS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	UINT_8 set;
+	UINT_32 adr;
+	UINT_32 data;
+} NL80211_DRIVER_SW_CMD_PARAMS, *P_NL80211_DRIVER_SW_CMD_PARAMS;
+
+typedef struct _NL80211_DRIVER_SUSPEND_PARAMS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	UINT_8 suspend;
+} NL80211_DRIVER_SUSPEND_PARAMS, *P_NL80211_DRIVER_SUSPEND_PARAMS;
+struct iw_encode_exts {
+	__u32 ext_flags;	/*!< IW_ENCODE_EXT_* */
+	__u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE];	/*!< LSB first */
+	__u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE];	/*!< LSB first */
+	__u8 addr[MAC_ADDR_LEN];	/*!< ff:ff:ff:ff:ff:ff for broadcast/multicast
+					 *   (group) keys or unicast address for
+					 *   individual keys */
+	__u16 alg;		/*!< IW_ENCODE_ALG_* */
+	__u16 key_len;
+	__u8 key[32];
+};
+
+/*SET KEY EXT */
+typedef struct _NL80211_DRIVER_SET_KEY_EXTS {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	UINT_8 key_index;
+	UINT_8 key_len;
+	struct iw_encode_exts ext;
+} NL80211_DRIVER_SET_KEY_EXTS, *P_NL80211_DRIVER_SET_KEY_EXTS;
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+
+struct param_hs20_set_bssid_pool {
+	u8 fgBssidPoolIsEnable;
+	u8 ucNumBssidPool;
+	u8 arBssidPool[8][ETH_ALEN];
+};
+
+struct wpa_driver_hs20_data_s {
+	NL80211_DRIVER_TEST_MODE_PARAMS hdr;
+	enum Hs20CmdType CmdType;
+	struct param_hs20_set_bssid_pool hs20_set_bssid_pool;
+};
+
+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */
+
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Macros of SPIN LOCK operations for using in Glue Layer                     */
+/*----------------------------------------------------------------------------*/
+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF
+#define GLUE_SPIN_LOCK_DECLARATION()
+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory)   \
+	{ \
+		if (rLockCategory < SPIN_LOCK_NUM) \
+			spin_lock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \
+	}
+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory)   \
+	{ \
+		if (rLockCategory < SPIN_LOCK_NUM) \
+			spin_unlock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \
+	}
+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock)                  \
+	spin_lock_bh(prLock)
+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock)                  \
+	spin_unlock_bh(prLock)
+
+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
+#define GLUE_SPIN_LOCK_DECLARATION()                        unsigned long __u4Flags = 0
+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory)   \
+	{ \
+		if (rLockCategory < SPIN_LOCK_NUM) \
+			spin_lock_irqsave(&(prGlueInfo)->rSpinLock[rLockCategory], __u4Flags); \
+	}
+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory)   \
+	{ \
+		if (rLockCategory < SPIN_LOCK_NUM) \
+			spin_unlock_irqrestore(&(prGlueInfo->rSpinLock[rLockCategory]), __u4Flags); \
+	}
+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock)                  \
+	    spin_lock_irqsave(prLock, __u4Flags)
+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock)                  \
+	    spin_unlock_irqrestore(prLock, __u4Flags)
+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
+
+/*----------------------------------------------------------------------------*/
+/* Macros for accessing Reserved Fields of native packet                      */
+/*----------------------------------------------------------------------------*/
+#define GLUE_CB_OFFSET					4	/* For 64-bit platform, avoiding that the cb
+								isoverwrited by "(prQueueEntry)->prNext =
+								(P_QUE_ENTRY_T)NULL;" in QUEUE_INSERT_TAIL */
+#define GLUE_GET_PKT_QUEUE_ENTRY(_p)    \
+	(&(((struct sk_buff *)(_p))->cb[0]))
+
+#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry)  \
+	((P_NATIVE_PACKET) ((ULONG)_prQueueEntry - offsetof(struct sk_buff, cb[0])))
+
+#define  GLUE_SET_PKT_FLAG_802_11(_p)  \
+	(*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(7))
+
+#define GLUE_SET_PKT_FLAG_1X(_p)  \
+	(*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(6))
+
+#define GLUE_SET_PKT_FLAG_PAL(_p)  \
+	(*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(5))
+
+#define GLUE_SET_PKT_FLAG_P2P(_p)  \
+	(*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(4))
+
+#define GLUE_SET_PKT_TID(_p, _tid)  \
+	(*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= (((UINT_8)((_tid) & (BITS(0, 3))))))
+
+#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \
+	(*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6])) = (UINT_16)(_u2PayloadLen))
+
+#define GLUE_GET_PKT_FRAME_LEN(_p)    \
+	(*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6])))
+
+#define  GLUE_GET_PKT_IS_802_11(_p)        \
+	((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(7)))
+
+#define  GLUE_GET_PKT_IS_1X(_p)        \
+	((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(6)))
+
+#define GLUE_GET_PKT_TID(_p)        \
+	((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BITS(0, 3)))
+
+#define GLUE_GET_PKT_IS_PAL(_p)        \
+	((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(5)))
+
+#define GLUE_GET_PKT_IS_P2P(_p)        \
+	((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(4)))
+
+#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen)    \
+	(*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5])) = (UINT_8)(_ucMacHeaderLen))
+
+#define GLUE_GET_PKT_HEADER_LEN(_p) \
+	(*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5])))
+
+#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \
+	(*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8])) = (OS_SYSTIME)(_rSysTime))
+
+#define GLUE_GET_PKT_ARRIVAL_TIME(_p)    \
+	(*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8])))
+
+#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \
+	(*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16])) = (UINT_64)(_rSysTime))
+
+#define GLUE_GET_PKT_XTIME(_p)    \
+	(*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16])))
+
+/* Check validity of prDev, private data, and pointers */
+#define GLUE_CHK_DEV(prDev) \
+	((prDev && *((P_GLUE_INFO_T *) netdev_priv(prDev))) ? TRUE : FALSE)
+
+#define GLUE_CHK_PR2(prDev, pr2) \
+	((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE)
+
+#define GLUE_CHK_PR3(prDev, pr2, pr3) \
+	((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE)
+
+#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \
+	((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE)
+
+#define GLUE_SET_EVENT(pr) \
+	kalSetEvent(pr)
+
+#define GLUE_INC_REF_CNT(_refCount)     atomic_inc((atomic_t *)&(_refCount))
+#define GLUE_DEC_REF_CNT(_refCount)     atomic_dec((atomic_t *)&(_refCount))
+
+#define DbgPrint(...)
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+#ifdef WLAN_INCLUDE_PROC
+INT_32 procRemoveProcfs(VOID);
+
+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo);
+INT_32 procInitFs(VOID);
+INT_32 procUninitProcFs(VOID);
+
+#endif /* WLAN_INCLUDE_PROC */
+
+#if CFG_ENABLE_BT_OVER_WIFI
+BOOLEAN glRegisterAmpc(P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN glUnregisterAmpc(P_GLUE_INFO_T prGlueInfo);
+#endif
+
+#if CFG_ENABLE_WIFI_DIRECT
+
+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo);
+
+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo);
+
+VOID
+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx);
+
+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr);
+
+BOOLEAN wlanIsLaunched(VOID);
+
+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo);
+
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _GL_OS_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h
new file mode 100644
index 0000000000000..a27294e335003
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h
@@ -0,0 +1,743 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_ioctl.h#9
+*/
+
+/*! \file   gl_p2p_ioctl.h
+    \brief  This file is for custom ioctls for Wi-Fi Direct only
+*/
+
+/*
+** Log: gl_p2p_ioctl.h
+**
+** 07 26 2012 yuche.tsai
+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
+** Update driver code of ALPS.JB for hot-spot.
+**
+** 07 19 2012 yuche.tsai
+** NULL
+** Code update for JB.
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 06 07 2011 yuche.tsai
+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue
+ * Fix RX SD request under AP mode issue.
+ *
+ * 03 25 2011 wh.su
+ * NULL
+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control.
+ *
+ * 11 22 2011 yuche.tsai
+ * NULL
+ * Update RSSI link quality of P2P Network query method. (Bug fix)
+ *
+ * 11 19 2011 yuche.tsai
+ * NULL
+ * Add RSSI support for P2P network.
+ *
+ * 11 11 2011 yuche.tsai
+ * NULL
+ * Fix work thread cancel issue.
+ *
+ * 11 08 2011 yuche.tsai
+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service
+ * discovery version check.
+ * Add support for driver version query & p2p supplicant verseion set.
+ * For new service discovery mechanism sync.
+ *
+ * 10 25 2011 cm.chang
+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
+ * .
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * New 2.1 branch
+
+ *
+ * 08 16 2011 chinglan.wang
+ * NULL
+ * Add the group id information in the invitation indication.
+ *
+ * 08 09 2011 yuche.tsai
+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
+ * Invitation Feature add on.
+ *
+ * 05 04 2011 chinglan.wang
+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver
+ * .
+ *
+ * 03 29 2011 wh.su
+ * [WCXRP00000095] [MT6620 Wi-Fi] [FW] Refine the P2P GO send broadcast protected code
+ * add the set power and get power function sample.
+ *
+ * 03 22 2011 george.huang
+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
+ * link with supplicant commands
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add Security check related code.
+ *
+ * 03 01 2011 wh.su
+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
+ * fixed the ioctl sumcmd to meet the p2p_supplicant setting.
+ *
+ * 02 23 2011 wh.su
+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
+ * adding the ioctl set int define for p2p parameter.
+ *
+ * 02 22 2011 wh.su
+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters
+ *
+ * 02 17 2011 wh.su
+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
+ * adjust the set wsc ie structure.
+ *
+ * 01 05 2011 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * ioctl implementations for P2P Service Discovery
+ *
+ * 12 22 2010 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * 1. header file restructure for more clear module isolation
+ * 2. add function interface definition for implementing Service Discovery callbacks
+ *
+ * 12 15 2010 cp.wu
+ * NULL
+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart()
+ *
+ * 12 07 2010 cp.wu
+ * [WCXRP00000237] [MT6620 Wi-Fi][Wi-Fi Direct][Driver] Add interface for supporting service discovery
+ * define a pair of i/o control for multiplexing layer
+ *
+ * 11 04 2010 wh.su
+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
+ * adding the p2p random ssid support.
+ *
+ * 10 20 2010 wh.su
+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
+ * Add the code to support disconnect p2p group
+ *
+ * 09 21 2010 kevin.huang
+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
+ * Isolate P2P related function for Hardware Software Bundle
+ *
+ * 09 10 2010 george.huang
+ * NULL
+ * update iwpriv LP related
+ *
+ * 09 07 2010 wh.su
+ * NULL
+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
+ *
+ * 08 25 2010 cp.wu
+ * NULL
+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater
+ *
+ * 08 20 2010 yuche.tsai
+ * NULL
+ * Refine a function parameter name.
+ *
+ * 08 19 2010 cp.wu
+ * NULL
+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address.
+ *
+ * 08 16 2010 george.huang
+ * NULL
+ * add wext handlers to link P2P set PS profile/ network address function (TBD)
+ *
+ * 08 16 2010 cp.wu
+ * NULL
+ * revised implementation of Wi-Fi Direct io controls.
+ *
+ * 08 12 2010 cp.wu
+ * NULL
+ * follow-up with ioctl interface update for Wi-Fi Direct application
+ *
+ * 08 06 2010 cp.wu
+ * NULL
+ * driver hook modifications corresponding to ioctl interface change.
+ *
+ * 08 03 2010 cp.wu
+ * NULL
+ * [Wi-Fi Direct] add framework for driver hooks
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 06 01 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl to configure scan mode for p2p connection
+ *
+ * 05 31 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add cfg80211 interface, which is to replace WE, for further extension
+ *
+ * 05 17 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement get scan result.
+ *
+ * 05 14 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * implement wireless extension ioctls in iw_handler form.
+ *
+ * 05 14 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * p2p ioctls revised.
+ *
+ * 05 11 2010 cp.wu
+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
+ * add ioctl for controlling p2p scan phase parameters
+ *
+*/
+
+#ifndef _GL_P2P_IOCTL_H
+#define _GL_P2P_IOCTL_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#endif
+
+#include "wlan_oid.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* Device private ioctl calls */
+/* #define SIOCDEVPRIVATE  0x89F0*/
+#define IOC_GET_PRIVATE_IOCTL_CMD	(SIOCDEVPRIVATE+1)
+
+/* (WirelessExtension) Private I/O Controls */
+#define IOC_P2P_CFG_DEVICE              (SIOCIWFIRSTPRIV+0)
+#define IOC_P2P_PROVISION_COMPLETE      (SIOCIWFIRSTPRIV+2)
+#define IOC_P2P_START_STOP_DISCOVERY    (SIOCIWFIRSTPRIV+4)
+#define IOC_P2P_DISCOVERY_RESULTS       (SIOCIWFIRSTPRIV+5)
+#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6)
+#define IOC_P2P_GO_WSC_IE               IOC_P2P_WSC_BEACON_PROBE_RSP_IE
+#define IOC_P2P_CONNECT_DISCONNECT      (SIOCIWFIRSTPRIV+8)
+#define IOC_P2P_PASSWORD_READY          (SIOCIWFIRSTPRIV+10)
+/* #define IOC_P2P_SET_PWR_MGMT_PARAM      (SIOCIWFIRSTPRIV+12) */
+#define IOC_P2P_SET_INT                 (SIOCIWFIRSTPRIV+12)
+#define IOC_P2P_GET_STRUCT              (SIOCIWFIRSTPRIV+13)
+#define IOC_P2P_SET_STRUCT              (SIOCIWFIRSTPRIV+14)
+#define IOC_P2P_GET_REQ_DEVICE_INFO     (SIOCIWFIRSTPRIV+15)
+
+#define PRIV_CMD_INT_P2P_SET            0
+
+/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */
+#define P2P_PROVISIONING_SUCCESS        0
+#define P2P_PROVISIONING_FAIL           1
+
+/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */
+#define P2P_STOP_DISCOVERY              0
+#define P2P_START_DISCOVERY             1
+
+/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */
+#define P2P_CONNECT                     0
+#define P2P_DISCONNECT                  1
+
+/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */
+#define P2P_SCAN_FULL_AND_FIND          0
+#define P2P_SCAN_FULL                   1
+#define P2P_SCAN_SEARCH_AND_LISTEN      2
+#define P2P_LISTEN                      3
+
+/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */
+#define P2P_SEND_SD_RESPONSE            0
+#define P2P_GET_SD_REQUEST              1
+#define P2P_SEND_SD_REQUEST             2
+#define P2P_GET_SD_RESPONSE             3
+#define P2P_TERMINATE_SD_PHASE          4
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/* Wireless Extension: Private I/O Control                                    */
+/*----------------------------------------------------------------------------*/
+typedef struct iw_p2p_cfg_device_type {
+	void __user *ssid;
+	UINT_8 ssid_len;
+	UINT_8 pri_device_type[8];
+	UINT_8 snd_device_type[8];
+	void __user *device_name;
+	UINT_8 device_name_len;
+	UINT_8 intend;
+	UINT_8 persistence;
+	UINT_8 sec_mode;
+	UINT_8 ch;
+	UINT_8 ch_width;	/* 0: 20 Mhz  1:20/40 Mhz auto */
+	UINT_8 max_scb;
+} IW_P2P_CFG_DEVICE_TYPE, *P_IW_P2P_CFG_DEVICE_TYPE;
+
+typedef struct iw_p2p_hostapd_param {
+	UINT_8 cmd;
+	UINT_8 rsv[3];
+	UINT_8 sta_addr[6];
+	void __user *data;
+	UINT_16 len;
+} IW_P2P_HOSTAPD_PARAM, *P_IW_P2P_HOSTAPD_PARAM;
+
+typedef struct iw_p2p_req_device_type {
+	UINT_8 scan_type;	/* 0: Full scan + Find
+				 * 1: Full scan
+				 * 2: Scan (Search +Listen)
+				 * 3: Listen
+				 * other : reserved
+				 */
+	UINT_8 pri_device_type[8];
+	void __user *probe_req_ie;
+	UINT_16 probe_req_len;
+	void __user *probe_rsp_ie;
+	UINT_16 probe_rsp_len;
+} IW_P2P_REQ_DEVICE_TYPE, *P_IW_P2P_REQ_DEVICE_TYPE;
+
+typedef struct iw_p2p_connect_device {
+	UINT_8 sta_addr[6];
+	UINT_8 p2pRole;		/* 0: P2P Device, 1:GC, 2: GO */
+	UINT_8 needProvision;	/* 0: Don't needed provision, 1: doing the wsc provision first */
+	UINT_8 authPeer;	/* 1: auth peer invitation request */
+	UINT_8 intend_config_method;	/* Request Peer Device used config method */
+} IW_P2P_CONNECT_DEVICE, *P_IW_P2P_CONNECT_DEVICE;
+
+typedef struct iw_p2p_password_ready {
+	UINT_8 active_config_method;
+	void __user *probe_req_ie;
+	UINT_16 probe_req_len;
+	void __user *probe_rsp_ie;
+	UINT_16 probe_rsp_len;
+} IW_P2P_PASSWORD_READY, *P_IW_P2P_PASSWORD_READY;
+
+typedef struct iw_p2p_device_req {
+	UINT_8 name[33];
+	UINT_32 name_len;
+	UINT_8 device_addr[6];
+	UINT_8 device_type;
+	INT_32 config_method;
+	INT_32 active_config_method;
+} IW_P2P_DEVICE_REQ, *P_IW_P2P_DEVICE_REQ;
+
+typedef struct iw_p2p_transport_struct {
+	UINT_32 u4CmdId;
+	UINT_32 inBufferLength;
+	UINT_32 outBufferLength;
+	UINT_8 aucBuffer[16];
+} IW_P2P_TRANSPORT_STRUCT, *P_IW_P2P_TRANSPORT_STRUCT;
+
+/* For Invitation */
+typedef struct iw_p2p_ioctl_invitation_struct {
+	UINT_8 aucDeviceID[6];
+	UINT_8 aucGroupID[6];	/* BSSID */
+	UINT_8 aucSsid[32];
+	UINT_32 u4SsidLen;
+	UINT_8 ucReinvoke;
+} IW_P2P_IOCTL_INVITATION_STRUCT, *P_IW_P2P_IOCTL_INVITATION_STRUCT;
+
+typedef struct iw_p2p_ioctl_abort_invitation {
+	UINT_8 dev_addr[6];
+} IW_P2P_IOCTL_ABORT_INVITATION, *P_IW_P2P_IOCTL_ABORT_INVITATION;
+
+typedef struct iw_p2p_ioctl_invitation_indicate {
+	UINT_8 dev_addr[6];
+	UINT_8 group_bssid[6];
+	INT_32 config_method;	/* peer device supported config method */
+	UINT_8 dev_name[32];	/* for reinvoke */
+	UINT_32 name_len;
+	UINT_8 operating_channel;	/* for re-invoke, target operating channel */
+	UINT_8 invitation_type;	/* invitation or re-invoke */
+} IW_P2P_IOCTL_INVITATION_INDICATE, *P_IW_P2P_IOCTL_INVITATION_INDICATE;
+
+typedef struct iw_p2p_ioctl_invitation_status {
+	UINT_32 status_code;
+} IW_P2P_IOCTL_INVITATION_STATUS, *P_IW_P2P_IOCTL_INVITATION_STATUS;
+
+/* For Formation */
+typedef struct iw_p2p_ioctl_start_formation {
+	UINT_8 dev_addr[6];	/* bssid */
+	UINT_8 role;		/* 0: P2P Device, 1:GC, 2: GO */
+	UINT_8 needProvision;	/* 0: Don't needed provision, 1: doing the wsc provision first */
+	UINT_8 auth;		/* 1: auth peer invitation request */
+	UINT_8 config_method;	/* Request Peer Device used config method */
+} IW_P2P_IOCTL_START_FORMATION, *P_IW_P2P_IOCTL_START_FORMATION;
+
+/* SET_STRUCT / GET_STRUCT */
+typedef enum _ENUM_P2P_CMD_ID_T {
+	P2P_CMD_ID_SEND_SD_RESPONSE = 0,	/* 0x00 (Set) */
+	P2P_CMD_ID_GET_SD_REQUEST,	/* 0x01 (Get) */
+	P2P_CMD_ID_SEND_SD_REQUEST,	/* 0x02 (Set) */
+	P2P_CMD_ID_GET_SD_RESPONSE,	/* 0x03 (Get) */
+	P2P_CMD_ID_TERMINATE_SD_PHASE,	/* 0x04 (Set) */
+#if 1				/* CFG_SUPPORT_ANTI_PIRACY */
+	P2P_CMD_ID_SEC_CHECK,	/* 0x05(Set) */
+#endif
+	P2P_CMD_ID_INVITATION,	/* 0x06 (Set) */
+	P2P_CMD_ID_INVITATION_INDICATE,	/* 0x07 (Get) */
+	P2P_CMD_ID_INVITATION_STATUS,	/* 0x08 (Get) */
+	P2P_CMD_ID_INVITATION_ABORT,	/* 0x09 (Set) */
+	P2P_CMD_ID_START_FORMATION,	/* 0x0A (Set) */
+	P2P_CMD_ID_P2P_VERSION,	/* 0x0B (Set/Get) */
+	P2P_CMD_ID_GET_CH_LIST = 12,	/* 0x0C (Get) */
+	P2P_CMD_ID_GET_OP_CH = 14	/* 0x0E (Get) */
+} ENUM_P2P_CMD_ID_T, *P_ENUM_P2P_CMD_ID_T;
+
+/* Service Discovery */
+typedef struct iw_p2p_cmd_send_sd_response {
+	PARAM_MAC_ADDRESS rReceiverAddr;
+	UINT_8 fgNeedTxDoneIndication;
+	UINT_8 ucSeqNum;
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} IW_P2P_CMD_SEND_SD_RESPONSE, *P_IW_P2P_CMD_SEND_SD_RESPONSE;
+
+typedef struct iw_p2p_cmd_get_sd_request {
+	PARAM_MAC_ADDRESS rTransmitterAddr;
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} IW_P2P_CMD_GET_SD_REQUEST, *P_IW_P2P_CMD_GET_SD_REQUEST;
+
+typedef struct iw_p2p_cmd_send_service_discovery_request {
+	PARAM_MAC_ADDRESS rReceiverAddr;
+	UINT_8 fgNeedTxDoneIndication;
+	UINT_8 ucSeqNum;
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} IW_P2P_CMD_SEND_SD_REQUEST, *P_IW_P2P_CMD_SEND_SD_REQUEST;
+
+typedef struct iw_p2p_cmd_get_sd_response {
+	PARAM_MAC_ADDRESS rTransmitterAddr;
+	UINT_16 u2PacketLength;
+	UINT_8 aucPacketContent[0];	/*native 802.11 */
+} IW_P2P_CMD_GET_SD_RESPONSE, *P_IW_P2P_CMD_GET_SD_RESPONSE;
+
+typedef struct iw_p2p_cmd_terminate_sd_phase {
+	PARAM_MAC_ADDRESS rPeerAddr;
+} IW_P2P_CMD_TERMINATE_SD_PHASE, *P_IW_P2P_CMD_TERMINATE_SD_PHASE;
+
+typedef struct iw_p2p_version {
+	UINT_32 u4Version;
+} IW_P2P_VERSION, *P_IW_P2P_VERSION;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+extern struct ieee80211_supported_band mtk_band_2ghz;
+extern struct ieee80211_supported_band mtk_band_5ghz;
+extern UINT_32 mtk_cipher_suites[5];
+#endif
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+int mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy,
+				  struct net_device *ndev,
+				  enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params);
+
+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy,
+			     struct net_device *ndev,
+			     u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params);
+
+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy,
+			     struct net_device *ndev,
+			     u8 key_index,
+			     bool pairwise,
+			     const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)
+);
+
+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy,
+			     struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr);
+
+int
+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy,
+				 struct net_device *netdev, u8 key_index, bool unicast, bool multicast);
+
+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
+					const u8 *mac, struct station_info *sinfo);
+
+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+
+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme);
+
+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code);
+
+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params);
+
+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
+
+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout);
+
+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params);
+
+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy,
+				       struct wireless_dev *wdev,
+				       struct ieee80211_channel *chan, unsigned int duration, u64 *cookie);
+
+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request);
+
+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie);
+
+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy,
+				 struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm);
+
+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm);
+
+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req);
+
+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req);
+
+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings);
+
+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info);
+
+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy,
+			     struct wireless_dev *wdev,
+			     struct cfg80211_mgmt_tx_params *params,
+			     u64 *cookie);
+
+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev);
+
+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params);
+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac);
+
+int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef);
+
+void mtk_p2p_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg);
+
+int
+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy,
+				  IN struct net_device *dev,
+				  IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask);
+
+#ifdef CONFIG_NL80211_TESTMODE
+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len);
+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len);
+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len);
+
+#if CFG_SUPPORT_WFD
+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len);
+#endif
+
+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len);
+#else
+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct"
+#endif
+
+#endif
+
+/* I/O control handlers */
+
+int
+mtk_p2p_wext_get_priv(IN struct net_device *prDev,
+		      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_reconnect(IN struct net_device *prDev,
+		       IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_auth(IN struct net_device *prDev,
+		      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_key(IN struct net_device *prDev,
+		     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev,
+			  IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_powermode(IN struct net_device *prDev,
+			   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_get_powermode(IN struct net_device *prDev,
+			   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+/* Private Wireless I/O Controls takes use of iw_handler */
+int
+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev,
+				IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev,
+				    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev,
+				  IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_discovery_results(IN struct net_device *prDev,
+			       IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev,
+		    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev,
+				IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_password_ready(IN struct net_device *prDev,
+			    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev,
+			      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev,
+				 IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_invitation_status(IN struct net_device *prDev,
+			       IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev,
+			  IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev,
+			    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_network_address(IN struct net_device *prDev,
+				 IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_int(IN struct net_device *prDev,
+		     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */
+int
+mtk_p2p_wext_set_struct(IN struct net_device *prDev,
+			IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_get_struct(IN struct net_device *prDev,
+			IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */
+int
+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev,
+					   IN struct iw_request_info *info,
+					   IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev,
+					    IN struct iw_request_info *info,
+					    IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev,
+					    IN struct iw_request_info *info,
+					    IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev,
+					     IN struct iw_request_info *info,
+					     IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev,
+					       IN struct iw_request_info *info,
+					       IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+#if CFG_SUPPORT_ANTI_PIRACY
+int
+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev,
+				   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev,
+				    IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+#endif
+
+int
+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev,
+			   IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev,
+			     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev,
+			     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+int
+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev,
+			     IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+void mtk_p2p_wext_set_Multicastlist(IN P_GLUE_INFO_T prGlueInfo);
+
+#if CFG_SUPPORT_P2P_RSSI_QUERY
+int
+mtk_p2p_wext_get_rssi(IN struct net_device *prDev,
+		      IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra);
+
+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev);
+
+#endif
+
+int
+mtk_p2p_wext_set_txpow(IN struct net_device *prDev,
+		       IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _GL_P2P_IOCTL_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h
new file mode 100644
index 0000000000000..bf9d8871ef48a
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h
@@ -0,0 +1,243 @@
+/*
+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_kal.h#2
+*/
+
+/*! \file   gl_p2p_kal.h
+    \brief  Declaration of KAL functions for Wi-Fi Direct support
+	    - kal*() which is provided by GLUE Layer.
+
+    Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+/*
+** Log: gl_p2p_kal.h
+**
+** 08 30 2012 chinglan.wang
+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
+** .
+ *
+ * 07 17 2012 yuche.tsai
+ * NULL
+ * Compile no error before trial run.
+ *
+ * 10 18 2011 yuche.tsai
+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
+ * New 2.1 branch
+
+ *
+ * 08 15 2011 yuche.tsai
+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
+ * Add group BSSID in invitation request indication.
+ * The BSSID is used for APP to decide the configure method.
+ *
+ * 08 09 2011 yuche.tsai
+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
+ * Invitation Feature add on.
+ *
+ * 03 19 2011 terry.wu
+ * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
+ * create V2.0 p2p driver release based on label "MT6620_WIFI_P2P_DRIVER_V2_0_2100_0319_2011" from main trunk.
+ *
+ * 03 07 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * rename the define to anti_pviracy.
+ *
+ * 03 05 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * add the code to get the check rsponse and indicate to app.
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add Security check related code.
+ *
+ * 12 22 2010 cp.wu
+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service
+ * Discovery
+ * 1. header file restructure for more clear module isolation
+ * 2. add function interface definition for implementing Service Discovery callbacks
+ *
+*/
+
+#ifndef _GL_P2P_KAL_H
+#define _GL_P2P_KAL_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "config.h"
+#include "gl_typedef.h"
+#include "gl_os.h"
+#include "wlan_lib.h"
+#include "wlan_oid.h"
+#include "wlan_p2p.h"
+#include "gl_kal.h"
+#include "gl_wext_priv.h"
+#include "nic/p2p.h"
+
+#if DBG
+extern int allocatedMemSize;
+#endif
+
+extern BOOLEAN
+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE);
+
+#if CFG_SUPPORT_WPS
+extern BOOLEAN
+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE);
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type);
+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo);
+
+/* Service Discovery */
+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum);
+
+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum);
+
+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus);
+
+/*----------------------------------------------------------------------------*/
+/* Wi-Fi Direct handling                                                      */
+/*----------------------------------------------------------------------------*/
+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID
+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo,
+	       IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole);
+
+VOID
+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo,
+		      IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest);
+
+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo);
+
+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID
+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo,
+	      IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole);
+
+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher);
+
+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode);
+
+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo);
+
+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType);
+
+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer);
+
+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength);
+
+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo);
+
+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength,
+			   IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType,	/* 0: P2P Device / 1: GC / 2: GO */
+			   IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod);
+
+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus);
+
+VOID
+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo,
+			   IN P_P2P_DEVICE_DESC_T prP2pDevDesc,
+			   IN PUINT_8 pucSsid,
+			   IN UINT_8 ucSsidLen,
+			   IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid);
+
+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo);
+
+VOID
+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo,
+	       IN ENUM_BAND_T eSpecificBand,
+	       IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList);
+
+#if CFG_SUPPORT_ANTI_PIRACY
+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen);
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+VOID
+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo,
+			   IN UINT_64 u8SeqNum,
+			   IN UINT_32 u4ChannelNum,
+			   IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration);
+
+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort);
+
+VOID
+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo,
+		      IN PUINT_8 pucFrameBuf,
+		      IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength);
+
+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb);
+
+VOID
+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo,
+			   IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen);
+
+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo);
+
+VOID
+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo,
+				 IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo,
+				 IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason,
+                                 IN WLAN_STATUS eStatus);
+
+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew);
+
+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock);
+
+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid);
+
+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient);
+
+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient);
+
+#endif /* _GL_P2P_KAL_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h
new file mode 100644
index 0000000000000..e5026e7e6eec5
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h
@@ -0,0 +1,242 @@
+/*
+** Id:
+//Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/os/linux/include/gl_p2p_os.h#28
+*/
+
+/*! \file   gl_p2p_os.h
+    \brief  List the external reference to OS for p2p GLUE Layer.
+
+    In this file we define the data structure - GLUE_INFO_T to store those objects
+    we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the
+    external reference (header file, extern func() ..) to OS for GLUE Layer should
+    also list down here.
+*/
+
+#ifndef _GL_P2P_OS_H
+#define _GL_P2P_OS_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/netdevice.h>
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+#include <net/cfg80211.h>
+#endif
+
+#include "wlan_oid.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+struct _GL_P2P_INFO_T {
+
+	/* Device handle */
+	struct net_device *prDevHandler;
+
+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211
+	/* cfg80211 */
+	struct wireless_dev *prWdev;
+
+	struct cfg80211_scan_request *prScanRequest;
+
+	UINT_64 u8Cookie;
+
+	/* Generation for station list update. */
+	INT_32 i4Generation;
+
+	UINT_32 u4OsMgmtFrameFilter;
+
+#endif
+
+	/* Device statistics */
+	struct net_device_stats rNetDevStats;
+
+	/* glue layer variables */
+	UINT_32 u4FreqInKHz;	/* frequency */
+	UINT_8 ucRole;		/* 0: P2P Device, 1: Group Client, 2: Group Owner */
+	UINT_8 ucIntent;	/* range: 0-15 */
+	UINT_8 ucScanMode;	/* 0: Search & Listen, 1: Scan without probe response */
+
+	ENUM_PARAM_MEDIA_STATE_T eState;
+	UINT_32 u4PacketFilter;
+	PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR];
+
+	/* connection-requested peer information */
+	UINT_8 aucConnReqDevName[32];
+	INT_32 u4ConnReqNameLength;
+	PARAM_MAC_ADDRESS rConnReqPeerAddr;
+	PARAM_MAC_ADDRESS rConnReqGroupAddr;	/* For invitation group. */
+	UINT_8 ucConnReqDevType;
+	INT_32 i4ConnReqConfigMethod;
+	INT_32 i4ConnReqActiveConfigMethod;
+
+	UINT_32 u4CipherPairwise;
+	UINT_8 ucWSCRunning;
+
+	UINT_8 aucWSCIE[3][400];	/* 0 for beacon, 1 for probe req, 2 for probe response */
+	UINT_16 u2WSCIELen[3];
+
+#if CFG_SUPPORT_WFD
+	UINT_8 aucVenderIE[1024];	/* Save the other IE for prove resp */
+	UINT_16 u2VenderIELen;
+#endif
+
+	UINT_8 ucOperatingChnl;
+	UINT_8 ucInvitationType;
+
+	UINT_32 u4InvStatus;
+
+	/* For SET_STRUCT/GET_STRUCT */
+	UINT_8 aucOidBuf[4096];
+
+#if 1				/* CFG_SUPPORT_ANTI_PIRACY */
+	UINT_8 aucSecCheck[256];
+	UINT_8 aucSecCheckRsp[256];
+#endif
+
+	/* Hotspot Client Management */
+	PARAM_MAC_ADDRESS aucblackMACList[8];
+	UINT_8 ucMaxClients;
+
+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
+	UINT_32 u4PsLevel;
+#endif
+};
+
+#ifdef CONFIG_NL80211_TESTMODE
+typedef struct _NL80211_DRIVER_TEST_PRE_PARAMS {
+	UINT_16 idx_mode;
+	UINT_16 idx;
+	UINT_32 value;
+} NL80211_DRIVER_TEST_PRE_PARAMS, *P_NL80211_DRIVER_TEST_PRE_PARAMS;
+
+typedef struct _NL80211_DRIVER_TEST_PARAMS {
+	UINT_32 index;
+	UINT_32 buflen;
+} NL80211_DRIVER_TEST_PARAMS, *P_NL80211_DRIVER_TEST_PARAMS;
+
+/* P2P Sigma*/
+typedef struct _NL80211_DRIVER_P2P_SIGMA_PARAMS {
+	NL80211_DRIVER_TEST_PARAMS hdr;
+	UINT_32 idx;
+	UINT_32 value;
+} NL80211_DRIVER_P2P_SIGMA_PARAMS, *P_NL80211_DRIVER_P2P_SIGMA_PARAMS;
+
+/* Hotspot Client Management */
+typedef struct _NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS {
+	NL80211_DRIVER_TEST_PARAMS hdr;
+	UINT_8 ucblocked;
+	UINT_8 aucBssid[MAC_ADDR_LEN];
+} NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS, *P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS;
+
+#if CFG_SUPPORT_WFD
+typedef struct _NL80211_DRIVER_WFD_PARAMS {
+	NL80211_DRIVER_TEST_PARAMS hdr;
+	UINT_32 WfdCmdType;
+	UINT_8 WfdEnable;
+	UINT_8 WfdCoupleSinkStatus;
+	UINT_8 WfdSessionAvailable;
+	UINT_8 WfdSigmaMode;
+	UINT_16 WfdDevInfo;
+	UINT_16 WfdControlPort;
+	UINT_16 WfdMaximumTp;
+	UINT_16 WfdExtendCap;
+	UINT_8 WfdCoupleSinkAddress[MAC_ADDR_LEN];
+	UINT_8 WfdAssociatedBssid[MAC_ADDR_LEN];
+	UINT_8 WfdVideoIp[4];
+	UINT_8 WfdAudioIp[4];
+	UINT_16 WfdVideoPort;
+	UINT_16 WfdAudioPort;
+	UINT_32 WfdFlag;
+	UINT_32 WfdPolicy;
+	UINT_32 WfdState;
+	UINT_8 WfdSessionInformationIE[24 * 8];	/* Include Subelement ID, length */
+	UINT_16 WfdSessionInformationIELen;
+	UINT_8 aucReserved1[2];
+	UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN];
+	UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN];
+	UINT_32 WfdAdvanceFlag;
+	/* Group 1 64 bytes */
+	UINT_8 aucWfdLocalIp[4];
+	UINT_16 WfdLifetimeAc2;	/* Unit is 2 TU */
+	UINT_16 WfdLifetimeAc3;	/* Unit is 2 TU */
+	UINT_16 WfdCounterThreshold;	/* Unit is ms */
+	UINT_8 aucReserved2[54];
+	/* Group 3 64 bytes */
+	UINT_8 aucReserved3[64];
+	/* Group 3 64 bytes */
+	UINT_8 aucReserved4[64];
+} NL80211_DRIVER_WFD_PARAMS, *P_NL80211_DRIVER_WFD_PARAMS;
+#endif
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo);
+
+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde);
+
+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode);
+
+VOID p2pEalySuspendReg(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsEnable);
+
+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired);
+
+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired);
+
+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo);
+
+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo);
+
+VOID glP2pDestroyWirelessDevice(VOID);
+
+VOID p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo);
+
+#endif
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h
new file mode 100644
index 0000000000000..f24ceee9e921a
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h
@@ -0,0 +1,133 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_rst.h#1
+*/
+
+/*! \file   gl_rst.h
+    \brief  Declaration of functions and finite state machine for
+	    MT6620 Whole-Chip Reset Mechanism
+*/
+
+#ifndef _GL_RST_H
+#define _GL_RST_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include "gl_typedef.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+#if 1
+typedef INT_32(*wmt_wlan_probe_cb) (VOID);
+typedef INT_32(*wmt_wlan_remove_cb) (VOID);
+typedef INT_32(*wmt_wlan_bus_cnt_get_cb) (VOID);
+typedef INT_32(*wmt_wlan_bus_cnt_clr_cb) (VOID);
+
+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO {
+	wmt_wlan_probe_cb wlan_probe_cb;
+	wmt_wlan_remove_cb wlan_remove_cb;
+	wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb;
+	wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb;
+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO;
+
+extern INT_32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo);
+extern INT_32 mtk_wcn_wmt_wlan_unreg(VOID);
+#endif
+
+typedef enum _ENUM_RESET_STATUS_T {
+	RESET_FAIL,
+	RESET_SUCCESS
+} ENUM_RESET_STATUS_T;
+
+typedef struct _RESET_STRUCT_T {
+	ENUM_RESET_STATUS_T rst_data;
+	struct work_struct rst_work;
+} RESET_STRUCT_T;
+
+typedef enum _ENUM_WMTRSTMSG_TYPE_T {
+	WMTRSTMSG_RESET_START = 0x0,
+	WMTRSTMSG_RESET_END = 0x1,
+	WMTRSTMSG_RESET_END_FAIL = 0x2,
+	WMTRSTMSG_RESET_MAX,
+	WMTRSTMSG_RESET_INVALID = 0xff
+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T;
+
+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T,	/* Source driver type */
+			   ENUM_WMTDRV_TYPE_T,	/* Destination driver type */
+			   ENUM_WMTMSG_TYPE_T,	/* Message type */
+			   void *,	/* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client
+					   can't touch this buffer after this function return. */
+			   unsigned int	/* Buffer size in unit of byte */
+);
+
+/*******************************************************************************
+*                    E X T E R N A L   F U N C T I O N S
+********************************************************************************
+*/
+#define glDoChipReset() \
+	do { \
+		if (!kalStrnCmp(current->comm, "mtk_wmtd", 8)) { \
+			g_IsNeedDoChipReset = 1; \
+			DBGLOG(INIT, ERROR, "forbid core dump in mtk_wmtd %s line %d\n", __func__, __LINE__); \
+			break; \
+		} \
+		DBGLOG(INIT, ERROR, "Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \
+		mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 0x40); \
+	} while (0)
+
+#if CFG_CHIP_RESET_SUPPORT
+extern int mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb);
+extern int mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType);
+extern int wifi_reset_start(void);
+extern int wifi_reset_end(ENUM_RESET_STATUS_T);
+#endif
+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason);
+extern BOOLEAN mtk_wcn_set_connsys_power_off_flag(BOOLEAN value);
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+extern UINT_32 g_IsNeedDoChipReset;
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+VOID glResetInit(VOID);
+
+VOID glResetUninit(VOID);
+
+VOID glSendResetRequest(VOID);
+
+BOOLEAN kalIsResetting(VOID);
+
+#endif /* _GL_RST_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h
new file mode 100644
index 0000000000000..3cc57780f2010
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h
@@ -0,0 +1,21 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_sec.h#1
+*/
+
+/*! \file   p2p_fsm.h
+    \brief  Declaration of functions and finite state machine for P2P Module.
+
+    Declaration of functions and finite state machine for P2P Module.
+*/
+
+#ifndef _GL_SEC_H
+#define _GL_SEC_H
+
+extern void handle_sec_msg_1(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len);
+extern void handle_sec_msg_2(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len);
+extern void handle_sec_msg_3(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len);
+extern void handle_sec_msg_4(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len);
+extern void handle_sec_msg_5(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len);
+extern void handle_sec_msg_final(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len);
+
+#endif /* _GL_SEC_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h
new file mode 100644
index 0000000000000..e9aa3e849eb2e
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h
@@ -0,0 +1,298 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_typedef.h#1
+*/
+
+/*! \file   gl_typedef.h
+    \brief  Definition of basic data type(os dependent).
+
+    In this file we define the basic data type.
+*/
+
+/*
+** Log: gl_typedef.h
+ *
+ * 06 22 2012 cp.wu
+ * [WCXRP00001257] [MT6620][MT5931][MT6628][Driver][Linux] Modify KAL_HZ to align ms accuracy
+ * modify KAL_HZ to (1000) for correct definition.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * portability improvement
+ *
+ * 02 15 2011 jeffrey.chang
+ * NULL
+ * to support early suspend in android
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\6 2009-08-18 22:57:14 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\5 2008-09-22 23:19:30 GMT mtk01461
+**  Update comment for code review
+**  \main\maintrunk.MT5921\4 2008-09-05 17:25:16 GMT mtk01461
+**  Update Driver for Code Review
+**  \main\maintrunk.MT5921\3 2007-11-09 11:00:50 GMT mtk01425
+**  1. Use macro to unify network-to-host and host-to-network related functions
+** Revision 1.3  2007/06/27 02:18:51  MTK01461
+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
+**
+** Revision 1.2  2007/06/25 06:16:24  MTK01461
+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
+**
+*/
+
+#ifndef _GL_TYPEDEF_H
+#define _GL_TYPEDEF_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* Define HZ of timer tick for function kalGetTimeTick() */
+#define KAL_HZ                  (1000)
+
+/* Miscellaneous Equates */
+#ifndef FALSE
+#define FALSE               ((BOOLEAN) 0)
+#define TRUE                ((BOOLEAN) 1)
+#endif /* FALSE */
+
+#ifndef NULL
+#if defined(__cplusplus)
+#define NULL            0
+#else
+#define NULL            ((void *) 0)
+#endif
+#endif
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* Type definition for void */
+/*mach/mt_typedefs.h define _TYPEDEFS_H, to avoid compile error*/
+#ifndef _TYPEDEFS_H
+typedef void VOID;
+#endif
+typedef void *PVOID, **PPVOID;
+
+/* Type definition for Boolean */
+typedef unsigned char BOOLEAN, *PBOOLEAN;
+
+/* Type definition for signed integers */
+typedef signed char CHAR, *PCHAR, **PPCHAR;
+typedef signed char INT_8, *PINT_8, **PPINT_8;
+typedef signed short INT_16, *PINT_16, **PPINT_16;
+typedef signed int INT_32, *PINT_32, **PPINT_32;
+typedef long LONG, *PLONG, **PPLONG;
+typedef signed long long INT_64, *PINT_64, **PPINT_64;
+
+/* Type definition for unsigned integers */
+typedef unsigned char UCHAR, *PUCHAR, **PPUCHAR;
+typedef unsigned char UINT_8, *PUINT_8, **PPUINT_8, *P_UINT_8;
+typedef unsigned short UINT_16, *PUINT_16, **PPUINT_16;
+typedef unsigned int UINT32, *PUINT32;
+typedef unsigned int UINT_32, *PUINT_32, **PPUINT_32;
+typedef unsigned long ULONG, *PULONG, **PPULONG;
+typedef unsigned long long UINT_64, *PUINT_64, **PPUINT_64;
+
+typedef unsigned int OS_SYSTIME, *POS_SYSTIME, **PPOS_SYSTIME;
+
+#ifndef _TYPEDEFS_H
+typedef signed char INT8, *PINT8;
+typedef signed short INT16, *PINT16;
+typedef signed int INT32, *PINT32;
+typedef unsigned char UINT8, *PUINT8;
+typedef unsigned short UINT16, *PUINT16;
+typedef unsigned int UINT32, *PUINT32;
+#endif
+
+/* Type definition of large integer (64bits) union to be comptaible with
+ * Windows definition, so we won't apply our own coding style to these data types.
+ * NOTE: LARGE_INTEGER must NOT be floating variable.
+ * <TODO>: Check for big-endian compatibility.
+ */
+typedef union _LARGE_INTEGER {
+	struct {
+		UINT_32 LowPart;
+		INT_32 HighPart;
+	} u;
+	INT_64 QuadPart;
+} LARGE_INTEGER, *PLARGE_INTEGER;
+
+typedef union _ULARGE_INTEGER {
+	struct {
+		UINT_32 LowPart;
+		UINT_32 HighPart;
+	} u;
+	UINT_64 QuadPart;
+} ULARGE_INTEGER, *PULARGE_INTEGER;
+
+typedef INT_32(*probe_card) (PVOID pvData);
+typedef VOID(*remove_card) (VOID);
+
+/* duplicated from wmt_exp.h for better driver isolation */
+typedef enum _ENUM_WMTDRV_TYPE_T {
+	WMTDRV_TYPE_BT = 0,
+	WMTDRV_TYPE_FM = 1,
+	WMTDRV_TYPE_GPS = 2,
+	WMTDRV_TYPE_WIFI = 3,
+	WMTDRV_TYPE_WMT = 4,
+	WMTDRV_TYPE_STP = 5,
+	WMTDRV_TYPE_SDIO1 = 6,
+	WMTDRV_TYPE_SDIO2 = 7,
+	WMTDRV_TYPE_LPBK = 8,
+	WMTDRV_TYPE_MAX
+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T;
+
+typedef enum _ENUM_WMTMSG_TYPE_T {
+	WMTMSG_TYPE_POWER_ON = 0,
+	WMTMSG_TYPE_POWER_OFF = 1,
+	WMTMSG_TYPE_RESET = 2,
+	WMTMSG_TYPE_STP_RDY = 3,
+	WMTMSG_TYPE_HW_FUNC_ON = 4,
+	WMTMSG_TYPE_MAX
+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T;
+
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+#define IN			/* volatile */
+#define OUT			/* volatile */
+
+#define __KAL_ATTRIB_PACKED__           __attribute__((__packed__))
+#define __KAL_ATTRIB_ALIGN_4__          __aligned(4)
+
+#ifndef BIT
+#define BIT(n)                          ((UINT_32) 1U << (n))
+#endif /* BIT */
+
+#ifndef BITS
+/* bits range: for example BITS(16,23) = 0xFF0000
+ *   ==>  (BIT(m)-1)   = 0x0000FFFF     ~(BIT(m)-1)   => 0xFFFF0000
+ *   ==>  (BIT(n+1)-1) = 0x00FFFFFF
+ */
+#define BITS(m, n)                       (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n)))
+#endif /* BIT */
+
+/* This macro returns the byte offset of a named field in a known structure
+   type.
+   _type - structure name,
+   _field - field name of the structure */
+#ifndef OFFSET_OF
+#define OFFSET_OF(_type, _field)    ((ULONG)&(((_type *)0)->_field))
+#endif /* OFFSET_OF */
+
+/* This macro returns the base address of an instance of a structure
+ * given the type of the structure and the address of a field within the
+ * containing structure.
+ * _addrOfField - address of current field of the structure,
+ * _type - structure name,
+ * _field - field name of the structure
+ */
+#ifndef ENTRY_OF
+#define ENTRY_OF(_addrOfField, _type, _field) \
+	((_type *)((PINT_8)(_addrOfField) - (PINT_8)OFFSET_OF(_type, _field)))
+#endif /* ENTRY_OF */
+
+/* This macro align the input value to the DW boundary.
+ * _value - value need to check
+ */
+#ifndef ALIGN_4
+#define ALIGN_4(_value)             (((_value) + 3) & ~3u)
+#endif /* ALIGN_4 */
+
+/* This macro check the DW alignment of the input value.
+ * _value - value of address need to check
+ */
+#ifndef IS_ALIGN_4
+#define IS_ALIGN_4(_value)          (((_value) & 0x3) ? FALSE : TRUE)
+#endif /* IS_ALIGN_4 */
+
+#ifndef IS_NOT_ALIGN_4
+#define IS_NOT_ALIGN_4(_value)      (((_value) & 0x3) ? TRUE : FALSE)
+#endif /* IS_NOT_ALIGN_4 */
+
+/* This macro evaluate the input length in unit of Double Word(4 Bytes).
+ * _value - value in unit of Byte, output will round up to DW boundary.
+ */
+#ifndef BYTE_TO_DWORD
+#define BYTE_TO_DWORD(_value)       ((_value + 3) >> 2)
+#endif /* BYTE_TO_DWORD */
+
+/* This macro evaluate the input length in unit of Byte.
+ * _value - value in unit of DW, output is in unit of Byte.
+ */
+#ifndef DWORD_TO_BYTE
+#define DWORD_TO_BYTE(_value)       ((_value) << 2)
+#endif /* DWORD_TO_BYTE */
+
+#if 1				/* Little-Endian */
+#define CONST_NTOHS(_x)     ntohs(_x)
+
+#define CONST_HTONS(_x)     htons(_x)
+
+#define NTOHS(_x)           ntohs(_x)
+
+#define HTONS(_x)           htons(_x)
+
+#define NTOHL(_x)           ntohl(_x)
+
+#define HTONL(_x)           htonl(_x)
+
+#else /* Big-Endian */
+
+#define CONST_NTOHS(_x)
+
+#define CONST_HTONS(_x)
+
+#define NTOHS(_x)
+
+#define HTONS(_x)
+
+#endif
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _GL_TYPEDEF_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h
new file mode 100644
index 0000000000000..d8d5b0fb67402
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h
@@ -0,0 +1,619 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_vendor.h#1
+*/
+
+/*! \file   gl_vendor.h
+	\brief  This file is for Portable Driver linux gl_vendor support.
+*/
+
+/*
+** Log: gl_vendor.h
+**
+** 10 14 2014
+** add vendor declaration
+**
+ *
+*/
+
+#ifndef _GL_VENDOR_H
+#define _GL_VENDOR_H
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#include <linux/can/netlink.h>
+#include <net/netlink.h>
+
+#include "gl_os.h"
+
+#include "wlan_lib.h"
+#include "gl_wext.h"
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define GOOGLE_OUI 0x001A11
+
+typedef enum {
+	/* Don't use 0 as a valid subcommand */
+	ANDROID_NL80211_SUBCMD_UNSPECIFIED,
+
+	/* Define all vendor startup commands between 0x0 and 0x0FFF */
+	ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001,
+	ANDROID_NL80211_SUBCMD_WIFI_RANGE_END   = 0x0FFF,
+
+	/* Define all GScan related commands between 0x1000 and 0x10FF */
+	ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
+	ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END   = 0x10FF,
+
+	/* Define all RTT related commands between 0x1100 and 0x11FF */
+	ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
+	ANDROID_NL80211_SUBCMD_RTT_RANGE_END   = 0x11FF,
+
+	ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
+	ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END   = 0x12FF,
+
+	/* Define all Logger related commands between 0x1400 and 0x14FF */
+	ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
+	ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END   = 0x14FF,
+
+	/* Define all wifi offload related commands between 0x1600 and 0x16FF */
+	ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
+	ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END   = 0x16FF,
+
+	/* This is reserved for future usage */
+
+} ANDROID_VENDOR_SUB_COMMAND;
+
+typedef enum {
+	WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START,
+
+	WIFI_SUBCMD_GET_FEATURE_SET,                     /* 0x0001 */
+	WIFI_SUBCMD_GET_FEATURE_SET_MATRIX,              /* 0x0002 */
+	WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI,              /* 0x0003 */
+	WIFI_SUBCMD_NODFS_SET,                           /* 0x0004 */
+	WIFI_SUBCMD_SET_COUNTRY_CODE,                    /* 0x0005 */
+	/* Add more sub commands here */
+
+} WIFI_SUB_COMMAND;
+
+typedef enum {
+	GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
+
+	GSCAN_SUBCMD_SET_CONFIG,                          /* 0x1001 */
+	GSCAN_SUBCMD_SET_SCAN_CONFIG,                     /* 0x1002 */
+	GSCAN_SUBCMD_ENABLE_GSCAN,                        /* 0x1003 */
+	GSCAN_SUBCMD_GET_SCAN_RESULTS,                    /* 0x1004 */
+	GSCAN_SUBCMD_SCAN_RESULTS,                        /* 0x1005 */
+
+	GSCAN_SUBCMD_SET_HOTLIST,                         /* 0x1006 */
+
+	GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,       /* 0x1007 */
+	GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,            /* 0x1008 */
+	/* Add more sub commands here */
+
+} GSCAN_SUB_COMMAND;
+
+typedef enum {
+	RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
+	RTT_SUBCMD_CANCEL_CONFIG,
+	RTT_SUBCMD_GETCAPABILITY,
+} RTT_SUB_COMMAND;
+
+typedef enum {
+	LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
+} LSTATS_SUB_COMMAND;
+
+typedef enum {
+	GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS,
+	GSCAN_EVENT_HOTLIST_RESULTS_FOUND,
+	GSCAN_EVENT_SCAN_RESULTS_AVAILABLE,
+	GSCAN_EVENT_FULL_SCAN_RESULTS,
+	RTT_EVENT_COMPLETE,
+	GSCAN_EVENT_COMPLETE_SCAN,
+	GSCAN_EVENT_HOTLIST_RESULTS_LOST
+} WIFI_VENDOR_EVENT;
+
+typedef enum {
+	WIFI_ATTRIBUTE_BAND,
+	WIFI_ATTRIBUTE_NUM_CHANNELS,
+	WIFI_ATTRIBUTE_CHANNEL_LIST,
+
+	WIFI_ATTRIBUTE_NUM_FEATURE_SET,
+	WIFI_ATTRIBUTE_FEATURE_SET,
+	WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
+	WIFI_ATTRIBUTE_NODFS_VALUE,
+	WIFI_ATTRIBUTE_COUNTRY_CODE
+
+} WIFI_ATTRIBUTE;
+
+typedef enum {
+	GSCAN_ATTRIBUTE_CAPABILITIES = 1,
+
+	GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
+	GSCAN_ATTRIBUTE_BASE_PERIOD,
+	GSCAN_ATTRIBUTE_BUCKETS_BAND,
+	GSCAN_ATTRIBUTE_BUCKET_ID,
+	GSCAN_ATTRIBUTE_BUCKET_PERIOD,
+	GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
+	GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
+	GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
+	GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
+	GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
+
+	GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
+	GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE,	/* indicates no more results */
+	GSCAN_ATTRIBUTE_FLUSH_FEATURE,	/* Flush all the configs */
+	GSCAN_ENABLE_FULL_SCAN_RESULTS,
+	GSCAN_ATTRIBUTE_REPORT_EVENTS,
+
+	GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
+	GSCAN_ATTRIBUTE_FLUSH_RESULTS,
+	GSCAN_ATTRIBUTE_SCAN_RESULTS,	/* flat array of wifi_scan_result */
+	GSCAN_ATTRIBUTE_SCAN_ID,	/* indicates scan number */
+	GSCAN_ATTRIBUTE_SCAN_FLAGS,	/* indicates if scan was aborted */
+	GSCAN_ATTRIBUTE_AP_FLAGS,	/* flags on significant change event */
+
+	GSCAN_ATTRIBUTE_SSID = 40,
+	GSCAN_ATTRIBUTE_BSSID,
+	GSCAN_ATTRIBUTE_CHANNEL,
+	GSCAN_ATTRIBUTE_RSSI,
+	GSCAN_ATTRIBUTE_TIMESTAMP,
+	GSCAN_ATTRIBUTE_RTT,
+	GSCAN_ATTRIBUTE_RTTSD,
+
+	GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50,
+	GSCAN_ATTRIBUTE_RSSI_LOW,
+	GSCAN_ATTRIBUTE_RSSI_HIGH,
+	GSCAN_ATTRIBUTE_HOTLIST_ELEM,
+	GSCAN_ATTRIBUTE_HOTLIST_FLUSH,
+
+	GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60,
+	GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE,
+	GSCAN_ATTRIBUTE_MIN_BREACHING,
+	GSCAN_ATTRIBUTE_NUM_AP,
+	GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS,
+	GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH
+
+} GSCAN_ATTRIBUTE;
+
+typedef enum {
+	RTT_ATTRIBUTE_CAPABILITIES = 1,
+
+	RTT_ATTRIBUTE_TARGET_CNT = 10,
+	RTT_ATTRIBUTE_TARGET_INFO,
+	RTT_ATTRIBUTE_TARGET_MAC,
+	RTT_ATTRIBUTE_TARGET_TYPE,
+	RTT_ATTRIBUTE_TARGET_PEER,
+	RTT_ATTRIBUTE_TARGET_CHAN,
+	RTT_ATTRIBUTE_TARGET_PERIOD,
+	RTT_ATTRIBUTE_TARGET_NUM_BURST,
+	RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
+	RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
+	RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
+	RTT_ATTRIBUTE_TARGET_LCI,
+	RTT_ATTRIBUTE_TARGET_LCR,
+	RTT_ATTRIBUTE_TARGET_BURST_DURATION,
+	RTT_ATTRIBUTE_TARGET_PREAMBLE,
+	RTT_ATTRIBUTE_TARGET_BW,
+	RTT_ATTRIBUTE_RESULTS_COMPLETE = 30,
+	RTT_ATTRIBUTE_RESULTS_PER_TARGET,
+	RTT_ATTRIBUTE_RESULT_CNT,
+	RTT_ATTRIBUTE_RESULT
+} RTT_ATTRIBUTE;
+
+typedef enum {
+	LSTATS_ATTRIBUTE_STATS = 2,
+} LSTATS_ATTRIBUTE;
+
+typedef enum {
+	WIFI_BAND_UNSPECIFIED,
+	WIFI_BAND_BG = 1,	    /* 2.4 GHz */
+	WIFI_BAND_A = 2,	    /* 5 GHz without DFS */
+	WIFI_BAND_A_DFS = 4,	    /* 5 GHz DFS only */
+	WIFI_BAND_A_WITH_DFS = 6,   /* 5 GHz with DFS */
+	WIFI_BAND_ABG = 3,	    /* 2.4 GHz + 5 GHz; no DFS */
+	WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */
+} WIFI_BAND;
+
+typedef enum {
+	WIFI_SCAN_BUFFER_FULL,
+	WIFI_SCAN_COMPLETE,
+} WIFI_SCAN_EVENT;
+
+#define GSCAN_MAX_REPORT_THRESHOLD   1024000
+#define GSCAN_MAX_CHANNELS                 8
+#define GSCAN_MAX_BUCKETS                  8
+#define MAX_HOTLIST_APS                   16
+#define MAX_SIGNIFICANT_CHANGE_APS        16
+#define PSCAN_MAX_SCAN_CACHE_SIZE         16
+#define PSCAN_MAX_AP_CACHE_PER_SCAN       16
+#define PSCAN_VERSION                      1
+
+#define MAX_BUFFERED_GSCN_RESULTS 5
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef UINT_64 wifi_timestamp;	/* In microseconds (us) */
+typedef UINT_64 wifi_timespan;	/* In nanoseconds  (ns) */
+
+typedef UINT_8 mac_addr[6];
+typedef UINT_32 wifi_channel;	/* Indicates channel frequency in MHz */
+typedef INT_32 wifi_rssi;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+typedef struct _PARAM_WIFI_GSCAN_GET_RESULT_PARAMS {
+	UINT_32 get_num;
+	UINT_8 flush;
+} PARAM_WIFI_GSCAN_GET_RESULT_PARAMS, *P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS;
+
+typedef struct _PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS {
+	UINT_8 ucPscanAct;
+	UINT_8 aucReserved[3];
+} PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS;
+
+typedef struct _PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T {
+	UINT_32 max_scan_cache_size;	/* total space allocated for scan (in bytes) */
+	UINT_32 max_scan_buckets;	/* maximum number of channel buckets */
+	UINT_32 max_ap_cache_per_scan;	/* maximum number of APs that can be stored per scan */
+	UINT_32 max_rssi_sample_size;	/* number of RSSI samples used for averaging RSSI */
+	UINT_32 max_scan_reporting_threshold;	/* max possible report_threshold as described */
+	/* in wifi_scan_cmd_params */
+	UINT_32 max_hotlist_aps;	/* maximum number of entries for hotlist APs */
+	UINT_32 max_significant_wifi_change_aps;	/* maximum number of entries for */
+	/* significant wifi change APs */
+	UINT_32 max_bssid_history_entries;	/* number of BSSID/RSSI entries that device can hold */
+} PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T, *P_PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T;
+
+typedef struct _PARAM_WIFI_GSCAN_CHANNEL_SPEC {
+	UINT_32 channel;	/* frequency */
+	UINT_32 dwellTimeMs;	/* dwell time hint */
+	UINT_32 passive;	/* 0 => active, 1 => passive scan; ignored for DFS */
+	/* Add channel class */
+} PARAM_WIFI_GSCAN_CHANNEL_SPEC, *P_PARAM_WIFI_GSCAN_CHANNEL_SPEC;
+
+typedef struct _PARAM_WIFI_GSCAN_BUCKET_SPEC {
+	UINT_32 bucket;		/* bucket index, 0 based */
+	WIFI_BAND band;		/* when UNSPECIFIED, use channel list */
+	UINT_32 period;		/* desired period, in millisecond; if this is too */
+	/* low, the firmware should choose to generate results as */
+	/* fast as it can instead of failing the command */
+	/* report_events semantics -
+	 *  0 => report only when scan history is % full
+	 *  1 => same as 0 + report a scan completion event after scanning this bucket
+	 *  2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL
+	 *  3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to
+	 supplicant as well (optional) . */
+	UINT_8 report_events;
+
+	UINT_32 num_channels;
+	PARAM_WIFI_GSCAN_CHANNEL_SPEC channels[GSCAN_MAX_CHANNELS];	/* channels to scan;
+									these may include DFS channels */
+} PARAM_WIFI_GSCAN_BUCKET_SPEC, *P_PARAM_WIFI_GSCAN_BUCKET_SPEC;
+
+typedef struct _PARAM_WIFI_GSCAN_CMD_PARAMS {
+	UINT_32 base_period;	/* base timer period in ms */
+	UINT_32 max_ap_per_scan;	/* number of APs to store in each scan in the */
+	/* BSSID/RSSI history buffer (keep the highest RSSI APs) */
+	UINT_32 report_threshold;	/* in %, when scan buffer is this much full, wake up AP */
+	UINT_32 num_scans;
+	UINT_32 num_buckets;
+	PARAM_WIFI_GSCAN_BUCKET_SPEC buckets[GSCAN_MAX_BUCKETS];
+} PARAM_WIFI_GSCAN_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_CMD_PARAMS;
+
+typedef struct _PARAM_WIFI_GSCAN_RESULT {
+	wifi_timestamp ts;	/* time since boot (in microsecond) when the result was */
+	/* retrieved */
+	UINT_8 ssid[32 + 1];	/* null terminated */
+	mac_addr bssid;
+	wifi_channel channel;	/* channel frequency in MHz */
+	wifi_rssi rssi;		/* in db */
+	wifi_timespan rtt;	/* in nanoseconds */
+	wifi_timespan rtt_sd;	/* standard deviation in rtt */
+	UINT_16 beacon_period;	/* period advertised in the beacon */
+	UINT_16 capability;	/* capabilities advertised in the beacon */
+	UINT_32 ie_length;	/* size of the ie_data blob */
+	UINT_8 ie_data[1];	/* blob of all the information elements found in the */
+	/* beacon; this data should be a packed list of */
+	/* wifi_information_element objects, one after the other. */
+	/* other fields */
+} PARAM_WIFI_GSCAN_RESULT, *P_PARAM_WIFI_GSCAN_RESULT;
+
+/* Significant wifi change*/
+/*typedef struct _PARAM_WIFI_CHANGE_RESULT{
+	mac_addr bssid;                     // BSSID
+	wifi_channel channel;               // channel frequency in MHz
+	UINT_32 num_rssi;                       // number of rssi samples
+	wifi_rssi rssi[8];                   // RSSI history in db
+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT;*/
+
+typedef struct _PARAM_WIFI_CHANGE_RESULT {
+	UINT_16 flags;
+	UINT_16 channel;
+	mac_addr bssid;		/* BSSID */
+	INT_8 rssi[8];		/* RSSI history in db */
+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT;
+
+typedef struct _PARAM_AP_THRESHOLD {
+	mac_addr bssid;		/* AP BSSID */
+	wifi_rssi low;		/* low threshold */
+	wifi_rssi high;		/* high threshold */
+	wifi_channel channel;	/* channel hint */
+} PARAM_AP_THRESHOLD, *P_PARAM_AP_THRESHOLD;
+
+typedef struct _PARAM_WIFI_BSSID_HOTLIST {
+	UINT_32 lost_ap_sample_size;
+	UINT_32 num_ap;		/* number of hotlist APs */
+	PARAM_AP_THRESHOLD ap[MAX_HOTLIST_APS];	/* hotlist APs */
+} PARAM_WIFI_BSSID_HOTLIST, *P_PARAM_WIFI_BSSID_HOTLIST;
+
+typedef struct _PARAM_WIFI_SIGNIFICANT_CHANGE {
+	UINT_16 rssi_sample_size;	/* number of samples for averaging RSSI */
+	UINT_16 lost_ap_sample_size;	/* number of samples to confirm AP loss */
+	UINT_16 min_breaching;	/* number of APs breaching threshold */
+	UINT_16 num_ap;		/* max 64 */
+	PARAM_AP_THRESHOLD ap[MAX_SIGNIFICANT_CHANGE_APS];
+} PARAM_WIFI_SIGNIFICANT_CHANGE, *P_PARAM_WIFI_SIGNIFICANT_CHANGE;
+
+/* RTT Capabilities */
+typedef struct _PARAM_WIFI_RTT_CAPABILITIES {
+	UINT_8 rtt_one_sided_supported;  /* if 1-sided rtt data collection is supported */
+	UINT_8 rtt_ftm_supported;        /* if ftm rtt data collection is supported */
+	UINT_8 lci_support;              /* if initiator supports LCI request. Applies to 2-sided RTT */
+	UINT_8 lcr_support;              /* if initiator supports LCR request. Applies to 2-sided RTT */
+	UINT_8 preamble_support;         /* bit mask indicates what preamble is supported by initiator */
+	UINT_8 bw_support;               /* bit mask indicates what BW is supported by initiator */
+} PARAM_WIFI_RTT_CAPABILITIES, *P_PARAM_WIFI_RTT_CAPABILITIES;
+
+/* channel operating width */
+typedef enum {
+	WIFI_CHAN_WIDTH_20 = 0,
+	WIFI_CHAN_WIDTH_40 = 1,
+	WIFI_CHAN_WIDTH_80 = 2,
+	WIFI_CHAN_WIDTH_160 = 3,
+	WIFI_CHAN_WIDTH_80P80 = 4,
+	WIFI_CHAN_WIDTH_5 = 5,
+	WIFI_CHAN_WIDTH_10 = 6,
+	WIFI_CHAN_WIDTH_INVALID = -1
+} WIFI_CHANNEL_WIDTH;
+
+/* channel information */
+typedef struct {
+	WIFI_CHANNEL_WIDTH width;	/* channel width (20, 40, 80, 80+80, 160) */
+	UINT_32 center_freq;	/* primary 20 MHz channel */
+	UINT_32 center_freq0;	/* center frequency (MHz) first segment */
+	UINT_32 center_freq1;	/* center frequency (MHz) second segment */
+} WIFI_CHANNEL_INFO;
+
+/* channel statistics */
+typedef struct {
+	WIFI_CHANNEL_INFO channel;	/* channel */
+	UINT_32 on_time;	/* msecs the radio is awake (32 bits number accruing over time) */
+	UINT_32 cca_busy_time;	/* msecs the CCA register is busy (32 bits number accruing over time) */
+} WIFI_CHANNEL_STAT;
+
+/* radio statistics */
+typedef struct {
+	UINT_32 radio;		/* wifi radio (if multiple radio supported) */
+	UINT_32 on_time;	/* msecs the radio is awake (32 bits number accruing over time) */
+	UINT_32 tx_time;	/* msecs the radio is transmitting (32 bits number accruing over time) */
+	UINT_32 rx_time;	/* msecs the radio is in active receive (32 bits number accruing over time) */
+	UINT_32 on_time_scan;	/* msecs the radio is awake due to all scan (32 bits number accruing over time) */
+	UINT_32 on_time_nbd;	/* msecs the radio is awake due to NAN (32 bits number accruing over time) */
+	UINT_32 on_time_gscan;	/* msecs the radio is awake due to G?scan (32 bits number accruing over time) */
+	UINT_32 on_time_roam_scan;	/* msecs the radio is awake due to roam?scan
+					(32 bits number accruing over time) */
+	UINT_32 on_time_pno_scan;	/* msecs the radio is awake due to PNO scan
+					(32 bits number accruing over time) */
+	UINT_32 on_time_hs20;	/* msecs the radio is awake due to HS2.0 scans and GAS exchange
+					32 bits number accruing over time) */
+	UINT_32 num_channels;	/* number of channels */
+	WIFI_CHANNEL_STAT channels[];	/* channel statistics */
+} WIFI_RADIO_STAT;
+
+/* wifi rate */
+typedef struct {
+	UINT_32 preamble:3;	/* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */
+	UINT_32 nss:2;		/* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */
+	UINT_32 bw:3;		/* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */
+	UINT_32 rateMcsIdx:8;	/* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */
+	/* HT/VHT it would be mcs index */
+	UINT_32 reserved:16;	/* reserved */
+	UINT_32 bitrate;	/* units of 100 Kbps */
+} WIFI_RATE;
+
+/* per rate statistics */
+typedef struct {
+	WIFI_RATE rate;		/* rate information */
+	UINT_32 tx_mpdu;	/* number of successfully transmitted data pkts (ACK rcvd) */
+	UINT_32 rx_mpdu;	/* number of received data pkts */
+	UINT_32 mpdu_lost;	/* number of data packet losses (no ACK) */
+	UINT_32 retries;	/* total number of data pkt retries */
+	UINT_32 retries_short;	/* number of short data pkt retries */
+	UINT_32 retries_long;	/* number of long data pkt retries */
+} WIFI_RATE_STAT;
+
+/*wifi_interface_link_layer_info*/
+typedef enum {
+	WIFI_DISCONNECTED = 0,
+	WIFI_AUTHENTICATING = 1,
+	WIFI_ASSOCIATING = 2,
+	WIFI_ASSOCIATED = 3,
+	WIFI_EAPOL_STARTED = 4,	/* if done by firmware/driver */
+	WIFI_EAPOL_COMPLETED = 5,	/* if done by firmware/driver */
+} WIFI_CONNECTION_STATE;
+
+typedef enum {
+	WIFI_ROAMING_IDLE = 0,
+	WIFI_ROAMING_ACTIVE = 1,
+} WIFI_ROAM_STATE;
+
+typedef enum {
+	WIFI_INTERFACE_STA = 0,
+	WIFI_INTERFACE_SOFTAP = 1,
+	WIFI_INTERFACE_IBSS = 2,
+	WIFI_INTERFACE_P2P_CLIENT = 3,
+	WIFI_INTERFACE_P2P_GO = 4,
+	WIFI_INTERFACE_NAN = 5,
+	WIFI_INTERFACE_MESH = 6,
+	WIFI_INTERFACE_UNKNOWN = -1
+} WIFI_INTERFACE_MODE;
+
+typedef struct {
+	WIFI_INTERFACE_MODE mode;	/* interface mode */
+	u8 mac_addr[6];		/* interface mac address (self) */
+	WIFI_CONNECTION_STATE state;	/* connection state (valid for STA, CLI only) */
+	WIFI_ROAM_STATE roaming;	/* roaming state */
+	u32 capabilities;	/* WIFI_CAPABILITY_XXX (self) */
+	u8 ssid[33];		/* null terminated SSID */
+	u8 bssid[6];		/* bssid */
+	u8 ap_country_str[3];	/* country string advertised by AP */
+	u8 country_str[3];	/* country string for this association */
+} WIFI_INTERFACE_LINK_LAYER_INFO;
+
+/* access categories */
+typedef enum {
+	WIFI_AC_VO = 0,
+	WIFI_AC_VI = 1,
+	WIFI_AC_BE = 2,
+	WIFI_AC_BK = 3,
+	WIFI_AC_MAX = 4,
+} WIFI_TRAFFIC_AC;
+
+/* wifi peer type */
+typedef enum {
+	WIFI_PEER_STA,
+	WIFI_PEER_AP,
+	WIFI_PEER_P2P_GO,
+	WIFI_PEER_P2P_CLIENT,
+	WIFI_PEER_NAN,
+	WIFI_PEER_TDLS,
+	WIFI_PEER_INVALID,
+} WIFI_PEER_TYPE;
+
+/* per peer statistics */
+typedef struct {
+	WIFI_PEER_TYPE type;	/* peer type (AP, TDLS, GO etc.) */
+	UINT_8 peer_mac_address[6];	/* mac address */
+	UINT_32 capabilities;	/* peer WIFI_CAPABILITY_XXX */
+	UINT_32 num_rate;	/* number of rates */
+	WIFI_RATE_STAT rate_stats[];	/* per rate statistics, number of entries  = num_rate */
+} WIFI_PEER_INFO;
+
+/* per access category statistics */
+typedef struct {
+	WIFI_TRAFFIC_AC ac;	/* access category (VI, VO, BE, BK) */
+	UINT_32 tx_mpdu;	/* number of successfully transmitted unicast data pkts (ACK rcvd) */
+	UINT_32 rx_mpdu;	/* number of received unicast mpdus */
+	UINT_32 tx_mcast;	/* number of successfully transmitted multicast data packets */
+	/* STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent */
+	UINT_32 rx_mcast;	/* number of received multicast data packets */
+	UINT_32 rx_ampdu;	/* number of received unicast a-mpdus */
+	UINT_32 tx_ampdu;	/* number of transmitted unicast a-mpdus */
+	UINT_32 mpdu_lost;	/* number of data pkt losses (no ACK) */
+	UINT_32 retries;	/* total number of data pkt retries */
+	UINT_32 retries_short;	/* number of short data pkt retries */
+	UINT_32 retries_long;	/* number of long data pkt retries */
+	UINT_32 contention_time_min;	/* data pkt min contention time (usecs) */
+	UINT_32 contention_time_max;	/* data pkt max contention time (usecs) */
+	UINT_32 contention_time_avg;	/* data pkt avg contention time (usecs) */
+	UINT_32 contention_num_samples;	/* num of data pkts used for contention statistics */
+} WIFI_WMM_AC_STAT;
+
+/* interface statistics */
+typedef struct {
+	/* wifi_interface_handle iface;          // wifi interface */
+	WIFI_INTERFACE_LINK_LAYER_INFO info;	/* current state of the interface */
+	UINT_32 beacon_rx;	/* access point beacon received count from connected AP */
+	UINT_32 mgmt_rx;	/* access point mgmt frames received count from connected AP (including Beacon) */
+	UINT_32 mgmt_action_rx;	/* action frames received count */
+	UINT_32 mgmt_action_tx;	/* action frames transmit count */
+	wifi_rssi rssi_mgmt;	/* access Point Beacon and Management frames RSSI (averaged) */
+	wifi_rssi rssi_data;	/* access Point Data Frames RSSI (averaged) from connected AP */
+	wifi_rssi rssi_ack;	/* access Point ACK RSSI (averaged) from connected AP */
+	WIFI_WMM_AC_STAT ac[WIFI_AC_MAX];	/* per ac data packet statistics */
+	UINT_32 num_peers;	/* number of peers */
+	WIFI_PEER_INFO peer_info[];	/* per peer statistics */
+} WIFI_IFACE_STAT;
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len);
+
+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len);
+
+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len);
+
+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len);
+
+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 const void *data, int data_len);
+
+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete);
+
+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num);
+
+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len);
+
+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len);
+
+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len);
+
+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev,
+					 P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len);
+
+#endif /* _GL_VENDOR_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h
new file mode 100644
index 0000000000000..827ff92b1581f
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h
@@ -0,0 +1,357 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext.h#1
+*/
+
+/*! \file   gl_wext.h
+    \brief  This file is for Portable Driver linux wireless extension support.
+*/
+
+/*
+** Log: gl_wext.h
+ *
+ * 10 12 2011 wh.su
+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
+ * adding the 802.11w related function and define .
+ *
+ * 09 20 2011 chinglan.wang
+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
+ * .
+ *
+ * 09 20 2011 chinglan.wang
+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
+ * .
+ *
+ * 01 11 2011 chinglan.wang
+ * NULL
+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP.
+ * Connection establish successfully.
+ * Use the WPS function to connect AP, the privacy bit always is set to 1. .
+ *
+ * 09 27 2010 wh.su
+ * NULL
+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\12 2009-10-20 17:38:33 GMT mtk01090
+**  Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests,
+**  and then stop hw.
+**  \main\maintrunk.MT5921\11 2009-09-28 20:19:28 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\10 2009-09-03 12:12:35 GMT mtk01088
+**  adding the function declaration
+**  \main\maintrunk.MT5921\9 2009-08-18 22:57:17 GMT mtk01090
+**  Add Linux SDIO (with mmc core) support.
+**  Add Linux 2.6.21, 2.6.25, 2.6.26.
+**  Fix compile warning in Linux.
+**  \main\maintrunk.MT5921\8 2008-08-29 16:59:07 GMT mtk01088
+**  fixed compiling error
+**  \main\maintrunk.MT5921\7 2008-08-29 14:13:28 GMT mtk01088
+**  adjust the header file for code refine
+**  \main\maintrunk.MT5921\6 2008-03-28 10:40:31 GMT mtk01461
+**  Add set desired rate in Linux STD IOCTL
+**  \main\maintrunk.MT5921\5 2008-03-11 14:51:08 GMT mtk01461
+**  Refine private IOCTL functions
+**  \main\maintrunk.MT5921\4 2008-02-12 23:45:45 GMT mtk01461
+**  Add Set Frequency & Channel oid support for Linux
+**  \main\maintrunk.MT5921\3 2007-11-06 19:36:19 GMT mtk01088
+**  add the WPS related code
+*/
+
+#ifndef _GL_WEXT_H
+#define _GL_WEXT_H
+
+#ifdef WIRELESS_EXT
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define KILO          1000
+#define RATE_5_5M     11	/* 5.5M */
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef struct _PARAM_FIXED_IEs {
+	UINT_8 aucTimestamp[8];
+	UINT_16 u2BeaconInterval;
+	UINT_16 u2Capabilities;
+} PARAM_FIXED_IEs;
+
+typedef struct _PARAM_VARIABLE_IE_T {
+	UINT_8 ucElementID;
+	UINT_8 ucLength;
+	UINT_8 aucData[1];
+} PARAM_VARIABLE_IE_T, *P_PARAM_VARIABLE_IE_T;
+
+#if WIRELESS_EXT < 18
+
+#define SIOCSIWMLME 0x8B16	/* request MLME operation; uses struct iw_mlme */
+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
+#define IW_MLME_DEAUTH      0
+#define IW_MLME_DISASSOC    1
+
+/*! \brief SIOCSIWMLME data */
+struct iw_mlme {
+	__u16 cmd;		/*!< IW_MLME_* */
+	__u16 reason_code;
+	struct sockaddr addr;
+};
+
+#define SIOCSIWAUTH 0x8B32	/* set authentication mode params */
+#define SIOCGIWAUTH 0x8B33	/* get authentication mode params */
+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
+#define IW_AUTH_INDEX       0x0FFF
+#define IW_AUTH_FLAGS       0xF000
+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095)
+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the
+ * parameter that is being set/get to; value will be read/written to
+ * struct iw_param value field) */
+#define IW_AUTH_WPA_VERSION             0
+#define IW_AUTH_CIPHER_PAIRWISE         1
+#define IW_AUTH_CIPHER_GROUP            2
+#define IW_AUTH_KEY_MGMT                3
+#define IW_AUTH_TKIP_COUNTERMEASURES    4
+#define IW_AUTH_DROP_UNENCRYPTED        5
+#define IW_AUTH_80211_AUTH_ALG          6
+#define IW_AUTH_WPA_ENABLED             7
+#define IW_AUTH_RX_UNENCRYPTED_EAPOL    8
+#define IW_AUTH_ROAMING_CONTROL         9
+#define IW_AUTH_PRIVACY_INVOKED        10
+#if CFG_SUPPORT_802_11W
+#define IW_AUTH_MFP                    12
+
+#define IW_AUTH_MFP_DISABLED    0	/* MFP disabled */
+#define IW_AUTH_MFP_OPTIONAL    1	/* MFP optional */
+#define IW_AUTH_MFP_REQUIRED    2	/* MFP required */
+#endif
+
+/* IW_AUTH_WPA_VERSION values (bit field) */
+#define IW_AUTH_WPA_VERSION_DISABLED    0x00000001
+#define IW_AUTH_WPA_VERSION_WPA         0x00000002
+#define IW_AUTH_WPA_VERSION_WPA2        0x00000004
+
+/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */
+#define IW_AUTH_CIPHER_NONE     0x00000001
+#define IW_AUTH_CIPHER_WEP40    0x00000002
+#define IW_AUTH_CIPHER_TKIP     0x00000004
+#define IW_AUTH_CIPHER_CCMP     0x00000008
+#define IW_AUTH_CIPHER_WEP104   0x00000010
+
+/* IW_AUTH_KEY_MGMT values (bit field) */
+#define IW_AUTH_KEY_MGMT_802_1X     1
+#define IW_AUTH_KEY_MGMT_PSK        2
+#define IW_AUTH_KEY_MGMT_WPA_NONE   4
+
+/* IW_AUTH_80211_AUTH_ALG values (bit field) */
+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
+#define IW_AUTH_ALG_SHARED_KEY  0x00000002
+#define IW_AUTH_ALG_LEAP        0x00000004
+
+/* IW_AUTH_ROAMING_CONTROL values */
+#define IW_AUTH_ROAMING_ENABLE  0	/* driver/firmware based roaming */
+#define IW_AUTH_ROAMING_DISABLE 1	/* user space program used for roaming
+					 * control */
+
+#define SIOCSIWENCODEEXT 0x8B34	/* set encoding token & mode */
+#define SIOCGIWENCODEEXT 0x8B35	/* get encoding token & mode */
+/* SIOCSIWENCODEEXT definitions */
+#define IW_ENCODE_SEQ_MAX_SIZE  8
+/* struct iw_encode_ext ->alg */
+#define IW_ENCODE_ALG_NONE  0
+#define IW_ENCODE_ALG_WEP   1
+#define IW_ENCODE_ALG_TKIP  2
+#define IW_ENCODE_ALG_CCMP  3
+#if CFG_SUPPORT_802_11W
+#define IW_ENCODE_ALG_AES_CMAC  5
+#endif
+
+/* struct iw_encode_ext ->ext_flags */
+#define IW_ENCODE_EXT_TX_SEQ_VALID  0x00000001
+#define IW_ENCODE_EXT_RX_SEQ_VALID  0x00000002
+#define IW_ENCODE_EXT_GROUP_KEY     0x00000004
+#define IW_ENCODE_EXT_SET_TX_KEY    0x00000008
+
+struct iw_encode_ext {
+	__u32 ext_flags;	/*!< IW_ENCODE_EXT_* */
+	__u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE];	/*!< LSB first */
+	__u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE];	/*!< LSB first */
+	struct sockaddr addr;	/*!< ff:ff:ff:ff:ff:ff for broadcast/multicast
+				 *   (group) keys or unicast address for
+				 *   individual keys */
+	__u16 alg;		/*!< IW_ENCODE_ALG_* */
+	__u16 key_len;
+	__u8 key[0];
+};
+
+#define SIOCSIWPMKSA        0x8B36	/* PMKSA cache operation */
+#define IW_PMKSA_ADD        1
+#define IW_PMKSA_REMOVE     2
+#define IW_PMKSA_FLUSH      3
+
+#define IW_PMKID_LEN        16
+
+struct iw_pmksa {
+	__u32 cmd;		/*!< IW_PMKSA_* */
+	struct sockaddr bssid;
+	__u8 pmkid[IW_PMKID_LEN];
+};
+
+#define IWEVGENIE   0x8C05	/* Generic IE (WPA, RSN, WMM, ..)
+				 * (scan results); This includes id and
+				 * length fields. One IWEVGENIE may
+				 * contain more than one IE. Scan
+				 * results may contain one or more
+				 * IWEVGENIE events. */
+#define IWEVMICHAELMICFAILURE 0x8C06	/* Michael MIC failure
+					 * (struct iw_michaelmicfailure)
+					 */
+#define IWEVASSOCREQIE  0x8C07	/* IEs used in (Re)Association Request.
+				 * The data includes id and length
+				 * fields and may contain more than one
+				 * IE. This event is required in
+				 * Managed mode if the driver
+				 * generates its own WPA/RSN IE. This
+				 * should be sent just before
+				 * IWEVREGISTERED event for the
+				 * association. */
+#define IWEVASSOCRESPIE 0x8C08	/* IEs used in (Re)Association
+				 * Response. The data includes id and
+				 * length fields and may contain more
+				 * than one IE. This may be sent
+				 * between IWEVASSOCREQIE and
+				 * IWEVREGISTERED events for the
+				 * association. */
+#define IWEVPMKIDCAND   0x8C09	/* PMKID candidate for RSN
+				 * pre-authentication
+				 * (struct iw_pmkid_cand) */
+
+#endif /* WIRELESS_EXT < 18 */
+
+#if WIRELESS_EXT < 17
+/* Statistics flags (bitmask in updated) */
+#define IW_QUAL_QUAL_UPDATED    0x1	/* Value was updated since last read */
+#define IW_QUAL_LEVEL_UPDATED   0x2
+#define IW_QUAL_NOISE_UPDATED   0x4
+#define IW_QUAL_QUAL_INVALID    0x10	/* Driver doesn't provide value */
+#define IW_QUAL_LEVEL_INVALID   0x20
+#define IW_QUAL_NOISE_INVALID   0x40
+#endif
+
+enum {
+	IEEE80211_FILTER_TYPE_BEACON = 1 << 0,
+	IEEE80211_FILTER_TYPE_PROBE_REQ = 1 << 1,
+	IEEE80211_FILTER_TYPE_PROBE_RESP = 1 << 2,
+	IEEE80211_FILTER_TYPE_ASSOC_REQ = 1 << 3,
+	IEEE80211_FILTER_TYPE_ASSOC_RESP = 1 << 4,
+	IEEE80211_FILTER_TYPE_AUTH = 1 << 5,
+	IEEE80211_FILTER_TYPE_DEAUTH = 1 << 6,
+	IEEE80211_FILTER_TYPE_DISASSOC = 1 << 7,
+	IEEE80211_FILTER_TYPE_ALL = 0xFF	/* used to check the valid filter bits */
+};
+
+#if CFG_SUPPORT_WAPI
+#define IW_AUTH_WAPI_ENABLED     0x20
+#define IW_ENCODE_ALG_SMS4  0x20
+#endif
+
+#if CFG_SUPPORT_WAPI		/* Android+ */
+#define IW_AUTH_KEY_MGMT_WAPI_PSK   3
+#define IW_AUTH_KEY_MGMT_WAPI_CERT  4
+#endif
+#define IW_AUTH_KEY_MGMT_WPS  5
+
+#if CFG_SUPPORT_802_11W
+#define IW_AUTH_KEY_MGMT_802_1X_SHA256 7
+#define IW_AUTH_KEY_MGMT_PSK_SHA256 8
+#endif
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+extern const struct iw_handler_def wext_handler_def;
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+/* wireless extensions' ioctls */
+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd);
+
+int
+wext_set_rate(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra);
+
+void
+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo,
+			 IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4DataLen);
+
+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev);
+
+BOOLEAN
+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE);
+
+#if CFG_SUPPORT_WPS
+BOOLEAN
+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart,
+		     IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE);
+#endif
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE);
+
+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE);
+
+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE);
+
+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE);
+#endif
+
+#if CFG_SUPPORT_WAPI
+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE);
+#endif
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* WIRELESS_EXT */
+
+#endif /* _GL_WEXT_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h
new file mode 100644
index 0000000000000..31933fc6a461e
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h
@@ -0,0 +1,402 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext_priv.h#3
+*/
+
+/*! \file   gl_wext_priv.h
+    \brief  This file includes private ioctl support.
+*/
+
+/*
+** Log: gl_wext_priv.h
+ *
+ * 01 16 2012 wh.su
+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl
+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6)..
+ *
+ * 01 05 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the related ioctl / wlan oid function to set the Tx power cfg.
+ *
+ * 01 02 2012 wh.su
+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
+ *
+ * 11 08 2011 yuche.tsai
+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service
+ * discovery version check.
+ * Add a CMD ID for P2P driver version query.
+ *
+ * 03 17 2011 chinglan.wang
+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
+ * .
+ *
+ * 03 02 2011 wh.su
+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
+ * Add security check code.
+ *
+ * 01 27 2011 cm.chang
+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default
+ * .
+ *
+ * 01 20 2011 eddie.chen
+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
+ * Add Oid for sw control debug command
+ *
+ * 01 07 2011 cm.chang
+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
+ * Add a new compiling option to control if MCR read/write is permitted
+ *
+ * 12 31 2010 cm.chang
+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
+ * Add some iwpriv commands to support test mode operation
+ *
+ * 11 08 2010 wh.su
+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
+ * add the message check code from mt5921.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
+ * The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 09 23 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * add skeleton for NVRAM integration
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * revert changelist #15371, efuse read/write access will be done by RF test approach
+ *
+ * 08 04 2010 cp.wu
+ * NULL
+ * add OID definitions for EFUSE read/write access.
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+ *
+ * 03 31 2010 wh.su
+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support
+ * modify the wapi related code for new driver's design.
+ *
+ * 03 24 2010 jeffrey.chang
+ * [WPD00003826]Initial import for Linux port
+ * initial import for Linux port
+**  \main\maintrunk.MT5921\16 2009-09-29 16:47:23 GMT mtk01090
+**  Remove unused functions
+**  \main\maintrunk.MT5921\15 2009-09-28 20:19:31 GMT mtk01090
+**  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
+**  \main\maintrunk.MT5921\14 2009-05-07 22:26:06 GMT mtk01089
+**  add private IO control for Linux BWCS
+**  \main\maintrunk.MT5921\13 2008-08-29 14:55:20 GMT mtk01088
+**  adjust the code to meet coding style
+**  \main\maintrunk.MT5921\12 2008-07-16 15:23:45 GMT mtk01104
+**  Support GPIO2 mode
+**  \main\maintrunk.MT5921\11 2008-07-14 13:55:58 GMT mtk01104
+**  Support PRIV_CMD_BT_COEXIST
+**  \main\maintrunk.MT5921\10 2008-07-09 00:20:24 GMT mtk01461
+**  Add priv oid to support WMM_PS_TEST
+**  \main\maintrunk.MT5921\9 2008-05-30 20:27:24 GMT mtk01461
+**  Add POWER_MODE Private IOCTL cmd
+**  \main\maintrunk.MT5921\8 2008-04-17 23:06:44 GMT mtk01461
+**  Add iwpriv support for AdHocMode setting
+**  \main\maintrunk.MT5921\7 2008-03-31 21:01:24 GMT mtk01461
+**  Add priv IOCTL for VOIP settings
+**  \main\maintrunk.MT5921\6 2008-03-31 13:49:47 GMT mtk01461
+**  add priv ioctl arg definition for turning on / off roaming
+**  \main\maintrunk.MT5921\5 2008-03-26 15:35:09 GMT mtk01461
+**  Add CSUM offload priv ioctl for Linux
+**  \main\maintrunk.MT5921\4 2008-03-11 14:51:11 GMT mtk01461
+**  Refine private IOCTL functions
+**  \main\maintrunk.MT5921\3 2007-11-06 19:36:25 GMT mtk01088
+**  add the WPS related code
+*/
+
+#ifndef _GL_WEXT_PRIV_H
+#define _GL_WEXT_PRIV_H
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+/* If it is set to 1, iwpriv will support register read/write */
+#define CFG_SUPPORT_PRIV_MCR_RW         1
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+#if CFG_ENABLE_WIFI_DIRECT
+extern int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode);
+#if 0
+extern BOOLEAN fgIsResetting;
+extern BOOLEAN g_u4HaltFlag;
+extern spinlock_t g_p2p_lock;
+extern int g_u4P2PEnding;
+extern int g_u4P2POnOffing;
+#endif
+#endif
+
+
+#if (CFG_SUPPORT_TXR_ENC == 1)
+extern VOID rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen);
+#endif		/* CFG_SUPPORT_TXR_ENC */
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+/* New wireless extensions API - SET/GET convention (even ioctl numbers are
+ * root only)
+ */
+#define IOCTL_SET_INT                   (SIOCIWFIRSTPRIV + 0)
+#define IOCTL_GET_INT                   (SIOCIWFIRSTPRIV + 1)
+
+#define IOCTL_SET_ADDRESS               (SIOCIWFIRSTPRIV + 2)
+#define IOCTL_GET_ADDRESS               (SIOCIWFIRSTPRIV + 3)
+#define IOCTL_SET_STR                   (SIOCIWFIRSTPRIV + 4)
+#define IOCTL_GET_STR                   (SIOCIWFIRSTPRIV + 5)
+#define IOCTL_SET_KEY                   (SIOCIWFIRSTPRIV + 6)
+#define IOCTL_GET_KEY                   (SIOCIWFIRSTPRIV + 7)
+#define IOCTL_SET_STRUCT                (SIOCIWFIRSTPRIV + 8)
+#define IOCTL_GET_STRUCT                (SIOCIWFIRSTPRIV + 9)
+#define IOCTL_SET_STRUCT_FOR_EM         (SIOCIWFIRSTPRIV + 11)
+#define IOCTL_SET_INTS                  (SIOCIWFIRSTPRIV + 12)
+#define IOCTL_GET_INTS                  (SIOCIWFIRSTPRIV + 13)
+#define IOCTL_SET_STRING				(SIOCIWFIRSTPRIV + 14)
+
+#define PRIV_CMD_REG_DOMAIN             0
+#define PRIV_CMD_BEACON_PERIOD          1
+#define PRIV_CMD_ADHOC_MODE             2
+
+#if CFG_TCP_IP_CHKSUM_OFFLOAD
+#define PRIV_CMD_CSUM_OFFLOAD       3
+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
+
+#define PRIV_CMD_ROAMING                4
+#define PRIV_CMD_VOIP_DELAY             5
+#define PRIV_CMD_POWER_MODE             6
+
+#define PRIV_CMD_WMM_PS                 7
+#define PRIV_CMD_BT_COEXIST             8
+#define PRIV_GPIO2_MODE                 9
+
+#define PRIV_CUSTOM_SET_PTA			10
+#define PRIV_CUSTOM_CONTINUOUS_POLL     11
+#define PRIV_CUSTOM_SINGLE_ANTENNA		12
+#define PRIV_CUSTOM_BWCS_CMD			13
+#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION	14	/* later */
+#define PRIV_CMD_OID                    15
+#define PRIV_SEC_MSG_OID                16
+
+#define PRIV_CMD_TEST_MODE              17
+#define PRIV_CMD_TEST_CMD               18
+#define PRIV_CMD_ACCESS_MCR             19
+#define PRIV_CMD_SW_CTRL                20
+
+#if 1				/* ANTI_PRIVCY */
+#define PRIV_SEC_CHECK_OID              21
+#endif
+
+#define PRIV_CMD_WSC_PROBE_REQ          22
+
+#define PRIV_CMD_P2P_VERSION                   23
+
+#define PRIV_CMD_GET_CH_LIST            24
+
+#define PRIV_CMD_SET_TX_POWER           25
+
+#define PRIV_CMD_BAND_CONFIG            26
+
+#define PRIV_CMD_DUMP_MEM               27
+
+#define PRIV_CMD_P2P_MODE               28
+
+#define PRIV_CMD_GET_BUILD_DATE_CODE    29
+
+#define PRIV_CMD_GET_DEBUG_CODE			30
+
+#define PRIV_CMD_OTHER					31
+
+#define PRIV_CMD_WFD_DEBUG_CODE			32
+
+#define PRIV_CMD_MET_PROFILING			33
+
+/* other string command ID */
+#define PRIV_CMD_OTHER_TDLS				0x00
+#define PRIV_CMD_OTHER_TAR				0x01 /* TX auto rate */
+
+/* 802.3 Objects (Ethernet) */
+#define OID_802_3_CURRENT_ADDRESS           0x01010102
+
+/* IEEE 802.11 OIDs */
+#define OID_802_11_SUPPORTED_RATES              0x0D01020E
+#define OID_802_11_CONFIGURATION                0x0D010211
+
+/* PnP and PM OIDs, NDIS default OIDS */
+#define OID_PNP_SET_POWER                               0xFD010101
+
+#define OID_CUSTOM_OID_INTERFACE_VERSION                0xFFA0C000
+
+/* MT5921 specific OIDs */
+#define OID_CUSTOM_BT_COEXIST_CTRL                      0xFFA0C580
+#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE             0xFFA0C581
+#define OID_CUSTOM_PATTERN_CONFIG                       0xFFA0C582
+#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG                0xFFA0C583
+#define OID_CUSTOM_VOIP_SETUP                           0xFFA0C584
+#define OID_CUSTOM_ADD_TS                               0xFFA0C585
+#define OID_CUSTOM_DEL_TS                               0xFFA0C586
+#define OID_CUSTOM_SLT                               0xFFA0C587
+#define OID_CUSTOM_ROAMING_EN                           0xFFA0C588
+#define OID_CUSTOM_WMM_PS_TEST                          0xFFA0C589
+#define OID_CUSTOM_COUNTRY_STRING                       0xFFA0C58A
+#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY              0xFFA0C58B
+#define OID_CUSTOM_GPIO2_MODE                           0xFFA0C58C
+#define OID_CUSTOM_CONTINUOUS_POLL                      0xFFA0C58D
+#define OID_CUSTOM_DISABLE_BEACON_DETECTION             0xFFA0C58E
+
+/* CR1460, WPS privacy bit check disable */
+#define OID_CUSTOM_DISABLE_PRIVACY_CHECK                0xFFA0C600
+
+/* Precedent OIDs */
+#define OID_CUSTOM_MCR_RW                               0xFFA0C801
+#define OID_CUSTOM_EEPROM_RW                            0xFFA0C803
+#define OID_CUSTOM_SW_CTRL                              0xFFA0C805
+#define OID_CUSTOM_MEM_DUMP                             0xFFA0C807
+
+/* RF Test specific OIDs */
+#define OID_CUSTOM_TEST_MODE                            0xFFA0C901
+#define OID_CUSTOM_TEST_RX_STATUS                       0xFFA0C903
+#define OID_CUSTOM_TEST_TX_STATUS                       0xFFA0C905
+#define OID_CUSTOM_ABORT_TEST_MODE                      0xFFA0C906
+#define OID_CUSTOM_MTK_WIFI_TEST                        0xFFA0C911
+
+/* BWCS */
+#define OID_CUSTOM_BWCS_CMD                             0xFFA0C931
+#define OID_CUSTOM_SINGLE_ANTENNA                       0xFFA0C932
+#define OID_CUSTOM_SET_PTA                              0xFFA0C933
+
+/* NVRAM */
+#define OID_CUSTOM_MTK_NVRAM_RW                         0xFFA0C941
+#define OID_CUSTOM_CFG_SRC_TYPE                         0xFFA0C942
+#define OID_CUSTOM_EEPROM_TYPE                          0xFFA0C943
+
+#if CFG_SUPPORT_WAPI
+#define OID_802_11_WAPI_MODE                            0xFFA0CA00
+#define OID_802_11_WAPI_ASSOC_INFO                      0xFFA0CA01
+#define OID_802_11_SET_WAPI_KEY                         0xFFA0CA02
+#endif
+
+#if CFG_SUPPORT_WPS2
+#define OID_802_11_WSC_ASSOC_INFO                       0xFFA0CB00
+#endif
+
+/* Define magic key of test mode (Don't change it for future compatibity) */
+#define PRIV_CMD_TEST_MAGIC_KEY                         2011
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+/* NIC BBCR configuration entry structure */
+typedef struct _PRIV_CONFIG_ENTRY {
+	UINT_8 ucOffset;
+	UINT_8 ucValue;
+} PRIV_CONFIG_ENTRY, *PPRIV_CONFIG_ENTRY;
+
+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC_REQ) (IN PVOID prAdapter,
+						IN OUT PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen);
+
+typedef enum _ENUM_OID_METHOD_T {
+	ENUM_OID_GLUE_ONLY,
+	ENUM_OID_GLUE_EXTENSION,
+	ENUM_OID_DRIVER_CORE
+} ENUM_OID_METHOD_T, *P_ENUM_OID_METHOD_T;
+
+/* OID set/query processing entry */
+typedef struct _WLAN_REQ_ENTRY {
+	UINT_32 rOid;		/* OID */
+	PUINT_8 pucOidName;	/* OID name text */
+	BOOLEAN fgQryBufLenChecking;
+	BOOLEAN fgSetBufLenChecking;
+	ENUM_OID_METHOD_T eOidMethod;
+	UINT_32 u4InfoBufLen;
+	PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler;	/*  PFN_OID_HANDLER_FUNC */
+	PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler;	/* PFN_OID_HANDLER_FUNC */
+} WLAN_REQ_ENTRY, *P_WLAN_REQ_ENTRY;
+
+typedef struct _NDIS_TRANSPORT_STRUCT {
+	UINT_32 ndisOidCmd;
+	UINT_32 inNdisOidlength;
+	UINT_32 outNdisOidLength;
+	UINT_8 ndisOidContent[16];
+} NDIS_TRANSPORT_STRUCT, *P_NDIS_TRANSPORT_STRUCT;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+int
+priv_set_int(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra);
+
+int
+priv_get_int(IN struct net_device *prNetDev,
+	     IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra);
+
+int
+priv_set_ints(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra);
+
+int
+priv_get_ints(IN struct net_device *prNetDev,
+	      IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra);
+
+int
+priv_set_struct(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra);
+
+int
+priv_get_struct(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra);
+
+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen);
+
+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac);
+
+int
+priv_set_string(IN struct net_device *prNetDev,
+		IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra);
+
+int priv_support_ioctl(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd);
+
+int priv_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd);
+
+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen);
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _GL_WEXT_PRIV_H */
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c
new file mode 100644
index 0000000000000..fba854cfd68e1
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c
@@ -0,0 +1,542 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#1
+*/
+
+/*! \file   "platform.c"
+    \brief  This file including the protocol layer privacy function.
+
+    This file provided the macros and functions library support for the
+    protocol layer security setting from wlan_oid.c and for parse.c and
+    rsn.c and nic_privacy.c
+
+*/
+
+/*
+** Log: platform.c
+ *
+ * 11 14 2011 cm.chang
+ * NULL
+ * Fix compiling warning
+ *
+ * 11 10 2011 cp.wu
+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
+ * 1. eliminaite direct calls to printk in porting layer.
+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
+ *
+ * 09 13 2011 jeffrey.chang
+ * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection
+ * fix the pointer casting
+ *
+ * 06 29 2011 george.huang
+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
+ * .
+ *
+ * 06 28 2011 george.huang
+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
+ * remove un-used code
+ *
+ * 05 11 2011 jeffrey.chang
+ * NULL
+ * fix build error
+ *
+ * 05 09 2011 jeffrey.chang
+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
+ * support ARP filter through kernel notifier
+ *
+ * 04 08 2011 pat.lu
+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver
+ *
+ * 03 22 2011 pat.lu
+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
+ *
+ * 03 21 2011 cp.wu
+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
+ * improve portability for awareness of early version of linux kernel and wireless extension.
+ *
+ * 03 18 2011 jeffrey.chang
+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
+ * remove early suspend functions
+ *
+ * 03 03 2011 jeffrey.chang
+ * NULL
+ * add the ARP filter callback
+ *
+ * 02 15 2011 jeffrey.chang
+ * NULL
+ * to support early suspend in android
+ *
+ * 02 01 2011 cp.wu
+ * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1
+ * branch
+ * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/...
+ *
+ * 11 01 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
+ * Add implementation for querying current TX rate from firmware auto rate module
+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
+ * 2) Remove CNM CH-RECOVER event handling
+ * 3) cfg read/write API renamed with kal prefix for unified naming rules.
+ *
+ * 10 18 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
+ * The mac address is all zero at android
+ * complete implementation of Android NVRAM access
+ *
+ * 10 05 2010 cp.wu
+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
+ * 1) add NVRAM access API
+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
+ * 3) add OID implementation for NVRAM read/write service
+ *
+**
+*/
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+
+#include <linux/uaccess.h>
+
+#include "gl_os.h"
+
+#ifndef CONFIG_X86
+#if defined(CONFIG_HAS_EARLY_SUSPEND)
+#include <linux/earlysuspend.h>
+#endif
+#endif
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+#define WIFI_NVRAM_FILE_NAME   "/lib/firmware/mediatek/nvram/WIFI"
+#define WIFI_NVRAM_CUSTOM_NAME "/lib/firmware/mediatek/nvram/WIFI_CUSTOM"
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
+{
+	UINT_8 ip[4] = { 0 };
+	UINT_32 u4NumIPv4 = 0;
+/* #ifdef  CONFIG_IPV6 */
+#if 0
+	UINT_8 ip6[16] = { 0 };	/* FIX ME: avoid to allocate large memory in stack */
+	UINT_32 u4NumIPv6 = 0;
+#endif
+	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+	struct net_device *prDev = ifa->ifa_dev->dev;
+	UINT_32 i;
+	P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	if (prDev == NULL) {
+		DBGLOG(REQ, ERROR, "netdev_event: device is empty.\n");
+		return NOTIFY_DONE;
+	}
+	DBGLOG(REQ, INFO, "netdev_event, addr=%x, notification=%lx, dev_name=%s\n",
+			ifa->ifa_address, notification, prDev->name);
+	if (!fgIsUnderSuspend)
+		return NOTIFY_DONE;
+	if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) {
+		DBGLOG(REQ, WARN, "netdev_event: not our device\n");
+		return NOTIFY_DONE;
+	}
+#if 0				/* CFG_SUPPORT_HOTSPOT_2_0 */
+	{
+		/* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */
+		prGlueInfo->fgIsDad = FALSE;
+	}
+#endif
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+
+	if (prGlueInfo == NULL) {
+		DBGLOG(REQ, ERROR, "netdev_event: prGlueInfo is empty.\n");
+		return NOTIFY_DONE;
+	}
+	ASSERT(prGlueInfo);
+
+	/* <3> get the IPv4 address */
+	if (!prDev || !(prDev->ip_ptr) ||
+	    !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
+		DBGLOG(REQ, INFO, "ip is not available.\n");
+		return NOTIFY_DONE;
+	}
+
+	kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
+	DBGLOG(REQ, INFO, "ip is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
+
+	/* todo: traverse between list to find whole sets of IPv4 addresses */
+	if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)))
+		u4NumIPv4++;
+/* #ifdef  CONFIG_IPV6 */
+#if 0
+	if (!prDev || !(prDev->ip6_ptr) ||
+	    !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
+	    !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
+		DBGLOG(REQ, INFO, "ipv6 is not available.\n");
+		return NOTIFY_DONE;
+	}
+
+	kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
+	DBGLOG(REQ, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
+	       ip6[0], ip6[1], ip6[2], ip6[3],
+	       ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]);
+
+	/* todo: traverse between list to find whole sets of IPv6 addresses */
+	if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0)))
+		/* u4NumIPv6++; */
+#endif
+
+	/* here we can compare the dev with other network's netdev to */
+	/* set the proper arp filter */
+	/*  */
+	/* IMPORTANT: please make sure if the context can sleep, if the context can't sleep */
+	/* we should schedule a kernel thread to do this for us */
+
+	/* <7> set up the ARP filter */
+	{
+		WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
+		UINT_32 u4SetInfoLen = 0;
+		UINT_8 aucBuf[32] = { 0 };
+		UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
+		P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) aucBuf;
+		P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
+
+/* #ifdef  CONFIG_IPV6 */
+#if 0
+		prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
+#else
+		prParamNetAddrList->u4AddressCount = u4NumIPv4;
+#endif
+		prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+		for (i = 0; i < u4NumIPv4; i++) {
+			prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);	/* 4;; */
+			prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+#if 0
+			kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
+			prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip));
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
+#else
+			prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress;
+			kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
+			prParamNetAddr =
+			    (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
+#endif
+		}
+/* #ifdef  CONFIG_IPV6 */
+#if 0
+		for (i = 0; i < u4NumIPv6; i++) {
+			prParamNetAddr->u2AddressLength = 6;
+			prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
+			kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
+			prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip6));
+			u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
+		}
+#endif
+		ASSERT(u4Len <= sizeof(aucBuf));
+
+		DBGLOG(REQ, INFO, "kalIoctl (0x%p, 0x%p)\n", prGlueInfo, prParamNetAddrList);
+
+		rStatus = kalIoctl(prGlueInfo,
+				   wlanoidSetNetworkAddress,
+				   (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
+
+		if (rStatus != WLAN_STATUS_SUCCESS)
+			DBGLOG(REQ, ERROR, "set HW pattern filter fail 0x%x\n", rStatus);
+	}
+
+	return NOTIFY_DONE;
+
+}
+
+/* #if CFG_SUPPORT_HOTSPOT_2_0 */
+#if 0
+static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
+{
+	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
+	struct net_device *prDev = ifa->idev->dev;
+	P_GLUE_INFO_T prGlueInfo = NULL;
+
+	if (prDev == NULL) {
+		DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n");
+		return NOTIFY_DONE;
+	}
+
+	if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) {
+		DBGLOG(REQ, INFO, "net6dev_event: xxx\n");
+		return NOTIFY_DONE;
+	}
+
+	if (strncmp(prDev->name, "p2p", 3) == 0) {
+		/* because we store the address of prGlueInfo in p2p's private date of net device */
+		/* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */
+		prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
+	} else {		/* wlan0 */
+		prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev);
+	}
+
+	if (prGlueInfo == NULL) {
+		DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n");
+		return NOTIFY_DONE;
+	}
+	/* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */
+	prGlueInfo->fgIs6Dad = FALSE;
+
+	return NOTIFY_DONE;
+}
+#endif
+
+static struct notifier_block inetaddr_notifier = {
+	.notifier_call = netdev_event,
+};
+
+#if 0				/* CFG_SUPPORT_HOTSPOT_2_0 */
+static struct notifier_block inet6addr_notifier = {
+	.notifier_call = net6dev_event,
+};
+#endif
+
+void wlanRegisterNotifier(void)
+{
+	register_inetaddr_notifier(&inetaddr_notifier);
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+	/* register_inet6addr_notifier(&inet6addr_notifier); */
+#endif
+}
+
+/* EXPORT_SYMBOL(wlanRegisterNotifier); */
+
+void wlanUnregisterNotifier(void)
+{
+	unregister_inetaddr_notifier(&inetaddr_notifier);
+
+#if CFG_SUPPORT_HOTSPOT_2_0
+	/* unregister_inetaddr_notifier(&inet6addr_notifier); */
+#endif
+}
+
+/* EXPORT_SYMBOL(wlanUnregisterNotifier); */
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Utility function for reading data from files on NVRAM-FS
+*
+* \param[in]
+*           filename
+*           len
+*           offset
+* \param[out]
+*           buf
+* \return
+*           actual length of data being read
+*/
+/*----------------------------------------------------------------------------*/
+static int nvram_read(char *filename, char *buf, ssize_t len, int offset)
+{
+#if CFG_SUPPORT_NVRAM
+	struct file *fd;
+	int retLen = -1;
+
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(KERNEL_DS);
+
+	fd = filp_open(filename, O_RDONLY, 0644);
+
+	if (IS_ERR(fd)) {
+		DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to open!!\n");
+		return -1;
+	}
+
+	do {
+		//if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) {
+		if ( fd->f_op == NULL ) {
+			DBGLOG(INIT, INFO, "[MT6620][nvram_read] : file can not be read!!\n");
+			break;
+		}
+
+		if (fd->f_pos != offset) {
+			if (fd->f_op->llseek) {
+				if (fd->f_op->llseek(fd, offset, 0) != offset) {
+					DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to seek!!\n");
+					break;
+				}
+			} else {
+				fd->f_pos = offset;
+			}
+		}
+
+		retLen = vfs_read(fd, buf, len, &fd->f_pos);
+
+	} while (FALSE);
+
+	filp_close(fd, NULL);
+
+	set_fs(old_fs);
+
+	return retLen;
+
+#else /* !CFG_SUPPORT_NVRAM */
+
+	return -EIO;
+
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief Utility function for writing data to files on NVRAM-FS
+*
+* \param[in]
+*           filename
+*           buf
+*           len
+*           offset
+* \return
+*           actual length of data being written
+*/
+/*----------------------------------------------------------------------------*/
+static int nvram_write(char *filename, char *buf, ssize_t len, int offset)
+{
+#if CFG_SUPPORT_NVRAM
+	struct file *fd;
+	int retLen = -1;
+
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(KERNEL_DS);
+
+	fd = filp_open(filename, O_WRONLY | O_CREAT, 0644);
+
+	if (IS_ERR(fd)) {
+		DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to open!!\n");
+		return -1;
+	}
+
+	do {
+		if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) {
+			DBGLOG(INIT, INFO, "[MT6620][nvram_write] : file can not be write!!\n");
+			break;
+		}
+		/* End of if */
+		if (fd->f_pos != offset) {
+			if (fd->f_op->llseek) {
+				if (fd->f_op->llseek(fd, offset, 0) != offset) {
+					DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to seek!!\n");
+					break;
+				}
+			} else {
+				fd->f_pos = offset;
+			}
+		}
+
+		retLen = vfs_write(fd, buf, len, &fd->f_pos);
+
+	} while (FALSE);
+
+	filp_close(fd, NULL);
+
+	set_fs(old_fs);
+
+	return retLen;
+
+#else /* !CFG_SUPPORT_NVRAMS */
+
+	return -EIO;
+
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief API for reading data on NVRAM
+*
+* \param[in]
+*           prGlueInfo
+*           u4Offset
+* \param[out]
+*           pu2Data
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data)
+{
+	if (pu2Data == NULL)
+		return FALSE;
+
+	if (nvram_read(WIFI_NVRAM_FILE_NAME,
+		       (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) {
+		return FALSE;
+	} else {
+		return TRUE;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief API for writing data on NVRAM
+*
+* \param[in]
+*           prGlueInfo
+*           u4Offset
+*           u2Data
+* \return
+*           TRUE
+*           FALSE
+*/
+/*----------------------------------------------------------------------------*/
+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data)
+{
+	if (nvram_write(WIFI_NVRAM_FILE_NAME,
+			(char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) {
+		return FALSE;
+	} else {
+		return TRUE;
+	}
+}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h
new file mode 100644
index 0000000000000..9444d415c60e8
--- /dev/null
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h
@@ -0,0 +1,190 @@
+/*
+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/version.h#1
+*/
+
+/*! \file   "version.h"
+    \brief  Driver's version definition
+
+*/
+
+/*
+** Log: version.h
+ *
+ * 11 01 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.1.1.
+ *
+ * 08 26 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.9..
+ *
+ * 08 23 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.8.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * correct typo.
+ *
+ * 08 15 2011 cp.wu
+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
+ * for building MT6628 Win32 driver environment
+ *
+ * 08 03 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.7.
+ *
+ * 07 24 2011 puff.wen
+ * NULL
+ * [MT5931][Beta 5]Change the version number to v0.2.2.0
+ *
+ * 06 01 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.6..
+ *
+ * 05 09 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.5..
+ *
+ * 04 19 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.4.
+ *
+ * 04 18 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.3.
+ *
+ * 03 25 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.2.
+ *
+ * 03 21 2011 chinglan.wang
+ * NULL
+ * Change the version number to 2.0.0.1.
+ *
+ * 03 18 2011 chinglan.wang
+ * NULL
+ * Change the version number to v2.0.0.0.
+ *
+ * 02 11 2011 chinglan.wang
+ * NULL
+ * Change to the version 1.2.0.2.
+ *
+ * 02 10 2011 chinglan.wang
+ * NULL
+ * Change the version to 1.2.0.1.
+ *
+ * 02 08 2011 cp.wu
+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number
+ * change version number to v1.2.0.0 for preparing v1.2 software package release.
+ *
+ * 12 10 2010 kevin.huang
+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
+ * Add Linux Proc Support
+ *
+ * 10 07 2010 cp.wu
+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
+ * [WINDDK] build system changes for MT5931
+ *
+ * 07 08 2010 cp.wu
+ *
+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
+ *
+ * 06 06 2010 kevin.huang
+ * [WPD00003832][MT6620 5931] Create driver base
+ * [MT6620 5931] Create driver base
+**  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-12-14 14:10:55 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-17 22:41:00 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-13 16:20:33 GMT mtk01084
+**  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:27:13 GMT mtk01426
+**  Init for develop
+**
+*/
+
+#ifndef _VERSION_H
+#define _VERSION_H
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+#ifndef NIC_AUTHOR
+#define NIC_AUTHOR      "NIC_AUTHOR"
+#endif
+#ifndef NIC_DESC
+#define NIC_DESC        "NIC_DESC"
+#endif
+
+#ifndef NIC_NAME
+#if defined(MT6620)
+#define NIC_NAME            "MT6620"
+#define NIC_DEVICE_ID       "MT6620"
+#define NIC_DEVICE_ID_LOW   "mt6620"
+#elif defined(MT6628)
+#define NIC_NAME            "MT6582"
+#define NIC_DEVICE_ID       "MT6582"
+#define NIC_DEVICE_ID_LOW   "mt6582"
+#endif
+#endif
+
+/* NIC driver information */
+#define NIC_VENDOR                      "MediaTek Inc."
+#define NIC_VENDOR_OUI                  {0x00, 0x0C, 0xE7}
+
+#if defined(MT6620)
+#define NIC_PRODUCT_NAME                "MediaTek Inc. MT6620 Wireless LAN Adapter"
+#define NIC_DRIVER_NAME                 "MediaTek Inc. MT6620 Wireless LAN Adapter Driver"
+#elif defined(MT6628)
+/* #define NIC_PRODUCT_NAME                "MediaTek Inc. MT6628 Wireless LAN Adapter" */
+/* #define NIC_DRIVER_NAME                 "MediaTek Inc. MT6628 Wireless LAN Adapter Driver" */
+#define NIC_PRODUCT_NAME                "MediaTek Inc. MT6582 Wireless LAN Adapter"
+#define NIC_DRIVER_NAME                 "MediaTek Inc. MT6582 Wireless LAN Adapter Driver"
+#endif
+
+/* Define our driver version */
+#define NIC_DRIVER_MAJOR_VERSION        2
+#define NIC_DRIVER_MINOR_VERSION        0
+#define NIC_DRIVER_VERSION              (2, 0, 1, 1)
+#define NIC_DRIVER_VERSION_STRING       "2.0.1.1"
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                   F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _VERSION_H */
diff --git a/drivers/misc/mediatek/include/mt-plat/aee.h b/drivers/misc/mediatek/include/mt-plat/aee.h
new file mode 100644
index 0000000000000..d1cf448dafb21
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/aee.h
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#if !defined(__AEE_H__)
+#define __AEE_H__
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#define AEE_MODULE_NAME_LENGTH 64
+#define AEE_PROCESS_NAME_LENGTH 256
+#define AEE_BACKTRACE_LENGTH 3072
+
+typedef enum {
+	AE_DEFECT_FATAL,
+	AE_DEFECT_EXCEPTION,
+	AE_DEFECT_WARNING,
+	AE_DEFECT_REMINDING,
+	AE_DEFECT_ATTR_END
+} AE_DEFECT_ATTR;
+
+typedef enum {
+	AE_KE = 0,		/* Fatal Exception */
+	AE_HWT,
+	AE_REBOOT,
+	AE_NE,
+	AE_JE,
+	AE_SWT,
+	AE_EE,
+	AE_EXP_ERR_END,
+	AE_ANR,			/* Error or Warning or Defect */
+	AE_RESMON,
+	AE_MODEM_WARNING,
+	AE_WTF,
+	AE_WRN_ERR_END,
+	AE_MANUAL,		/* Manual Raise */
+	AE_EXP_CLASS_END,
+
+	AE_KERNEL_PROBLEM_REPORT = 1000,
+	AE_SYSTEM_JAVA_DEFECT,
+	AE_SYSTEM_NATIVE_DEFECT,
+	AE_MANUAL_MRDUMP_KEY,
+} AE_EXP_CLASS;			/* General Program Exception Class */
+
+typedef enum {
+	AEE_REBOOT_MODE_NORMAL = 0,
+	AEE_REBOOT_MODE_KERNEL_OOPS,
+	AEE_REBOOT_MODE_KERNEL_PANIC,
+	AEE_REBOOT_MODE_NESTED_EXCEPTION,
+	AEE_REBOOT_MODE_WDT,
+	AEE_REBOOT_MODE_MANUAL_KDUMP,
+} AEE_REBOOT_MODE;
+
+#define AEE_SZ_SYMBOL_L 140
+#define AEE_SZ_SYMBOL_S 80
+struct aee_bt_frame {
+	__u64 pc;
+	__u64 lr;
+	__u32 pad[5];
+	char pc_symbol[AEE_SZ_SYMBOL_S];	/* Now we use different symbol length for PC &LR */
+	char lr_symbol[AEE_SZ_SYMBOL_L];
+};
+
+/* aee_process_info struct should strictly small than ipanic_buffer, now 4KB */
+struct aee_process_info {
+	char process_path[AEE_PROCESS_NAME_LENGTH];
+	char backtrace[AEE_BACKTRACE_LENGTH];
+	struct aee_bt_frame ke_frame;
+};
+
+struct aee_process_bt {
+	__u32 pid;
+	__u32 nr_entries;
+	struct aee_bt_frame *entries;
+};
+
+
+struct aee_thread_reg {
+	pid_t tid;
+	struct pt_regs regs;
+};
+
+struct aee_user_thread_stack {
+	pid_t tid;
+	int StackLength;
+	unsigned char *Userthread_Stack; /*8k stack ,define to char only for match 64bit/32bit*/
+};
+
+struct aee_user_thread_maps {
+	pid_t tid;
+	int Userthread_mapsLength;
+	unsigned char *Userthread_maps; /*8k stack ,define to char only for match 64bit/32bit*/
+};
+
+
+
+struct aee_oops {
+	struct list_head list;
+	AE_DEFECT_ATTR attr;
+	AE_EXP_CLASS clazz;
+
+	char module[AEE_MODULE_NAME_LENGTH];
+	/* consist with struct aee_process_info */
+	char process_path[AEE_PROCESS_NAME_LENGTH];
+	char backtrace[AEE_BACKTRACE_LENGTH];
+	struct aee_bt_frame ke_frame;
+
+	char *detail;
+	int detail_len;
+
+	char *console;
+	int console_len;
+
+	char *android_main;
+	int android_main_len;
+	char *android_radio;
+	int android_radio_len;
+	char *android_system;
+	int android_system_len;
+
+	char *userspace_info;
+	int userspace_info_len;
+
+	char *mmprofile;
+	int mmprofile_len;
+
+	char *mini_rdump;
+	int mini_rdump_len;
+
+
+	struct aee_user_thread_stack userthread_stack;
+	struct aee_thread_reg userthread_reg;
+	struct aee_user_thread_maps userthread_maps;
+
+	int dump_option;
+};
+
+struct aee_kernel_api {
+	void (*kernel_reportAPI)(const AE_DEFECT_ATTR attr, const int db_opt, const char *module,
+		     const char *msg);
+	void (*md_exception)(const char *assert_type, const int *log, int log_size, const int *phy,
+		     int phy_size, const char *detail, const int db_opt);
+	void (*md32_exception)(const char *assert_type, const int *log, int log_size,
+		     const int *phy, int phy_size, const char *detail, const int db_opt);
+	void (*combo_exception)(const char *assert_type, const int *log, int log_size,
+		     const int *phy, int phy_size, const char *detail, const int db_opt);
+	void (*scp_exception)(const char *assert_type, const int *log, int log_size,
+		     const int *phy, int phy_size, const char *detail, const int db_opt);
+};
+
+void aee_sram_printk(const char *fmt, ...);
+int aee_nested_printf(const char *fmt, ...);
+void aee_wdt_irq_info(void);
+void aee_wdt_fiq_info(void *arg, void *regs, void *svc_sp);
+void aee_trigger_kdb(void);
+struct aee_oops *aee_oops_create(AE_DEFECT_ATTR attr, AE_EXP_CLASS clazz, const char *module);
+void aee_oops_set_backtrace(struct aee_oops *oops, const char *backtrace);
+void aee_oops_set_process_path(struct aee_oops *oops, const char *process_path);
+void aee_oops_free(struct aee_oops *oops);
+/* powerkey press,modules use bits */
+#define AE_WDT_Powerkey_DEVICE_PATH		"/dev/kick_powerkey"
+#define WDT_SETBY_DEFAULT		(0)
+#define WDT_SETBY_Backlight		(1<<0)
+#define WDT_SETBY_Display			(1<<1)
+#define WDT_SETBY_SF				(1<<2)
+#define WDT_SETBY_PM				(1<<3)
+#define WDT_SETBY_WMS_DISABLE_PWK_MONITOR	(0xAEEAEE00)
+#define WDT_SETBY_WMS_ENABLE_PWK_MONITOR	(0xAEEAEE01)
+#define WDT_PWK_HANG_FORCE_HWT				(0xAEE0FFFF)
+
+/* QHQ RT Monitor */
+#define AEEIOCTL_RT_MON_Kick _IOR('p', 0x0A, int)
+#define AE_WDT_DEVICE_PATH      "/dev/RT_Monitor"
+/* QHQ RT Monitor    end */
+
+/* DB dump option bits, set relative bit to 1 to include related file in db */
+#define DB_OPT_DEFAULT                  (0)
+#define DB_OPT_FTRACE                   (1<<0)
+#define DB_OPT_PRINTK_TOO_MUCH          (1<<1)
+#define DB_OPT_NE_JBT_TRACES            (1<<2)
+#define DB_OPT_SWT_JBT_TRACES           (1<<3)
+#define DB_OPT_VM_TRACES                (1<<4)
+#define DB_OPT_DUMPSYS_ACTIVITY         (1<<5)
+#define DB_OPT_DUMPSYS_WINDOW           (1<<6)
+#define DB_OPT_DUMPSYS_GFXINFO          (1<<7)
+#define DB_OPT_DUMPSYS_SURFACEFLINGER   (1<<8)
+#define DB_OPT_DISPLAY_HANG_DUMP        (1<<9)
+#define DB_OPT_LOW_MEMORY_KILLER        (1<<10)
+#define DB_OPT_PROC_MEM                 (1<<11)
+#define DB_OPT_FS_IO_LOG                (1<<12)
+#define DB_OPT_PROCESS_COREDUMP         (1<<13)
+#define DB_OPT_VM_HPROF                 (1<<14)
+#define DB_OPT_PROCMEM                  (1<<15)
+#define DB_OPT_DUMPSYS_INPUT            (1<<16)
+#define DB_OPT_MMPROFILE_BUFFER         (1<<17)
+#define DB_OPT_BINDER_INFO              (1<<18)
+#define DB_OPT_WCN_ISSUE_INFO           (1<<19)
+#define DB_OPT_DUMMY_DUMP               (1<<20)
+#define DB_OPT_PID_MEMORY_INFO          (1<<21)
+#define DB_OPT_VM_OOME_HPROF            (1<<22)
+#define DB_OPT_PID_SMAPS                (1<<23)
+#define DB_OPT_PROC_CMDQ_INFO           (1<<24)
+#define DB_OPT_PROC_USKTRK              (1<<25)
+#define DB_OPT_SF_RTT_DUMP              (1<<26)
+#define DB_OPT_PAGETYPE_INFO            (1<<27)
+#define DB_OPT_DUMPSYS_PROCSTATS        (1<<28)
+#define DB_OPT_DUMP_DISPLAY             (1<<29)
+#define DB_OPT_NATIVE_BACKTRACE		(1<<30)
+#define DB_OPT_AARCH64			(1<<31)
+
+#define aee_kernel_exception(module, msg...)	\
+	aee_kernel_exception_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg)
+#define aee_kernel_warning(module, msg...)	\
+	aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg)
+#define aee_kernel_reminding(module, msg...)	\
+	aee_kernel_reminding_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg)
+#define aee_kernel_dal_show(msg)	\
+	aee_kernel_dal_api(__FILE__, __LINE__, msg)
+
+#define aed_md_exception(log, log_size, phy, phy_size, detail)	\
+	aed_md_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT)
+#define aed_md32_exception(log, log_size, phy, phy_size, detail)	\
+	aed_md32_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT)
+#define aed_scp_exception(log, log_size, phy, phy_size, detail)	\
+	aed_scp_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT)
+#define aed_combo_exception(log, log_size, phy, phy_size, detail)	\
+	aed_combo_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT)
+
+void aee_kernel_exception_api(const char *file, const int line, const int db_opt,
+			      const char *module, const char *msg, ...);
+void aee_kernel_warning_api(const char *file, const int line, const int db_opt, const char *module,
+			    const char *msg, ...);
+void aee_kernel_reminding_api(const char *file, const int line, const int db_opt,
+			      const char *module, const char *msg, ...);
+void aee_kernel_dal_api(const char *file, const int line, const char *msg);
+
+void aed_md_exception_api(const int *log, int log_size, const int *phy, int phy_size,
+			  const char *detail, const int db_opt);
+void aed_md32_exception_api(const int *log, int log_size, const int *phy, int phy_size,
+			    const char *detail, const int db_opt);
+void aed_scp_exception_api(const int *log, int log_size, const int *phy, int phy_size,
+			    const char *detail, const int db_opt);
+void aed_combo_exception_api(const int *log, int log_size, const int *phy, int phy_size,
+			     const char *detail, const int db_opt);
+
+void aee_kernel_wdt_kick_Powkey_api(const char *module, int msg);
+int aee_kernel_wdt_kick_api(int kinterval);
+void aee_powerkey_notify_press(unsigned long pressed);
+int aee_kernel_Powerkey_is_press(void);
+
+void ipanic_recursive_ke(struct pt_regs *regs, struct pt_regs *excp_regs, int cpu);
+
+/* QHQ RT Monitor */
+void aee_kernel_RT_Monitor_api(int lParam);
+/* QHQ RT Monitor    end */
+void mt_fiq_printf(const char *fmt, ...);
+void aee_register_api(struct aee_kernel_api *aee_api);
+int aee_in_nested_panic(void);
+void aee_stop_nested_panic(struct pt_regs *regs);
+void aee_wdt_dump_info(void);
+void aee_wdt_printf(const char *fmt, ...);
+
+void aee_fiq_ipi_cpu_stop(void *arg, void *regs, void *svc_sp);
+
+#if defined(CONFIG_MTK_AEE_DRAM_CONSOLE)
+void aee_dram_console_reserve_memory(void);
+#else
+static inline void aee_dram_console_reserve_memory(void)
+{
+}
+#endif
+
+extern void *aee_excp_regs;	/* To store latest exception, in case of stack corruption */
+#endif				/* __AEE_H__ */
diff --git a/drivers/misc/mediatek/include/mt-plat/mrdump.h b/drivers/misc/mediatek/include/mt-plat/mrdump.h
new file mode 100644
index 0000000000000..b6bdfa2f7617c
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mrdump.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#if !defined(__MRDUMP_H__)
+#define __MRDUMP_H__
+
+#include <stdarg.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+#include <asm/ptrace.h>
+#include <mt-plat/aee.h>
+
+#ifdef __aarch64__
+#define reg_pc	pc
+#define reg_lr	regs[30]
+#define reg_sp	sp
+#define reg_fp	regs[29]
+#else
+#define reg_pc	ARM_pc
+#define reg_lr	ARM_lr
+#define reg_sp	ARM_sp
+#define reg_ip	ARM_ip
+#define reg_fp	ARM_fp
+#endif
+
+#define MRDUMP_CPU_MAX 16
+
+#define MRDUMP_DEV_NULL 0
+#define MRDUMP_DEV_SDCARD 1
+#define MRDUMP_DEV_EMMC 2
+
+#define MRDUMP_FS_NULL 0
+#define MRDUMP_FS_VFAT 1
+#define MRDUMP_FS_EXT4 2
+
+#define MRDUMP_GO_DUMP "MRDUMP04"
+
+typedef uint32_t arm32_gregset_t[18];
+typedef uint64_t aarch64_gregset_t[34];
+
+struct mrdump_crash_record {
+	int reboot_mode;
+
+	char msg[128];
+	char backtrace[512];
+
+	uint32_t fault_cpu;
+
+	union {
+		arm32_gregset_t arm32_regs;
+		aarch64_gregset_t aarch64_regs;
+	} cpu_regs[MRDUMP_CPU_MAX];
+};
+
+struct mrdump_machdesc {
+	uint32_t crc;
+
+	uint32_t output_device;
+
+	uint32_t nr_cpus;
+
+	uint64_t page_offset;
+	uint64_t high_memory;
+
+	uint64_t vmalloc_start;
+	uint64_t vmalloc_end;
+
+	uint64_t modules_start;
+	uint64_t modules_end;
+
+	uint64_t phys_offset;
+	uint64_t master_page_table;
+
+	uint32_t output_fstype;
+	uint32_t output_lbaooo;
+};
+
+struct mrdump_control_block {
+	char sig[8];
+
+	struct mrdump_machdesc machdesc;
+	struct mrdump_crash_record crash_record;
+};
+
+/* NOTE!! any change to this struct should be compatible in aed */
+struct mrdump_mini_reg_desc {
+	unsigned long reg;	/* register value */
+	unsigned long kstart;	/* start kernel addr of memory dump */
+	unsigned long kend;	/* end kernel addr of memory dump */
+	unsigned long pos;	/* next pos to dump */
+	int valid;		/* 1: valid regiser, 0: invalid regiser */
+	int pad;		/* reserved */
+	loff_t offset;		/* offset in buffer */
+};
+
+/* it should always be smaller than MRDUMP_MINI_HEADER_SIZE */
+struct mrdump_mini_header {
+	struct mrdump_mini_reg_desc reg_desc[ELF_NGREG];
+};
+
+#define MRDUMP_MINI_NR_SECTION 60
+#define MRDUMP_MINI_SECTION_SIZE (32 * 1024)
+#define NT_IPANIC_MISC 4095
+#define MRDUMP_MINI_NR_MISC 20
+
+struct mrdump_mini_elf_misc {
+	unsigned long vaddr;
+	unsigned long paddr;
+	unsigned long start;
+	unsigned long size;
+};
+
+#define NOTE_NAME_SHORT 12
+#define NOTE_NAME_LONG  20
+
+struct mrdump_mini_elf_psinfo {
+		struct elf_note note;
+		char name[NOTE_NAME_SHORT];
+		struct elf_prpsinfo data;
+};
+
+struct mrdump_mini_elf_prstatus {
+		struct elf_note note;
+		char name[NOTE_NAME_SHORT];
+		struct elf_prstatus data;
+};
+
+struct mrdump_mini_elf_note {
+		struct elf_note note;
+		char name[NOTE_NAME_LONG];
+		struct mrdump_mini_elf_misc data;
+};
+
+struct mrdump_mini_elf_header {
+	struct elfhdr ehdr;
+	struct elf_phdr phdrs[MRDUMP_MINI_NR_SECTION];
+	struct mrdump_mini_elf_psinfo psinfo;
+	struct mrdump_mini_elf_prstatus prstatus[NR_CPUS + 1];
+	struct mrdump_mini_elf_note misc[MRDUMP_MINI_NR_MISC];
+};
+
+typedef struct mrdump_rsvmem_block {
+	phys_addr_t start_addr;
+	phys_addr_t size;
+} mrdump_rsvmem_block_t;
+
+
+#define MRDUMP_MINI_HEADER_SIZE ALIGN(sizeof(struct mrdump_mini_elf_header), PAGE_SIZE)
+#define MRDUMP_MINI_DATA_SIZE (MRDUMP_MINI_NR_SECTION * MRDUMP_MINI_SECTION_SIZE)
+#define MRDUMP_MINI_BUF_SIZE (MRDUMP_MINI_HEADER_SIZE + MRDUMP_MINI_DATA_SIZE)
+
+#ifdef CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR
+#define MRDUMP_MINI_BUF_PADDR (CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR + 0xf0000)
+#else
+#define MRDUMP_MINI_BUF_PADDR 0
+#endif
+
+int mrdump_init(void);
+void __mrdump_create_oops_dump(AEE_REBOOT_MODE reboot_mode, struct pt_regs *regs, const char *msg,
+			       ...);
+#if defined(CONFIG_MTK_AEE_IPANIC)
+void mrdump_rsvmem(void);
+#else
+static inline void mrdump_rsvmem(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MTK_AEE_MRDUMP)
+void aee_kdump_reboot(AEE_REBOOT_MODE, const char *msg, ...);
+#else
+static inline void aee_kdump_reboot(AEE_REBOOT_MODE reboot_mode, const char *msg, ...)
+{
+}
+#endif
+
+typedef int (*mrdump_write)(void *buf, int off, int len, int encrypt);
+#if defined(CONFIG_MTK_AEE_IPANIC)
+int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write,
+				 loff_t sd_offset, const char *msg, va_list ap);
+void mrdump_mini_reserve_memory(void);
+#else
+static inline int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write,
+					       loff_t sd_offset, const char *msg, va_list ap)
+{
+	return 0;
+}
+
+static inline void mrdump_mini_reserve_memory(void)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h
new file mode 100644
index 0000000000000..1b60f007d0fdf
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#ifndef _MT8167_THERMAL_H
+#define _MT8167_THERMAL_H
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include "sync_write.h"
+
+extern void __iomem *thermal_base;
+extern void __iomem *auxadc_ts_base;
+extern void __iomem *apmixed_base;
+extern void __iomem *pericfg_base;
+extern int auxadc_ts_phy_base;
+extern int apmixed_phy_base;
+
+#define THERM_CTRL_BASE_2 thermal_base
+#define AUXADC_BASE_2     auxadc_ts_base
+#define PERICFG_BASE	pericfg_base
+#define APMIXED_BASE_2    apmixed_base
+
+#define MT6752_EVB_BUILD_PASS /*Jerry fix build error FIX_ME*/
+
+/*******************************************************************************
+* AUXADC Register Definition
+******************************************************************************/
+/*AUXADC_BASE: 0xF1001000 from Vincent Liang 2014.5.8*/
+
+#define AUXADC_CON0_V       (AUXADC_BASE_2 + 0x000)	/*yes, 0x11003000*/
+#define AUXADC_CON1_V       (AUXADC_BASE_2 + 0x004)
+#define AUXADC_CON1_SET_V   (AUXADC_BASE_2 + 0x008)
+#define AUXADC_CON1_CLR_V   (AUXADC_BASE_2 + 0x00C)
+#define AUXADC_CON2_V       (AUXADC_BASE_2 + 0x010)
+/*#define AUXADC_CON3_V       (AUXADC_BASE_2 + 0x014)*/
+#define AUXADC_DAT0_V       (AUXADC_BASE_2 + 0x014)
+#define AUXADC_DAT1_V       (AUXADC_BASE_2 + 0x018)
+#define AUXADC_DAT2_V       (AUXADC_BASE_2 + 0x01C)
+#define AUXADC_DAT3_V       (AUXADC_BASE_2 + 0x020)
+#define AUXADC_DAT4_V       (AUXADC_BASE_2 + 0x024)
+#define AUXADC_DAT5_V       (AUXADC_BASE_2 + 0x028)
+#define AUXADC_DAT6_V       (AUXADC_BASE_2 + 0x02C)
+#define AUXADC_DAT7_V       (AUXADC_BASE_2 + 0x030)
+#define AUXADC_DAT8_V       (AUXADC_BASE_2 + 0x034)
+#define AUXADC_DAT9_V       (AUXADC_BASE_2 + 0x038)
+#define AUXADC_DAT10_V       (AUXADC_BASE_2 + 0x03C)
+#define AUXADC_DAT11_V       (AUXADC_BASE_2 + 0x040)
+#define AUXADC_MISC_V       (AUXADC_BASE_2 + 0x094)
+
+#define AUXADC_CON0_P       (auxadc_ts_phy_base + 0x000)
+#define AUXADC_CON1_P       (auxadc_ts_phy_base + 0x004)
+#define AUXADC_CON1_SET_P   (auxadc_ts_phy_base + 0x008)
+#define AUXADC_CON1_CLR_P   (auxadc_ts_phy_base + 0x00C)
+#define AUXADC_CON2_P       (auxadc_ts_phy_base + 0x010)
+/*#define AUXADC_CON3_P       (auxadc_ts_phy_base + 0x014)*/
+#define AUXADC_DAT0_P       (auxadc_ts_phy_base + 0x014)
+#define AUXADC_DAT1_P       (auxadc_ts_phy_base + 0x018)
+#define AUXADC_DAT2_P       (auxadc_ts_phy_base + 0x01C)
+#define AUXADC_DAT3_P       (auxadc_ts_phy_base + 0x020)
+#define AUXADC_DAT4_P       (auxadc_ts_phy_base + 0x024)
+#define AUXADC_DAT5_P       (auxadc_ts_phy_base + 0x028)
+#define AUXADC_DAT6_P       (auxadc_ts_phy_base + 0x02C)
+#define AUXADC_DAT7_P       (auxadc_ts_phy_base + 0x030)
+#define AUXADC_DAT8_P       (auxadc_ts_phy_base + 0x034)
+#define AUXADC_DAT9_P       (auxadc_ts_phy_base + 0x038)
+#define AUXADC_DAT10_P       (auxadc_ts_phy_base + 0x03C)
+#define AUXADC_DAT11_P       (auxadc_ts_phy_base + 0x040)
+
+#define AUXADC_MISC_P       (auxadc_ts_phy_base + 0x094)
+
+/*******************************************************************************
+* Peripheral Configuration Register Definition
+******************************************************************************/
+/*#define PERICFG_BASE (0x10002000)*/
+#define PERI_GLOBALCON_RST0 (pericfg_base + 0x000) /*yes, 0x10002000*/
+/*******************************************************************************
+ * APMixedSys Configuration Register Definition
+ ******************************************************************************/
+#define TS_CON0             (APMIXED_BASE_2 + 0x600) /*yes 0x10209000*/
+#define TS_CON1             (APMIXED_BASE_2 + 0x604)
+#define TS_CON0_TM             (APMIXED_BASE_2 + 0x600)	/* yes 0x10209000 */
+#define TS_CON1_TM             (APMIXED_BASE_2 + 0x604)
+#define TS_CON0_P           (apmixed_phy_base + 0x600)
+#define TS_CON1_P           (apmixed_phy_base + 0x604)
+
+/*******************************************************************************
+ * Thermal Controller Register Definition
+ ******************************************************************************/
+#define TEMPMONCTL0         (THERM_CTRL_BASE_2 + 0x000) /*yes 0x1100B000*/
+#define TEMPMONCTL1         (THERM_CTRL_BASE_2 + 0x004)
+#define TEMPMONCTL2         (THERM_CTRL_BASE_2 + 0x008)
+#define TEMPMONINT          (THERM_CTRL_BASE_2 + 0x00C)
+#define TEMPMONINTSTS       (THERM_CTRL_BASE_2 + 0x010)
+#define TEMPMONIDET0        (THERM_CTRL_BASE_2 + 0x014)
+#define TEMPMONIDET1        (THERM_CTRL_BASE_2 + 0x018)
+#define TEMPMONIDET2        (THERM_CTRL_BASE_2 + 0x01C)
+#define TEMPH2NTHRE         (THERM_CTRL_BASE_2 + 0x024)
+#define TEMPHTHRE           (THERM_CTRL_BASE_2 + 0x028)
+#define TEMPCTHRE           (THERM_CTRL_BASE_2 + 0x02C)
+#define TEMPOFFSETH         (THERM_CTRL_BASE_2 + 0x030)
+#define TEMPOFFSETL         (THERM_CTRL_BASE_2 + 0x034)
+#define TEMPMSRCTL0         (THERM_CTRL_BASE_2 + 0x038)
+#define TEMPMSRCTL1         (THERM_CTRL_BASE_2 + 0x03C)
+#define TEMPAHBPOLL         (THERM_CTRL_BASE_2 + 0x040)
+#define TEMPAHBTO           (THERM_CTRL_BASE_2 + 0x044)
+#define TEMPADCPNP0         (THERM_CTRL_BASE_2 + 0x048)
+#define TEMPADCPNP1         (THERM_CTRL_BASE_2 + 0x04C)
+#define TEMPADCPNP2         (THERM_CTRL_BASE_2 + 0x050)
+#define TEMPADCPNP3         (THERM_CTRL_BASE_2 + 0x0B4)
+
+#define TEMPADCMUX          (THERM_CTRL_BASE_2 + 0x054)
+#define TEMPADCEXT          (THERM_CTRL_BASE_2 + 0x058)
+#define TEMPADCEXT1         (THERM_CTRL_BASE_2 + 0x05C)
+#define TEMPADCEN           (THERM_CTRL_BASE_2 + 0x060)
+#define TEMPPNPMUXADDR      (THERM_CTRL_BASE_2 + 0x064)
+#define TEMPADCMUXADDR      (THERM_CTRL_BASE_2 + 0x068)
+#define TEMPADCEXTADDR      (THERM_CTRL_BASE_2 + 0x06C)
+#define TEMPADCEXT1ADDR     (THERM_CTRL_BASE_2 + 0x070)
+#define TEMPADCENADDR       (THERM_CTRL_BASE_2 + 0x074)
+#define TEMPADCVALIDADDR    (THERM_CTRL_BASE_2 + 0x078)
+#define TEMPADCVOLTADDR     (THERM_CTRL_BASE_2 + 0x07C)
+#define TEMPRDCTRL          (THERM_CTRL_BASE_2 + 0x080)
+#define TEMPADCVALIDMASK    (THERM_CTRL_BASE_2 + 0x084)
+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088)
+#define TEMPADCWRITECTRL    (THERM_CTRL_BASE_2 + 0x08C)
+#define TEMPMSR0            (THERM_CTRL_BASE_2 + 0x090)
+#define TEMPMSR1            (THERM_CTRL_BASE_2 + 0x094)
+#define TEMPMSR2            (THERM_CTRL_BASE_2 + 0x098)
+#define TEMPMSR3            (THERM_CTRL_BASE_2 + 0x0B8)
+
+#define TEMPIMMD0           (THERM_CTRL_BASE_2 + 0x0A0)
+#define TEMPIMMD1           (THERM_CTRL_BASE_2 + 0x0A4)
+#define TEMPIMMD2           (THERM_CTRL_BASE_2 + 0x0A8)
+#define TEMPIMMD3           (THERM_CTRL_BASE_2 + 0x0BC)
+
+
+#define TEMPPROTCTL         (THERM_CTRL_BASE_2 + 0x0C0)
+#define TEMPPROTTA          (THERM_CTRL_BASE_2 + 0x0C4)
+#define TEMPPROTTB          (THERM_CTRL_BASE_2 + 0x0C8)
+#define TEMPPROTTC          (THERM_CTRL_BASE_2 + 0x0CC)
+
+#define TEMPSPARE0          (THERM_CTRL_BASE_2 + 0x0F0)
+#define TEMPSPARE1          (THERM_CTRL_BASE_2 + 0x0F4)
+#define TEMPSPARE2          (THERM_CTRL_BASE_2 + 0x0F8)
+#define TEMPSPARE3          (THERM_CTRL_BASE_2 + 0x0FC)
+
+#define PTPCORESEL          (THERM_CTRL_BASE_2 + 0x400)
+#define THERMINTST          (THERM_CTRL_BASE_2 + 0x404)
+#define PTPODINTST          (THERM_CTRL_BASE_2 + 0x408)
+#define THSTAGE0ST          (THERM_CTRL_BASE_2 + 0x40C)
+#define THSTAGE1ST          (THERM_CTRL_BASE_2 + 0x410)
+#define THSTAGE2ST          (THERM_CTRL_BASE_2 + 0x414)
+#define THAHBST0            (THERM_CTRL_BASE_2 + 0x418)
+#define THAHBST1            (THERM_CTRL_BASE_2 + 0x41C) /*Only for DE debug*/
+#define PTPSPARE0           (THERM_CTRL_BASE_2 + 0x420)
+#define PTPSPARE1           (THERM_CTRL_BASE_2 + 0x424)
+#define PTPSPARE2           (THERM_CTRL_BASE_2 + 0x428)
+#define PTPSPARE3           (THERM_CTRL_BASE_2 + 0x42C)
+#define THSLPEVEB           (THERM_CTRL_BASE_2 + 0x430)
+
+
+#define PTPSPARE0_P           (thermal_phy_base + 0x420)
+#define PTPSPARE1_P           (thermal_phy_base + 0x424)
+#define PTPSPARE2_P           (thermal_phy_base + 0x428)
+#define PTPSPARE3_P           (thermal_phy_base + 0x42C)
+
+/*******************************************************************************
+ * Thermal Controller Register Mask Definition
+ ******************************************************************************/
+#define THERMAL_ENABLE_SEN0     0x1
+#define THERMAL_ENABLE_SEN1     0x2
+#define THERMAL_ENABLE_SEN2     0x4
+#define THERMAL_MONCTL0_MASK    0x00000007
+
+#define THERMAL_PUNT_MASK       0x00000FFF
+#define THERMAL_FSINTVL_MASK    0x03FF0000
+#define THERMAL_SPINTVL_MASK    0x000003FF
+#define THERMAL_MON_INT_MASK    0x0007FFFF
+
+#define THERMAL_MON_CINTSTS0    0x000001
+#define THERMAL_MON_HINTSTS0    0x000002
+#define THERMAL_MON_LOINTSTS0   0x000004
+#define THERMAL_MON_HOINTSTS0   0x000008
+#define THERMAL_MON_NHINTSTS0   0x000010
+#define THERMAL_MON_CINTSTS1    0x000020
+#define THERMAL_MON_HINTSTS1    0x000040
+#define THERMAL_MON_LOINTSTS1   0x000080
+#define THERMAL_MON_HOINTSTS1   0x000100
+#define THERMAL_MON_NHINTSTS1   0x000200
+#define THERMAL_MON_CINTSTS2    0x000400
+#define THERMAL_MON_HINTSTS2    0x000800
+#define THERMAL_MON_LOINTSTS2   0x001000
+#define THERMAL_MON_HOINTSTS2   0x002000
+#define THERMAL_MON_NHINTSTS2   0x004000
+#define THERMAL_MON_TOINTSTS    0x008000
+#define THERMAL_MON_IMMDINTSTS0 0x010000
+#define THERMAL_MON_IMMDINTSTS1 0x020000
+#define THERMAL_MON_IMMDINTSTS2 0x040000
+#define THERMAL_MON_FILTINTSTS0 0x080000
+#define THERMAL_MON_FILTINTSTS1 0x100000
+#define THERMAL_MON_FILTINTSTS2 0x200000
+
+
+#define THERMAL_tri_SPM_State0	0x20000000
+#define THERMAL_tri_SPM_State1	0x40000000
+#define THERMAL_tri_SPM_State2	0x80000000
+
+
+#define THERMAL_MSRCTL0_MASK    0x00000007
+#define THERMAL_MSRCTL1_MASK    0x00000038
+#define THERMAL_MSRCTL2_MASK    0x000001C0
+
+enum thermal_sensor_name {
+	THERMAL_SENSOR1     = 0,/*TS_MCU1*/
+	THERMAL_SENSOR_NUM
+};
+
+enum thermal_bank_name {
+	THERMAL_BANK0     = 0, /*CPU (TS_MCU1) (TS1)*/
+	THERMAL_BANK_NUM
+};
+
+struct TS_SVS {
+	unsigned int ts_MTS;
+	unsigned int ts_BTS;
+};
+
+struct mtk_gpu_power_info {
+	unsigned int gpufreq_khz;
+	unsigned int gpufreq_power;
+};
+
+/* svs driver need this function */
+extern void get_thermal_slope_intercept(struct TS_SVS *ts_info, enum thermal_bank_name ts_bank);
+
+/* mtk_thermal_platform.c need this */
+extern void set_taklking_flag(bool flag);
+
+#define THERMAL_WRAP_WR32(val, addr)  mt_reg_sync_writel((val), ((void *)addr))
+
+enum MTK_THERMAL_SENSOR_CPU_ID_MET {
+	MTK_THERMAL_SENSOR_TS1 = 0,
+	MTK_THERMAL_SENSOR_TS2,
+	MTK_THERMAL_SENSOR_TS3,
+	MTK_THERMAL_SENSOR_TS4,
+	MTK_THERMAL_SENSOR_TSABB,
+
+	ATM_CPU_LIMIT,
+	ATM_GPU_LIMIT,
+
+	MTK_THERMAL_SENSOR_CPU_COUNT
+};
+
+extern int tscpu_get_cpu_temp_met(enum MTK_THERMAL_SENSOR_CPU_ID_MET id);
+extern int mtk_gpufreq_register(struct mtk_gpu_power_info *freqs, int num);
+
+typedef void (*met_thermalsampler_funcMET)(void);
+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB);
+
+void tscpu_start_thermal(void);
+void tscpu_stop_thermal(void);
+void tscpu_cancel_thermal_timer(void);
+void tscpu_start_thermal_timer(void);
+int mtkts_bts_get_hw_temp(void);
+
+extern int get_immediate_ts1_wrap(void);
+extern int get_immediate_ts2_wrap(void);
+extern int get_immediate_ts3_wrap(void);
+
+extern int is_cpu_power_unlimit(void);	/* in mtk_ts_cpu.c */
+extern int is_cpu_power_min(void);	/* in mtk_ts_cpu.c */
+extern int get_cpu_target_tj(void);
+extern int get_cpu_target_offset(void);
+
+extern int mtktscpu_debug_log;
+
+#endif
+
diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h
new file mode 100644
index 0000000000000..142a007805b95
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 MediaTek, Inc.
+ *
+ * Author: Holmes Chiou <holmes.chiou@mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MT_FREQHOPPING_H__
+#define __MT_FREQHOPPING_H__
+
+#define MT_FHPLL_MAX 6
+#define MT_SSC_NR_PREDEFINE_SETTING 10	/* TODO: is 10 a good number ? */
+
+#define MEMPLL_SSC 0
+#define MAINPLL_SSC 1
+
+#define FHTAG "[FH]"
+
+#define VERBOSE_DEBUG 0
+
+#if VERBOSE_DEBUG
+#define FH_MSG(fmt, args...) \
+	pr_debug(FHTAG""fmt" <- %s(): L<%d>  PID<%s><%d>\n", ##args, __func__, __LINE__, current->comm, current->pid)
+#else
+
+#if 1				/* log level is 6 xlog */
+#define FH_MSG(fmt, args...)	pr_debug(fmt, ##args)
+#else				/* log level is 4 (printk) */
+#define FH_MSG(fmt, args...)	printk(FHTAG""fmt"\n", ##args)
+#endif
+
+#endif
+
+/* not support at mt2701 yet */
+/* DRAMC */
+#define FULLY_VERSION_FHCTL	0
+
+enum FH_FH_STATUS {
+	FH_FH_DISABLE = 0,
+	FH_FH_ENABLE_SSC,
+	FH_FH_ENABLE_DFH,
+	FH_FH_ENABLE_DVFS,
+};
+
+enum FH_PLL_STATUS {
+	FH_PLL_DISABLE = 0,
+	FH_PLL_ENABLE = 1
+};
+
+/* TODO: FREQ_MODIFIED should not be here */
+/* FH_PLL_STATUS_FREQ_MODIFIED = 3 */
+
+
+enum FH_CMD {
+	FH_CMD_ENABLE = 1,
+	FH_CMD_DISABLE,
+	FH_CMD_ENABLE_USR_DEFINED,
+	FH_CMD_DISABLE_USR_DEFINED,
+	FH_CMD_INTERNAL_MAX_CMD,
+/* TODO:  do we need these cmds ?
+ * FH_CMD_PLL_ENABLE,
+ * FH_CMD_PLL_DISABLE,
+ * FH_CMD_EXT_ALL_FULL_RANGE_CMD,
+ * FH_CMD_EXT_ALL_HALF_RANGE_CMD,
+ * FH_CMD_EXT_DISABLE_ALL_CMD,
+ * FH_CMD_EXT_DESIGNATED_PLL_FULL_RANGE_CMD,
+ * FH_CMD_EXT_DESIGNATED_PLL_AND_SETTING_CMD
+*/
+};
+
+/*
+ * enum FH_OPCODE{
+ * FH_OPCODE_ENABLE_WITH_ID = 1,
+ * FH_OPCODE_ENABLE_WITHOUT_ID,
+ * FH_OPCODE_DISABLE,
+ * };
+*/
+
+enum FH_PLL_ID {
+	MT658X_FH_MINIMUMM_PLL = 0,
+	MT658X_FH_ARM_PLL = MT658X_FH_MINIMUMM_PLL,
+	MT658X_FH_MAIN_PLL = 1,
+	MT658X_FH_MEM_PLL = 2,
+	MT658X_FH_MSDC_PLL = 3,
+	MT658X_FH_MM_PLL = 4,	/* MT658X_FH_TVD_PLL        = 4, */
+	MT658X_FH_VENC_PLL = 5,	/* MT658X_FH_LVDS_PLL       = 5, */
+	/* 8127 FHCTL MB */
+	MT658X_FH_TVD_PLL = 6,	/* MT658X_FH_TVD_PLL     = 6, */
+	MT658X_FH_MAXIMUMM_PLL = MT658X_FH_TVD_PLL,
+	/* 8127 FHCTL ME */
+	MT658X_FH_PLL_TOTAL_NUM
+};
+
+/* keep track the status of each PLL */
+/* TODO: do we need another "uint mode" for Dynamic FH */
+typedef struct {
+	unsigned int fh_status;
+	unsigned int pll_status;
+	unsigned int setting_id;
+	unsigned int curr_freq;
+	unsigned int user_defined;
+} fh_pll_t;
+
+
+/* Record the owner of enable freq hopping <==TBD */
+struct freqhopping_pll {
+	union {
+		int mt_pll[MT_FHPLL_MAX];
+		struct {
+			int mt_arm_fhpll;
+			int mt_main_fhpll;
+			int mt_mem_fhpll;
+			int mt_msdc_fhpll;
+			int mt_mm_fhpll;
+			int mt_venc_fhpll;
+		};
+	};
+};
+
+struct freqhopping_ssc {
+	unsigned int freq;
+	unsigned int dt;
+	unsigned int df;
+	unsigned int upbnd;
+	unsigned int lowbnd;
+	unsigned int dds;
+};
+
+struct freqhopping_ioctl {
+	unsigned int pll_id;
+	struct freqhopping_ssc ssc_setting;	/* used only when user-define */
+	int result;
+};
+
+int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable);
+void mt_freqhopping_init(void);
+void mt_freqhopping_pll_init(void);
+int mt_h2l_mempll(void);
+int mt_l2h_mempll(void);
+int mt_h2l_dvfs_mempll(void);
+int mt_l2h_dvfs_mempll(void);
+int mt_dfs_armpll(unsigned int current_freq, unsigned int target_freq);
+int mt_is_support_DFS_mode(void);
+void mt_fh_popod_save(void);
+void mt_fh_popod_restore(void);
+int mt_fh_dram_overclock(int clk);
+int mt_fh_get_dramc(void);
+unsigned int mt_get_emi_freq(void);
+
+#endif				/* !__MT_FREQHOPPING_H__ */
diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h
new file mode 100644
index 0000000000000..0c049db9aa977
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+
+#define STA_POWER_DOWN  0
+#define STA_POWER_ON    1
+
+/*
+ * 1. for CPU MTCMOS: CPU0, CPU1, CPU2, CPU3, DBG0, CPU4, CPU5, CPU6, CPU7, DBG1, CPUSYS1
+ * 2. call spm_mtcmos_cpu_lock/unlock() before/after any operations
+ */
+extern int spm_mtcmos_cpu_init(void);
+extern void spm_mtcmos_cpu_lock(unsigned long *flags);
+extern void spm_mtcmos_cpu_unlock(unsigned long *flags);
+extern int spm_mtcmos_ctrl_cpu(unsigned int cpu, int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu0(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu1(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu2(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu3(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu4(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu5(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu6(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpu7(int state, int chkWfiBeforePdn);
+extern int spm_mtcmos_ctrl_cpusys0(int state, int chkWfiBeforePdn);
+extern bool spm_cpusys0_can_power_down(void);
diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h
new file mode 100644
index 0000000000000..28176b3cd9af1
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_BOOT_SHARE_PAGE_H__
+#define __MTK_BOOT_SHARE_PAGE_H__
+
+#define BOOT_SHARE_BASE  (0xC0002000)      /* address in linux kernel */
+#define BOOT_SHARE_SIZE  (0x1000)          /* page size 4K bytes */
+
+#define BOOT_SHARE_MAGIC (0x4545544D)      /* MTEE */
+
+/* Memory map & defines for boot share page */
+/*
+ *  Note:
+ *  1. BOOT_SHARE_XXXXX_OFST is the address offset related to BOOT_SHARE_BASE
+ */
+#define BOOT_SHARE_MAGIC1_OFST   (0)
+#define BOOT_SHARE_MAGIC1_SIZE   (4)
+
+#define BOOT_SHARE_DEV_INFO_OFST (BOOT_SHARE_MAGIC1_OFST+BOOT_SHARE_MAGIC1_SIZE)
+#define BOOT_SHARE_DEV_INFO_SIZE (16)
+
+#define BOOT_SHARE_HOTPLUG_OFST  (1008)    /* 16 bytes for hotplug/jump-reg */
+#define BOOT_SHARE_HOTPLUG_SIZE  (32)
+
+#define BOOT_SHARE_MAGIC2_OFST   (4092)
+#define BOOT_SHARE_MAGIC2_SIZE   (4)
+
+#endif /* __MTK_BOOT_SHARE_PAGE_H__ */
diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h
new file mode 100644
index 0000000000000..eefdaad4aaa5d
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#ifndef _MT8127_THERMAL_H
+#define _MT8127_THERMAL_H
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include "mt-plat/sync_write.h"
+#include <linux/types.h>
+
+/* #include <mach/mt_gpufreq.h> */
+/* #include "../../../../../thermal/mt8127/inc/mt_gpufreq.h" */
+
+#if 1
+extern void __iomem *thermal_base;
+extern void __iomem *auxadc_ts_base;
+extern void __iomem *pericfg_base;
+extern void __iomem *apmixed_ts_base;
+
+extern int mtktscpu_limited_dmips;
+
+void __attribute__ ((weak)) mt_gpufreq_thermal_protect(unsigned int limited_power) {
+}
+
+unsigned int __attribute__ ((weak)) mt_gpufreq_get_cur_freq(void) {
+	return 0;
+}
+
+u32 __attribute__ ((weak)) get_devinfo_with_index(u32 index) {
+	return 0;
+}
+
+extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata);
+extern int IMM_IsAdcInitReady(void);
+extern int PMIC_IMM_GetOneChannelValue(int dwChannel, int deCount, int trimd);
+extern int thermal_phy_base;
+extern int auxadc_ts_phy_base;
+extern int apmixed_phy_base;
+extern int pericfg_phy_base;
+
+/* extern int last_abb_t; */
+/* extern int last_CPU2_t; */
+extern int get_immediate_temp2_wrap(void);
+extern void mtkts_dump_cali_info(void);
+extern u32 get_devinfo_with_index(u32 index);
+extern int bts_cur_temp;
+
+#define THERM_CTRL_BASE_2  thermal_base
+#define AUXADC_BASE_2      auxadc_ts_base
+#define PERICFG_BASE_2     pericfg_base
+#define APMIXED_BASE_2     apmixed_ts_base
+#endif
+
+/*******************************************************************************
+ * AUXADC Register Definition
+ ******************************************************************************/
+#define AUXADC_CON0_V       (AUXADC_BASE_2 + 0x000)	/* yes, 0x11001000 */
+#define AUXADC_CON1_V       (AUXADC_BASE_2 + 0x004)
+#define AUXADC_CON1_SET_V   (AUXADC_BASE_2 + 0x008)
+#define AUXADC_CON1_CLR_V   (AUXADC_BASE_2 + 0x00C)
+#define AUXADC_CON2_V       (AUXADC_BASE_2 + 0x010)
+#define AUXADC_DAT0_V       (AUXADC_BASE_2 + 0x014)
+#define AUXADC_DAT1_V       (AUXADC_BASE_2 + 0x018)
+#define AUXADC_DAT2_V       (AUXADC_BASE_2 + 0x01C)
+#define AUXADC_DAT3_V       (AUXADC_BASE_2 + 0x020)
+#define AUXADC_DAT4_V       (AUXADC_BASE_2 + 0x024)
+#define AUXADC_DAT5_V       (AUXADC_BASE_2 + 0x028)
+#define AUXADC_DAT6_V       (AUXADC_BASE_2 + 0x02C)
+#define AUXADC_DAT7_V       (AUXADC_BASE_2 + 0x030)
+#define AUXADC_DAT8_V       (AUXADC_BASE_2 + 0x034)
+#define AUXADC_DAT9_V       (AUXADC_BASE_2 + 0x038)
+#define AUXADC_DAT10_V       (AUXADC_BASE_2 + 0x03C)
+#define AUXADC_DAT11_V       (AUXADC_BASE_2 + 0x040)
+#define AUXADC_MISC_V       (AUXADC_BASE_2 + 0x094)
+#define AUXADC_CON0_P       (auxadc_ts_phy_base + 0x000)
+#define AUXADC_CON1_P       (auxadc_ts_phy_base + 0x004)
+#define AUXADC_CON1_SET_P   (auxadc_ts_phy_base + 0x008)
+#define AUXADC_CON1_CLR_P   (auxadc_ts_phy_base + 0x00C)
+#define AUXADC_CON2_P       (auxadc_ts_phy_base + 0x010)
+#define AUXADC_DAT0_P       (auxadc_ts_phy_base + 0x014)
+#define AUXADC_DAT1_P       (auxadc_ts_phy_base + 0x018)
+#define AUXADC_DAT2_P       (auxadc_ts_phy_base + 0x01C)
+#define AUXADC_DAT3_P       (auxadc_ts_phy_base + 0x020)
+#define AUXADC_DAT4_P       (auxadc_ts_phy_base + 0x024)
+#define AUXADC_DAT5_P       (auxadc_ts_phy_base + 0x028)
+#define AUXADC_DAT6_P       (auxadc_ts_phy_base + 0x02C)
+#define AUXADC_DAT7_P       (auxadc_ts_phy_base + 0x030)
+#define AUXADC_DAT8_P       (auxadc_ts_phy_base + 0x034)
+#define AUXADC_DAT9_P       (auxadc_ts_phy_base + 0x038)
+#define AUXADC_DAT10_P       (auxadc_ts_phy_base + 0x03C)
+#define AUXADC_DAT11_P       (auxadc_ts_phy_base + 0x040)
+#define AUXADC_MISC_P       (auxadc_ts_phy_base + 0x094)
+
+/*******************************************************************************
+ * Peripheral Configuration Register Definition
+ ******************************************************************************/
+#define PERI_GLOBALCON_RST0 (PERICFG_BASE_2 + 0x000)	/* yes, 0x10003000 */
+
+/*******************************************************************************
+ * APMixedSys Configuration Register Definition
+ ******************************************************************************/
+#define TS_CON0             (APMIXED_BASE_2 + 0x600)	/* yes 0x10209000 */
+#define TS_CON1             (APMIXED_BASE_2 + 0x604)
+/*******************************************************************************
+ * Thermal Controller Register Definition
+ ******************************************************************************/
+#define TEMPMONCTL0         (THERM_CTRL_BASE_2 + 0x000)	/* yes 0x1100B000 */
+#define TEMPMONCTL1         (THERM_CTRL_BASE_2 + 0x004)
+#define TEMPMONCTL2         (THERM_CTRL_BASE_2 + 0x008)
+#define TEMPMONINT          (THERM_CTRL_BASE_2 + 0x00C)
+#define TEMPMONINTSTS       (THERM_CTRL_BASE_2 + 0x010)
+#define TEMPMONIDET0        (THERM_CTRL_BASE_2 + 0x014)
+#define TEMPMONIDET1        (THERM_CTRL_BASE_2 + 0x018)
+#define TEMPMONIDET2        (THERM_CTRL_BASE_2 + 0x01C)
+#define TEMPH2NTHRE         (THERM_CTRL_BASE_2 + 0x024)
+#define TEMPHTHRE           (THERM_CTRL_BASE_2 + 0x028)
+#define TEMPCTHRE           (THERM_CTRL_BASE_2 + 0x02C)
+#define TEMPOFFSETH         (THERM_CTRL_BASE_2 + 0x030)
+#define TEMPOFFSETL         (THERM_CTRL_BASE_2 + 0x034)
+#define TEMPMSRCTL0         (THERM_CTRL_BASE_2 + 0x038)
+#define TEMPMSRCTL1         (THERM_CTRL_BASE_2 + 0x03C)
+#define TEMPAHBPOLL         (THERM_CTRL_BASE_2 + 0x040)
+#define TEMPAHBTO           (THERM_CTRL_BASE_2 + 0x044)
+#define TEMPADCPNP0         (THERM_CTRL_BASE_2 + 0x048)
+#define TEMPADCPNP1         (THERM_CTRL_BASE_2 + 0x04C)
+#define TEMPADCPNP2         (THERM_CTRL_BASE_2 + 0x050)
+#define TEMPADCPNP3         (THERM_CTRL_BASE_2 + 0x0B4)
+
+#define TEMPADCMUX          (THERM_CTRL_BASE_2 + 0x054)
+#define TEMPADCEXT          (THERM_CTRL_BASE_2 + 0x058)
+#define TEMPADCEXT1         (THERM_CTRL_BASE_2 + 0x05C)
+#define TEMPADCEN           (THERM_CTRL_BASE_2 + 0x060)
+#define TEMPPNPMUXADDR      (THERM_CTRL_BASE_2 + 0x064)
+#define TEMPADCMUXADDR      (THERM_CTRL_BASE_2 + 0x068)
+#define TEMPADCEXTADDR      (THERM_CTRL_BASE_2 + 0x06C)
+#define TEMPADCEXT1ADDR     (THERM_CTRL_BASE_2 + 0x070)
+#define TEMPADCENADDR       (THERM_CTRL_BASE_2 + 0x074)
+#define TEMPADCVALIDADDR    (THERM_CTRL_BASE_2 + 0x078)
+#define TEMPADCVOLTADDR     (THERM_CTRL_BASE_2 + 0x07C)
+#define TEMPRDCTRL          (THERM_CTRL_BASE_2 + 0x080)
+#define TEMPADCVALIDMASK    (THERM_CTRL_BASE_2 + 0x084)
+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088)
+#define TEMPADCWRITECTRL    (THERM_CTRL_BASE_2 + 0x08C)
+#define TEMPMSR0            (THERM_CTRL_BASE_2 + 0x090)
+#define TEMPMSR1            (THERM_CTRL_BASE_2 + 0x094)
+#define TEMPMSR2            (THERM_CTRL_BASE_2 + 0x098)
+#define TEMPMSR3            (THERM_CTRL_BASE_2 + 0x0B8)
+
+#define TEMPIMMD0           (THERM_CTRL_BASE_2 + 0x0A0)
+#define TEMPIMMD1           (THERM_CTRL_BASE_2 + 0x0A4)
+#define TEMPIMMD2           (THERM_CTRL_BASE_2 + 0x0A8)
+
+#define TEMPPROTCTL         (THERM_CTRL_BASE_2 + 0x0C0)
+#define TEMPPROTTA          (THERM_CTRL_BASE_2 + 0x0C4)
+#define TEMPPROTTB          (THERM_CTRL_BASE_2 + 0x0C8)
+#define TEMPPROTTC          (THERM_CTRL_BASE_2 + 0x0CC)
+
+#define TEMPSPARE0          (THERM_CTRL_BASE_2 + 0x0F0)
+#define TEMPSPARE1          (THERM_CTRL_BASE_2 + 0x0F4)
+#define TEMPSPARE2          (THERM_CTRL_BASE_2 + 0x0F8)
+#define TEMPSPARE3          (THERM_CTRL_BASE_2 + 0x0FC)
+
+#define PTPCORESEL          (THERM_CTRL_BASE_2 + 0x400)
+#define THERMINTST          (THERM_CTRL_BASE_2 + 0x404)
+#define PTPODINTST          (THERM_CTRL_BASE_2 + 0x408)
+#define THSTAGE0ST          (THERM_CTRL_BASE_2 + 0x40C)
+#define THSTAGE1ST          (THERM_CTRL_BASE_2 + 0x410)
+#define THSTAGE2ST          (THERM_CTRL_BASE_2 + 0x414)
+#define THAHBST0            (THERM_CTRL_BASE_2 + 0x418)
+#define THAHBST1            (THERM_CTRL_BASE_2 + 0x41C)	/* Only for DE debug */
+#define PTPSPARE0           (THERM_CTRL_BASE_2 + 0x420)
+#define PTPSPARE1           (THERM_CTRL_BASE_2 + 0x424)
+#define PTPSPARE2           (THERM_CTRL_BASE_2 + 0x428)
+#define PTPSPARE3           (THERM_CTRL_BASE_2 + 0x42C)
+#define THSLPEVEB           (THERM_CTRL_BASE_2 + 0x430)
+
+/*******************************************************************************
+ * Thermal Controller Register Mask Definition
+ ******************************************************************************/
+#define THERMAL_ENABLE_SEN0     0x1
+#define THERMAL_ENABLE_SEN1     0x2
+#define THERMAL_ENABLE_SEN2     0x4
+#define THERMAL_MONCTL0_MASK    0x00000007
+
+#define THERMAL_PUNT_MASK       0x00000FFF
+#define THERMAL_FSINTVL_MASK    0x03FF0000
+#define THERMAL_SPINTVL_MASK    0x000003FF
+#define THERMAL_MON_INT_MASK    0x0007FFFF
+
+#define THERMAL_MON_CINTSTS0    0x000001
+#define THERMAL_MON_HINTSTS0    0x000002
+#define THERMAL_MON_LOINTSTS0   0x000004
+#define THERMAL_MON_HOINTSTS0   0x000008
+#define THERMAL_MON_NHINTSTS0   0x000010
+#define THERMAL_MON_CINTSTS1    0x000020
+#define THERMAL_MON_HINTSTS1    0x000040
+#define THERMAL_MON_LOINTSTS1   0x000080
+#define THERMAL_MON_HOINTSTS1   0x000100
+#define THERMAL_MON_NHINTSTS1   0x000200
+#define THERMAL_MON_CINTSTS2    0x000400
+#define THERMAL_MON_HINTSTS2    0x000800
+#define THERMAL_MON_LOINTSTS2   0x001000
+#define THERMAL_MON_HOINTSTS2   0x002000
+#define THERMAL_MON_NHINTSTS2   0x004000
+#define THERMAL_MON_TOINTSTS    0x008000
+#define THERMAL_MON_IMMDINTSTS0 0x010000
+#define THERMAL_MON_IMMDINTSTS1 0x020000
+#define THERMAL_MON_IMMDINTSTS2 0x040000
+#define THERMAL_MON_FILTINTSTS0 0x080000
+#define THERMAL_MON_FILTINTSTS1 0x100000
+#define THERMAL_MON_FILTINTSTS2 0x200000
+
+
+#define THERMAL_tri_SPM_State0	0x20000000
+#define THERMAL_tri_SPM_State1	0x40000000
+#define THERMAL_tri_SPM_State2	0x80000000
+
+
+#define THERMAL_MSRCTL0_MASK    0x00000007
+#define THERMAL_MSRCTL1_MASK    0x00000038
+#define THERMAL_MSRCTL2_MASK    0x000001C0
+
+/* extern int thermal_one_shot_handler(int times); */
+
+typedef enum {
+	THERMAL_SENSOR1 = 0,	/* TS1 */
+	THERMAL_SENSOR_NUM
+} thermal_sensor_name;
+
+struct TS_PTPOD {
+	unsigned int ts_MTS;
+	unsigned int ts_BTS;
+};
+
+extern void get_thermal_slope_intercept(struct TS_PTPOD *ts_info);
+extern void set_taklking_flag(bool flag);
+extern int tscpu_get_cpu_temp(void);
+
+/*5 thermal sensors*/
+typedef enum {
+	MTK_THERMAL_SENSOR_TS1 = 0,
+	ATM_CPU_LIMIT,
+	ATM_GPU_LIMIT,
+	MTK_THERMAL_SENSOR_CPU_COUNT
+} MTK_THERMAL_SENSOR_CPU_ID_MET;
+
+struct mtk_cpu_power_info {
+	unsigned int cpufreq_khz;
+	unsigned int cpufreq_ncpu;
+	unsigned int cpufreq_power;
+};
+extern int mtk_cpufreq_register(struct mtk_cpu_power_info *freqs, int num);
+
+extern int tscpu_get_cpu_temp_met(MTK_THERMAL_SENSOR_CPU_ID_MET id);
+
+
+typedef void (*met_thermalsampler_funcMET) (void);
+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB);
+
+void tscpu_start_thermal(void);
+void tscpu_stop_thermal(void);
+void tscpu_cancel_thermal_timer(void);
+void tscpu_start_thermal_timer(void);
+int mtkts_AP_get_hw_temp(void);
+
+extern int amddulthro_backoff(int level);
+/* extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); */
+/* extern int IMM_IsAdcInitReady(void); */
+extern int get_immediate_temp2_wrap(void);
+extern void mtkts_dump_cali_info(void);
+extern unsigned int read_dram_temperature(void);
+extern int mtk_thermal_get_cpu_load_sum(void);
+
+/**********************************
+ * Power table struct for thermal
+ **********************************/
+struct mt_gpufreq_power_table_info {
+	unsigned int gpufreq_khz;
+	unsigned int gpufreq_volt;
+	unsigned int gpufreq_power;
+};
+
+extern int mtk_gpufreq_register(struct mt_gpufreq_power_table_info *freqs, int num);
+#endif
diff --git a/drivers/misc/mediatek/include/mt-plat/mt_sched.h b/drivers/misc/mediatek/include/mt-plat/mt_sched.h
new file mode 100644
index 0000000000000..71206f0805482
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mt_sched.h
@@ -0,0 +1,34 @@
+/*
+* Copyright (C) 2016 MediaTek Inc.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+* See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+*/
+
+#ifdef CONFIG_MTK_SCHED_RQAVG_US
+/*
+ * @cpu: cpu id
+ * @reset: reset the statistic start time after this time query
+ * @use_maxfreq: caculate cpu loading with max cpu max frequency
+ * return: cpu loading as percentage (0~100)
+ */
+extern unsigned int sched_get_percpu_load(int cpu, bool reset, bool use_maxfreq);
+
+/*
+ * return: heavy task(loading>90%) number in the system
+ */
+extern unsigned int sched_get_nr_heavy_task(void);
+
+/*
+ * @threshold: heavy task loading threshold (0~1023)
+ * return: heavy task(loading>threshold) number in the system
+ */
+extern unsigned int sched_get_nr_heavy_task_by_threshold(unsigned int threshold);
+#endif /* CONFIG_MTK_SCHED_RQAVG_US */
+
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_io.h b/drivers/misc/mediatek/include/mt-plat/mtk_io.h
new file mode 100644
index 0000000000000..de17db505d3e5
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_io.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MT_IO_H__
+#define __MT_IO_H__
+
+/* only for arm64 */
+#ifdef CONFIG_ARM64
+#define IOMEM(a)	((void __force __iomem *)((a)))
+#endif
+
+#endif  /* !__MT_IO_H__ */
+
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h
new file mode 100644
index 0000000000000..d679c5a1ce738
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_LPAE_H__
+#define __MTK_LPAE_H__
+#ifdef CONFIG_MTK_LM_MODE
+
+#include <mt-plat/mtk_io.h>
+
+#define INTERAL_MAPPING_OFFSET (0x40000000)
+#define INTERAL_MAPPING_LIMIT (INTERAL_MAPPING_OFFSET + 0x80000000)
+
+#define MT_OVERFLOW_ADDR_START 0x100000000ULL
+
+unsigned int __attribute__((weak)) enable_4G(void)
+{
+	return 0;
+}
+
+/* For HW modules which support 33-bit address setting */
+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) \
+	do { \
+		ret = 0; \
+		if (enable_4G()) {\
+			if (((phys_addr_t)phy_addr < MT_OVERFLOW_ADDR_START)\
+					&& (((phys_addr_t)phy_addr + size) >= MT_OVERFLOW_ADDR_START)) \
+				ret = MT_OVERFLOW_ADDR_START - phy_addr; \
+		} \
+	}  while (0) \
+
+/* For SPM and MD32 only in ROME */
+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) \
+	do { \
+		if (enable_4G()) {\
+			if (phy_addr >= INTERAL_MAPPING_OFFSET && phy_addr < INTERAL_MAPPING_LIMIT) \
+				phy_addr += INTERAL_MAPPING_OFFSET; \
+		} \
+	} while (0)\
+
+#else /* !CONFIG_ARM_LPAE */
+
+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret)
+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr)
+#define MT_OVERFLOW_ADDR_START 0
+
+static inline unsigned int enable_4G(void)
+{
+	return 0;
+}
+
+#endif
+#endif  /*!__MTK_LPAE_H__ */
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h
new file mode 100644
index 0000000000000..7baafc4329bfc
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_MDM_MONITOR_H
+#define _MTK_MDM_MONITOR_H
+
+struct md_info {
+	char *attribute;
+	int value;
+	char *unit;
+	int invalid_value;
+	int index;
+};
+
+extern
+int mtk_mdm_get_md_info(struct md_info **p_inf, int *size);
+
+extern
+int mtk_mdm_start_query(void);
+
+extern
+int mtk_mdm_stop_query(void);
+
+extern
+int mtk_mdm_set_signal_period(int second);
+
+extern
+int mtk_mdm_set_md1_signal_period(int second);
+
+extern
+int mtk_mdm_set_md2_signal_period(int second);
+#endif
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h
new file mode 100644
index 0000000000000..8f20f38b75d6c
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_PLATFORM_DEBUG_H__
+#define __MTK_PLATFORM_DEBUG_H__
+
+#ifdef CONFIG_MTK_PLAT_SRAM_FLAG
+/* plat_sram_flag */
+extern int set_sram_flag_lastpc_valid(void);
+extern int set_sram_flag_dfd_valid(void);
+extern int set_sram_flag_etb_user(unsigned int etb_id, unsigned int user_id);
+#endif
+
+#ifdef CONFIG_MTK_DFD_INTERNAL_DUMP
+extern int dfd_setup(void);
+#endif
+
+#endif /* __MTK_PLATFORM_DEBUG_H__ */
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h
new file mode 100644
index 0000000000000..3a94a1bbcd241
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_RAM_CONSOLE_H__
+#define __MTK_RAM_CONSOLE_H__
+
+#include <linux/console.h>
+#include <linux/pstore.h>
+
+typedef enum {
+	AEE_FIQ_STEP_FIQ_ISR_BASE = 1,
+	AEE_FIQ_STEP_WDT_FIQ_INFO = 4,
+	AEE_FIQ_STEP_WDT_FIQ_STACK,
+	AEE_FIQ_STEP_WDT_FIQ_LOOP,
+	AEE_FIQ_STEP_WDT_FIQ_DONE,
+	AEE_FIQ_STEP_WDT_IRQ_INFO = 8,
+	AEE_FIQ_STEP_WDT_IRQ_KICK,
+	AEE_FIQ_STEP_WDT_IRQ_SMP_STOP,
+	AEE_FIQ_STEP_WDT_IRQ_TIME,
+	AEE_FIQ_STEP_WDT_IRQ_STACK,
+	AEE_FIQ_STEP_WDT_IRQ_GIC,
+	AEE_FIQ_STEP_WDT_IRQ_LOCALTIMER,
+	AEE_FIQ_STEP_WDT_IRQ_IDLE,
+	AEE_FIQ_STEP_WDT_IRQ_SCHED,
+	AEE_FIQ_STEP_WDT_IRQ_DONE,
+	AEE_FIQ_STEP_KE_WDT_INFO = 20,
+	AEE_FIQ_STEP_KE_WDT_PERCPU,
+	AEE_FIQ_STEP_KE_WDT_LOG,
+	AEE_FIQ_STEP_KE_SCHED_DEBUG,
+	AEE_FIQ_STEP_KE_EINT_DEBUG,
+	AEE_FIQ_STEP_KE_WDT_DONE,
+	AEE_FIQ_STEP_KE_IPANIC_DIE = 32,
+	AEE_FIQ_STEP_KE_IPANIC_START,
+	AEE_FIQ_STEP_KE_IPANIC_OOP_HEADER,
+	AEE_FIQ_STEP_KE_IPANIC_DETAIL,
+	AEE_FIQ_STEP_KE_IPANIC_CONSOLE,
+	AEE_FIQ_STEP_KE_IPANIC_USERSPACE,
+	AEE_FIQ_STEP_KE_IPANIC_ANDROID,
+	AEE_FIQ_STEP_KE_IPANIC_MMPROFILE,
+	AEE_FIQ_STEP_KE_IPANIC_HEADER,
+	AEE_FIQ_STEP_KE_IPANIC_DONE,
+	AEE_FIQ_STEP_KE_NESTED_PANIC = 64,
+} AEE_FIQ_STEP_NUM;
+
+#ifdef CONFIG_MTK_RAM_CONSOLE
+extern int aee_rr_curr_fiq_step(void);
+extern void aee_rr_rec_fiq_step(u8 i);
+extern void aee_rr_rec_reboot_mode(u8 mode);
+extern void aee_rr_rec_kdump_params(void *params);
+extern void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j);
+extern void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j);
+extern void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm);
+extern void aee_sram_fiq_log(const char *msg);
+extern void ram_console_write(struct console *console, const char *s, unsigned int count);
+extern void aee_sram_fiq_save_bin(const char *buffer, size_t len);
+extern void aee_rr_rec_hotplug_footprint(int cpu, u8 fp);
+extern void aee_rr_rec_hotplug_cpu_event(u8 val);
+extern void aee_rr_rec_hotplug_cb_index(u8 val);
+extern void aee_rr_rec_hotplug_cb_fp(unsigned long val);
+#ifdef CONFIG_MTK_EMMC_SUPPORT
+extern void last_kmsg_store_to_emmc(void);
+#endif
+
+#else
+static inline void aee_rr_rec_hotplug_footprint(int cpu, u8 fp)
+{
+}
+static inline void aee_rr_rec_hotplug_cpu_event(u8 val)
+{
+}
+static inline void aee_rr_rec_hotplug_cb_index(u8 val)
+{
+}
+static inline void aee_rr_rec_hotplug_cb_fp(unsigned long val)
+{
+}
+static inline int aee_rr_curr_fiq_step(void)
+{
+	return 0;
+}
+
+static inline void aee_rr_rec_fiq_step(u8 i)
+{
+}
+
+static inline unsigned int aee_rr_curr_exp_type(void)
+{
+	return 0;
+}
+
+static inline void aee_rr_rec_exp_type(unsigned int type)
+{
+}
+
+static inline void aee_rr_rec_reboot_mode(u8 mode)
+{
+}
+
+static inline void aee_rr_rec_kdump_params(void *params)
+{
+}
+
+static inline void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j)
+{
+}
+
+static inline void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j)
+{
+}
+
+static inline void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm)
+{
+}
+
+static inline void aee_sram_fiq_log(const char *msg)
+{
+}
+
+static inline void ram_console_write(struct console *console, const char *s, unsigned int count)
+{
+}
+
+static inline void aee_sram_fiq_save_bin(unsigned char *buffer, size_t len)
+{
+}
+
+#ifdef CONFIG_MTK_EMMC_SUPPORT
+static inline void last_kmsg_store_to_emmc(void)
+{
+}
+#endif
+
+#endif /* CONFIG_MTK_RAM_CONSOLE */
+
+#ifdef CONFIG_MTK_AEE_IPANIC
+extern int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size);
+extern int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time,
+				  char **buf, struct pstore_info *psi);
+#else
+static inline int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size)
+{
+	return 0;
+}
+
+static inline int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time,
+				  char **buf, struct pstore_info *psi)
+{
+	return 0;
+}
+#endif /* CONFIG_MTK_AEE_IPANIC */
+
+#endif
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h
new file mode 100644
index 0000000000000..2181e99895934
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MTK_RTC_H
+#define MTK_RTC_H
+
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
+#include <linux/types.h>
+
+typedef enum {
+	RTC_GPIO_USER_WIFI = 8,
+	RTC_GPIO_USER_GPS = 9,
+	RTC_GPIO_USER_BT = 10,
+	RTC_GPIO_USER_FM = 11,
+	RTC_GPIO_USER_PMIC = 12,
+} rtc_gpio_user_t;
+
+#ifdef CONFIG_MTK_RTC
+
+/*
+ * NOTE:
+ * 1. RTC_GPIO always exports 32K enabled by some user even if the phone is powered off
+ */
+
+extern unsigned long rtc_read_hw_time(void);
+extern void rtc_gpio_enable_32k(rtc_gpio_user_t user);
+extern void rtc_gpio_disable_32k(rtc_gpio_user_t user);
+extern bool rtc_gpio_32k_status(void);
+
+/* for AUDIOPLL (deprecated) */
+extern void rtc_enable_abb_32k(void);
+extern void rtc_disable_abb_32k(void);
+
+/* NOTE: used in Sleep driver to workaround Vrtc-Vore level shifter issue */
+extern void rtc_enable_writeif(void);
+extern void rtc_disable_writeif(void);
+
+extern void rtc_mark_recovery(void);
+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)
+extern void rtc_mark_kpoc(void);
+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/
+extern void rtc_mark_fast(void);
+extern u16 rtc_rdwr_uart_bits(u16 *val);
+extern void rtc_bbpu_power_down(void);
+extern void rtc_read_pwron_alarm(struct rtc_wkalrm *alm);
+extern int get_rtc_spare_fg_value(void);
+extern int set_rtc_spare_fg_value(int val);
+extern void rtc_irq_handler(void);
+extern bool crystal_exist_status(void);
+extern void mt_power_off(void);
+#else/*ifdef CONFIG_MTK_RTC*/
+#define rtc_read_hw_time()              ({ 0; })
+#define rtc_gpio_enable_32k(user)	do {} while (0)
+#define rtc_gpio_disable_32k(user)	do {} while (0)
+#define rtc_gpio_32k_status()		do {} while (0)
+#define rtc_enable_abb_32k()		do {} while (0)
+#define rtc_disable_abb_32k()		do {} while (0)
+#define rtc_enable_writeif()		do {} while (0)
+#define rtc_disable_writeif()		do {} while (0)
+#define rtc_mark_recovery()             do {} while (0)
+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)
+#define rtc_mark_kpoc()                 do {} while (0)
+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/
+#define rtc_mark_fast()		        do {} while (0)
+#define rtc_rdwr_uart_bits(val)		({ 0; })
+#define rtc_bbpu_power_down()		do {} while (0)
+#define rtc_read_pwron_alarm(alm)	do {} while (0)
+#define get_rtc_spare_fg_value()	({ 0; })
+#define set_rtc_spare_fg_value(val)	({ 0; })
+#define rtc_irq_handler()			do {} while (0)
+#define crystal_exist_status()		do {} while (0)
+__weak void mt_power_off(void);
+#endif/*ifdef CONFIG_MTK_RTC*/
+#endif
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h
new file mode 100644
index 0000000000000..eac6bc713c985
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _MTK_THERMAL_EXT_CONTROL_H
+#define _MTK_THERMAL_EXT_CONTROL_H
+
+#define THERMAL_MD32_IPI_MSG_BASE 0x1F00
+#define THERMAL_AP_IPI_MSG_BASE   0x2F00
+
+typedef enum {
+	THERMAL_AP_IPI_MSG_SET_TZ_THRESHOLD = THERMAL_AP_IPI_MSG_BASE,
+	THERMAL_AP_IPI_MSG_MD32_START,
+
+	THERMAL_MD32_IPI_MSG_READY = THERMAL_MD32_IPI_MSG_BASE,
+	THERMAL_MD32_IPI_MSG_MD32_START_ACK,
+	THERMAL_MD32_IPI_MSG_REACH_THRESHOLD,
+} thermal_ipi_msg_id;
+
+typedef enum {
+/* MTK_THERMAL_EXT_SENSOR_CPU = 0, */
+	MTK_THERMAL_EXT_SENSOR_ABB = 0,
+	MTK_THERMAL_EXT_SENSOR_PMIC,
+	MTK_THERMAL_EXT_SENSOR_BATTERY,
+	MTK_THERMAL_EXT_SENSOR_COUNT
+} MTK_THERMAL_EXT_SENSOR_ID;
+
+typedef struct {
+	int id;			/* id of this tz */
+	int polling_delay;	/* polling delay of this tz */
+	long high_trip_point;	/* high threshold of this tz */
+	long low_trip_point;	/* low threshold of this tz */
+} thermal_zone_data;
+
+typedef struct {
+	int id;			/* id of this tz */
+	long high_trip_point;	/* high threshold of this tz */
+	long low_trip_point;	/* low threshold of this tz */
+	long temperature;	/* Current temperature gotten from TS */
+} thermal_zone_status;
+
+typedef struct {
+	short id;
+	union {
+		thermal_zone_data tz;
+		thermal_zone_status tz_status;
+	} data;
+} thermal_ipi_msg;
+
+#endif				/* _MTK_THERMAL_EXT_CONTROL_H */
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h
new file mode 100644
index 0000000000000..7903b49dc419c
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_THERMAL_MONITOR_H
+#define _MTK_THERMAL_MONITOR_H
+
+#include <linux/thermal.h>
+
+/*
+ *  MTK_THERMAL_WRAPPER_BYPASS = 1 (use original Linux Thermal API)
+ *  MTK_THERMAL_WRAPPER_BYPASS = 0 (use MTK Thermal API Monitor)
+ */
+#define MTK_THERMAL_WRAPPER_BYPASS 0
+
+#if MTK_THERMAL_WRAPPER_BYPASS
+/* Original LTF API */
+#define mtk_thermal_zone_device_register      thermal_zone_device_register
+#define mtk_thermal_zone_device_unregister    thermal_zone_device_unregister
+#define mtk_thermal_cooling_device_unregister thermal_cooling_device_unregister
+#define mtk_thermal_cooling_device_register   thermal_cooling_device_register
+#define mtk_thermal_zone_bind_cooling_device  thermal_zone_bind_cooling_device
+
+#else
+
+struct thermal_cooling_device_ops_extra {
+	int (*set_cur_temp)(struct thermal_cooling_device *, unsigned long);
+};
+
+extern
+struct thermal_zone_device *mtk_thermal_zone_device_register_wrapper
+(char *type, int trips, void *devdata, const struct thermal_zone_device_ops *ops,
+int tc1, int tc2, int passive_delay, int polling_delay);
+
+extern
+void mtk_thermal_zone_device_unregister_wrapper(struct thermal_zone_device *tz);
+
+extern
+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper
+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops);
+
+extern
+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper_extra
+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops,
+const struct thermal_cooling_device_ops_extra *ops_ext);
+
+extern
+int mtk_thermal_cooling_device_add_exit_point
+(struct thermal_cooling_device *cdev, int exit_point);
+
+extern
+void mtk_thermal_cooling_device_unregister_wrapper(struct thermal_cooling_device *cdev);
+
+extern int mtk_thermal_zone_bind_cooling_device_wrapper
+(struct thermal_zone_device *tz, int trip, struct thermal_cooling_device *cdev);
+
+extern int mtk_thermal_zone_bind_trigger_trip(struct thermal_zone_device *tz, int trip, int mode);
+#define mtk_thermal_zone_device_register      mtk_thermal_zone_device_register_wrapper
+#define mtk_thermal_zone_device_unregister    mtk_thermal_zone_device_unregister_wrapper
+#define mtk_thermal_cooling_device_unregister mtk_thermal_cooling_device_unregister_wrapper
+#define mtk_thermal_cooling_device_register   mtk_thermal_cooling_device_register_wrapper
+#define mtk_thermal_zone_bind_cooling_device  mtk_thermal_zone_bind_cooling_device_wrapper
+
+#endif
+
+typedef enum {
+	MTK_THERMAL_SENSOR_CPU = 0,
+	MTK_THERMAL_SENSOR_ABB,
+	MTK_THERMAL_SENSOR_PMIC,
+	MTK_THERMAL_SENSOR_BATTERY,
+	MTK_THERMAL_SENSOR_MD1,
+	MTK_THERMAL_SENSOR_MD2,
+	MTK_THERMAL_SENSOR_WIFI,
+	MTK_THERMAL_SENSOR_BATTERY2,
+	MTK_THERMAL_SENSOR_BUCK,
+	MTK_THERMAL_SENSOR_AP,
+	MTK_THERMAL_SENSOR_PCB1,
+	MTK_THERMAL_SENSOR_PCB2,
+	MTK_THERMAL_SENSOR_SKIN,
+	MTK_THERMAL_SENSOR_XTAL,
+	MTK_THERMAL_SENSOR_MD_PA,
+
+	MTK_THERMAL_SENSOR_COUNT
+} MTK_THERMAL_SENSOR_ID;
+
+extern int mtk_thermal_get_temp(MTK_THERMAL_SENSOR_ID id);
+extern struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void);
+
+/* This API function is implemented in mediatek/kernel/drivers/leds/leds.c */
+extern int setMaxbrightness(int max_level, int enable);
+
+extern void machine_power_off(void);
+#endif
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h
new file mode 100644
index 0000000000000..305574031196a
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_THERMAL_PLATFORM_H
+#define _MTK_THERMAL_PLATFORM_H
+
+#include <linux/thermal.h>
+#include <mtk_thermal_typedefs.h>
+
+extern
+int mtk_thermal_get_cpu_info(int *nocores, int **cpufreq, int **cpuloading);
+
+extern
+int mtk_thermal_get_gpu_info(int *nocores, int **gpufreq, int **gpuloading);
+
+extern
+int mtk_thermal_get_batt_info(int *batt_voltage, int *batt_current, int *batt_temp);
+
+extern
+int mtk_thermal_get_extra_info(int *no_extra_attr,
+			       char ***attr_names, int **attr_values, char ***attr_unit);
+
+extern
+int mtk_thermal_force_get_batt_temp(void);
+
+
+enum {
+	MTK_THERMAL_SCEN_CALL = 0x1
+};
+
+extern
+unsigned int mtk_thermal_set_user_scenarios(unsigned int mask);
+
+extern
+unsigned int mtk_thermal_clear_user_scenarios(unsigned int mask);
+
+
+#if defined(CONFIG_MTK_SMART_BATTERY)
+/* global variable from battery driver... */
+extern kal_bool gFG_Is_Charging;
+#endif
+
+extern int force_get_tbat(void);
+#endif				/* _MTK_THERMAL_PLATFORM_H */
+
+
+typedef enum {
+	TA_DAEMON_CMD_GET_INIT_FLAG = 0,
+	TA_DAEMON_CMD_SET_DAEMON_PID,
+	TA_DAEMON_CMD_NOTIFY_DAEMON,
+	TA_DAEMON_CMD_NOTIFY_DAEMON_CATMINIT,
+	TA_DAEMON_CMD_SET_TTJ,
+	TA_DAEMON_CMD_GET_TPCB,
+
+	TA_DAEMON_CMD_TO_KERNEL_NUMBER
+} TA_DAEMON_CTRL_CMD_TO_KERNEL; /*must sync userspace/kernel: TA_DAEMON_CTRL_CMD_FROM_USER*/
+
+#define TAD_NL_MSG_T_HDR_LEN 12
+#define TAD_NL_MSG_MAX_LEN 2048
+
+struct tad_nl_msg_t {
+	unsigned int tad_cmd;
+	unsigned int tad_data_len;
+	unsigned int tad_ret_data_len;
+	char tad_data[TAD_NL_MSG_MAX_LEN];
+};
+
+enum {
+	TA_CATMPLUS = 1,
+	TA_CONTINUOUS = 2,
+	TA_CATMPLUS_TTJ = 3
+};
+
+
+struct cATM_params_t {
+	int CATM_ON;
+	int K_TT;
+	int K_SUM_TT_LOW;
+	int K_SUM_TT_HIGH;
+	int MIN_SUM_TT;
+	int MAX_SUM_TT;
+	int MIN_TTJ;
+	int CATMP_STEADY_TTJ_DELTA;
+};
+struct continuetm_params_t {
+	int STEADY_TARGET_TJ;
+	int MAX_TARGET_TJ;
+	int TRIP_TPCB;
+	int STEADY_TARGET_TPCB;
+};
+
+
+struct CATM_T {
+	struct cATM_params_t t_catm_par;
+	struct continuetm_params_t t_continuetm_par;
+};
+extern struct CATM_T thermal_atm_t;
+int wakeup_ta_algo(int flow_state);
+int ta_get_ttj(void);
+
+extern int mtk_thermal_get_tpcb_target(void);
+extern int tsatm_thermal_get_catm_type(void);
+
+
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h
new file mode 100644
index 0000000000000..1c23a9f4a862e
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM thermal
+
+#if !defined(_MTK_THERMAL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _MTK_THERMAL_TRACE_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(cooling_device_state,
+	    TP_PROTO(int device, unsigned long state),
+	    TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device)
+						     __field(unsigned long, state)
+	    ),
+	    TP_fast_assign(__entry->device = device;
+			   __entry->state = state;),
+	    TP_printk("cooling_device=%d, state=%lu\n", __entry->device, __entry->state)
+);
+
+TRACE_EVENT(thermal_zone_state,
+	    TP_PROTO(int device, int state),
+	    TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device)
+						     __field(int, state)
+	    ),
+	    TP_fast_assign(__entry->device = device;
+			   __entry->state = state;),
+	    TP_printk("thermal_zone=%d, state=%d\n", __entry->device, __entry->state)
+);
+#endif				/* _MTK_THERMAL_TRACE_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE mach/mtk_thermal_trace
+#include <trace/define_trace.h>
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h
new file mode 100644
index 0000000000000..dfcef3d952fc7
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _TYPEDEFS_H
+#define _TYPEDEFS_H
+
+#include <linux/bug.h>
+
+/* --------------------------------------------------------------------------- */
+/* Basic Type Definitions */
+/* --------------------------------------------------------------------------- */
+
+typedef volatile unsigned char *P_kal_uint8;
+typedef volatile unsigned short *P_kal_uint16;
+typedef volatile unsigned int *P_kal_uint32;
+
+typedef long LONG;
+typedef unsigned char UBYTE;
+typedef short SHORT;
+
+typedef signed char kal_int8;
+typedef signed short kal_int16;
+typedef signed int kal_int32;
+typedef long long kal_int64;
+typedef unsigned char kal_uint8;
+typedef unsigned short kal_uint16;
+typedef unsigned int kal_uint32;
+typedef unsigned long long kal_uint64;
+typedef char kal_char;
+
+typedef unsigned int *UINT32P;
+typedef volatile unsigned short *UINT16P;
+typedef volatile unsigned char *UINT8P;
+typedef unsigned char *U8P;
+
+typedef volatile unsigned char *P_U8;
+typedef volatile signed char *P_S8;
+typedef volatile unsigned short *P_U16;
+typedef volatile signed short *P_S16;
+typedef volatile unsigned int *P_U32;
+typedef volatile signed int *P_S32;
+typedef unsigned long long *P_U64;
+typedef signed long long *P_S64;
+
+typedef unsigned char U8;
+typedef signed char S8;
+typedef unsigned short U16;
+typedef signed short S16;
+typedef unsigned int U32;
+typedef signed int S32;
+typedef unsigned long long U64;
+typedef signed long long S64;
+/* typedef unsigned char       bool; */
+
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef unsigned short USHORT;
+typedef signed char INT8;
+typedef signed short INT16;
+typedef signed int INT32;
+typedef unsigned int DWORD;
+typedef void VOID;
+typedef unsigned char BYTE;
+typedef float FLOAT;
+
+typedef char *LPCSTR;
+typedef short *LPWSTR;
+
+
+/* --------------------------------------------------------------------------- */
+/* Constants */
+/* --------------------------------------------------------------------------- */
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef TRUE
+#define TRUE  (1)
+#endif
+
+#ifndef NULL
+#define NULL  (0)
+#endif
+
+/* enum boolean {false, true}; */
+enum { RX, TX, NONE };
+
+#ifndef BOOL
+typedef unsigned char BOOL;
+#endif
+
+#ifndef BATTERY_BOOL
+#define BATTERY_BOOL
+typedef enum {
+	KAL_FALSE = 0,
+	KAL_TRUE = 1,
+} kal_bool;
+#endif
+
+/* --------------------------------------------------------------------------- */
+/* Type Casting */
+/* --------------------------------------------------------------------------- */
+
+#define AS_INT32(x)     (*(INT32 *)((void *)x))
+#define AS_INT16(x)     (*(INT16 *)((void *)x))
+#define AS_INT8(x)      (*(INT8  *)((void *)x))
+
+#define AS_UINT32(x)    (*(UINT32 *)((void *)x))
+#define AS_UINT16(x)    (*(UINT16 *)((void *)x))
+#define AS_UINT8(x)     (*(UINT8  *)((void *)x))
+
+
+/* --------------------------------------------------------------------------- */
+/* Register Manipulations */
+/* --------------------------------------------------------------------------- */
+
+#define READ_REGISTER_UINT32(reg) \
+	(*(volatile UINT32 * const)(reg))
+
+#define WRITE_REGISTER_UINT32(reg, val) \
+	((*(volatile UINT32 * const)(reg)) = (val))
+
+#define READ_REGISTER_UINT16(reg) \
+	((*(volatile UINT16 * const)(reg)))
+
+#define WRITE_REGISTER_UINT16(reg, val) \
+	((*(volatile UINT16 * const)(reg)) = (val))
+
+#define READ_REGISTER_UINT8(reg) \
+	((*(volatile UINT8 * const)(reg)))
+
+#define WRITE_REGISTER_UINT8(reg, val) \
+	((*(volatile UINT8 * const)(reg)) = (val))
+
+#define INREG8(x)           READ_REGISTER_UINT8((UINT8 *)((void *)(x)))
+#define OUTREG8(x, y)       WRITE_REGISTER_UINT8((UINT8 *)((void *)(x)), (UINT8)(y))
+#define SETREG8(x, y)       OUTREG8(x, INREG8(x)|(y))
+#define CLRREG8(x, y)       OUTREG8(x, INREG8(x)&~(y))
+#define MASKREG8(x, y, z)   OUTREG8(x, (INREG8(x)&~(y))|(z))
+
+#define INREG16(x)          READ_REGISTER_UINT16((UINT16 *)((void *)(x)))
+#define OUTREG16(x, y)      WRITE_REGISTER_UINT16((UINT16 *)((void *)(x)), (UINT16)(y))
+#define SETREG16(x, y)      OUTREG16(x, INREG16(x)|(y))
+#define CLRREG16(x, y)      OUTREG16(x, INREG16(x)&~(y))
+#define MASKREG16(x, y, z)  OUTREG16(x, (INREG16(x)&~(y))|(z))
+
+#define INREG32(x)          READ_REGISTER_UINT32((UINT32 *)((void *)(x)))
+#define OUTREG32(x, y)      WRITE_REGISTER_UINT32((UINT32 *)((void *)(x)), (UINT32)(y))
+#define SETREG32(x, y)      OUTREG32(x, INREG32(x)|(y))
+#define CLRREG32(x, y)      OUTREG32(x, INREG32(x)&~(y))
+#define MASKREG32(x, y, z)  OUTREG32(x, (INREG32(x)&~(y))|(z))
+
+
+#define DRV_Reg8(addr)              INREG8(addr)
+#define DRV_WriteReg8(addr, data)   OUTREG8(addr, data)
+#define DRV_SetReg8(addr, data)     SETREG8(addr, data)
+#define DRV_ClrReg8(addr, data)     CLRREG8(addr, data)
+
+#define DRV_Reg16(addr)             INREG16(addr)
+#define DRV_WriteReg16(addr, data)  OUTREG16(addr, data)
+#define DRV_SetReg16(addr, data)    SETREG16(addr, data)
+#define DRV_ClrReg16(addr, data)    CLRREG16(addr, data)
+
+#define DRV_Reg32(addr)             INREG32(addr)
+#define DRV_WriteReg32(addr, data)  OUTREG32(addr, data)
+#define DRV_SetReg32(addr, data)    SETREG32(addr, data)
+#define DRV_ClrReg32(addr, data)    CLRREG32(addr, data)
+
+/* !!! DEPRECATED, WILL BE REMOVED LATER !!! */
+#define DRV_Reg(addr)               DRV_Reg16(addr)
+#define DRV_WriteReg(addr, data)    DRV_WriteReg16(addr, data)
+#define DRV_SetReg(addr, data)      DRV_SetReg16(addr, data)
+#define DRV_ClrReg(addr, data)      DRV_ClrReg16(addr, data)
+
+
+/* --------------------------------------------------------------------------- */
+/* Compiler Time Deduction Macros */
+/* --------------------------------------------------------------------------- */
+
+
+
+/* --------------------------------------------------------------------------- */
+/* Assertions */
+/* --------------------------------------------------------------------------- */
+
+/*
+*#ifndef ASSERT
+*#define ASSERT(expr)        BUG_ON(!(expr))
+*#endif
+*
+*#ifndef NOT_IMPLEMENTED
+*#define NOT_IMPLEMENTED()   BUG_ON(1)
+*#endif
+*/
+#define STATIC_ASSERT(pred)         STATIC_ASSERT_X(pred, __LINE__)
+#define STATIC_ASSERT_X(pred, line) STATIC_ASSERT_XX(pred, line)
+#define STATIC_ASSERT_XX(pred, line) \
+extern char assertion_failed_at_##line[(pred) ? 1 : -1]
+
+/* --------------------------------------------------------------------------- */
+/* Resolve Compiler Warnings */
+/* --------------------------------------------------------------------------- */
+
+#define NOT_REFERENCED(x)   { (x) = (x); }
+
+
+/* --------------------------------------------------------------------------- */
+/* Utilities */
+/* --------------------------------------------------------------------------- */
+
+#define MAXIMUM(A, B)       (((A) > (B))?(A):(B))
+#define MINIMUM(A, B)       (((A) < (B))?(A):(B))
+
+#define ARY_SIZE(x) (sizeof((x)) / sizeof((x[0])))
+#define DVT_DELAYMACRO(u4Num)                                            \
+{                                                                        \
+	UINT32 u4Count = 0;                                                 \
+	for (u4Count = 0; u4Count < u4Num; u4Count++)			\
+		;							\
+}                                                                        \
+
+#define    A68351B      0
+#define    B68351B      1
+#define    B68351D      2
+#define    B68351E      3
+#define    UNKNOWN_IC_VERSION   0xFF
+
+
+#endif				/* _TYPEDEFS_H */
diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h
new file mode 100644
index 0000000000000..0a4fda1916540
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*! \file
+ *   \brief  Declaration of library functions
+ *
+ *   Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _MTK_WCN_CMB_STUB_H_
+#define _MTK_WCN_CMB_STUB_H_
+
+#include <linux/pm.h>
+
+/*******************************************************************************
+*                         C O M P I L E R   F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                                 M A C R O S
+********************************************************************************
+*/
+/* Audio GPIO naming style for 73/75/77 */
+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_0 1 */
+/* Audio GPIO naming style for 89/8135 */
+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_1 1 */
+/* Audio GPIO naming style for 6592 */
+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_2 1 */
+/* Audio GPIO naming style for 6595 */
+#define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_3 1
+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 1
+
+/*******************************************************************************
+*                    E X T E R N A L   R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                              C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                             D A T A   T Y P E S
+********************************************************************************
+*/
+typedef enum {
+	CMB_STUB_AIF_0 = 0,	/* 0000: BT_PCM_OFF & FM analog (line in/out) */
+	CMB_STUB_AIF_1 = 1,	/* 0001: BT_PCM_ON & FM analog (in/out) */
+	CMB_STUB_AIF_2 = 2,	/* 0010: BT_PCM_OFF & FM digital (I2S) */
+	CMB_STUB_AIF_3 = 3,	/* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */
+	CMB_STUB_AIF_4 = 4, /* 0100: BT_I2S & FM disable in special projects, e.g. protea*/
+	CMB_STUB_AIF_MAX = 5,
+} CMB_STUB_AIF_X;
+
+/*COMBO_CHIP_AUDIO_PIN_CTRL*/
+typedef enum {
+	CMB_STUB_AIF_CTRL_DIS = 0,
+	CMB_STUB_AIF_CTRL_EN = 1,
+	CMB_STUB_AIF_CTRL_MAX = 2,
+} CMB_STUB_AIF_CTRL;
+
+typedef enum {
+	COMBO_FUNC_TYPE_BT = 0,
+	COMBO_FUNC_TYPE_FM = 1,
+	COMBO_FUNC_TYPE_GPS = 2,
+	COMBO_FUNC_TYPE_WIFI = 3,
+	COMBO_FUNC_TYPE_WMT = 4,
+	COMBO_FUNC_TYPE_STP = 5,
+	COMBO_FUNC_TYPE_NUM = 6
+} COMBO_FUNC_TYPE;
+
+typedef enum {
+	COMBO_IF_UART = 0,
+	COMBO_IF_MSDC = 1,
+	COMBO_IF_BTIF = 2,
+	COMBO_IF_MAX,
+} COMBO_IF;
+
+typedef void (*wmt_bgf_eirq_cb) (void);
+typedef int (*wmt_aif_ctrl_cb) (CMB_STUB_AIF_X, CMB_STUB_AIF_CTRL);
+typedef void (*wmt_func_ctrl_cb) (unsigned int, unsigned int);
+typedef signed long (*wmt_thermal_query_cb) (void);
+typedef int (*wmt_deep_idle_ctrl_cb) (unsigned int);
+typedef int (*wmt_func_do_reset) (unsigned int);
+
+/* for DVFS driver do 1v autok */
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+typedef unsigned int (*wmt_get_drv_status)(unsigned int);
+#endif
+
+typedef void (*msdc_sdio_irq_handler_t) (void *);	/* external irq handler */
+typedef void (*pm_callback_t) (pm_message_t state, void *data);
+
+struct sdio_ops {
+	void (*sdio_request_eirq)(msdc_sdio_irq_handler_t irq_handler, void *data);
+	void (*sdio_enable_eirq)(void);
+	void (*sdio_disable_eirq)(void);
+	void (*sdio_register_pm)(pm_callback_t pm_cb, void *data);
+};
+
+typedef struct _CMB_STUB_CB_ {
+	unsigned int size;	/* structure size */
+	/*wmt_bgf_eirq_cb bgf_eirq_cb; *//* remove bgf_eirq_cb from stub. handle it in platform */
+	wmt_aif_ctrl_cb aif_ctrl_cb;
+	wmt_func_ctrl_cb func_ctrl_cb;
+	wmt_thermal_query_cb thermal_query_cb;
+	wmt_deep_idle_ctrl_cb deep_idle_ctrl_cb;
+	wmt_func_do_reset wmt_do_reset_cb;
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+	wmt_get_drv_status get_drv_status_cb;
+#endif
+} CMB_STUB_CB, *P_CMB_STUB_CB;
+
+/*******************************************************************************
+*                            P U B L I C   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                           P R I V A T E   D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+*                  F U N C T I O N   D E C L A R A T I O N S
+********************************************************************************
+*/
+
+extern struct sdio_ops mt_sdio_ops[4];
+
+extern int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb);
+extern int mtk_wcn_cmb_stub_unreg(void);
+
+extern int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl);
+
+static inline int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state)
+{
+/* return mtk_wcn_cmb_stub_aif_ctrl(state, 1); */
+	return 0;
+}
+
+extern int mt_combo_plt_enter_deep_idle(COMBO_IF src);
+extern int mt_combo_plt_exit_deep_idle(COMBO_IF src);
+
+/* Use new mtk_wcn_stub APIs instead of old mt_combo ones for kernel to control
+ * function on/off.
+ */
+extern void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on);
+extern int mtk_wcn_cmb_stub_query_ctrl(void);
+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on);
+extern int mtk_wcn_sdio_irq_flag_set(int falg);
+
+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK
+extern int mtk_wcn_cmb_stub_1vautok_for_dvfs(void);
+#endif
+
+extern int mtk_wcn_wmt_chipid_query(void);
+extern void mtk_wcn_wmt_set_chipid(int chipid);
+
+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver
+ *
+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2"
+ * @ enable - "1", enable deep idle; "0", disable deep idle
+ *
+ * Return 0 if success, else -1
+ */
+extern unsigned int mtk_uart_pdn_enable(char *port, int enable);
+/*******************************************************************************
+*                              F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _MTK_WCN_CMB_STUB_H_ */
diff --git a/drivers/misc/mediatek/include/mt-plat/rt-regmap.h b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h
new file mode 100644
index 0000000000000..9a45e23005cad
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h
@@ -0,0 +1,291 @@
+/* drivers/misc/mediatek/include/mt-plat/rt-regmap.h
+ * Header of Richtek regmap with debugfs Driver
+ *
+ * Copyright (C) 2014 Richtek Technology Corp.
+ * Jeff Chang <jeff_chang@richtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MISC_MEDIATEK_RT_REGMAP_H
+#define MISC_MEDIATEK_RT_REGMAP_H
+
+#include <linux/debugfs.h>
+#include <linux/i2c.h>
+
+/* #define RT_REGMAP_VERSION	"1.1.11_G" */
+
+enum rt_access_mode {
+	RT_1BYTE_MODE = 1,
+	RT_2BYTE_MODE = 2,
+	RT_4BYTE_MODE = 4,
+};
+
+/* start : the start address of group
+ * end : the end address of group
+ * mode : access mode (1,2,4 bytes)
+ */
+struct rt_access_group {
+	u32 start;
+	u32 end;
+	enum rt_access_mode mode;
+};
+
+/* rt_reg_type
+ * RT_NORMAL	: Write data without mask
+ *			Read from cache
+ * RT_WBITS	: Write data with mask
+ *			Read from cache
+ * RT_VOLATILE	: Write data to chip directly
+ *			Read data from chip
+ * RT_RESERVE	: Reserve registers (Write/Read as RT_NORMAL)
+ */
+
+#define RT_REG_TYPE_MASK	(0x03)
+#define RT_NORMAL		(0x00)
+#define RT_WBITS		(0x01)
+#define RT_VOLATILE		(0x02)
+#define RT_RESERVE		(0x03)
+
+/* RT_WR_ONCE : write once will check write data and cache data,
+ *		if write data = cache data, data will not be writen.
+ */
+#define RT_WR_ONCE		(0x08)
+#define RT_NORMAL_WR_ONCE	(RT_NORMAL|RT_WR_ONCE)
+#define RT_WBITS_WR_ONCE	(RT_WBITS|RT_WR_ONCE)
+
+enum rt_data_format {
+	RT_LITTLE_ENDIAN,
+	RT_BIG_ENDIAN,
+};
+
+/* rt_regmap_mode
+ *  0  0  0  0  0  0  0  0
+ *	  |  |  |  |  |  |
+ *	  |  |  |  |__|  byte_mode
+ *        |  |__|   ||
+ *        |   ||   Cache_mode
+ *        |   Block_mode
+ *        Debug_mode
+ */
+
+#define RT_BYTE_MODE_MASK	(0x01)
+/* 1 byte for each register*/
+#define RT_SINGLE_BYTE		(0 << 0)
+/* multi bytes for each regiseter*/
+#define RT_MULTI_BYTE		(1 << 0)
+
+#define RT_CACHE_MODE_MASK	 (0x06)
+/* write to cache and chip synchronously */
+#define RT_CACHE_WR_THROUGH	 (0 << 1)
+/* write to cache and chip asynchronously */
+#define RT_CACHE_WR_BACK	 (1 << 1)
+/* disable cache */
+#define RT_CACHE_DISABLE	 (2 << 1)
+
+#define RT_IO_BLK_MODE_MASK (0x18)
+/* pass through all write function */
+#define RT_IO_PASS_THROUGH	(0 << 3)
+/* block all write function */
+#define RT_IO_BLK_ALL		(1 << 3)
+/* block cache write function */
+#define RT_IO_BLK_CACHE		(2 << 3)
+/* block chip write function */
+#define RT_IO_BLK_CHIP		(3 << 3)
+
+#define DBG_MODE_MASK	(0x20)
+/* create general debugfs for register map */
+#define RT_DBG_GENERAL	(0 << 5)
+/* create node for each regisetr map by register address*/
+#define RT_DBG_SPECIAL	(1 << 5)
+
+
+/* struct rt_register
+ *
+ * Ricktek register map structure for store mapping data
+ * @addr: register address.
+ * @name: register name.
+ * @size: register byte size.
+ * @reg_type: register R/W type ( RT_NORMAL, RT_WBITS, RT_VOLATILE, RT_RESERVE)
+ * @wbit_mask: register writeable bits mask;
+ * @cache_data: cache data for store cache value.
+ */
+struct rt_register {
+	u32 addr;
+	const char *name;
+	unsigned int size;
+	unsigned char reg_type;
+	unsigned char *wbit_mask;
+	unsigned char *cache_data;
+};
+
+/* Declare a rt_register by RT_REG_DECL
+ * @_addr: regisetr address.
+ * @_reg_length: register data length.
+ * @_reg_type: register type (rt_reg_type).
+ * @_mask: register writealbe mask.
+ */
+#define RT_REG_DECL(_addr, _reg_length, _reg_type, _mask_...)	\
+	static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\
+	static struct rt_register rt_register_##_addr = {	\
+		.addr = _addr, \
+		.size = _reg_length,\
+		.reg_type = _reg_type,\
+		.wbit_mask = rt_writable_mask_##_addr,\
+	}
+
+/* Declare a rt_register by RT_NAMED_REG_DECL
+ * @_name: a name for a rt_register.
+ */
+#define RT_NAMED_REG_DECL(_addr, _name, _reg_length, _reg_type, _mask_...) \
+	static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\
+	static struct rt_register rt_register_##_addr = {	\
+		.addr = _addr, \
+		.name = _name, \
+		.size = _reg_length,\
+		.reg_type = _reg_type,\
+		.wbit_mask = rt_writable_mask_##_addr,\
+	}
+
+#define RT_REG(_addr) (&rt_register_##_addr)
+
+/* rt_regmap_properties
+ * @name: the name of debug node.
+ * @aliases: alisis name of rt_regmap_device.
+ * @register_num: the number of rt_register_map registers.
+ * @rm: rt_regiseter_map pointer array.
+ * @group: register map access group.
+ * @rt_format: default is little endian.
+ * @rt_regmap_mode: rt_regmap_device mode.
+ * @io_log_en: enable/disable io log
+ */
+struct rt_regmap_properties {
+	const char *name;
+	const char *aliases;
+	int register_num;
+	struct rt_register **rm;
+	struct rt_access_group *group;
+	enum rt_data_format rt_format;
+	unsigned char rt_regmap_mode;
+	unsigned char io_log_en:1;
+};
+
+/* A passing struct for rt_regmap_reg_read and rt_regmap_reg_write function
+ * reg: regmap addr.
+ * mask: mask for update bits.
+ * rt_data: register value.
+ */
+struct rt_reg_data {
+	u32 reg;
+	u32 mask;
+	union {
+		u32 data_u32;
+		u16 data_u16;
+		u8 data_u8;
+		u8 data[4];
+	} rt_data;
+};
+
+struct rt_regmap_device;
+
+struct rt_debug_st {
+	void *info;
+	int id;
+};
+
+/* basic chip read/write function */
+struct rt_regmap_fops {
+	int (*read_device)(void *client, u32 addr, int leng, void *dst);
+	int (*write_device)(void *client, u32 addr, int leng, const void *src);
+};
+
+/* with slave address */
+extern struct rt_regmap_device*
+	rt_regmap_device_register_ex(struct rt_regmap_properties *props,
+				struct rt_regmap_fops *rops,
+				struct device *parent,
+				void *client, int slv_addr, void *drvdata);
+
+static inline struct rt_regmap_device*
+	rt_regmap_device_register(struct rt_regmap_properties *props,
+				struct rt_regmap_fops *rops,
+				struct device *parent,
+				struct i2c_client *client, void *drvdata)
+{
+	return rt_regmap_device_register_ex(props, rops, parent,
+		client, client->addr, drvdata);
+}
+
+extern void rt_regmap_device_unregister(struct rt_regmap_device *rd);
+
+extern int rt_regmap_cache_init(struct rt_regmap_device *rd);
+
+extern int rt_regmap_cache_reload(struct rt_regmap_device *rd);
+
+extern int rt_regmap_block_write(struct rt_regmap_device *rd, u32 reg,
+					int bytes, const void *rc);
+extern int rt_asyn_regmap_block_write(struct rt_regmap_device *rd, u32 reg,
+					int bytes, const void *rc);
+extern int rt_regmap_block_read(struct rt_regmap_device *rd, u32 reg,
+					int bytes, void *dst);
+
+extern int _rt_regmap_reg_read(struct rt_regmap_device *rd,
+					struct rt_reg_data *rrd);
+extern int _rt_regmap_reg_write(struct rt_regmap_device *rd,
+					struct rt_reg_data *rrd);
+extern int _rt_asyn_regmap_reg_write(struct rt_regmap_device *rd,
+					struct rt_reg_data *rrd);
+extern int _rt_regmap_update_bits(struct rt_regmap_device *rd,
+					struct rt_reg_data *rrd);
+
+static inline int rt_regmap_reg_read(struct rt_regmap_device *rd,
+					struct rt_reg_data *rrd, u32 reg)
+{
+	rrd->reg = reg;
+	return _rt_regmap_reg_read(rd, rrd);
+};
+
+static inline int rt_regmap_reg_write(struct rt_regmap_device *rd,
+			struct rt_reg_data *rrd, u32 reg, const u32 data)
+{
+	rrd->reg = reg;
+	rrd->rt_data.data_u32 = data;
+	return _rt_regmap_reg_write(rd, rrd);
+};
+
+static inline int rt_asyn_regmap_reg_write(struct rt_regmap_device *rd,
+			struct rt_reg_data *rrd, u32 reg, const u32 data)
+{
+	rrd->reg = reg;
+	rrd->rt_data.data_u32 = data;
+	return _rt_asyn_regmap_reg_write(rd, rrd);
+};
+
+static inline int rt_regmap_update_bits(struct rt_regmap_device *rd,
+			struct rt_reg_data *rrd, u32 reg, u32 mask, u32 data)
+{
+	rrd->reg = reg;
+	rrd->mask = mask;
+	rrd->rt_data.data_u32 = data;
+	return _rt_regmap_update_bits(rd, rrd);
+}
+
+extern void rt_regmap_cache_backup(struct rt_regmap_device *rd);
+
+extern void rt_regmap_cache_sync(struct rt_regmap_device *rd);
+extern void rt_regmap_cache_write_back(struct rt_regmap_device *rd, u32 reg);
+
+extern int rt_is_reg_readable(struct rt_regmap_device *rd, u32 reg);
+extern int rt_is_reg_volatile(struct rt_regmap_device *rd, u32 reg);
+extern int rt_get_regsize(struct rt_regmap_device *rd, u32 reg);
+extern void rt_cache_getlasterror(struct rt_regmap_device *rd, char *buf);
+extern void rt_cache_clrlasterror(struct rt_regmap_device *rd);
+
+extern int rt_regmap_add_debugfs(struct rt_regmap_device *rd, const char *name,
+		umode_t mode, void *data, const struct file_operations *fops);
+
+#define to_rt_regmap_device(obj) container_of(obj, struct rt_regmap_device, dev)
+
+#endif /*MISC_MEDIATEK_RT_REGMAP_H*/
diff --git a/drivers/misc/mediatek/include/mt-plat/sync_write.h b/drivers/misc/mediatek/include/mt-plat/sync_write.h
new file mode 100644
index 0000000000000..f9e5fe4c23e17
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/sync_write.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MT_SYNC_WRITE_H
+#define _MT_SYNC_WRITE_H
+
+#if defined(__KERNEL__)
+
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Define macros.
+ */
+#define mt_reg_sync_writel(v, a) \
+	do {    \
+		__raw_writel((v), (void __force __iomem *)((a)));   \
+		mb();  \
+	} while (0)
+
+#define mt_reg_sync_writew(v, a) \
+	do {    \
+		__raw_writew((v), (void __force __iomem *)((a)));   \
+		mb();  \
+	} while (0)
+
+#define mt_reg_sync_writeb(v, a) \
+	do {    \
+		__raw_writeb((v), (void __force __iomem *)((a)));   \
+		mb();  \
+	} while (0)
+
+#ifdef CONFIG_64BIT
+#define mt_reg_sync_writeq(v, a) \
+	do {    \
+		__raw_writeq((v), (void __force __iomem *)((a)));   \
+		mb();  \
+	} while (0)
+#endif
+
+#else				/* __KERNEL__ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#define mt_reg_sync_writel(v, a)        mt65xx_reg_sync_writel(v, a)
+#define mt_reg_sync_writew(v, a)        mt65xx_reg_sync_writew(v, a)
+#define mt_reg_sync_writeb(v, a)        mt65xx_reg_sync_writeb(v, a)
+
+#define mb()   \
+	{    \
+		__asm__ __volatile__ ("dsb" : : : "memory"); \
+	}
+
+#define mt65xx_reg_sync_writel(v, a) \
+	do {    \
+		*(volatile unsigned int *)(a) = (v);    \
+		mb(); \
+	} while (0)
+
+#define mt65xx_reg_sync_writew(v, a) \
+	do {    \
+		*(volatile unsigned short *)(a) = (v);    \
+		mb(); \
+	} while (0)
+
+#define mt65xx_reg_sync_writeb(v, a) \
+	do {    \
+		*(volatile unsigned char *)(a) = (v);    \
+		mb(); \
+	} while (0)
+
+#endif				/* __KERNEL__ */
+
+#endif				/* !_MT_SYNC_WRITE_H */
diff --git a/drivers/misc/mediatek/include/mt-plat/wakelock.h b/drivers/misc/mediatek/include/mt-plat/wakelock.h
new file mode 100644
index 0000000000000..f4a698a228803
--- /dev/null
+++ b/drivers/misc/mediatek/include/mt-plat/wakelock.h
@@ -0,0 +1,67 @@
+/* include/linux/wakelock.h
+ *
+ * Copyright (C) 2007-2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_WAKELOCK_H
+#define _LINUX_WAKELOCK_H
+
+#include <linux/ktime.h>
+#include <linux/device.h>
+
+/* A wake_lock prevents the system from entering suspend or other low power
+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
+ * prevents a full system suspend.
+ */
+
+enum {
+	WAKE_LOCK_SUSPEND, /* Prevent suspend */
+	WAKE_LOCK_TYPE_COUNT
+};
+
+struct wake_lock {
+	struct wakeup_source ws;
+};
+
+static inline void wake_lock_init(struct wake_lock *lock, int type,
+				  const char *name)
+{
+	wakeup_source_init(&lock->ws, name);
+}
+
+static inline void wake_lock_destroy(struct wake_lock *lock)
+{
+	wakeup_source_trash(&lock->ws);
+}
+
+static inline void wake_lock(struct wake_lock *lock)
+{
+	__pm_stay_awake(&lock->ws);
+}
+
+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout)
+{
+	__pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout));
+}
+
+static inline void wake_unlock(struct wake_lock *lock)
+{
+	__pm_relax(&lock->ws);
+}
+
+static inline int wake_lock_active(struct wake_lock *lock)
+{
+	return lock->ws.active;
+}
+
+#endif
